|
|
@@ -3,12 +3,12 @@ import {format} from '@e22m4u/js-format';
|
|
|
import {projectData} from './project-data.js';
|
|
|
|
|
|
describe('projectData', function () {
|
|
|
- it('should require the parameter "schemaOrSource" to be a valid value', function () {
|
|
|
+ it('should require the parameter "schemaOrFactory" to be a valid value', function () {
|
|
|
const throwable = v => () => projectData(v, {});
|
|
|
const error = s =>
|
|
|
format(
|
|
|
- 'Projection schema must be an Object, a Function ' +
|
|
|
- 'or a non-empty String, but %s was given.',
|
|
|
+ 'Projection schema must be an Object, a Function, ' +
|
|
|
+ 'a non-empty String or a Symbol, but %s was given.',
|
|
|
s,
|
|
|
);
|
|
|
expect(throwable('')).to.throw(error('""'));
|
|
|
@@ -152,8 +152,8 @@ describe('projectData', function () {
|
|
|
const throwable = v => () => projectData(() => v, {});
|
|
|
const error = s =>
|
|
|
format(
|
|
|
- 'Projection schema factory must return an Object ' +
|
|
|
- 'or a non-empty String, but %s was given.',
|
|
|
+ 'Projection schema factory must return an Object, ' +
|
|
|
+ 'a non-empty String or a Symbol, but %s was given.',
|
|
|
s,
|
|
|
);
|
|
|
expect(throwable('')).to.throw(error('""'));
|
|
|
@@ -166,6 +166,7 @@ describe('projectData', function () {
|
|
|
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
|
projectData(() => ({}), {});
|
|
|
projectData(() => 'mySchema', {}, {resolver: () => ({})});
|
|
|
+ projectData(() => Symbol('mySchema'), {}, {resolver: () => ({})});
|
|
|
});
|
|
|
|
|
|
it('should resolve a schema object from the given factory', function () {
|
|
|
@@ -194,7 +195,7 @@ describe('projectData', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('named schema', function () {
|
|
|
+ describe('string key', function () {
|
|
|
it('should throw an error if the schema resolver returns an invalid value', function () {
|
|
|
const throwable = v => () =>
|
|
|
projectData('mySchema', {}, {resolver: () => v});
|
|
|
@@ -215,7 +216,7 @@ describe('projectData', function () {
|
|
|
throwable({})();
|
|
|
});
|
|
|
|
|
|
- it('should throw an error if no schema resolver is provided when a schema name is given', function () {
|
|
|
+ it('should throw an error if no schema resolver is provided when a string key is given', function () {
|
|
|
const throwable = () => projectData('mySchema', {});
|
|
|
expect(throwable).to.throw(
|
|
|
'Unable to resolve the projection schema "mySchema" ' +
|
|
|
@@ -223,10 +224,10 @@ describe('projectData', function () {
|
|
|
);
|
|
|
});
|
|
|
|
|
|
- it('should pass the schema name to the schema resolver and project the given data', function () {
|
|
|
+ it('should pass the string key to the schema resolver and project the given data', function () {
|
|
|
let invoked = 0;
|
|
|
- const resolver = name => {
|
|
|
- expect(name).to.be.eq('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq('mySchema');
|
|
|
invoked++;
|
|
|
return {foo: true, bar: false};
|
|
|
};
|
|
|
@@ -237,8 +238,8 @@ describe('projectData', function () {
|
|
|
|
|
|
it('should use the schema resolver in the nested schema', function () {
|
|
|
let invoked = 0;
|
|
|
- const resolver = name => {
|
|
|
- expect(name).to.be.eq('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq('mySchema');
|
|
|
invoked++;
|
|
|
return {baz: true, qux: false};
|
|
|
};
|
|
|
@@ -251,10 +252,10 @@ describe('projectData', function () {
|
|
|
expect(invoked).to.be.eq(1);
|
|
|
});
|
|
|
|
|
|
- it('should resolve the schema name from the schema factory', function () {
|
|
|
+ it('should resolve the string key from the schema factory', function () {
|
|
|
let invoked = 0;
|
|
|
- const resolver = name => {
|
|
|
- expect(name).to.be.eq('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq('mySchema');
|
|
|
invoked++;
|
|
|
return {foo: true, bar: false};
|
|
|
};
|
|
|
@@ -264,6 +265,79 @@ describe('projectData', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
+ describe('symbol key', function () {
|
|
|
+ it('should throw an error if the schema resolver returns an invalid value', function () {
|
|
|
+ const throwable = v => () =>
|
|
|
+ projectData(Symbol('mySchema'), {}, {resolver: () => v});
|
|
|
+ const error = s =>
|
|
|
+ format(
|
|
|
+ 'Projection schema resolver must return an Object, but %s was given.',
|
|
|
+ s,
|
|
|
+ );
|
|
|
+ expect(throwable('str')).to.throw(error('"str"'));
|
|
|
+ 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'));
|
|
|
+ expect(throwable([])).to.throw(error('Array'));
|
|
|
+ expect(throwable(null)).to.throw(error('null'));
|
|
|
+ expect(throwable(undefined)).to.throw(error('undefined'));
|
|
|
+ throwable({})();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should throw an error if no schema resolver is provided when a symbol key is given', function () {
|
|
|
+ const throwable = () => projectData(Symbol('mySchema'), {});
|
|
|
+ expect(throwable).to.throw(
|
|
|
+ 'Unable to resolve the projection schema Symbol("mySchema") ' +
|
|
|
+ 'without a provided resolver.',
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should pass the symbol key to the schema resolver and project the given data', function () {
|
|
|
+ let invoked = 0;
|
|
|
+ const symbolKey = Symbol('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq(symbolKey);
|
|
|
+ invoked++;
|
|
|
+ return {foo: true, bar: false};
|
|
|
+ };
|
|
|
+ const res = projectData(symbolKey, {foo: 10, bar: 20}, {resolver});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(invoked).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should use the schema resolver in the nested schema', function () {
|
|
|
+ let invoked = 0;
|
|
|
+ const symbolKey = Symbol('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq(symbolKey);
|
|
|
+ invoked++;
|
|
|
+ return {baz: true, qux: false};
|
|
|
+ };
|
|
|
+ const res = projectData(
|
|
|
+ {foo: true, bar: {schema: symbolKey}},
|
|
|
+ {foo: 10, bar: {baz: 20, qux: 30}},
|
|
|
+ {resolver},
|
|
|
+ );
|
|
|
+ expect(res).to.be.eql({foo: 10, bar: {baz: 20}});
|
|
|
+ expect(invoked).to.be.eq(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should resolve the symbol key from the schema factory', function () {
|
|
|
+ let invoked = 0;
|
|
|
+ const symbolKey = Symbol('mySchema');
|
|
|
+ const resolver = key => {
|
|
|
+ expect(key).to.be.eq(symbolKey);
|
|
|
+ invoked++;
|
|
|
+ return {foo: true, bar: false};
|
|
|
+ };
|
|
|
+ const res = projectData(() => symbolKey, {foo: 10, bar: 20}, {resolver});
|
|
|
+ expect(res).to.be.eql({foo: 10});
|
|
|
+ expect(invoked).to.be.eq(1);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
describe('strict mode', function () {
|
|
|
it('should preserve fields not defined in the schema when the strict option is false', function () {
|
|
|
const res = projectData({}, {foo: 10});
|