Skip to content

Commit

Permalink
[OV JS] Expose Model.setFriendlyName and Model.getFriendlyName method…
Browse files Browse the repository at this point in the history
…s to Node.js api (openvinotoolkit#23743)

This fixes openvinotoolkit#23566   

Implemented Model.setFriendlyName and Model.getFriendlyName in Node.js
api

- Added Parameter Validation
- Added Tests in model.test.js

---------

Co-authored-by: Vishniakov Nikolai <[email protected]>
  • Loading branch information
2 people authored and alvoron committed Apr 29, 2024
1 parent 014d19c commit 882e3b3
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 6 deletions.
17 changes: 17 additions & 0 deletions src/bindings/js/node/include/model_wrap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ class ModelWrap : public Napi::ObjectWrap<ModelWrap> {
*/
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,
* throws Napi::Undefined if more than 1 arguments are provided or the provided argument is not of type String
* @return Napi::Undefined
*/
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<ov::Model> _model;
ov::Core _core;
Expand Down
2 changes: 2 additions & 0 deletions src/bindings/js/node/lib/addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ interface Model {
input(nameOrId?: string | number): Output;
getName(): string;
isDynamic(): boolean;
setFriendlyName(name: string): void;
getFriendlyName(): string;
}

interface CompiledModel {
Expand Down
26 changes: 26 additions & 0 deletions src/bindings/js/node/src/model_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Napi::Function ModelWrap::get_class(Napi::Env env) {
InstanceMethod("output", &ModelWrap::get_output),
InstanceMethod("input", &ModelWrap::get_input),
InstanceMethod("isDynamic", &ModelWrap::is_dynamic),
InstanceMethod("setFriendlyName", &ModelWrap::set_friendly_name),
InstanceMethod("getFriendlyName", &ModelWrap::get_friendly_name),
InstanceAccessor<&ModelWrap::get_inputs>("inputs"),
InstanceAccessor<&ModelWrap::get_outputs>("outputs")});
}
Expand Down Expand Up @@ -128,3 +130,27 @@ Napi::Value ModelWrap::is_dynamic(const Napi::CallbackInfo& info) {
const auto result = _model->is_dynamic();
return Napi::Boolean::New(env, result);
}

Napi::Value ModelWrap::set_friendly_name(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
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<Napi::String>().Utf8Value();
_model->set_friendly_name(name);
} catch (const std::exception& e) {
reportError(env, e.what());
}
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);
}
78 changes: 72 additions & 6 deletions src/bindings/js/node/tests/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,86 @@ 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/
);
});
});
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');
});
});
});

0 comments on commit 882e3b3

Please sign in to comment.