Просмотр исходного кода

chore: makes model name resolution case-insensitive

e22m4u 3 месяцев назад
Родитель
Сommit
170932117f

+ 36 - 8
dist/cjs/index.cjs

@@ -396,6 +396,23 @@ var init_exclude_object_keys = __esm({
   }
 });
 
+// src/utils/model-name-to-model-key.js
+function modelNameToModelKey(modelName) {
+  if (!modelName || typeof modelName !== "string" || /\s/.test(modelName))
+    throw new InvalidArgumentError(
+      "The model name should be a non-empty String without spaces, but %v given.",
+      modelName
+    );
+  return modelName.toLowerCase().replace(/[-_]/g, "");
+}
+var init_model_name_to_model_key = __esm({
+  "src/utils/model-name-to-model-key.js"() {
+    "use strict";
+    init_errors();
+    __name(modelNameToModelKey, "modelNameToModelKey");
+  }
+});
+
 // src/utils/get-decorator-target-type.js
 function getDecoratorTargetType(target, propertyKey, descriptorOrIndex) {
   const isCtor2 = typeof target === "function";
@@ -452,6 +469,7 @@ var init_utils = __esm({
     init_transform_promise();
     init_select_object_keys();
     init_exclude_object_keys();
+    init_model_name_to_model_key();
     init_get_decorator_target_type();
   }
 });
