|
|
@@ -2,6 +2,7 @@ import {expect} from 'chai';
|
|
|
import {format} from '@e22m4u/js-format';
|
|
|
import {DataType} from './properties/index.js';
|
|
|
import {DatabaseSchema} from '../../database-schema.js';
|
|
|
+import {EmptyValuesService} from '@e22m4u/js-empty-values';
|
|
|
import {DefinitionRegistry} from '../definition-registry.js';
|
|
|
import {ModelDataTransformer} from './model-data-transformer.js';
|
|
|
import {PropertyTransformerRegistry} from './properties/index.js';
|
|
|
@@ -21,7 +22,7 @@ describe('ModelDataTransformer', function () {
|
|
|
const throwable = v => () => T.transform('model', v);
|
|
|
const error = v =>
|
|
|
format(
|
|
|
- 'The data of the model "model" should be an Object, but %s given.',
|
|
|
+ 'The data of the model "model" should be an Object, but %s was given.',
|
|
|
v,
|
|
|
);
|
|
|
expect(throwable('str')).to.throw(error('"str"'));
|
|
|
@@ -54,42 +55,58 @@ describe('ModelDataTransformer', function () {
|
|
|
expect(res).to.be.eql(modelData);
|
|
|
});
|
|
|
|
|
|
- describe('the option "transform" with a string value', function () {
|
|
|
- it('transforms the property value by its transformer', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = value => String(value);
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: 'myTransformer',
|
|
|
- },
|
|
|
+ it('the option "transform" requires a non-empty String, a Function, an Array or an Object', function () {
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs
|
|
|
+ .getService(PropertyTransformerRegistry)
|
|
|
+ .addTransformer('myTransformer', () => 'transformed');
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: undefined,
|
|
|
},
|
|
|
- });
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 10});
|
|
|
- expect(res).to.be.eql({foo: '10'});
|
|
|
+ },
|
|
|
});
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = v => () => {
|
|
|
+ const models = dbs.getService(DefinitionRegistry)['_models'];
|
|
|
+ models.model.properties.foo.transform = v;
|
|
|
+ T.transform('model', {foo: 'bar'});
|
|
|
+ };
|
|
|
+ const error = v =>
|
|
|
+ format(
|
|
|
+ 'The provided option "transform" for the property "foo" in the model "model" ' +
|
|
|
+ 'should be either a transformer name, a transformer function, an array ' +
|
|
|
+ 'of transformer names or functions, or an object mapping transformer ' +
|
|
|
+ 'names to their arguments, but %s was given.',
|
|
|
+ v,
|
|
|
+ );
|
|
|
+ expect(throwable('')).to.throw(error('""'));
|
|
|
+ expect(throwable(10)).to.throw(error('10'));
|
|
|
+ expect(throwable(0)).to.throw(error('0'));
|
|
|
+ expect(throwable(true)).to.throw(error('true'));
|
|
|
+ expect(throwable(false)).to.throw(error('false'));
|
|
|
+ throwable('myTransformer')();
|
|
|
+ throwable(() => 10)();
|
|
|
+ throwable(() => Promise.resolve('bar'))();
|
|
|
+ throwable(['myTransformer'])();
|
|
|
+ throwable([() => Promise.resolve('bar')])();
|
|
|
+ throwable([])();
|
|
|
+ throwable({myTransformer: true})();
|
|
|
+ throwable({})();
|
|
|
+ });
|
|
|
|
|
|
- it('passes specific arguments to the transformer function', function () {
|
|
|
+ describe('when the option "transform" is a String', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = (value, options, context) => {
|
|
|
- expect(value).to.be.eq('input');
|
|
|
- expect(options).to.be.undefined;
|
|
|
- expect(context).to.be.eql({
|
|
|
- transformerName: 'myTransformer',
|
|
|
- modelName: 'model',
|
|
|
- propName: 'foo',
|
|
|
- });
|
|
|
- return 'transformed';
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
@@ -100,41 +117,51 @@ describe('ModelDataTransformer', function () {
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 'input'});
|
|
|
- expect(res).to.be.eql({foo: 'transformed'});
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
|
|
|
- it('does not transform a property value if it is not provided', function () {
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: 'myTransformer',
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {});
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
|
|
|
- it('does not transform undefined and null values', function () {
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
+ type: DataType.ANY,
|
|
|
transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
@@ -144,70 +171,64 @@ describe('ModelDataTransformer', function () {
|
|
|
const res2 = T.transform('model', {foo: null});
|
|
|
expect(res1).to.be.eql({foo: undefined});
|
|
|
expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
|
|
|
- it('the parameter "isPartial" prevents to transform values of not provided properties', function () {
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
+ type: DataType.ANY,
|
|
|
transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
+ dbs.getService(EmptyValuesService).setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {}, true);
|
|
|
- expect(res).to.be.eql({});
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
|
|
|
- it('transforms the property value by its asynchronous transformer', async function () {
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer1 = (value, options) => {
|
|
|
- expect(options).to.be.undefined;
|
|
|
- return Promise.resolve(`${value}2`);
|
|
|
- };
|
|
|
- const myTransformer2 = (value, options) => {
|
|
|
- expect(options).to.be.undefined;
|
|
|
- return Promise.resolve(`${value}3`);
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer1', myTransformer1)
|
|
|
- .addTransformer('myTransformer2', myTransformer2);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: 'myTransformer1',
|
|
|
- },
|
|
|
- bar: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: 'myTransformer2',
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const promise = T.transform('model', {foo: '1', bar: '2'});
|
|
|
- expect(promise).to.be.instanceof(Promise);
|
|
|
- const res = await promise;
|
|
|
- expect(res).to.be.eql({foo: '12', bar: '23'});
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- describe('the option "transform" with an array value', function () {
|
|
|
- it('transforms given properties by their transformers', function () {
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = value => String(value);
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
@@ -219,428 +240,2073 @@ describe('ModelDataTransformer', function () {
|
|
|
type: DataType.ANY,
|
|
|
transform: ['myTransformer'],
|
|
|
},
|
|
|
- baz: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: ['myTransformer'],
|
|
|
- },
|
|
|
- },
|
|
|
- });
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 1, bar: 2, baz: 3});
|
|
|
- expect(res).to.be.eql({foo: '1', bar: '2', baz: '3'});
|
|
|
- });
|
|
|
-
|
|
|
- it('transforms the property value by its transformers in specified order', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const order = [];
|
|
|
- const myTransformer1 = value => {
|
|
|
- order.push('myTransformer1');
|
|
|
- return value + '1';
|
|
|
- };
|
|
|
- const myTransformer2 = value => {
|
|
|
- order.push('myTransformer2');
|
|
|
- return value + '2';
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer1', myTransformer1)
|
|
|
- .addTransformer('myTransformer2', myTransformer2);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: ['myTransformer1', 'myTransformer2'],
|
|
|
- },
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 'value'});
|
|
|
- expect(res).to.be.eql({foo: 'value12'});
|
|
|
- expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
});
|
|
|
|
|
|
- it('passes specific arguments to the transformer function', function () {
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = (value, options, context) => {
|
|
|
- expect(value).to.be.eq('input');
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', (value, options, context) => {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
expect(options).to.be.undefined;
|
|
|
expect(context).to.be.eql({
|
|
|
transformerName: 'myTransformer',
|
|
|
modelName: 'model',
|
|
|
propName: 'foo',
|
|
|
});
|
|
|
- return 'transformed';
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
type: DataType.ANY,
|
|
|
- transform: ['myTransformer'],
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 'input'});
|
|
|
- expect(res).to.be.eql({foo: 'transformed'});
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
|
|
|
- it('does not transform a property value if it is not provided', function () {
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: ['myTransformer'],
|
|
|
- },
|
|
|
- },
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {});
|
|
|
- expect(res).to.be.eql({});
|
|
|
- });
|
|
|
-
|
|
|
- it('transforms undefined and null values', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: ['myTransformer'],
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res1 = T.transform('model', {foo: undefined});
|
|
|
- const res2 = T.transform('model', {foo: null});
|
|
|
- expect(res1).to.be.eql({foo: undefined});
|
|
|
- expect(res2).to.be.eql({foo: null});
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
|
|
|
- it('the parameter "isPartial" prevents to transform values of not provided properties', function () {
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: ['myTransformer'],
|
|
|
- },
|
|
|
- },
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {}, true);
|
|
|
- expect(res).to.be.eql({});
|
|
|
- });
|
|
|
-
|
|
|
- it('transforms the property value by its asynchronous transformers', async function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer1 = (value, options) => {
|
|
|
- expect(options).to.be.undefined;
|
|
|
- return Promise.resolve(`${value}2`);
|
|
|
- };
|
|
|
- const myTransformer2 = (value, options) => {
|
|
|
- expect(options).to.be.undefined;
|
|
|
- return Promise.resolve(`${value}3`);
|
|
|
- };
|
|
|
- const myTransformer3 = (value, options) => {
|
|
|
- expect(options).to.be.undefined;
|
|
|
- return Promise.resolve(`${value}4`);
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer1', myTransformer1)
|
|
|
- .addTransformer('myTransformer2', myTransformer2)
|
|
|
- .addTransformer('myTransformer3', myTransformer3);
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: ['myTransformer1', 'myTransformer2'],
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
bar: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: ['myTransformer2', 'myTransformer3'],
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const promise = T.transform('model', {foo: '1', bar: '2'});
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
expect(promise).to.be.instanceof(Promise);
|
|
|
const res = await promise;
|
|
|
- expect(res).to.be.eql({foo: '123', bar: '234'});
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- describe('the option "transform" with an object value', function () {
|
|
|
- it('transforms given properties by their transformers', function () {
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = value => String(value);
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
type: DataType.ANY,
|
|
|
- transform: {myTransformer: true},
|
|
|
- },
|
|
|
- bar: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: {myTransformer: true},
|
|
|
- },
|
|
|
- baz: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: {myTransformer: true},
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 1, bar: 2, baz: 3});
|
|
|
- expect(res).to.be.eql({foo: '1', bar: '2', baz: '3'});
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
|
|
|
- it('transforms the property value by its transformers in specified order', function () {
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
const dbs = new DatabaseSchema();
|
|
|
- const order = [];
|
|
|
- const myTransformer1 = value => {
|
|
|
- order.push('myTransformer1');
|
|
|
- return value + '1';
|
|
|
- };
|
|
|
- const myTransformer2 = value => {
|
|
|
- order.push('myTransformer2');
|
|
|
- return value + '2';
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer1', myTransformer1)
|
|
|
- .addTransformer('myTransformer2', myTransformer2);
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', async () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
dbs.defineModel({
|
|
|
name: 'model',
|
|
|
properties: {
|
|
|
foo: {
|
|
|
type: DataType.ANY,
|
|
|
- transform: {
|
|
|
- myTransformer1: true,
|
|
|
- myTransformer2: true,
|
|
|
- },
|
|
|
+ transform: 'myTransformer',
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 'value'});
|
|
|
- expect(res).to.be.eql({foo: 'value12'});
|
|
|
- expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
+ });
|
|
|
|
|
|
- it('passes specific arguments to the transformer function', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = (value, options, context) => {
|
|
|
- expect(value).to.be.eq('input');
|
|
|
- expect(options).to.be.eql({
|
|
|
- option1: 'value1',
|
|
|
- option2: 'value2',
|
|
|
+ describe('when the option "transform" is a Function', function () {
|
|
|
+ describe('named transformers', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ },
|
|
|
});
|
|
|
- expect(context).to.be.eql({
|
|
|
- transformerName: 'myTransformer',
|
|
|
- modelName: 'model',
|
|
|
- propName: 'foo',
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ },
|
|
|
});
|
|
|
- return 'transformed';
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: {
|
|
|
- myTransformer: {
|
|
|
- option1: 'value1',
|
|
|
- option2: 'value2',
|
|
|
- },
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {foo: 'input'});
|
|
|
- expect(res).to.be.eql({foo: 'transformed'});
|
|
|
- });
|
|
|
|
|
|
- it('does not transform a property value if it is not provided', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: {
|
|
|
- myTransformer: true,
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ dbs
|
|
|
+ .getService(EmptyValuesService)
|
|
|
+ .setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {});
|
|
|
- expect(res).to.be.eql({});
|
|
|
- });
|
|
|
|
|
|
- it('transforms undefined and null values', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: {
|
|
|
- myTransformer: true,
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res1 = T.transform('model', {foo: undefined});
|
|
|
- const res2 = T.transform('model', {foo: null});
|
|
|
- expect(res1).to.be.eql({foo: undefined});
|
|
|
- expect(res2).to.be.eql({foo: null});
|
|
|
- });
|
|
|
|
|
|
- it('the parameter "isPartial" prevents to transform values of not provided properties', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer = () => 'transformed';
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', myTransformer);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: {
|
|
|
- myTransformer: true,
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const res = T.transform('model', {}, true);
|
|
|
- expect(res).to.be.eql({});
|
|
|
- });
|
|
|
|
|
|
- it('transforms the property value by its asynchronous transformers', async function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- const myTransformer1 = (value, options) => {
|
|
|
- expect(options).to.be.eq('foo');
|
|
|
- return Promise.resolve(`${value}2`);
|
|
|
- };
|
|
|
- const myTransformer2 = (value, options) => {
|
|
|
- expect(options).to.be.eq('bar');
|
|
|
- return Promise.resolve(`${value}3`);
|
|
|
- };
|
|
|
- const myTransformer3 = (value, options) => {
|
|
|
- expect(options).to.be.eq('baz');
|
|
|
- return Promise.resolve(`${value}4`);
|
|
|
- };
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer1', myTransformer1)
|
|
|
- .addTransformer('myTransformer2', myTransformer2)
|
|
|
- .addTransformer('myTransformer3', myTransformer3);
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: {
|
|
|
- myTransformer1: 'foo',
|
|
|
- myTransformer2: 'bar',
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value, options, context) {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.undefined;
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: 'myTransformer',
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- bar: {
|
|
|
- type: DataType.STRING,
|
|
|
- transform: {
|
|
|
- myTransformer2: 'bar',
|
|
|
- myTransformer3: 'baz',
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const promise = T.transform('model', {foo: '1', bar: '2'});
|
|
|
- expect(promise).to.be.instanceof(Promise);
|
|
|
- const res = await promise;
|
|
|
- expect(res).to.be.eql({foo: '123', bar: '234'});
|
|
|
- });
|
|
|
- });
|
|
|
|
|
|
- it('the option "transform" requires a non-empty String, an Array or an Object', function () {
|
|
|
- const dbs = new DatabaseSchema();
|
|
|
- dbs
|
|
|
- .getService(PropertyTransformerRegistry)
|
|
|
- .addTransformer('myTransformer', () => 'transformed');
|
|
|
- dbs.defineModel({
|
|
|
- name: 'model',
|
|
|
- properties: {
|
|
|
- foo: {
|
|
|
- type: DataType.ANY,
|
|
|
- transform: undefined,
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = async function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: myTransformer,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('anonymous transformers', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ dbs
|
|
|
+ .getService(EmptyValuesService)
|
|
|
+ .setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value, options, context) {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.undefined;
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: undefined,
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform(value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ async transform() {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when the option "transform" is an Array', function () {
|
|
|
+ describe('when an Array element is a String', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ dbs
|
|
|
+ .getService(EmptyValuesService)
|
|
|
+ .setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', (value, options, context) => {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.undefined;
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: 'myTransformer',
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', async () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by transformers with the correct order', function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer1', value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ reg.addTransformer('myTransformer2', value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer1', 'myTransformer2'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by asynchronous transformers with the correct order', async function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer1', async value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ reg.addTransformer('myTransformer2', async value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: ['myTransformer1', 'myTransformer2'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = await T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when an Array element is a Function', function () {
|
|
|
+ describe('named transformers', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ dbs
|
|
|
+ .getService(EmptyValuesService)
|
|
|
+ .setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value, options, context) {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.undefined;
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: 'myTransformer',
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function (value) {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer = async function () {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by transformers with the correct order', function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer1 = function (value) {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ const myTransformer2 = function (value) {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer1, myTransformer2],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by asynchronous transformers with the correct order', async function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const myTransformer1 = async function (value) {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ };
|
|
|
+ const myTransformer2 = async function (value) {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ };
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [myTransformer1, myTransformer2],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = await T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('anonymous transformers', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ dbs
|
|
|
+ .getService(EmptyValuesService)
|
|
|
+ .setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ (value, options, context) => {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.undefined;
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: undefined,
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ async () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by transformers with the correct order', function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by asynchronous transformers with the correct order', async function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: [
|
|
|
+ async value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ },
|
|
|
+ async value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = await T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when the option "transform" is an Object', function () {
|
|
|
+ it('should not transform the non-provided property', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {});
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform non-provided properties when the option "isPartial" is true', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
},
|
|
|
- },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {}, true);
|
|
|
+ expect(res).to.be.eql({});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform undefined and null values', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res1 = T.transform('model', {foo: undefined});
|
|
|
+ const res2 = T.transform('model', {foo: null});
|
|
|
+ expect(res1).to.be.eql({foo: undefined});
|
|
|
+ expect(res2).to.be.eql({foo: null});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not transform the empty value', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('Should not to be called.');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ dbs.getService(EmptyValuesService).setEmptyValuesOf(DataType.ANY, [10]);
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(calls).to.be.eq(0);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by transformers', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 1, bar: 2});
|
|
|
+ expect(res).to.be.eql({foo: '1', bar: '2'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass arguments to the transformer', function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', (value, options, context) => {
|
|
|
+ calls++;
|
|
|
+ expect(value).to.be.eq(10);
|
|
|
+ expect(options).to.be.eq('test');
|
|
|
+ expect(context).to.be.eql({
|
|
|
+ transformerName: 'myTransformer',
|
|
|
+ modelName: 'model',
|
|
|
+ propName: 'foo',
|
|
|
+ });
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: 'test',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: 10});
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10'});
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform properties by the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', value => {
|
|
|
+ calls++;
|
|
|
+ return Promise.resolve(String(value));
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ bar: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10, bar: 20});
|
|
|
+ expect(promise).to.be.instanceof(Promise);
|
|
|
+ const res = await promise;
|
|
|
+ expect(res).to.be.eql({foo: '10', bar: '20'});
|
|
|
+ expect(calls).to.be.eq(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const throwable = () => T.transform('model', {foo: 10});
|
|
|
+ expect(throwable).to.throw('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error from the asynchronous transformer', async function () {
|
|
|
+ let calls = 0;
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer', async () => {
|
|
|
+ calls++;
|
|
|
+ throw new Error('My error');
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const promise = T.transform('model', {foo: 10});
|
|
|
+ await expect(promise).to.rejectedWith('My error');
|
|
|
+ expect(calls).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by transformers with the correct order', function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer1', value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ reg.addTransformer('myTransformer2', value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer1: true,
|
|
|
+ myTransformer2: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should transform the property by asynchronous transformers with the correct order', async function () {
|
|
|
+ const order = [];
|
|
|
+ const dbs = new DatabaseSchema();
|
|
|
+ const reg = dbs.getService(PropertyTransformerRegistry);
|
|
|
+ reg.addTransformer('myTransformer1', async value => {
|
|
|
+ order.push('myTransformer1');
|
|
|
+ return String(value);
|
|
|
+ });
|
|
|
+ reg.addTransformer('myTransformer2', async value => {
|
|
|
+ order.push('myTransformer2');
|
|
|
+ return value.toUpperCase();
|
|
|
+ });
|
|
|
+ dbs.defineModel({
|
|
|
+ name: 'model',
|
|
|
+ properties: {
|
|
|
+ foo: {
|
|
|
+ type: DataType.ANY,
|
|
|
+ transform: {
|
|
|
+ myTransformer1: true,
|
|
|
+ myTransformer2: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const T = dbs.getService(ModelDataTransformer);
|
|
|
+ const res = await T.transform('model', {foo: true});
|
|
|
+ expect(res).to.be.eql({foo: 'TRUE'});
|
|
|
+ expect(order).to.be.eql(['myTransformer1', 'myTransformer2']);
|
|
|
});
|
|
|
- const T = dbs.getService(ModelDataTransformer);
|
|
|
- const throwable = v => () => {
|
|
|
- const models = dbs.getService(DefinitionRegistry)['_models'];
|
|
|
- models.model.properties.foo.transform = v;
|
|
|
- T.transform('model', {foo: 'bar'});
|
|
|
- };
|
|
|
- const error = v =>
|
|
|
- format(
|
|
|
- 'The provided option "transform" of the property "foo" in the model "model" ' +
|
|
|
- 'should be a non-empty String, an Array of String or an Object, ' +
|
|
|
- 'but %s given.',
|
|
|
- v,
|
|
|
- );
|
|
|
- expect(throwable('')).to.throw(error('""'));
|
|
|
- expect(throwable(10)).to.throw(error('10'));
|
|
|
- expect(throwable(0)).to.throw(error('0'));
|
|
|
- expect(throwable(true)).to.throw(error('true'));
|
|
|
- expect(throwable(false)).to.throw(error('false'));
|
|
|
- throwable('myTransformer')();
|
|
|
- throwable(['myTransformer'])();
|
|
|
- throwable([])();
|
|
|
- throwable({myTransformer: true})();
|
|
|
- throwable({})();
|
|
|
});
|
|
|
});
|
|
|
});
|