From 4f685d978dd939bed51c2665e827290258e20092 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 28 Mar 2024 15:53:43 +0530 Subject: [PATCH 1/4] implemented get_set_friendly_name api --- src/bindings/js/node/include/model_wrap.hpp | 17 +++++++ src/bindings/js/node/lib/addon.ts | 2 + src/bindings/js/node/src/model_wrap.cpp | 29 +++++++++++ src/bindings/js/node/tests/model.test.js | 55 +++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 src/bindings/js/node/tests/model.test.js diff --git a/src/bindings/js/node/include/model_wrap.hpp b/src/bindings/js/node/include/model_wrap.hpp index 365bfbff87dc4b..e5bfb855b84d2c 100644 --- a/src/bindings/js/node/include/model_wrap.hpp +++ b/src/bindings/js/node/include/model_wrap.hpp @@ -76,6 +76,23 @@ class ModelWrap : public Napi::ObjectWrap { */ Napi::Value get_outputs(const Napi::CallbackInfo& info); + /** + * @brief Sets a friendly name for a model. + * @param info Contains information about the environment and passed arguments + * this method accepts only one argument of type string , + * throws ov::Exception if more than 1 arguments are provided or the provided argument is not of type String + * @return Null + */ + Napi::Value set_friendly_name(const Napi::CallbackInfo& info); + + /** + * @brief Gets the friendly name for a model , if not set , gets the unique name + * @param info Contains information about the environment and passed arguments + * this method does not accept any arguments. If arguments are provided it throws ov::Exception. + * @return Napi::String containing friendly name + */ + Napi::Value get_friendly_name(const Napi::CallbackInfo& info); + private: std::shared_ptr _model; ov::Core _core; diff --git a/src/bindings/js/node/lib/addon.ts b/src/bindings/js/node/lib/addon.ts index 281430f27d7a6b..06a097c6f1709c 100644 --- a/src/bindings/js/node/lib/addon.ts +++ b/src/bindings/js/node/lib/addon.ts @@ -59,6 +59,8 @@ interface Model { output(nameOrId?: string | number): Output; input(nameOrId?: string | number): Output; getName(): string; + setFriendlyName(name: string): void; + getFriendlyName(): string; } interface CompiledModel { diff --git a/src/bindings/js/node/src/model_wrap.cpp b/src/bindings/js/node/src/model_wrap.cpp index 67cc6a5dec184c..c9dd2439005a35 100644 --- a/src/bindings/js/node/src/model_wrap.cpp +++ b/src/bindings/js/node/src/model_wrap.cpp @@ -19,6 +19,8 @@ Napi::Function ModelWrap::get_class(Napi::Env env) { {InstanceMethod("getName", &ModelWrap::get_name), InstanceMethod("output", &ModelWrap::get_output), InstanceMethod("input", &ModelWrap::get_input), + InstanceMethod("setFriendlyName", &ModelWrap::set_friendly_name), + InstanceMethod("getFriendlyName", &ModelWrap::get_friendly_name), InstanceAccessor<&ModelWrap::get_inputs>("inputs"), InstanceAccessor<&ModelWrap::get_outputs>("outputs")}); } @@ -117,3 +119,30 @@ Napi::Value ModelWrap::get_outputs(const Napi::CallbackInfo& info) { return js_outputs; } + +Napi::Value ModelWrap::set_friendly_name(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (info.Length() != 1 || !info[0].IsString()) { + reportError(env , "Expected a single string argument for the friendly name" ); + return env.Undefined(); + } + const auto name = info[0].As().Utf8Value(); + try { + _model->set_friendly_name(name); + } catch (const std::exception& e) { + reportError(env , e.what()); + return env.Undefined(); + } + return env.Undefined(); +} + +Napi::Value ModelWrap::get_friendly_name(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (info.Length() > 0) { + reportError(env , "getFriendlyName() does not take any arguments"); + return env.Undefined(); + } + const auto friendly_name = _model->get_friendly_name(); + return Napi::String::New(env , friendly_name); +} + diff --git a/src/bindings/js/node/tests/model.test.js b/src/bindings/js/node/tests/model.test.js new file mode 100644 index 00000000000000..cb998c4ca70ee9 --- /dev/null +++ b/src/bindings/js/node/tests/model.test.js @@ -0,0 +1,55 @@ +// -*- coding: utf-8 -*- +// Copyright (C) 2018-2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +const { addon: ov } = require('..'); +const assert = require('assert'); +const { describe, it } = require('node:test'); +const { getModelPath } = require('./utils.js'); +const testXml = getModelPath().xml; +const core = new ov.Core(); +const model = core.readModelSync(testXml); + +describe('Node.js getFriendlyName() / setFriendlyName()', () => { + + describe('getFriendlyName()', () => { + it('returns the unique name of the model if no friendly name is set', () => { + const expectedName = 'test_model'; + assert.strictEqual(model.getFriendlyName(), expectedName); + }); + it('throws an error when called with arguments', () => { + assert.throws(() => model.getFriendlyName('unexpected argument'), /getFriendlyName\(\) does not take any arguments/); + }); + }); + describe('setFriendlyName()', () => { + it('sets a friendly name for the model', () => { + assert.doesNotThrow(() => model.setFriendlyName('MyFriendlyName')); + }); + + it('throws an error when called without a string argument', () => { + assert.throws(() => model.setFriendlyName(), /Expected a single string argument for the friendly name/); + assert.throws(() => model.setFriendlyName(123), /Expected a single string argument for the friendly name/); + }); + + it('throws an error when called with multiple arguments', () => { + assert.throws(() => model.setFriendlyName('Name1', 'Name2'), /Expected a single string argument for the friendly name/); + }); + + it('returns the set friendly name of the model', () => { + const friendlyName = 'MyFriendlyModel'; + model.setFriendlyName(friendlyName); + assert.strictEqual(model.getFriendlyName(), friendlyName); + }); + + it('retains the last set friendly name when set multiple times', () => { + model.setFriendlyName('InitialName'); + model.setFriendlyName('FinalName'); + assert.strictEqual(model.getFriendlyName(), 'FinalName'); + }); + + it('handles setting an empty string as a friendly name', () => { + assert.doesNotThrow(() => model.setFriendlyName('')); + assert.strictEqual(model.getFriendlyName(), 'Model1'); + }); + }); +}); From ef3277e6fcb5b56b4a5adf6e48517b7e98a4c7f2 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 28 Mar 2024 21:01:24 +0530 Subject: [PATCH 2/4] formatting fixes --- src/bindings/js/node/include/model_wrap.hpp | 6 +++--- src/bindings/js/node/src/model_wrap.cpp | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/bindings/js/node/include/model_wrap.hpp b/src/bindings/js/node/include/model_wrap.hpp index e5bfb855b84d2c..bc379adcfb56d4 100644 --- a/src/bindings/js/node/include/model_wrap.hpp +++ b/src/bindings/js/node/include/model_wrap.hpp @@ -79,14 +79,14 @@ class ModelWrap : public Napi::ObjectWrap { /** * @brief Sets a friendly name for a model. * @param info Contains information about the environment and passed arguments - * this method accepts only one argument of type string , - * throws ov::Exception if more than 1 arguments are provided or the provided argument is not of type String + * this method accepts only one argument of type String, + * throws Napi::Undefined if more than 1 arguments are provided or the provided argument is not of type String * @return Null */ Napi::Value set_friendly_name(const Napi::CallbackInfo& info); /** - * @brief Gets the friendly name for a model , if not set , gets the unique name + * @brief Gets the friendly name for a model, if not set, gets the unique name * @param info Contains information about the environment and passed arguments * this method does not accept any arguments. If arguments are provided it throws ov::Exception. * @return Napi::String containing friendly name diff --git a/src/bindings/js/node/src/model_wrap.cpp b/src/bindings/js/node/src/model_wrap.cpp index c9dd2439005a35..ced4ab05cd6c66 100644 --- a/src/bindings/js/node/src/model_wrap.cpp +++ b/src/bindings/js/node/src/model_wrap.cpp @@ -123,15 +123,14 @@ Napi::Value ModelWrap::get_outputs(const Napi::CallbackInfo& info) { Napi::Value ModelWrap::set_friendly_name(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); if (info.Length() != 1 || !info[0].IsString()) { - reportError(env , "Expected a single string argument for the friendly name" ); + reportError(env, "Expected a single string argument for the friendly name"); return env.Undefined(); } const auto name = info[0].As().Utf8Value(); try { _model->set_friendly_name(name); } catch (const std::exception& e) { - reportError(env , e.what()); - return env.Undefined(); + reportError(env, e.what()); } return env.Undefined(); } @@ -139,10 +138,9 @@ Napi::Value ModelWrap::set_friendly_name(const Napi::CallbackInfo& info) { Napi::Value ModelWrap::get_friendly_name(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); if (info.Length() > 0) { - reportError(env , "getFriendlyName() does not take any arguments"); + reportError(env, "getFriendlyName() does not take any arguments"); return env.Undefined(); } const auto friendly_name = _model->get_friendly_name(); - return Napi::String::New(env , friendly_name); + return Napi::String::New(env, friendly_name); } - From fed04b0f2cf0240b4d43aa025e34b27500f2a251 Mon Sep 17 00:00:00 2001 From: Prakash Date: Fri, 29 Mar 2024 01:32:14 +0530 Subject: [PATCH 3/4] formating fixes after merge --- src/bindings/js/node/include/model_wrap.hpp | 6 +-- src/bindings/js/node/lib/addon.ts | 2 +- src/bindings/js/node/tests/model.test.js | 48 +++++++++++++++------ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/bindings/js/node/include/model_wrap.hpp b/src/bindings/js/node/include/model_wrap.hpp index f577e20c86ca26..651823227c60e8 100644 --- a/src/bindings/js/node/include/model_wrap.hpp +++ b/src/bindings/js/node/include/model_wrap.hpp @@ -83,8 +83,8 @@ class ModelWrap : public Napi::ObjectWrap { * @return Boolean indicating if the model is dynamic or not */ Napi::Value is_dynamic(const Napi::CallbackInfo& info); - - /** + + /** * @brief Sets a friendly name for a model. * @param info Contains information about the environment and passed arguments * this method accepts only one argument of type String, @@ -100,7 +100,7 @@ class ModelWrap : public Napi::ObjectWrap { * @return Napi::String containing friendly name */ Napi::Value get_friendly_name(const Napi::CallbackInfo& info); - + private: std::shared_ptr _model; ov::Core _core; diff --git a/src/bindings/js/node/lib/addon.ts b/src/bindings/js/node/lib/addon.ts index 74351ae11c5fb9..f431deb8473276 100644 --- a/src/bindings/js/node/lib/addon.ts +++ b/src/bindings/js/node/lib/addon.ts @@ -61,7 +61,7 @@ interface Model { getName(): string; isDynamic(): boolean; setFriendlyName(name: string): void; - getFriendlyName(): string; + getFriendlyName(): string; } interface CompiledModel { diff --git a/src/bindings/js/node/tests/model.test.js b/src/bindings/js/node/tests/model.test.js index 1e51e2937ac19a..c157c003e18f6f 100644 --- a/src/bindings/js/node/tests/model.test.js +++ b/src/bindings/js/node/tests/model.test.js @@ -11,33 +11,46 @@ const core = new ov.Core(); const model = core.readModelSync(testXml); describe('Node.js Model.isDynamic()', () => { - it('should return a boolean value indicating if the model is dynamic', () => { const result = model.isDynamic(); - assert.strictEqual(typeof result, 'boolean', 'isDynamic() should return a boolean value'); + assert.strictEqual( + typeof result, + 'boolean', + 'isDynamic() should return a boolean value' + ); }); it('should not accept any arguments', () => { - assert.throws(() => { - model.isDynamic('unexpected argument'); - }, /^Error: isDynamic\(\) does not accept any arguments\.$/, 'Expected isDynamic to throw an error when called with arguments'); + assert.throws( + () => { + model.isDynamic('unexpected argument'); + }, + /^Error: isDynamic\(\) does not accept any arguments\.$/, + 'Expected isDynamic to throw an error when called with arguments' + ); }); it('returns false for a static model', () => { const expectedStatus = false; - assert.strictEqual(model.isDynamic(), expectedStatus, 'Expected isDynamic to return false for a static model'); + assert.strictEqual( + model.isDynamic(), + expectedStatus, + 'Expected isDynamic to return false for a static model' + ); }); }); describe('Node.js getFriendlyName() / setFriendlyName()', () => { - describe('getFriendlyName()', () => { it('returns the unique name of the model if no friendly name is set', () => { const expectedName = 'test_model'; assert.strictEqual(model.getFriendlyName(), expectedName); }); it('throws an error when called with arguments', () => { - assert.throws(() => model.getFriendlyName('unexpected argument'), /getFriendlyName\(\) does not take any arguments/); + assert.throws( + () => model.getFriendlyName('unexpected argument'), + /getFriendlyName\(\) does not take any arguments/ + ); }); }); describe('setFriendlyName()', () => { @@ -46,12 +59,21 @@ describe('Node.js getFriendlyName() / setFriendlyName()', () => { }); it('throws an error when called without a string argument', () => { - assert.throws(() => model.setFriendlyName(), /Expected a single string argument for the friendly name/); - assert.throws(() => model.setFriendlyName(123), /Expected a single string argument for the friendly name/); + assert.throws( + () => model.setFriendlyName(), + /Expected a single string argument for the friendly name/ + ); + assert.throws( + () => model.setFriendlyName(123), + /Expected a single string argument for the friendly name/ + ); }); it('throws an error when called with multiple arguments', () => { - assert.throws(() => model.setFriendlyName('Name1', 'Name2'), /Expected a single string argument for the friendly name/); + assert.throws( + () => model.setFriendlyName('Name1', 'Name2'), + /Expected a single string argument for the friendly name/ + ); }); it('returns the set friendly name of the model', () => { @@ -69,4 +91,6 @@ describe('Node.js getFriendlyName() / setFriendlyName()', () => { it('handles setting an empty string as a friendly name', () => { assert.doesNotThrow(() => model.setFriendlyName('')); assert.strictEqual(model.getFriendlyName(), 'Model1'); - }); \ No newline at end of file + }); + }); +}); From bb6d2cae82e87d728d575444db7fa56316e5936d Mon Sep 17 00:00:00 2001 From: Prakash Date: Tue, 2 Apr 2024 22:05:24 +0530 Subject: [PATCH 4/4] made suggested changes --- src/bindings/js/node/include/model_wrap.hpp | 2 +- src/bindings/js/node/src/model_wrap.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bindings/js/node/include/model_wrap.hpp b/src/bindings/js/node/include/model_wrap.hpp index 651823227c60e8..1e3373b6185095 100644 --- a/src/bindings/js/node/include/model_wrap.hpp +++ b/src/bindings/js/node/include/model_wrap.hpp @@ -89,7 +89,7 @@ class ModelWrap : public Napi::ObjectWrap { * @param info Contains information about the environment and passed arguments * this method accepts only one argument of type String, * throws Napi::Undefined if more than 1 arguments are provided or the provided argument is not of type String - * @return Null + * @return Napi::Undefined */ Napi::Value set_friendly_name(const Napi::CallbackInfo& info); diff --git a/src/bindings/js/node/src/model_wrap.cpp b/src/bindings/js/node/src/model_wrap.cpp index 5a4d56a8aeb1dc..d22dd6701ab156 100644 --- a/src/bindings/js/node/src/model_wrap.cpp +++ b/src/bindings/js/node/src/model_wrap.cpp @@ -133,12 +133,11 @@ Napi::Value ModelWrap::is_dynamic(const Napi::CallbackInfo& info) { Napi::Value ModelWrap::set_friendly_name(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); - if (info.Length() != 1 || !info[0].IsString()) { - reportError(env, "Expected a single string argument for the friendly name"); - return env.Undefined(); - } - const auto name = info[0].As().Utf8Value(); try { + if (info.Length() != 1 || !info[0].IsString()) { + OPENVINO_THROW("Expected a single string argument for the friendly name"); + } + const auto name = info[0].As().Utf8Value(); _model->set_friendly_name(name); } catch (const std::exception& e) { reportError(env, e.what());