@@ -2040,6 +2058,7 @@ var init_definition_registry = __esm({
   "src/definition/definition-registry.js"() {
     "use strict";
     import_js_service8 = require("@e22m4u/js-service");
+    init_utils();
     init_errors();
     init_model();
     init_definition();
@@ -2099,10 +2118,13 @@ var init_definition_registry = __esm({
        */
       addModel(modelDef) {
         this.getService(ModelDefinitionValidator).validate(modelDef);
-        const name = modelDef.name;
-        if (name in this._models)
-          throw new InvalidArgumentError("The model %v is already defined.", name);
-        this._models[name] = modelDef;
+        const modelKey = modelNameToModelKey(modelDef.name);
+        if (modelKey in this._models)
+          throw new InvalidArgumentError(
+            "The model %v is already defined.",
+            modelDef.name
+          );
+        this._models[modelKey] = modelDef;
       }
       /**
        * Has model.
@@ -2111,7 +2133,8 @@ var init_definition_registry = __esm({
        * @returns {boolean}
        */
       hasModel(name) {
-        return Boolean(this._models[name]);
+        const modelKey = modelNameToModelKey(name);
+        return Boolean(this._models[modelKey]);
       }
       /**
        * Get model.
@@ -2120,7 +2143,8 @@ var init_definition_registry = __esm({
        * @returns {object}
        */
       getModel(name) {
-        const modelDef = this._models[name];
+        const modelKey = modelNameToModelKey(name);
+        const modelDef = this._models[modelKey];
         if (!modelDef)
           throw new InvalidArgumentError("The model %v is not defined.", name);
         return modelDef;
@@ -5060,6 +5084,7 @@ var init_repository_registry = __esm({
     "use strict";
     import_js_service30 = require("@e22m4u/js-service");
     init_repository();
+    init_utils();
     init_errors();
     _RepositoryRegistry = class _RepositoryRegistry extends import_js_service30.Service {
       /**
@@ -5096,10 +5121,11 @@ var init_repository_registry = __esm({
        * @returns {Repository}
        */
       getRepository(modelName) {
-        let repository = this._repositories[modelName];
+        const modelKey = modelNameToModelKey(modelName);
+        let repository = this._repositories[modelKey];
         if (repository) return repository;
         repository = new this._repositoryCtor(this.container, modelName);
-        this._repositories[modelName] = repository;
+        this._repositories[modelKey] = repository;
         return repository;
       }
     };
@@ -6361,6 +6387,7 @@ __export(index_exports, {
   isDeepEqual: () => isDeepEqual,
   isPromise: () => isPromise,
   isPureObject: () => isPureObject,
+  modelNameToModelKey: () => modelNameToModelKey,
   selectObjectKeys: () => selectObjectKeys,
   singularize: () => singularize,
   stringToRegexp: () => stringToRegexp,
@@ -6465,6 +6492,7 @@ init_repository2();
   isDeepEqual,
   isPromise,
   isPureObject,
+  modelNameToModelKey,
   selectObjectKeys,
   singularize,
   stringToRegexp,

+ 6 - 6
package.json

@@ -41,7 +41,7 @@
   "dependencies": {
     "@e22m4u/js-empty-values": "~0.0.2",
     "@e22m4u/js-format": "~0.1.8",
-    "@e22m4u/js-service": "~0.3.3"
+    "@e22m4u/js-service": "~0.3.6"
   },
   "devDependencies": {
     "@commitlint/cli": "~19.8.1",
@@ -51,14 +51,14 @@
     "@types/chai-spies": "~1.0.6",
     "@types/mocha": "~10.0.10",
     "c8": "~10.1.3",
-    "chai": "~5.2.1",
-    "chai-as-promised": "~8.0.1",
+    "chai": "~6.0.1",
+    "chai-as-promised": "~8.0.2",
     "chai-spies": "~1.1.0",
     "esbuild": "~0.25.9",
-    "eslint": "~9.33.0",
+    "eslint": "~9.34.0",
     "eslint-config-prettier": "~10.1.8",
     "eslint-plugin-chai-expect": "~3.1.0",
-    "eslint-plugin-jsdoc": "~54.1.0",
+    "eslint-plugin-jsdoc": "~54.1.1",
     "eslint-plugin-mocha": "~11.1.0",
     "husky": "~9.1.7",
     "mocha": "~11.7.1",
@@ -66,6 +66,6 @@
     "rimraf": "~6.0.1",
     "ts-node": "~10.9.2",
     "typescript": "~5.9.2",
-    "typescript-eslint": "~8.39.1"
+    "typescript-eslint": "~8.41.0"
   }
 }

+ 12 - 6
src/definition/definition-registry.js

@@ -1,4 +1,5 @@
 import {Service} from '@e22m4u/js-service';
+import {modelNameToModelKey} from '../utils/index.js';
 import {InvalidArgumentError} from '../errors/index.js';
 import {ModelDefinitionValidator} from './model/index.js';
 import {DatasourceDefinitionValidator} from '../definition/index.js';
@@ -67,10 +68,13 @@ export class DefinitionRegistry extends Service {
    */
   addModel(modelDef) {
     this.getService(ModelDefinitionValidator).validate(modelDef);
-    const name = modelDef.name;
-    if (name in this._models)
-      throw new InvalidArgumentError('The model %v is already defined.', name);
-    this._models[name] = modelDef;
+    const modelKey = modelNameToModelKey(modelDef.name);
+    if (modelKey in this._models)
+      throw new InvalidArgumentError(
+        'The model %v is already defined.',
+        modelDef.name,
+      );
+    this._models[modelKey] = modelDef;
   }
 
   /**
@@ -80,7 +84,8 @@ export class DefinitionRegistry extends Service {
    * @returns {boolean}
    */
   hasModel(name) {
-    return Boolean(this._models[name]);
+    const modelKey = modelNameToModelKey(name);
+    return Boolean(this._models[modelKey]);
   }
 
   /**
@@ -90,7 +95,8 @@ export class DefinitionRegistry extends Service {
    * @returns {object}
    */
   getModel(name) {
-    const modelDef = this._models[name];
+    const modelKey = modelNameToModelKey(name);
+    const modelDef = this._models[modelKey];
     if (!modelDef)
       throw new InvalidArgumentError('The model %v is not defined.', name);
     return modelDef;

+ 173 - 46
src/definition/definition-registry.spec.js

@@ -17,63 +17,190 @@ describe('DefinitionRegistry', function () {
     sandbox.restore();
   });
 
-  it('sets a given datasource to the state', function () {
-    const datasource = {name: 'datasource', adapter: 'adapter'};
-    S.addDatasource(datasource);
-    const result = S.getDatasource('datasource');
-    expect(result).to.be.eql(datasource);
-  });
+  describe('addDatasource', function () {
+    it('adds the given datasource to the registry', function () {
+      const datasource = {name: 'datasource', adapter: 'adapter'};
+      S.addDatasource(datasource);
+      const result = S.getDatasource('datasource');
+      expect(result).to.be.eql(datasource);
+    });
 
-  it('throws an error if a given datasource is already defined', function () {
-    const datasource1 = {name: 'datasource', adapter: 'adapter'};
-    const datasource2 = {name: 'datasource', adapter: 'adapter'};
-    S.addDatasource(datasource1);
-    const throwable = () => S.addDatasource(datasource2);
-    expect(throwable).to.throw(
-      'The datasource "datasource" is already defined.',
-    );
-  });
+    it('uses DatasourceDefinitionValidator to validate a given datasource', function () {
+      const V = S.getService(DatasourceDefinitionValidator);
+      sandbox.on(V, 'validate');
+      const datasource = {name: 'datasource', adapter: 'adapter'};
+      S.addDatasource(datasource);
+      expect(V.validate).to.have.been.called.once;
+      expect(V.validate).to.have.been.called.with.exactly(datasource);
+    });
 
-  it('throws an error when getting a not defined datasource', function () {
-    const throwable = () => S.getDatasource('undefined');
-    expect(throwable).to.throw('The datasource "undefined" is not defined.');
+    it('throws an error if a given datasource is already defined', function () {
+      const datasource1 = {name: 'datasource', adapter: 'adapter'};
+      const datasource2 = {name: 'datasource', adapter: 'adapter'};
+      S.addDatasource(datasource1);
+      const throwable = () => S.addDatasource(datasource2);
+      expect(throwable).to.throw(
+        'The datasource "datasource" is already defined.',
+      );
+    });
   });
 
-  it('uses DatasourceDefinitionValidator to validate a given datasource', function () {
-    const V = S.getService(DatasourceDefinitionValidator);
-    sandbox.on(V, 'validate');
-    const datasource = {name: 'datasource', adapter: 'adapter'};
-    S.addDatasource(datasource);
-    expect(V.validate).to.have.been.called.once;
-    expect(V.validate).to.have.been.called.with.exactly(datasource);
+  describe('hasDatasource', function () {
+    it('should check the datasource registration by its name', function () {
+      const datasource = {name: 'datasource', adapter: 'adapter'};
+      expect(S.hasDatasource(datasource.name)).to.be.false;
+      S.addDatasource(datasource);
+      expect(S.hasDatasource(datasource.name)).to.be.true;
+    });
   });
 
-  it('sets a given model to the state', function () {
-    const model = {name: 'model'};
-    S.addModel(model);
-    const result = S.getModel('model');
-    expect(result).to.be.eql(model);
+  describe('getDatasource', function () {
+    it('returns the datasource by its name', function () {
+      const datasource = {name: 'datasource', adapter: 'adapter'};
+      S.addDatasource(datasource);
+      const result = S.getDatasource('datasource');
+      expect(result).to.be.eql(datasource);
+    });
+
+    it('throws an error if ths datasource is not defined', function () {
+      const throwable = () => S.getDatasource('undefined');
+      expect(throwable).to.throw('The datasource "undefined" is not defined.');
+    });
   });
 
-  it('throws an error if a given model is already defined', function () {
-    const model1 = {name: 'model'};
-    const model2 = {name: 'model'};
-    S.addModel(model1);
-    const throwable = () => S.addModel(model2);
-    expect(throwable).to.throw('The model "model" is already defined.');
+  describe('addModel', function () {
+    it('adds the given model to the registry', function () {
+      const model = {name: 'model'};
+      S.addModel(model);
+      const result = S.getModel('model');
+      expect(result).to.be.eql(model);
+    });
+
+    it('uses ModelDefinitionValidator to validate a given model', function () {
+      const V = S.getService(ModelDefinitionValidator);
+      sandbox.on(V, 'validate');
+      const model = {name: 'model'};
+      S.addModel(model);
+      expect(V.validate).to.have.been.called.once;
+      expect(V.validate).to.have.been.called.with.exactly(model);
+    });
+
+    it('throws an error if a given model is already defined', function () {
+      const model1 = {name: 'TestModel'};
+      const model2 = {name: 'TestModel'};
+      S.addModel(model1);
+      const throwable = () => S.addModel(model2);
+      expect(throwable).to.throw('The model "TestModel" is already defined.');
+    });
   });
 
-  it('throws an error when getting a not defined model', function () {
-    const throwable = () => S.getModel('undefined');
-    expect(throwable).to.throw('The model "undefined" is not defined.');
+  describe('hasModel', function () {
+    it('should check the model registration by its name', function () {
+      const model = {name: 'model'};
+      expect(S.hasModel(model.name)).to.be.false;
+      S.addModel(model);
+      expect(S.hasModel(model.name)).to.be.true;
+    });
+
+    it('should ignore naming convention of the model name', function () {
+      const model = {name: 'UserProfileDetails'};
+      const modelNames = [
+        'userProfileDetails',
+        'UserProfileDetails',
+        'user-profile-details',
+        'user_profile_details',
+        'USER-PROFILE-DETAILS',
+        'USER_PROFILE_DETAILS',
+        'USERPROFILEDETAILS',
+        'userprofiledetails',
+      ];
+      modelNames.forEach(v => expect(S.hasModel(v)).to.be.false);
+      S.addModel(model);
+      modelNames.forEach(v => expect(S.hasModel(v)).to.be.true);
+    });
+
+    it('should respect numbers in the model name', function () {
+      const model1 = {name: 'UserProfileDetails1'};
+      const modelNames1 = [
+        'userProfileDetails1',
+        'UserProfileDetails1',
+        'user-profile-details-1',
+        'user_profile_details_1',
+        'USER-PROFILE-DETAILS-1',
+        'USER_PROFILE_DETAILS_1',
+        'USERPROFILEDETAILS1',
+        'userprofiledetails1',
+      ];
+      const modelNames2 = [
+        'userProfileDetails2',
+        'UserProfileDetails2',
+        'user-profile-details-2',
+        'user_profile_details_2',
+        'USER-PROFILE-DETAILS-2',
+        'USER_PROFILE_DETAILS_2',
+        'USERPROFILEDETAILS2',
+        'userprofiledetails2',
+      ];
+      S.addModel(model1);
+      modelNames1.forEach(v => expect(S.hasModel(v)).to.be.true);
+      modelNames2.forEach(v => expect(S.hasModel(v)).to.be.false);
+    });
   });
 
-  it('uses ModelDefinitionValidator to validate a given model', function () {
-    const V = S.getService(ModelDefinitionValidator);
-    sandbox.on(V, 'validate');
-    const model = {name: 'model'};
-    S.addModel(model);
-    expect(V.validate).to.have.been.called.once;
-    expect(V.validate).to.have.been.called.with.exactly(model);
+  describe('getModel', function () {
+    it('returns the model by its name', function () {
+      const model = {name: 'model'};
+      S.addModel(model);
+      const result = S.getModel('model');
+      expect(result).to.be.eql(model);
+    });
+
+    it('throws an error if the model is not defined', function () {
+      const throwable = () => S.getModel('undefined');
+      expect(throwable).to.throw('The model "undefined" is not defined.');
+    });
+
+    it('should ignore naming convention of the model name', function () {
+      const model = {name: 'userProfileDetails'};
+      const modelNames = [
+        'userProfileDetails',
+        'UserProfileDetails',
+        'user-profile-details',
+        'user_profile_details',
+        'USER-PROFILE-DETAILS',
+        'USER_PROFILE_DETAILS',
+        'USERPROFILEDETAILS',
+        'userprofiledetails',
+      ];
+      S.addModel(model);
+      modelNames.forEach(v => expect(S.getModel(v)).to.be.eq(model));
+    });
+
+    it('should respect numbers in the model name', function () {
+      const model1 = {name: 'userProfileDetails1'};
+      const modelNames1 = [
+        'userProfileDetails1',
+        'UserProfileDetails1',
+        'user-profile-details-1',
+        'user_profile_details_1',
+        'USER-PROFILE-DETAILS-1',
+        'USER_PROFILE_DETAILS_1',
+        'USERPROFILEDETAILS1',
+        'userprofiledetails1',
+      ];
+      const modelNames2 = [
+        'userProfileDetails2',
+        'UserProfileDetails2',
+        'user-profile-details-2',
+        'user_profile_details_2',
+        'USER-PROFILE-DETAILS-2',
+        'USER_PROFILE_DETAILS_2',
+        'USERPROFILEDETAILS2',
+        'userprofiledetails2',
+      ];
+      S.addModel(model1);
+      modelNames1.forEach(v => expect(S.getModel(v)).to.be.eq(model1));
+      modelNames2.forEach(v => expect(() => S.getModel(v)).to.throw(Error));
+    });
   });
 });

+ 4 - 2
src/repository/repository-registry.js

@@ -1,5 +1,6 @@
 import {Service} from '@e22m4u/js-service';
 import {Repository} from './repository.js';
+import {modelNameToModelKey} from '../utils/index.js';
 import {InvalidArgumentError} from '../errors/index.js';
 
 /**
@@ -48,10 +49,11 @@ export class RepositoryRegistry extends Service {
    * @returns {Repository}
    */
   getRepository(modelName) {
-    let repository = this._repositories[modelName];
+    const modelKey = modelNameToModelKey(modelName);
+    let repository = this._repositories[modelKey];
     if (repository) return repository;
     repository = new this._repositoryCtor(this.container, modelName);
-    this._repositories[modelName] = repository;
+    this._repositories[modelKey] = repository;
     return repository;
   }
 }

+ 39 - 9
src/repository/repository-registry.spec.js

@@ -10,29 +10,59 @@ describe('RepositoryRegistry', function () {
       const dbs = new DatabaseSchema();
       dbs.defineDatasource({name: 'datasource', adapter: 'memory'});
       dbs.defineModel({name: 'model', datasource: 'datasource'});
-      const registry = dbs.getService(RepositoryRegistry);
-      registry.setRepositoryCtor(MyRepository);
-      const rep = registry.getRepository('model');
+      const reg = dbs.getService(RepositoryRegistry);
+      reg.setRepositoryCtor(MyRepository);
+      const rep = reg.getRepository('model');
       expect(rep).to.be.instanceof(Repository);
       expect(rep).to.be.instanceof(MyRepository);
     });
   });
 
   describe('getRepository', function () {
-    it('uses a given model name to return an existing repository or create the new', function () {
+    it('returns an existing repository by the given name or create new one', function () {
       const dbs = new DatabaseSchema();
       dbs.defineDatasource({name: 'datasource', adapter: 'memory'});
       dbs.defineModel({name: 'modelA', datasource: 'datasource'});
       dbs.defineModel({name: 'modelB', datasource: 'datasource'});
-      const registry = dbs.getService(RepositoryRegistry);
-      const repA1 = registry.getRepository('modelA');
-      const repA2 = registry.getRepository('modelA');
-      const repB1 = registry.getRepository('modelB');
-      const repB2 = registry.getRepository('modelB');
+      const reg = dbs.getService(RepositoryRegistry);
+      const repA1 = reg.getRepository('modelA');
+      const repA2 = reg.getRepository('modelA');
+      const repB1 = reg.getRepository('modelB');
+      const repB2 = reg.getRepository('modelB');
       expect(repA1).to.be.eq(repA2);
       expect(repB1).to.be.eq(repB2);
       expect(repA1).to.be.not.eq(repB1);
       expect(repA2).to.be.not.eq(repB2);
     });
+
+    it('should ignore naming convention of the model name', function () {
+      const dbs = new DatabaseSchema();
+      const modelName = 'userProfileDetails';
+      dbs.defineDatasource({name: 'datasource', adapter: 'memory'});
+      dbs.defineModel({name: modelName, datasource: 'datasource'});
+      const reg = dbs.getService(RepositoryRegistry);
+      const rep = reg.getRepository(modelName);
+      const modelNames = [
+        'UserProfileDetails',
+        'user-profile-details',
+        'user_profile_details',
+        'USER-PROFILE-DETAILS',
+        'USER_PROFILE_DETAILS',
+        'USERPROFILEDETAILS',
+        'userprofiledetails',
+      ];
+      modelNames.forEach(v => expect(reg.getRepository(v)).to.be.eq(rep));
+    });
+
+    it('should respect numbers in the model name', function () {
+      const dbs = new DatabaseSchema();
+      dbs.defineDatasource({name: 'datasource', adapter: 'memory'});
+      dbs.defineModel({name: 'model1', datasource: 'datasource'});
+      dbs.defineModel({name: 'model2', datasource: 'datasource'});
+      const reg = dbs.getService(RepositoryRegistry);
+      const rep1 = reg.getRepository('model1');
+      const rep2 = reg.getRepository('model2');
+      expect(rep1).to.be.not.eq(rep2);
+    });
   });
 });

+ 1 - 0
src/utils/index.d.ts

@@ -11,4 +11,5 @@ export * from './get-value-by-path.js';
 export * from './transform-promise.js';
 export * from './select-object-keys.js';
 export * from './exclude-object-keys.js';
+export * from './model-name-to-model-key.js';
 export * from './get-decorator-target-type.js';

+ 1 - 0
src/utils/index.js

@@ -11,4 +11,5 @@ export * from './get-value-by-path.js';
 export * from './transform-promise.js';
 export * from './select-object-keys.js';
 export * from './exclude-object-keys.js';
+export * from './model-name-to-model-key.js';
 export * from './get-decorator-target-type.js';

+ 6 - 0
src/utils/model-name-to-model-key.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Model name to model key.
+ * 
+ * @param modelName
+ */
+export function modelNameToModelKey(modelName: string): string;

+ 17 - 0
src/utils/model-name-to-model-key.js

@@ -0,0 +1,17 @@
+import {InvalidArgumentError} from '../errors/index.js';
+
+/**
+ * Model name to model key.
+ *
+ * @param {string} modelName
+ * @returns {string}
+ */
+export function modelNameToModelKey(modelName) {
+  if (!modelName || typeof modelName !== 'string' || /\s/.test(modelName))
+    throw new InvalidArgumentError(
+      'The model name should be a non-empty String ' +
+        'without spaces, but %v given.',
+      modelName,
+    );
+  return modelName.toLowerCase().replace(/[-_]/g, '');
+}

+ 92 - 0
src/utils/model-name-to-model-key.spec.js

@@ -0,0 +1,92 @@
+import {expect} from 'chai';
+import {modelNameToModelKey} from './model-name-to-model-key.js';
+
+describe('modelNameToModelKey', function () {
+  it('should return a simple lowercase string as is', function () {
+    expect(modelNameToModelKey('user')).to.be.eq('user');
+  });
+
+  it('should convert to lowercase and remove hyphens and underscores', function () {
+    const modelNames = [
+      'userProfileDetails',
+      'UserProfileDetails',
+      'user-profile-details',
+      'user_profile_details',
+      'USER-PROFILE-DETAILS',
+      'USER_PROFILE_DETAILS',
+      'USERPROFILEDETAILS',
+      'userprofiledetails',
+    ];
+    modelNames.forEach(v =>
+      expect(modelNameToModelKey(v)).to.be.eq('userprofiledetails'),
+    );
+  });
+
+  it('should handle a mixed string with uppercase, hyphens and underscores', function () {
+    const modelName = 'User_Profile-Details';
+    const expected = 'userprofiledetails';
+    expect(modelNameToModelKey(modelName)).to.be.eq(expected);
+  });
+
+  it('should not remove numbers from the string', function () {
+    const modelName = 'Type1-Model_2';
+    const expected = 'type1model2';
+    expect(modelNameToModelKey(modelName)).to.be.eq(expected);
+  });
+
+  it('should throw an error for an empty string', function () {
+    const throwable = () => modelNameToModelKey('');
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but "" given.',
+    );
+  });
+
+  it('should throw an error for a string with spaces', function () {
+    const throwable = () => modelNameToModelKey('user profile');
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but "user profile" given.',
+    );
+  });
+
+  it('should throw an error for null', function () {
+    const throwable = () => modelNameToModelKey(null);
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but null given.',
+    );
+  });
+
+  it('should throw an error for undefined', function () {
+    const throwable = () => modelNameToModelKey(undefined);
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but undefined given.',
+    );
+  });
+
+  it('should throw an error for a number', function () {
+    const throwable = () => modelNameToModelKey(123);
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but 123 given.',
+    );
+  });
+
+  it('should throw an error for an object', function () {
+    const throwable = () => modelNameToModelKey({name: 'test'});
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but Object given.',
+    );
+  });
+
+  it('should throw an error for an array', function () {
+    const throwable = () => modelNameToModelKey(['test']);
+    expect(throwable).to.throw(
+      'The model name should be a non-empty String ' +
+        'without spaces, but Array given.',
+    );
+  });
+});