From 98210cd7712604b2e177162e1cfb447b3bcc42dd Mon Sep 17 00:00:00 2001 From: LongYinan Date: Mon, 24 Aug 2020 16:04:03 +0800 Subject: [PATCH] feat(napi): implement more napi --- README.md | 10 +++--- napi/src/env.rs | 9 +++++ napi/src/js_values/mod.rs | 35 +++++++++++++++++++ test_module/__test__/js-value.spec.js | 49 +++++++++++++++++++++++++++ test_module/src/lib.rs | 39 ++++++++++++++++++++- 5 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 test_module/__test__/js-value.spec.js diff --git a/README.md b/README.md index f778f3a3..6f09dc08 100644 --- a/README.md +++ b/README.md @@ -199,14 +199,14 @@ yarn test | [napi_coerce_to_object](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_object) | 1 | v8.0.0 | ✅ | | [napi_coerce_to_string](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_string) | 1 | v8.0.0 | ✅ | | [napi_typeof](https://nodejs.org/api/n-api.html#n_api_napi_typeof) | 1 | v8.0.0 | ✅ | -| [napi_instanceof](https://nodejs.org/api/n-api.html#n_api_napi_instanceof) | 1 | v8.0.0 | ⛔️ | +| [napi_instanceof](https://nodejs.org/api/n-api.html#n_api_napi_instanceof) | 1 | v8.0.0 | ✅ | | [napi_is_array](https://nodejs.org/api/n-api.html#n_api_napi_is_array) | 1 | v8.0.0 | ✅ | | [napi_is_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_arraybuffer) | 1 | v8.0.0 | ✅ | | [napi_is_buffer](https://nodejs.org/api/n-api.html#n_api_napi_is_buffer) | 1 | v8.0.0 | ✅ | | [napi_is_date](https://nodejs.org/api/n-api.html#n_api_napi_is_date) | 1 | v8.0.0 | ✅ | -| [napi_is_error](https://nodejs.org/api/n-api.html#n_api_napi_is_error_1) | 1 | v8.0.0 | ⛔️ | -| [napi_is_typedarray](https://nodejs.org/api/n-api.html#n_api_napi_is_typedarray) | 1 | v8.0.0 | ⛔️ | -| [napi_is_dataview](https://nodejs.org/api/n-api.html#n_api_napi_is_dataview) | 1 | v8.3.0 | ⛔️ | -| [napi_strict_equals](https://nodejs.org/api/n-api.html#n_api_napi_strict_equals) | 1 | v8.0.0 | ⛔️ | +| [napi_is_error](https://nodejs.org/api/n-api.html#n_api_napi_is_error_1) | 1 | v8.0.0 | ✅ | +| [napi_is_typedarray](https://nodejs.org/api/n-api.html#n_api_napi_is_typedarray) | 1 | v8.0.0 | ✅ | +| [napi_is_dataview](https://nodejs.org/api/n-api.html#n_api_napi_is_dataview) | 1 | v8.3.0 | ✅ | +| [napi_strict_equals](https://nodejs.org/api/n-api.html#n_api_napi_strict_equals) | 1 | v8.0.0 | ✅ | | [napi_detach_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_detach_arraybuffer) | Experimental | v13.3.0 | ⛔️ | | [napi_is_detached_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_detached_arraybuffer) | Experimental | v13.3.0 | ⛔️ | diff --git a/napi/src/env.rs b/napi/src/env.rs index ecb722cc..0c2c72a6 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -608,6 +608,15 @@ impl Env { Ok(JsObject::from_raw_unchecked(self.0, raw_promise)) } + #[inline] + pub fn strict_equals(&self, a: A, b: B) -> Result { + let mut result = false; + check_status(unsafe { + sys::napi_strict_equals(self.0, a.raw_value(), b.raw_value(), &mut result) + })?; + Ok(result) + } + #[inline] pub fn get_node_version(&self) -> Result { let mut result = ptr::null(); diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index c0946557..7770e68a 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -150,6 +150,41 @@ macro_rules! impl_js_value_methods { check_status(status)?; Ok(is_date) } + + #[inline] + pub fn is_error(&self) -> Result { + let mut result = false; + check_status(unsafe { sys::napi_is_error(self.0.env, self.0.value, &mut result) })?; + Ok(result) + } + + #[inline] + pub fn is_typedarray(&self) -> Result { + let mut result = false; + check_status(unsafe { sys::napi_is_typedarray(self.0.env, self.0.value, &mut result) })?; + Ok(result) + } + + #[inline] + pub fn is_dataview(&self) -> Result { + let mut result = false; + check_status(unsafe { sys::napi_is_dataview(self.0.env, self.0.value, &mut result) })?; + Ok(result) + } + + #[inline] + pub fn instanceof(&self, constructor: Constructor) -> Result { + let mut result = false; + check_status(unsafe { + sys::napi_instanceof( + self.0.env, + self.0.value, + constructor.raw_value(), + &mut result, + ) + })?; + Ok(result) + } } }; } diff --git a/test_module/__test__/js-value.spec.js b/test_module/__test__/js-value.spec.js new file mode 100644 index 00000000..fa727bca --- /dev/null +++ b/test_module/__test__/js-value.spec.js @@ -0,0 +1,49 @@ +const test = require('ava') + +const bindings = require('../index.node') + +test('instanceof', (t) => { + const day = new Date() + t.true(bindings.instanceof(day, Date)) + t.false(bindings.instanceof(day, Number)) + t.false(bindings.instanceof(1, Date)) +}) + +test('is_error', (t) => { + t.true(bindings.isError(new Error())) + t.true(bindings.isError(new TypeError())) + t.true(bindings.isError(new SyntaxError())) + t.false(bindings.isError('111')) + t.false(bindings.isError(2)) + t.false(bindings.isError(Symbol())) +}) + +test('is_typedarray', (t) => { + t.true(bindings.isTypedarray(new Uint8Array())) + t.true(bindings.isTypedarray(new Uint16Array())) + t.true(bindings.isTypedarray(new Uint32Array())) + t.true(bindings.isTypedarray(new Int8Array())) + t.true(bindings.isTypedarray(new Int16Array())) + t.true(bindings.isTypedarray(new Int32Array())) + t.true(bindings.isTypedarray(Buffer.from('123'))) + t.false(bindings.isTypedarray(Buffer.from('123').buffer)) + t.false(bindings.isTypedarray([])) +}) + +test('is_dataview', (t) => { + const data = new Uint8Array(100) + t.true(bindings.isDataview(new DataView(data.buffer))) + t.false(bindings.isDataview(Buffer.from('123'))) +}) + +test('strict_equals', (t) => { + const a = { + foo: 'bar', + } + const b = { ...a } + t.false(bindings.strictEquals(a, b)) + t.false(bindings.strictEquals(1, '1')) + t.false(bindings.strictEquals(null, undefined)) + t.false(bindings.strictEquals(NaN, NaN)) + t.true(bindings.strictEquals(a, a)) +}) diff --git a/test_module/src/lib.rs b/test_module/src/lib.rs index 6a0225e0..1066c52f 100644 --- a/test_module/src/lib.rs +++ b/test_module/src/lib.rs @@ -3,7 +3,7 @@ extern crate napi; #[macro_use] extern crate napi_derive; -use napi::{CallContext, Error, JsString, JsUnknown, Module, Result, Status}; +use napi::{CallContext, Error, JsBoolean, JsString, JsUnknown, Module, Result, Status}; #[cfg(napi4)] mod libuv; @@ -71,6 +71,11 @@ fn init(module: &mut Module) -> Result<()> { module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?; module.create_named_method("createTestClass", class::create_test_class)?; module.create_named_method("concatString", string::concat_string)?; + module.create_named_method("instanceof", instanceof)?; + module.create_named_method("isError", is_error)?; + module.create_named_method("isTypedarray", is_typedarray)?; + module.create_named_method("isDataview", is_dataview)?; + module.create_named_method("strictEquals", strict_equals)?; #[cfg(napi4)] module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?; #[cfg(napi4)] @@ -118,3 +123,35 @@ fn test_throw_with_reason(ctx: CallContext) -> Result { pub fn test_throw_with_panic(_ctx: CallContext) -> Result { panic!("don't panic."); } + +#[js_function(2)] +pub fn instanceof(ctx: CallContext) -> Result { + let object = ctx.get::(0)?; + let constructor = ctx.get::(1)?; + ctx.env.get_boolean(object.instanceof(constructor)?) +} + +#[js_function(1)] +pub fn is_error(ctx: CallContext) -> Result { + let js_value = ctx.get::(0)?; + ctx.env.get_boolean(js_value.is_error()?) +} + +#[js_function(1)] +pub fn is_typedarray(ctx: CallContext) -> Result { + let js_value = ctx.get::(0)?; + ctx.env.get_boolean(js_value.is_typedarray()?) +} + +#[js_function(1)] +pub fn is_dataview(ctx: CallContext) -> Result { + let js_value = ctx.get::(0)?; + ctx.env.get_boolean(js_value.is_dataview()?) +} + +#[js_function(2)] +pub fn strict_equals(ctx: CallContext) -> Result { + let a: JsUnknown = ctx.get(0)?; + let b: JsUnknown = ctx.get(1)?; + ctx.env.get_boolean(ctx.env.strict_equals(a, b)?) +}