Browse Source

refactor: replaces chai-spies with @e22m4u/js-spy

e22m4u 1 day ago
parent
commit
c6553393b9

+ 2 - 1
.mocharc.json

@@ -1,4 +1,5 @@
 {
   "extension": ["js"],
-  "spec": "src/**/*.spec.js"
+  "spec": "src/**/*.spec.js",
+  "require": "mocha.setup.js"
 }

+ 6 - 0
mocha.setup.js

@@ -0,0 +1,6 @@
+import * as chai from 'chai';
+import {chaiSpies} from '@e22m4u/js-spy';
+import chaiAsPromised from 'chai-as-promised';
+
+chai.use(chaiSpies);
+chai.use(chaiAsPromised);

+ 1 - 1
package.json

@@ -46,9 +46,9 @@
   "devDependencies": {
     "@commitlint/cli": "~20.1.0",
     "@commitlint/config-conventional": "~20.0.0",
+    "@e22m4u/js-spy": "~0.3.4",
     "@types/chai": "~5.2.3",
     "@types/chai-as-promised": "~8.0.2",
-    "@types/chai-spies": "~1.0.6",
     "@types/mocha": "~10.0.10",
     "c8": "~10.1.3",
     "chai": "~6.2.1",

+ 8 - 8
src/adapter/adapter.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {chai} from '../chai.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {DatabaseSchema} from '../database-schema.js';
 import {Adapter, ADAPTER_CLASS_NAME} from './adapter.js';
 import {Service, ServiceContainer} from '@e22m4u/js-service';
@@ -12,7 +12,7 @@ import {
   PropertyUniquenessDecorator,
 } from './decorator/index.js';
 
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('Adapter', function () {
   it('exposes static property "kinds"', function () {
@@ -24,7 +24,7 @@ describe('Adapter', function () {
 
   describe('constructor', function () {
     afterEach(function () {
-      sandbox.restore();
+      spies.restore();
     });
 
     it('inherits from the Service class', function () {
@@ -52,11 +52,11 @@ describe('Adapter', function () {
         expect(ctx).to.be.instanceof(Adapter);
         order.push(this);
       };
-      sandbox.on(dec1, 'decorate', decorate);
-      sandbox.on(dec2, 'decorate', decorate);
-      sandbox.on(dec3, 'decorate', decorate);
-      sandbox.on(dec4, 'decorate', decorate);
-      sandbox.on(dec5, 'decorate', decorate);
+      spies.on(dec1, 'decorate', decorate);
+      spies.on(dec2, 'decorate', decorate);
+      spies.on(dec3, 'decorate', decorate);
+      spies.on(dec4, 'decorate', decorate);
+      spies.on(dec5, 'decorate', decorate);
       new Adapter(dbs.container);
       expect(order).to.be.empty;
       expect(dec1.decorate).to.be.not.called;

+ 13 - 13
src/adapter/decorator/data-sanitizing-decorator.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {Adapter} from '../adapter.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {DatabaseSchema} from '../../database-schema.js';
 import {ModelDataSanitizer} from '../../definition/index.js';
 
@@ -36,50 +36,50 @@ class TestAdapter extends Adapter {
 
 const A = dbs.getService(TestAdapter);
 const V = dbs.getService(ModelDataSanitizer);
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('DataSanitizingDecorator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   it('overrides the "create" method and sanitizes a given data', async function () {
-    sandbox.on(V, 'sanitize');
+    spies.on(V, 'sanitize');
     const data = {};
     await A.create('model', data);
     expect(V.sanitize).to.be.called.once;
-    expect(V.sanitize).to.be.called.with.exactly('model', data);
+    expect(V.sanitize).to.be.called.with('model', data);
   });
 
   it('overrides the "replaceById" method and sanitizes a given data', async function () {
-    sandbox.on(V, 'sanitize');
+    spies.on(V, 'sanitize');
     const data = {};
     await A.replaceById('model', 1, data);
     expect(V.sanitize).to.be.called.once;
-    expect(V.sanitize).to.be.called.with.exactly('model', data);
+    expect(V.sanitize).to.be.called.with('model', data);
   });
 
   it('overrides the "replaceOrCreate" method and sanitizes a given data', async function () {
-    sandbox.on(V, 'sanitize');
+    spies.on(V, 'sanitize');
     const data = {};
     await A.replaceOrCreate('model', data);
     expect(V.sanitize).to.be.called.once;
-    expect(V.sanitize).to.be.called.with.exactly('model', data);
+    expect(V.sanitize).to.be.called.with('model', data);
   });
 
   it('overrides the "patch" method and sanitizes a given data', async function () {
-    sandbox.on(V, 'sanitize');
+    spies.on(V, 'sanitize');
     const data = {};
     await A.patch('model', data);
     expect(V.sanitize).to.be.called.once;
-    expect(V.sanitize).to.be.called.with.exactly('model', data);
+    expect(V.sanitize).to.be.called.with('model', data);
   });
 
   it('overrides the "patchById" method and sanitizes a given data', async function () {
-    sandbox.on(V, 'sanitize');
+    spies.on(V, 'sanitize');
     const data = {};
     await A.patchById('model', 1, data);
     expect(V.sanitize).to.be.called.once;
-    expect(V.sanitize).to.be.called.with.exactly('model', data);
+    expect(V.sanitize).to.be.called.with('model', data);
   });
 });

+ 10 - 10
src/adapter/decorator/default-values-decorator.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {Adapter} from '../adapter.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {DatabaseSchema} from '../../database-schema.js';
 import {DataType, ModelDefinitionUtils} from '../../definition/index.js';
 
@@ -57,15 +57,15 @@ class TestAdapter extends Adapter {
 
 const A = dbs.getService(TestAdapter);
 const U = dbs.getService(ModelDefinitionUtils);
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('DefaultValuesDecorator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   it('overrides the "create" method method and sets default values to input data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -81,7 +81,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "replaceById" method and sets default values to input data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -97,7 +97,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "replaceOrCreate" method and sets default values to input data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -113,7 +113,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "patch" method and sets default values to input data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -129,7 +129,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "patchById" method and sets default values to input data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -145,7 +145,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "find" method and sets default values to output data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {
@@ -161,7 +161,7 @@ describe('DefaultValuesDecorator', function () {
   });
 
   it('overrides the "findById" method and sets default values to output data', async function () {
-    sandbox.on(
+    spies.on(
       U,
       'setDefaultValuesToEmptyProperties',
       (modelName, modelData, onlyProvidedProperties = false) => {

+ 14 - 34
src/adapter/decorator/fields-filtering-decorator.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {Adapter} from '../adapter.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {FieldsClauseTool} from '../../filter/index.js';
 import {DatabaseSchema} from '../../database-schema.js';
 
@@ -55,63 +55,47 @@ class TestAdapter extends Adapter {
 
 const A = dbs.getService(TestAdapter);
 const T = dbs.getService(FieldsClauseTool);
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('FieldsFilteringDecorator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   it('overrides the "create" method method and filtering output fields', async function () {
-    sandbox.on(T, 'filter');
+    spies.on(T, 'filter');
     const retval = await A.create(MODEL_NAME, {}, FILTER);
     expect(retval).to.be.eql(RETVAL_DATA);
     expect(T.filter).to.be.called.once;
-    expect(T.filter).to.be.called.with.exactly(
-      MODEL_DATA,
-      MODEL_NAME,
-      FILTER.fields,
-    );
+    expect(T.filter).to.be.called.with(MODEL_DATA, MODEL_NAME, FILTER.fields);
   });
 
   it('overrides the "replaceById" method and filtering output fields', async function () {
-    sandbox.on(T, 'filter');
+    spies.on(T, 'filter');
     const retval = await A.replaceById(MODEL_NAME, 1, {}, FILTER);
     expect(retval).to.be.eql(RETVAL_DATA);
     expect(T.filter).to.be.called.once;
-    expect(T.filter).to.be.called.with.exactly(
-      MODEL_DATA,
-      MODEL_NAME,
-      FILTER.fields,
-    );
+    expect(T.filter).to.be.called.with(MODEL_DATA, MODEL_NAME, FILTER.fields);
   });
 
   it('overrides the "replaceOrCreate" method and filtering output fields', async function () {
-    sandbox.on(T, 'filter');
+    spies.on(T, 'filter');
     const retval = await A.replaceOrCreate(MODEL_NAME, {}, FILTER);
     expect(retval).to.be.eql(RETVAL_DATA);
     expect(T.filter).to.be.called.once;
-    expect(T.filter).to.be.called.with.exactly(
-      MODEL_DATA,
-      MODEL_NAME,
-      FILTER.fields,
-    );
+    expect(T.filter).to.be.called.with(MODEL_DATA, MODEL_NAME, FILTER.fields);
   });
 
   it('overrides the "patchById" method and filtering output fields', async function () {
-    sandbox.on(T, 'filter');
+    spies.on(T, 'filter');
     const retval = await A.patchById(MODEL_NAME, 1, {}, FILTER);
     expect(retval).to.be.eql(RETVAL_DATA);
     expect(T.filter).to.be.called.once;
-    expect(T.filter).to.be.called.with.exactly(
-      MODEL_DATA,
-      MODEL_NAME,
-      FILTER.fields,
-    );
+    expect(T.filter).to.be.called.with(MODEL_DATA, MODEL_NAME, FILTER.fields);
   });
 
   it('overrides the "find" method and filtering output fields', async function () {
-    sandbox.on(T, 'filter', function (entities, modelName, fields) {
+    spies.on(T, 'filter', function (entities, modelName, fields) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eq(MODEL_NAME);
       expect(fields).to.be.eql(FILTER.fields);
@@ -123,14 +107,10 @@ describe('FieldsFilteringDecorator', function () {
   });
 
   it('overrides the "findById" method and filtering output fields', async function () {
-    sandbox.on(T, 'filter');
+    spies.on(T, 'filter');
     const retval = await A.findById(MODEL_NAME, 1, FILTER);
     expect(retval).to.be.eql(RETVAL_DATA);
     expect(T.filter).to.be.called.once;
-    expect(T.filter).to.be.called.with.exactly(
-      MODEL_DATA,
-      MODEL_NAME,
-      FILTER.fields,
-    );
+    expect(T.filter).to.be.called.with(MODEL_DATA, MODEL_NAME, FILTER.fields);
   });
 });

+ 9 - 9
src/adapter/decorator/inclusion-decorator.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {Adapter} from '../adapter.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {DatabaseSchema} from '../../database-schema.js';
 import {IncludeClauseTool} from '../../filter/index.js';
 
@@ -53,15 +53,15 @@ class TestAdapter extends Adapter {
 
 const A = dbs.getService(TestAdapter);
 const T = dbs.getService(IncludeClauseTool);
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('InclusionDecorator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   it('overrides the "create" method method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);
@@ -73,7 +73,7 @@ describe('InclusionDecorator', function () {
   });
 
   it('overrides the "replaceById" method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);
@@ -85,7 +85,7 @@ describe('InclusionDecorator', function () {
   });
 
   it('overrides the "replaceOrCreate" method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);
@@ -97,7 +97,7 @@ describe('InclusionDecorator', function () {
   });
 
   it('overrides the "patchById" method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);
@@ -109,7 +109,7 @@ describe('InclusionDecorator', function () {
   });
 
   it('overrides the "find" method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);
@@ -121,7 +121,7 @@ describe('InclusionDecorator', function () {
   });
 
   it('overrides the "findById" method and applies clause inclusion', async function () {
-    sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
+    spies.on(T, 'includeTo', function (entities, modelName, clause) {
       expect(entities).to.be.eql([MODEL_DATA]);
       expect(modelName).to.be.eql('model');
       expect(clause).to.be.eql(FILTER.include);

+ 8 - 8
src/adapter/decorator/property-uniqueness-decorator.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {Adapter} from '../adapter.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {DatabaseSchema} from '../../database-schema.js';
 import {PropertyUniquenessValidator} from '../../definition/index.js';
 
@@ -36,16 +36,16 @@ class TestAdapter extends Adapter {
 
 const A = dbs.getService(TestAdapter);
 const V = dbs.getService(PropertyUniquenessValidator);
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('PropertyUniquenessDecorator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   it('overrides the "create" method and validates a given data', async function () {
     const data = {kind: 'data'};
-    sandbox.on(
+    spies.on(
       V,
       'validate',
       (countMethod, methodName, modelName, modelData, id = undefined) => {
@@ -63,7 +63,7 @@ describe('PropertyUniquenessDecorator', function () {
 
   it('overrides the "replaceById" method and validates a given data', async function () {
     const data = {kind: 'data'};
-    sandbox.on(
+    spies.on(
       V,
       'validate',
       (countMethod, methodName, modelName, modelData, id = undefined) => {
@@ -81,7 +81,7 @@ describe('PropertyUniquenessDecorator', function () {
 
   it('overrides the "replaceOrCreate" method and validates a given data', async function () {
     const data = {kind: 'data'};
-    sandbox.on(
+    spies.on(
       V,
       'validate',
       (countMethod, methodName, modelName, modelData, id = undefined) => {
@@ -99,7 +99,7 @@ describe('PropertyUniquenessDecorator', function () {
 
   it('overrides the "patch" method and validates a given data', async function () {
     const data = {kind: 'data'};
-    sandbox.on(
+    spies.on(
       V,
       'validate',
       (countMethod, methodName, modelName, modelData, id = undefined) => {
@@ -117,7 +117,7 @@ describe('PropertyUniquenessDecorator', function () {
 
   it('overrides the "patchById" method and validates a given data', async function () {
     const data = {kind: 'data'};
-    sandbox.on(
+    spies.on(
       V,
       'validate',
       (countMethod, methodName, modelName, modelData, id = undefined) => {

+ 0 - 9
src/chai.js

@@ -1,9 +0,0 @@
-import * as chaiModule from 'chai';
-import chaiSpies from 'chai-spies';
-import chaiAsPromised from 'chai-as-promised';
-const chai = {...chaiModule};
-
-chaiSpies(chai, chai.util);
-chaiAsPromised(chai, chai.util);
-
-export {chai};

+ 7 - 7
src/definition/definition-registry.spec.js

@@ -1,10 +1,10 @@
 import {expect} from 'chai';
-import {chai} from '../chai.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {ModelDefinitionValidator} from './model/index.js';
 import {DefinitionRegistry} from './definition-registry.js';
 import {DatasourceDefinitionValidator} from '../definition/index.js';
 
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('DefinitionRegistry', function () {
   let S;
@@ -14,7 +14,7 @@ describe('DefinitionRegistry', function () {
   });
 
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   describe('addDatasource', function () {
@@ -27,11 +27,11 @@ describe('DefinitionRegistry', function () {
 
     it('uses DatasourceDefinitionValidator to validate a given datasource', function () {
       const V = S.getService(DatasourceDefinitionValidator);
-      sandbox.on(V, 'validate');
+      spies.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);
+      expect(V.validate).to.have.been.called.with(datasource);
     });
 
     it('throws an error if a given datasource is already defined', function () {
@@ -78,11 +78,11 @@ describe('DefinitionRegistry', function () {
 
     it('uses ModelDefinitionValidator to validate a given model', function () {
       const V = S.getService(ModelDefinitionValidator);
-      sandbox.on(V, 'validate');
+      spies.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);
+      expect(V.validate).to.have.been.called.with(model);
     });
 
     it('throws an error if a given model is already defined', function () {

+ 5 - 5
src/definition/model/model-definition-utils.spec.js

@@ -1,7 +1,7 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {format} from '@e22m4u/js-format';
 import {DataType} from './properties/index.js';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {RelationType} from './relations/index.js';
 import {DatabaseSchema} from '../../database-schema.js';
 import {EmptyValuesService} from '@e22m4u/js-empty-values';
@@ -12,11 +12,11 @@ import {
   DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK,
 } from './model-definition-utils.js';
 
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('ModelDefinitionUtils', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   describe('getPrimaryKeyAsPropertyName', function () {
@@ -34,7 +34,7 @@ describe('ModelDefinitionUtils', function () {
     it('throws an error if a property name of a default primary key already in use as a regular property', function () {
       const dbs = new DatabaseSchema();
       const mdu = dbs.getService(ModelDefinitionUtils);
-      sandbox.on(
+      spies.on(
         mdu,
         'getPropertiesDefinitionInBaseModelHierarchy',
         function (modelName) {
@@ -169,7 +169,7 @@ describe('ModelDefinitionUtils', function () {
     it('throws an error if a property name of a default primary key already in use as a regular property', function () {
       const dbs = new DatabaseSchema();
       const mdu = dbs.getService(ModelDefinitionUtils);
-      sandbox.on(
+      spies.on(
         mdu,
         'getPropertiesDefinitionInBaseModelHierarchy',
         function (modelName) {

+ 7 - 7
src/definition/model/model-definition-validator.spec.js

@@ -1,16 +1,16 @@
 import {expect} from 'chai';
-import {chai} from '../../chai.js';
 import {format} from '@e22m4u/js-format';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {RelationsDefinitionValidator} from './relations/index.js';
 import {PropertiesDefinitionValidator} from './properties/index.js';
 import {ModelDefinitionValidator} from './model-definition-validator.js';
 
 const S = new ModelDefinitionValidator();
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('ModelDefinitionValidator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   describe('validate', function () {
@@ -127,20 +127,20 @@ describe('ModelDefinitionValidator', function () {
 
     it('uses PropertiesDefinitionValidator service to validate model properties', function () {
       const V = S.getService(PropertiesDefinitionValidator);
-      sandbox.on(V, 'validate');
+      spies.on(V, 'validate');
       const properties = {};
       S.validate({name: 'model', properties});
       expect(V.validate).to.have.been.called.once;
-      expect(V.validate).to.have.been.called.with.exactly('model', properties);
+      expect(V.validate).to.have.been.called.with('model', properties);
     });
 
     it('uses RelationsDefinitionValidator service to validate model relations', function () {
       const V = S.getService(RelationsDefinitionValidator);
-      sandbox.on(V, 'validate');
+      spies.on(V, 'validate');
       const relations = {};
       S.validate({name: 'model', relations});
       expect(V.validate).to.have.been.called.once;
-      expect(V.validate).to.have.been.called.with.exactly('model', relations);
+      expect(V.validate).to.have.been.called.with('model', relations);
     });
   });
 });

+ 5 - 5
src/definition/model/properties/properties-definition-validator.spec.js

@@ -1,17 +1,17 @@
 import {expect} from 'chai';
-import {chai} from '../../../chai.js';
 import {DataType} from './data-type.js';
 import {format} from '@e22m4u/js-format';
+import {createSpiesGroup} from '@e22m4u/js-spy';
 import {PropertyUniqueness} from './property-uniqueness.js';
 import {PropertiesDefinitionValidator} from './properties-definition-validator.js';
 import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
 
 const S = new PropertiesDefinitionValidator();
-const sandbox = chai.spy.sandbox();
+const spies = createSpiesGroup();
 
 describe('PropertiesDefinitionValidator', function () {
   afterEach(function () {
-    sandbox.restore();
+    spies.restore();
   });
 
   describe('validate', function () {
@@ -411,11 +411,11 @@ describe('PropertiesDefinitionValidator', function () {
 
     it('uses PrimaryKeysDefinitionValidator to validate primary keys', function () {
       const V = S.getService(PrimaryKeysDefinitionValidator);
-      sandbox.on(V, 'validate');
+      spies.on(V, 'validate');
       const propDefs = {};
       S.validate('model', propDefs);
       expect(V.validate).to.have.been.called.once;
-      expect(V.validate).to.have.been.called.with.exactly('model', propDefs);
+      expect(V.validate).to.have.been.called.with('model', propDefs);
     });
 
     it('expects the provided option "unique" to be a Boolean or the PropertyUniqueness', function () {