test(napi): add more object functions tests
This commit is contained in:
parent
76d1258592
commit
1c3d9b4e9a
15 changed files with 705 additions and 107 deletions
|
@ -16,8 +16,7 @@ impl<T: Task> AsyncWork<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn run(env: sys::napi_env, task: T, deferred: sys::napi_deferred) -> Result<()> {
|
pub fn run(env: sys::napi_env, task: T, deferred: sys::napi_deferred) -> Result<()> {
|
||||||
let mut raw_resource = ptr::null_mut();
|
let mut raw_resource = ptr::null_mut();
|
||||||
let status = unsafe { sys::napi_create_object(env, &mut raw_resource) };
|
check_status(unsafe { sys::napi_create_object(env, &mut raw_resource) })?;
|
||||||
check_status(status)?;
|
|
||||||
let mut raw_name = ptr::null_mut();
|
let mut raw_name = ptr::null_mut();
|
||||||
let s = "napi_rs_async";
|
let s = "napi_rs_async";
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
|
|
|
@ -379,13 +379,13 @@ impl Env {
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
constructor_cb: Callback,
|
constructor_cb: Callback,
|
||||||
properties: &mut [Property],
|
properties: &[Property],
|
||||||
) -> Result<JsFunction> {
|
) -> Result<JsFunction> {
|
||||||
let mut raw_result = ptr::null_mut();
|
let mut raw_result = ptr::null_mut();
|
||||||
let raw_properties = properties
|
let raw_properties = properties
|
||||||
.iter_mut()
|
.iter()
|
||||||
.map(|prop| prop.as_raw(self.0))
|
.map(|prop| prop.raw())
|
||||||
.collect::<Result<Vec<sys::napi_property_descriptor>>>()?;
|
.collect::<Vec<sys::napi_property_descriptor>>();
|
||||||
|
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
sys::napi_define_class(
|
sys::napi_define_class(
|
||||||
|
@ -541,9 +541,9 @@ impl Env {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_napi_version(&self) -> Result<u32> {
|
pub fn get_napi_version(&self) -> Result<u32> {
|
||||||
let global = self.get_global()?;
|
let global = self.get_global()?;
|
||||||
let process = global.get_named_property::<JsObject>("process")?;
|
let process: JsObject = global.get_named_property("process")?;
|
||||||
let versions = process.get_named_property::<JsObject>("versions")?;
|
let versions: JsObject = process.get_named_property("versions")?;
|
||||||
let napi_version = versions.get_named_property::<JsString>("napi")?;
|
let napi_version: JsString = versions.get_named_property("napi")?;
|
||||||
napi_version
|
napi_version
|
||||||
.as_str()?
|
.as_str()?
|
||||||
.parse()
|
.parse()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use super::{JsObject, JsUnknown, NapiValue, Value, ValueType};
|
use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Value, ValueType};
|
||||||
use crate::error::check_status;
|
use crate::error::check_status;
|
||||||
use crate::{sys, Error, Result};
|
use crate::{sys, Error, Result};
|
||||||
|
|
||||||
|
@ -24,6 +24,114 @@ impl JsArrayBuffer {
|
||||||
len: 0,
|
len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||||
|
JsUnknown::from_raw(self.value.0.env, self.value.0.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_number(self) -> Result<JsNumber> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_number(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsNumber(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::Number,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_string(self) -> Result<JsString> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_string(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsString(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::String,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_object(self) -> Result<JsObject> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_object(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsObject(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::Object,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(napi5)]
|
||||||
|
pub fn is_date(&self) -> Result<bool> {
|
||||||
|
let mut is_date = true;
|
||||||
|
check_status(unsafe { sys::napi_is_date(self.value.0.env, self.value.0.value, &mut is_date) })?;
|
||||||
|
Ok(is_date)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_error(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe { sys::napi_is_error(self.value.0.env, self.value.0.value, &mut result) })?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_typedarray(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_typedarray(self.value.0.env, self.value.0.value, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_dataview(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_dataview(self.value.0.env, self.value.0.value, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_array(&self) -> Result<bool> {
|
||||||
|
let mut is_array = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_array(self.value.0.env, self.value.0.value, &mut is_array)
|
||||||
|
})?;
|
||||||
|
Ok(is_array)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_buffer(&self) -> Result<bool> {
|
||||||
|
let mut is_buffer = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_buffer(self.value.0.env, self.value.0.value, &mut is_buffer)
|
||||||
|
})?;
|
||||||
|
Ok(is_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_instanceof(
|
||||||
|
self.value.0.env,
|
||||||
|
self.value.0.value,
|
||||||
|
constructor.raw_value(),
|
||||||
|
&mut result,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NapiValue for JsArrayBuffer {
|
impl NapiValue for JsArrayBuffer {
|
||||||
|
@ -34,8 +142,7 @@ impl NapiValue for JsArrayBuffer {
|
||||||
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
|
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
|
||||||
let mut data = ptr::null_mut();
|
let mut data = ptr::null_mut();
|
||||||
let mut len: u64 = 0;
|
let mut len: u64 = 0;
|
||||||
let status = unsafe { sys::napi_get_arraybuffer_info(env, value, &mut data, &mut len) };
|
check_status(unsafe { sys::napi_get_arraybuffer_info(env, value, &mut data, &mut len) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(JsArrayBuffer {
|
Ok(JsArrayBuffer {
|
||||||
value: JsObject(Value {
|
value: JsObject(Value {
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -35,9 +35,9 @@ impl JsBigint {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coerce_to_number(self) -> Result<JsNumber> {
|
pub fn coerce_to_number(self) -> Result<JsNumber> {
|
||||||
let mut new_raw_value = ptr::null_mut();
|
let mut new_raw_value = ptr::null_mut();
|
||||||
let status =
|
check_status(unsafe {
|
||||||
unsafe { sys::napi_coerce_to_number(self.raw.env, self.raw.value, &mut new_raw_value) };
|
sys::napi_coerce_to_number(self.raw.env, self.raw.value, &mut new_raw_value)
|
||||||
check_status(status)?;
|
})?;
|
||||||
Ok(JsNumber(Value {
|
Ok(JsNumber(Value {
|
||||||
env: self.raw.env,
|
env: self.raw.env,
|
||||||
value: new_raw_value,
|
value: new_raw_value,
|
||||||
|
@ -48,9 +48,9 @@ impl JsBigint {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coerce_to_string(self) -> Result<JsString> {
|
pub fn coerce_to_string(self) -> Result<JsString> {
|
||||||
let mut new_raw_value = ptr::null_mut();
|
let mut new_raw_value = ptr::null_mut();
|
||||||
let status =
|
check_status(unsafe {
|
||||||
unsafe { sys::napi_coerce_to_string(self.raw.env, self.raw.value, &mut new_raw_value) };
|
sys::napi_coerce_to_string(self.raw.env, self.raw.value, &mut new_raw_value)
|
||||||
check_status(status)?;
|
})?;
|
||||||
Ok(JsString(Value {
|
Ok(JsString(Value {
|
||||||
env: self.raw.env,
|
env: self.raw.env,
|
||||||
value: new_raw_value,
|
value: new_raw_value,
|
||||||
|
@ -60,9 +60,9 @@ impl JsBigint {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coerce_to_object(self) -> Result<JsObject> {
|
pub fn coerce_to_object(self) -> Result<JsObject> {
|
||||||
let mut new_raw_value = ptr::null_mut();
|
let mut new_raw_value = ptr::null_mut();
|
||||||
let status =
|
check_status(unsafe {
|
||||||
unsafe { sys::napi_coerce_to_object(self.raw.env, self.raw.value, &mut new_raw_value) };
|
sys::napi_coerce_to_object(self.raw.env, self.raw.value, &mut new_raw_value)
|
||||||
check_status(status)?;
|
})?;
|
||||||
Ok(JsObject(Value {
|
Ok(JsObject(Value {
|
||||||
env: self.raw.env,
|
env: self.raw.env,
|
||||||
value: new_raw_value,
|
value: new_raw_value,
|
||||||
|
@ -74,8 +74,7 @@ impl JsBigint {
|
||||||
#[cfg(napi5)]
|
#[cfg(napi5)]
|
||||||
pub fn is_date(&self) -> Result<bool> {
|
pub fn is_date(&self) -> Result<bool> {
|
||||||
let mut is_date = true;
|
let mut is_date = true;
|
||||||
let status = unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) };
|
check_status(unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(is_date)
|
Ok(is_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +99,20 @@ impl JsBigint {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_array(&self) -> Result<bool> {
|
||||||
|
let mut is_array = false;
|
||||||
|
check_status(unsafe { sys::napi_is_array(self.raw.env, self.raw.value, &mut is_array) })?;
|
||||||
|
Ok(is_array)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_buffer(&self) -> Result<bool> {
|
||||||
|
let mut is_buffer = false;
|
||||||
|
check_status(unsafe { sys::napi_is_buffer(self.raw.env, self.raw.value, &mut is_buffer) })?;
|
||||||
|
Ok(is_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::ops::Deref;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
use super::{JsObject, JsUnknown, NapiValue, Value, ValueType};
|
use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Value, ValueType};
|
||||||
use crate::error::check_status;
|
use crate::error::check_status;
|
||||||
use crate::{sys, Error, Result};
|
use crate::{sys, Error, Result};
|
||||||
|
|
||||||
|
@ -30,8 +30,112 @@ impl JsBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn into_unknown(self) -> Result<JsUnknown> {
|
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||||
self.value.into_unknown()
|
JsUnknown::from_raw(self.value.0.env, self.value.0.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_number(self) -> Result<JsNumber> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_number(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsNumber(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::Number,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_string(self) -> Result<JsString> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_string(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsString(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::String,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn coerce_to_object(self) -> Result<JsObject> {
|
||||||
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_coerce_to_object(self.value.0.env, self.value.0.value, &mut new_raw_value)
|
||||||
|
})?;
|
||||||
|
Ok(JsObject(Value {
|
||||||
|
env: self.value.0.env,
|
||||||
|
value: new_raw_value,
|
||||||
|
value_type: ValueType::Object,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(napi5)]
|
||||||
|
pub fn is_date(&self) -> Result<bool> {
|
||||||
|
let mut is_date = true;
|
||||||
|
check_status(unsafe { sys::napi_is_date(self.value.0.env, self.value.0.value, &mut is_date) })?;
|
||||||
|
Ok(is_date)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_error(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe { sys::napi_is_error(self.value.0.env, self.value.0.value, &mut result) })?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_typedarray(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_typedarray(self.value.0.env, self.value.0.value, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_dataview(&self) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_dataview(self.value.0.env, self.value.0.value, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_array(&self) -> Result<bool> {
|
||||||
|
let mut is_array = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_array(self.value.0.env, self.value.0.value, &mut is_array)
|
||||||
|
})?;
|
||||||
|
Ok(is_array)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_buffer(&self) -> Result<bool> {
|
||||||
|
let mut is_buffer = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_is_buffer(self.value.0.env, self.value.0.value, &mut is_buffer)
|
||||||
|
})?;
|
||||||
|
Ok(is_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_instanceof(
|
||||||
|
self.value.0.env,
|
||||||
|
self.value.0.value,
|
||||||
|
constructor.raw_value(),
|
||||||
|
&mut result,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@ mod arraybuffer;
|
||||||
mod bigint;
|
mod bigint;
|
||||||
mod boolean;
|
mod boolean;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod class_property;
|
|
||||||
mod either;
|
mod either;
|
||||||
mod function;
|
mod function;
|
||||||
mod number;
|
mod number;
|
||||||
mod object;
|
mod object;
|
||||||
|
mod object_property;
|
||||||
mod string;
|
mod string;
|
||||||
mod tagged_object;
|
mod tagged_object;
|
||||||
mod undefined;
|
mod undefined;
|
||||||
|
@ -31,13 +31,13 @@ pub use arraybuffer::JsArrayBuffer;
|
||||||
pub use bigint::JsBigint;
|
pub use bigint::JsBigint;
|
||||||
pub use boolean::JsBoolean;
|
pub use boolean::JsBoolean;
|
||||||
pub use buffer::JsBuffer;
|
pub use buffer::JsBuffer;
|
||||||
pub use class_property::Property;
|
|
||||||
#[cfg(feature = "serde-json")]
|
#[cfg(feature = "serde-json")]
|
||||||
pub(crate) use de::De;
|
pub(crate) use de::De;
|
||||||
pub use either::Either;
|
pub use either::Either;
|
||||||
pub use function::JsFunction;
|
pub use function::JsFunction;
|
||||||
pub use number::JsNumber;
|
pub use number::JsNumber;
|
||||||
pub use object::JsObject;
|
pub use object::JsObject;
|
||||||
|
pub use object_property::Property;
|
||||||
#[cfg(feature = "serde-json")]
|
#[cfg(feature = "serde-json")]
|
||||||
pub(crate) use ser::Ser;
|
pub(crate) use ser::Ser;
|
||||||
pub use string::JsString;
|
pub use string::JsString;
|
||||||
|
@ -145,6 +145,7 @@ macro_rules! impl_js_value_methods {
|
||||||
value_type: ValueType::String,
|
value_type: ValueType::String,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coerce_to_object(self) -> Result<JsObject> {
|
pub fn coerce_to_object(self) -> Result<JsObject> {
|
||||||
let mut new_raw_value = ptr::null_mut();
|
let mut new_raw_value = ptr::null_mut();
|
||||||
|
@ -188,6 +189,20 @@ macro_rules! impl_js_value_methods {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_array(&self) -> Result<bool> {
|
||||||
|
let mut is_array = false;
|
||||||
|
check_status(unsafe { sys::napi_is_array(self.0.env, self.0.value, &mut is_array) })?;
|
||||||
|
Ok(is_array)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_buffer(&self) -> Result<bool> {
|
||||||
|
let mut is_buffer = false;
|
||||||
|
check_status(unsafe { sys::napi_is_buffer(self.0.env, self.0.value, &mut is_buffer) })?;
|
||||||
|
Ok(is_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
|
|
|
@ -12,8 +12,7 @@ impl TryFrom<JsNumber> for usize {
|
||||||
|
|
||||||
fn try_from(value: JsNumber) -> Result<usize> {
|
fn try_from(value: JsNumber) -> Result<usize> {
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
let status = unsafe { sys::napi_get_value_int64(value.0.env, value.0.value, &mut result) };
|
check_status(unsafe { sys::napi_get_value_int64(value.0.env, value.0.value, &mut result) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +22,7 @@ impl TryFrom<JsNumber> for u32 {
|
||||||
|
|
||||||
fn try_from(value: JsNumber) -> Result<u32> {
|
fn try_from(value: JsNumber) -> Result<u32> {
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
let status = unsafe { sys::napi_get_value_uint32(value.0.env, value.0.value, &mut result) };
|
check_status(unsafe { sys::napi_get_value_uint32(value.0.env, value.0.value, &mut result) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +32,7 @@ impl TryFrom<JsNumber> for i32 {
|
||||||
|
|
||||||
fn try_from(value: JsNumber) -> Result<i32> {
|
fn try_from(value: JsNumber) -> Result<i32> {
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
let status = unsafe { sys::napi_get_value_int32(value.0.env, value.0.value, &mut result) };
|
check_status(unsafe { sys::napi_get_value_int32(value.0.env, value.0.value, &mut result) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +42,7 @@ impl TryFrom<JsNumber> for i64 {
|
||||||
|
|
||||||
fn try_from(value: JsNumber) -> Result<i64> {
|
fn try_from(value: JsNumber) -> Result<i64> {
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
let status = unsafe { sys::napi_get_value_int64(value.0.env, value.0.value, &mut result) };
|
check_status(unsafe { sys::napi_get_value_int64(value.0.env, value.0.value, &mut result) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +52,7 @@ impl TryFrom<JsNumber> for f64 {
|
||||||
|
|
||||||
fn try_from(value: JsNumber) -> Result<f64> {
|
fn try_from(value: JsNumber) -> Result<f64> {
|
||||||
let mut result = 0_f64;
|
let mut result = 0_f64;
|
||||||
let status = unsafe { sys::napi_get_value_double(value.0.env, value.0.value, &mut result) };
|
check_status(unsafe { sys::napi_get_value_double(value.0.env, value.0.value, &mut result) })?;
|
||||||
check_status(status)?;
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,18 @@ impl JsObject {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_property<K, T>(&self, key: &K) -> Result<T>
|
||||||
|
where
|
||||||
|
K: NapiValue,
|
||||||
|
T: NapiValue,
|
||||||
|
{
|
||||||
|
let mut raw_value = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_get_property(self.0.env, self.0.value, key.raw_value(), &mut raw_value)
|
||||||
|
})?;
|
||||||
|
T::from_raw(self.0.env, raw_value)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_named_property<T>(&mut self, name: &str, value: T) -> Result<()>
|
pub fn set_named_property<T>(&mut self, name: &str, value: T) -> Result<()>
|
||||||
where
|
where
|
||||||
T: NapiValue,
|
T: NapiValue,
|
||||||
|
@ -40,15 +52,42 @@ impl JsObject {
|
||||||
T::from_raw(self.0.env, raw_value)
|
T::from_raw(self.0.env, raw_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_named_property(&self, name: &str) -> Result<bool> {
|
pub fn has_named_property<S>(&self, name: S) -> Result<bool>
|
||||||
|
where
|
||||||
|
S: AsRef<str>,
|
||||||
|
{
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
let key = CString::new(name)?;
|
let key = CString::new(name.as_ref())?;
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result)
|
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result)
|
||||||
})?;
|
})?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_property<S>(&mut self, name: S) -> Result<bool>
|
||||||
|
where
|
||||||
|
S: NapiValue,
|
||||||
|
{
|
||||||
|
let mut result = false;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_delete_property(self.0.env, self.0.value, name.raw_value(), &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_named_property(&mut self, name: &str) -> Result<bool> {
|
||||||
|
let mut result = false;
|
||||||
|
let key_str = CString::new(name)?;
|
||||||
|
let mut js_key = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_create_string_utf8(self.0.env, key_str.as_ptr(), name.len() as _, &mut js_key)
|
||||||
|
})?;
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_delete_property(self.0.env, self.0.value, js_key, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_own_property(&self, key: &str) -> Result<bool> {
|
pub fn has_own_property(&self, key: &str) -> Result<bool> {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
let string = CString::new(key)?;
|
let string = CString::new(key)?;
|
||||||
|
@ -95,18 +134,6 @@ impl JsObject {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_property<K, T>(&self, key: &K) -> Result<T>
|
|
||||||
where
|
|
||||||
K: NapiValue,
|
|
||||||
T: NapiValue,
|
|
||||||
{
|
|
||||||
let mut raw_value = ptr::null_mut();
|
|
||||||
check_status(unsafe {
|
|
||||||
sys::napi_get_property(self.0.env, self.0.value, key.raw_value(), &mut raw_value)
|
|
||||||
})?;
|
|
||||||
T::from_raw(self.0.env, raw_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_property_names<T>(&self) -> Result<T>
|
pub fn get_property_names<T>(&self) -> Result<T>
|
||||||
where
|
where
|
||||||
T: NapiValue,
|
T: NapiValue,
|
||||||
|
@ -141,7 +168,7 @@ impl JsObject {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_element<T>(&mut self, index: u32) -> Result<bool> {
|
pub fn delete_element(&mut self, index: u32) -> Result<bool> {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
sys::napi_delete_element(self.0.env, self.0.value, index, &mut result)
|
sys::napi_delete_element(self.0.env, self.0.value, index, &mut result)
|
||||||
|
@ -160,33 +187,21 @@ impl JsObject {
|
||||||
T::from_raw(self.0.env, raw_value)
|
T::from_raw(self.0.env, raw_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define_properties(&mut self, properties: &mut [Property]) -> Result<()> {
|
pub fn define_properties(&mut self, properties: &[Property]) -> Result<()> {
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
sys::napi_define_properties(
|
sys::napi_define_properties(
|
||||||
self.0.env,
|
self.0.env,
|
||||||
self.0.value,
|
self.0.value,
|
||||||
properties.len() as _,
|
properties.len() as _,
|
||||||
properties
|
properties
|
||||||
.iter_mut()
|
.iter()
|
||||||
.map(|property| property.as_raw(self.0.env))
|
.map(|property| property.raw())
|
||||||
.collect::<Result<Vec<sys::napi_property_descriptor>>>()?
|
.collect::<Vec<sys::napi_property_descriptor>>()
|
||||||
.as_ptr(),
|
.as_ptr(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_array(&self) -> Result<bool> {
|
|
||||||
let mut is_array = false;
|
|
||||||
check_status(unsafe { sys::napi_is_array(self.0.env, self.0.value, &mut is_array) })?;
|
|
||||||
Ok(is_array)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_buffer(&self) -> Result<bool> {
|
|
||||||
let mut is_buffer = false;
|
|
||||||
check_status(unsafe { sys::napi_is_buffer(self.0.env, self.0.value, &mut is_buffer) })?;
|
|
||||||
Ok(is_buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_array_length(&self) -> Result<u32> {
|
pub fn get_array_length(&self) -> Result<u32> {
|
||||||
if self.is_array()? != true {
|
if self.is_array()? != true {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::convert::From;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use crate::{error::check_status, sys, Callback, NapiValue, Result};
|
use crate::{error::check_status, sys, Callback, Env, NapiValue, Result};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Property<'env> {
|
pub struct Property<'env> {
|
||||||
|
@ -33,12 +33,17 @@ impl From<PropertyAttributes> for sys::napi_property_attributes {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'env> Property<'env> {
|
impl<'env> Property<'env> {
|
||||||
pub fn new(name: &'env str) -> Self {
|
pub fn new(env: &'env Env, name: &'env str) -> Result<Self> {
|
||||||
Property {
|
let string_value = CString::new(name)?;
|
||||||
|
let mut result = ptr::null_mut();
|
||||||
|
check_status(unsafe {
|
||||||
|
sys::napi_create_string_utf8(env.0, string_value.as_ptr(), name.len() as _, &mut result)
|
||||||
|
})?;
|
||||||
|
Ok(Property {
|
||||||
name,
|
name,
|
||||||
raw_descriptor: sys::napi_property_descriptor {
|
raw_descriptor: sys::napi_property_descriptor {
|
||||||
utf8name: ptr::null_mut(),
|
utf8name: ptr::null_mut(),
|
||||||
name: ptr::null_mut(),
|
name: result,
|
||||||
method: None,
|
method: None,
|
||||||
getter: None,
|
getter: None,
|
||||||
setter: None,
|
setter: None,
|
||||||
|
@ -46,7 +51,7 @@ impl<'env> Property<'env> {
|
||||||
attributes: sys::napi_property_attributes::napi_default,
|
attributes: sys::napi_property_attributes::napi_default,
|
||||||
data: ptr::null_mut(),
|
data: ptr::null_mut(),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_value<T: NapiValue>(mut self, value: T) -> Self {
|
pub fn with_value<T: NapiValue>(mut self, value: T) -> Self {
|
||||||
|
@ -73,18 +78,7 @@ impl<'env> Property<'env> {
|
||||||
self.raw_descriptor.attributes = attributes.into();
|
self.raw_descriptor.attributes = attributes.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_raw(&mut self, env: sys::napi_env) -> Result<sys::napi_property_descriptor> {
|
pub(crate) fn raw(&self) -> sys::napi_property_descriptor {
|
||||||
let string_value = CString::new(self.name)?;
|
self.raw_descriptor
|
||||||
let mut result = ptr::null_mut();
|
|
||||||
check_status(unsafe {
|
|
||||||
sys::napi_create_string_utf8(
|
|
||||||
env,
|
|
||||||
string_value.as_ptr(),
|
|
||||||
self.name.len() as _,
|
|
||||||
&mut result,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
self.raw_descriptor.name = result;
|
|
||||||
Ok(self.raw_descriptor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,15 +29,13 @@ impl JsString {
|
||||||
let len = self.len()? + 1;
|
let len = self.len()? + 1;
|
||||||
let mut result = Vec::with_capacity(len);
|
let mut result = Vec::with_capacity(len);
|
||||||
unsafe {
|
unsafe {
|
||||||
let status = sys::napi_get_value_string_utf8(
|
check_status(sys::napi_get_value_string_utf8(
|
||||||
self.0.env,
|
self.0.env,
|
||||||
self.0.value,
|
self.0.value,
|
||||||
result.as_mut_ptr(),
|
result.as_mut_ptr(),
|
||||||
len as u64,
|
len as u64,
|
||||||
&mut written_char_count,
|
&mut written_char_count,
|
||||||
);
|
))?;
|
||||||
|
|
||||||
check_status(status)?;
|
|
||||||
let ptr = result.as_ptr();
|
let ptr = result.as_ptr();
|
||||||
mem::forget(result);
|
mem::forget(result);
|
||||||
Ok(slice::from_raw_parts(
|
Ok(slice::from_raw_parts(
|
||||||
|
@ -53,15 +51,14 @@ impl JsString {
|
||||||
let len = self.len()? + 1;
|
let len = self.len()? + 1;
|
||||||
let mut result = Vec::with_capacity(len);
|
let mut result = Vec::with_capacity(len);
|
||||||
unsafe {
|
unsafe {
|
||||||
let status = sys::napi_get_value_string_utf8(
|
check_status(sys::napi_get_value_string_utf8(
|
||||||
self.0.env,
|
self.0.env,
|
||||||
self.0.value,
|
self.0.value,
|
||||||
result.as_mut_ptr(),
|
result.as_mut_ptr(),
|
||||||
len as u64,
|
len as u64,
|
||||||
&mut written_char_count,
|
&mut written_char_count,
|
||||||
);
|
))?;
|
||||||
|
|
||||||
check_status(status)?;
|
|
||||||
let ptr = result.as_ptr();
|
let ptr = result.as_ptr();
|
||||||
mem::forget(result);
|
mem::forget(result);
|
||||||
Ok(slice::from_raw_parts(
|
Ok(slice::from_raw_parts(
|
||||||
|
@ -81,15 +78,14 @@ impl JsString {
|
||||||
let len = self.len()? + 1;
|
let len = self.len()? + 1;
|
||||||
let mut result = Vec::with_capacity(len);
|
let mut result = Vec::with_capacity(len);
|
||||||
unsafe {
|
unsafe {
|
||||||
let status = sys::napi_get_value_string_utf8(
|
check_status(sys::napi_get_value_string_utf8(
|
||||||
self.0.env,
|
self.0.env,
|
||||||
self.0.value,
|
self.0.value,
|
||||||
result.as_mut_ptr(),
|
result.as_mut_ptr(),
|
||||||
len as u64,
|
len as u64,
|
||||||
&mut written_char_count,
|
&mut written_char_count,
|
||||||
);
|
))?;
|
||||||
|
|
||||||
check_status(status)?;
|
|
||||||
let ptr = result.as_ptr();
|
let ptr = result.as_ptr();
|
||||||
mem::forget(result);
|
mem::forget(result);
|
||||||
Ok(slice::from_raw_parts_mut(
|
Ok(slice::from_raw_parts_mut(
|
||||||
|
@ -108,14 +104,13 @@ impl TryFrom<JsString> for Vec<u16> {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut written_char_count = 0;
|
let mut written_char_count = 0;
|
||||||
let status = sys::napi_get_value_string_utf16(
|
check_status(sys::napi_get_value_string_utf16(
|
||||||
value.0.env,
|
value.0.env,
|
||||||
value.0.value,
|
value.0.value,
|
||||||
result.as_mut_ptr(),
|
result.as_mut_ptr(),
|
||||||
result.capacity() as u64,
|
result.capacity() as u64,
|
||||||
&mut written_char_count,
|
&mut written_char_count,
|
||||||
);
|
))?;
|
||||||
check_status(status)?;
|
|
||||||
result.set_len(written_char_count as usize);
|
result.set_len(written_char_count as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,15 @@ test('setProperty', (t) => {
|
||||||
t.snapshot(obj[key])
|
t.snapshot(obj[key])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('testGetProperty', (t) => {
|
||||||
|
const name = Symbol('JsSymbol')
|
||||||
|
const value = Symbol('JsValue')
|
||||||
|
const obj = {
|
||||||
|
[name]: value,
|
||||||
|
}
|
||||||
|
t.is(bindings.testGetProperty(obj, name), value)
|
||||||
|
})
|
||||||
|
|
||||||
test('setNamedProperty', (t) => {
|
test('setNamedProperty', (t) => {
|
||||||
const obj = {}
|
const obj = {}
|
||||||
const property = Symbol('JsSymbol')
|
const property = Symbol('JsSymbol')
|
||||||
|
@ -37,3 +46,181 @@ test('testHasNamedProperty', (t) => {
|
||||||
t.true(bindings.testHasNamedProperty(obj, 'b'))
|
t.true(bindings.testHasNamedProperty(obj, 'b'))
|
||||||
t.false(bindings.testHasNamedProperty(obj, 'c'))
|
t.false(bindings.testHasNamedProperty(obj, 'c'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('testHasOwnProperty', (t) => {
|
||||||
|
const obj = {
|
||||||
|
a: '1',
|
||||||
|
b: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = Object.create(obj, {
|
||||||
|
d: {
|
||||||
|
value: 1,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
t.false(bindings.testHasOwnProperty(child, 'a'))
|
||||||
|
t.false(bindings.testHasOwnProperty(child, 'b'))
|
||||||
|
t.true(bindings.testHasOwnProperty(child, 'd'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testHasOwnPropertyJs', (t) => {
|
||||||
|
const obj = {
|
||||||
|
a: '1',
|
||||||
|
b: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = Object.create(obj)
|
||||||
|
|
||||||
|
child.c = 'k1'
|
||||||
|
|
||||||
|
t.false(bindings.testHasOwnPropertyJs(child, 'a'))
|
||||||
|
t.false(bindings.testHasOwnPropertyJs(child, 'b'))
|
||||||
|
t.true(bindings.testHasOwnPropertyJs(child, 'c'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testHasProperty', (t) => {
|
||||||
|
const obj = {
|
||||||
|
a: '1',
|
||||||
|
b: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = Object.create(obj)
|
||||||
|
|
||||||
|
child.c = 'k1'
|
||||||
|
|
||||||
|
t.true(bindings.testHasProperty(child, 'a'))
|
||||||
|
t.true(bindings.testHasProperty(child, 'b'))
|
||||||
|
t.true(bindings.testHasProperty(child, 'c'))
|
||||||
|
t.false(bindings.testHasProperty(child, '__NOT_EXISTED__'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testHasPropertJs', (t) => {
|
||||||
|
const key = Symbol('JsString')
|
||||||
|
const obj = {
|
||||||
|
[key]: 1,
|
||||||
|
a: 0,
|
||||||
|
b: undefined,
|
||||||
|
2: 'c',
|
||||||
|
}
|
||||||
|
t.true(bindings.testHasPropertyJs(obj, key))
|
||||||
|
t.true(bindings.testHasPropertyJs(obj, 'a'))
|
||||||
|
t.true(bindings.testHasPropertyJs(obj, 'b'))
|
||||||
|
t.true(bindings.testHasPropertyJs(obj, 2))
|
||||||
|
t.false(bindings.testHasPropertyJs(obj, {}))
|
||||||
|
t.false(bindings.testHasPropertyJs(obj, Symbol('JsString')))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testDeleteProperty', (t) => {
|
||||||
|
const k1 = Symbol()
|
||||||
|
const k2 = 2
|
||||||
|
const k3 = 'foo'
|
||||||
|
const obj = {
|
||||||
|
[k1]: 1,
|
||||||
|
[k2]: 2,
|
||||||
|
k4: 4,
|
||||||
|
}
|
||||||
|
Object.defineProperty(obj, k3, {
|
||||||
|
configurable: false,
|
||||||
|
enumerable: true,
|
||||||
|
value: 'k3',
|
||||||
|
})
|
||||||
|
t.true(bindings.testDeleteProperty(obj, k1))
|
||||||
|
t.true(bindings.testDeleteProperty(obj, k2))
|
||||||
|
t.false(bindings.testDeleteProperty(obj, k3))
|
||||||
|
t.true(bindings.testDeleteProperty(obj, 'k4'))
|
||||||
|
t.true(bindings.testDeleteProperty(obj, '__NOT_EXISTED__'))
|
||||||
|
t.true(bindings.testDeleteProperty(obj, k1))
|
||||||
|
// @ts-expect-error
|
||||||
|
t.deepEqual(obj, { [k3]: 'k3' })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testDeleteNamedProperty', (t) => {
|
||||||
|
const k1 = 'k1'
|
||||||
|
const k2 = 'k2'
|
||||||
|
const k3 = 'foo'
|
||||||
|
const obj = {
|
||||||
|
[k1]: 1,
|
||||||
|
[k2]: 2,
|
||||||
|
k4: 4,
|
||||||
|
}
|
||||||
|
Object.defineProperty(obj, k3, {
|
||||||
|
configurable: false,
|
||||||
|
enumerable: true,
|
||||||
|
value: 'k3',
|
||||||
|
})
|
||||||
|
t.true(bindings.testDeleteNamedProperty(obj, k1))
|
||||||
|
t.true(bindings.testDeleteNamedProperty(obj, k2))
|
||||||
|
t.false(bindings.testDeleteNamedProperty(obj, k3))
|
||||||
|
t.true(bindings.testDeleteNamedProperty(obj, 'k4'))
|
||||||
|
t.true(bindings.testDeleteNamedProperty(obj, '__NOT_EXISTED__'))
|
||||||
|
t.true(bindings.testDeleteNamedProperty(obj, k1))
|
||||||
|
// @ts-expect-error
|
||||||
|
t.deepEqual(obj, { [k3]: 'k3' })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testGetPropertyNames', (t) => {
|
||||||
|
const k1 = Symbol()
|
||||||
|
const k2 = 2
|
||||||
|
const k3 = 'k3'
|
||||||
|
const obj = {
|
||||||
|
[k1]: 1,
|
||||||
|
[k2]: 1,
|
||||||
|
[k3]: 1,
|
||||||
|
}
|
||||||
|
t.snapshot(
|
||||||
|
bindings
|
||||||
|
.testGetPropertyNames(obj)
|
||||||
|
.map((v: string | number) => v.toString()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testGetPrototype', (t) => {
|
||||||
|
class A {}
|
||||||
|
class B extends A {}
|
||||||
|
const obj = new B()
|
||||||
|
t.is(bindings.testGetPrototype(obj), Object.getPrototypeOf(obj))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testSetElement', (t) => {
|
||||||
|
const arr: any[] = []
|
||||||
|
bindings.testSetElement(arr, 1, 1)
|
||||||
|
bindings.testSetElement(arr, 5, 'foo')
|
||||||
|
t.snapshot(arr)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testHasElement', (t) => {
|
||||||
|
const arr: number[] = []
|
||||||
|
arr[1] = 1
|
||||||
|
arr[4] = 0
|
||||||
|
t.false(bindings.testHasElement(arr, 0))
|
||||||
|
t.true(bindings.testHasElement(arr, 1))
|
||||||
|
t.false(bindings.testHasElement(arr, 2))
|
||||||
|
t.false(bindings.testHasElement(arr, 3))
|
||||||
|
t.true(bindings.testHasElement(arr, 4))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testGetElement', (t) => {
|
||||||
|
const arr = [Symbol(), Symbol()]
|
||||||
|
t.is(bindings.testGetElement(arr, 0), arr[0])
|
||||||
|
t.is(bindings.testGetElement(arr, 1), arr[1])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testDeleteElement', (t) => {
|
||||||
|
const arr = [0, 1, 2, 3]
|
||||||
|
bindings.testDeleteElement(arr, 1)
|
||||||
|
bindings.testDeleteElement(arr, 2)
|
||||||
|
t.snapshot(arr)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('testDefineProperties', (t) => {
|
||||||
|
const obj: any = {}
|
||||||
|
bindings.testDefineProperties(obj)
|
||||||
|
t.is(obj.count, 0)
|
||||||
|
obj.add(10)
|
||||||
|
t.is(obj.count, 10)
|
||||||
|
const descriptor = Object.getOwnPropertyDescriptor(obj, 'ro')
|
||||||
|
t.is(descriptor?.value ?? descriptor?.get?.(), 'readonly')
|
||||||
|
})
|
||||||
|
|
|
@ -15,3 +15,36 @@ Generated by [AVA](https://avajs.dev).
|
||||||
> Snapshot 1
|
> Snapshot 1
|
||||||
|
|
||||||
'RustPropertyKey'
|
'RustPropertyKey'
|
||||||
|
|
||||||
|
## testGetPropertyNames
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
[
|
||||||
|
'2',
|
||||||
|
'k3',
|
||||||
|
]
|
||||||
|
|
||||||
|
## testSetElement
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
[
|
||||||
|
undefined,
|
||||||
|
1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
'foo',
|
||||||
|
]
|
||||||
|
|
||||||
|
## testDeleteElement
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
3,
|
||||||
|
]
|
||||||
|
|
Binary file not shown.
|
@ -4,13 +4,11 @@ use napi::{CallContext, JsFunction, JsNumber, JsObject, JsUndefined, Module, Pro
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
|
fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
|
||||||
let add_count_method = Property::new("addCount").with_method(add_count);
|
let add_count_method = Property::new(&ctx.env, "addCount")?.with_method(add_count);
|
||||||
let mut properties = vec![add_count_method];
|
let properties = vec![add_count_method];
|
||||||
ctx.env.define_class(
|
ctx
|
||||||
"TestClass",
|
.env
|
||||||
test_class_constructor,
|
.define_class("TestClass", test_class_constructor, properties.as_slice())
|
||||||
properties.as_mut_slice(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use napi::{CallContext, JsBoolean, JsObject, JsString, JsUndefined, JsUnknown, Module, Result};
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use napi::{
|
||||||
|
CallContext, JsBoolean, JsNumber, JsObject, JsString, JsUndefined, JsUnknown, Module, Property,
|
||||||
|
Result,
|
||||||
|
};
|
||||||
|
|
||||||
#[js_function(2)]
|
#[js_function(2)]
|
||||||
fn test_set_property(ctx: CallContext) -> Result<JsUndefined> {
|
fn test_set_property(ctx: CallContext) -> Result<JsUndefined> {
|
||||||
|
@ -29,10 +34,148 @@ fn test_has_named_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
ctx.env.get_boolean(obj.has_named_property(key.as_str()?)?)
|
ctx.env.get_boolean(obj.has_named_property(key.as_str()?)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_has_own_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsString>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.has_own_property(key.as_str()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_has_own_property_js(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsUnknown>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.has_own_property_js(key)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_has_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsString>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.has_property(key.as_str()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_has_property_js(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsUnknown>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.has_property_js(key)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_delete_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let mut obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsUnknown>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.delete_property(key)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_delete_named_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let mut obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsString>(1)?;
|
||||||
|
ctx
|
||||||
|
.env
|
||||||
|
.get_boolean(obj.delete_named_property(key.as_str()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_get_property(ctx: CallContext) -> Result<JsUnknown> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let key = ctx.get::<JsUnknown>(1)?;
|
||||||
|
obj.get_property(&key)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(1)]
|
||||||
|
fn test_get_property_names(ctx: CallContext) -> Result<JsUnknown> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
obj.get_property_names()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(1)]
|
||||||
|
fn test_get_prototype(ctx: CallContext) -> Result<JsUnknown> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
obj.get_prototype()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(3)]
|
||||||
|
fn test_set_element(ctx: CallContext) -> Result<JsUndefined> {
|
||||||
|
let mut obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let index = ctx.get::<JsNumber>(1)?;
|
||||||
|
let js_value = ctx.get::<JsUnknown>(2)?;
|
||||||
|
obj.set_element(index.try_into()?, js_value)?;
|
||||||
|
ctx.env.get_undefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_has_element(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let index = ctx.get::<JsNumber>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.has_element(index.try_into()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_get_element(ctx: CallContext) -> Result<JsUnknown> {
|
||||||
|
let obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let index = ctx.get::<JsNumber>(1)?;
|
||||||
|
obj.get_element(index.try_into()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(2)]
|
||||||
|
fn test_delete_element(ctx: CallContext) -> Result<JsBoolean> {
|
||||||
|
let mut obj: JsObject = ctx.get(0)?;
|
||||||
|
let index = ctx.get::<JsNumber>(1)?;
|
||||||
|
ctx.env.get_boolean(obj.delete_element(index.try_into()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(1)]
|
||||||
|
fn test_define_properties(ctx: CallContext) -> Result<JsUndefined> {
|
||||||
|
let mut obj = ctx.get::<JsObject>(0)?;
|
||||||
|
let add_method = Property::new(&ctx.env, "add")?.with_method(add);
|
||||||
|
let readonly_property = Property::new(&ctx.env, "ro")?.with_getter(readonly_getter);
|
||||||
|
let properties = vec![add_method, readonly_property];
|
||||||
|
obj.define_properties(&properties)?;
|
||||||
|
obj.set_named_property("count", ctx.env.create_int32(0)?)?;
|
||||||
|
ctx.env.get_undefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function(1)]
|
||||||
|
fn add(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||||
|
let count: i32 = ctx
|
||||||
|
.this
|
||||||
|
.get_named_property::<JsNumber>("count")?
|
||||||
|
.try_into()?;
|
||||||
|
let value_to_add: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
|
||||||
|
ctx
|
||||||
|
.this
|
||||||
|
.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?;
|
||||||
|
ctx.env.get_undefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[js_function]
|
||||||
|
fn readonly_getter(ctx: CallContext) -> Result<JsString> {
|
||||||
|
ctx.env.create_string("readonly")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||||
module.create_named_method("testSetProperty", test_set_property)?;
|
module.create_named_method("testSetProperty", test_set_property)?;
|
||||||
|
module.create_named_method("testGetProperty", test_get_property)?;
|
||||||
|
|
||||||
module.create_named_method("testSetNamedProperty", test_set_named_property)?;
|
module.create_named_method("testSetNamedProperty", test_set_named_property)?;
|
||||||
module.create_named_method("testGetNamedProperty", test_get_named_property)?;
|
module.create_named_method("testGetNamedProperty", test_get_named_property)?;
|
||||||
module.create_named_method("testHasNamedProperty", test_has_named_property)?;
|
module.create_named_method("testHasNamedProperty", test_has_named_property)?;
|
||||||
|
|
||||||
|
module.create_named_method("testHasOwnProperty", test_has_own_property)?;
|
||||||
|
module.create_named_method("testHasOwnPropertyJs", test_has_own_property_js)?;
|
||||||
|
module.create_named_method("testHasProperty", test_has_property)?;
|
||||||
|
module.create_named_method("testHasPropertyJs", test_has_property_js)?;
|
||||||
|
module.create_named_method("testDeleteProperty", test_delete_property)?;
|
||||||
|
module.create_named_method("testDeleteNamedProperty", test_delete_named_property)?;
|
||||||
|
module.create_named_method("testGetPropertyNames", test_get_property_names)?;
|
||||||
|
module.create_named_method("testGetPrototype", test_get_prototype)?;
|
||||||
|
module.create_named_method("testSetElement", test_set_element)?;
|
||||||
|
module.create_named_method("testHasElement", test_has_element)?;
|
||||||
|
module.create_named_method("testGetElement", test_get_element)?;
|
||||||
|
module.create_named_method("testDeleteElement", test_delete_element)?;
|
||||||
|
module.create_named_method("testDefineProperties", test_define_properties)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue