@e22m4u/js-repository
Version:
Реализация репозитория для работы с базами данных в Node.js
698 lines (650 loc) • 25.5 kB
JavaScript
import {expect} from 'chai';
import {format} from '@e22m4u/js-format';
import {OrderClauseTool} from './order-clause-tool.js';
const S = new OrderClauseTool();
describe('OrderClauseTool', function () {
describe('sort', function () {
describe('single field', function () {
it('does not throw an error if the given field is not exist', function () {
const objects = [{foo: 1}, {foo: 2}, {foo: 3}, {foo: 4}];
S.sort(objects, 'bar');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
describe('with number values', function () {
it('orders in ascending by default', function () {
const objects = [{foo: 2}, {foo: 3}, {foo: 1}, {foo: 4}];
S.sort(objects, 'foo');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
it('orders in descending', function () {
const objects = [{foo: 2}, {foo: 3}, {foo: 1}, {foo: 4}];
S.sort(objects, 'foo DESC');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(4);
expect(objects[1].foo).to.be.eq(3);
expect(objects[2].foo).to.be.eq(2);
expect(objects[3].foo).to.be.eq(1);
});
it('orders in ascending', function () {
const objects = [{foo: 2}, {foo: 3}, {foo: 1}, {foo: 4}];
S.sort(objects, 'foo ASC');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
});
describe('with string values', function () {
it('orders in ascending by default', function () {
const objects = [{foo: 'b'}, {foo: 'c'}, {foo: 'a'}, {foo: 'd'}];
S.sort(objects, 'foo');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq('a');
expect(objects[1].foo).to.be.eq('b');
expect(objects[2].foo).to.be.eq('c');
expect(objects[3].foo).to.be.eq('d');
});
it('orders in descending', function () {
const objects = [{foo: 'b'}, {foo: 'c'}, {foo: 'a'}, {foo: 'd'}];
S.sort(objects, 'foo DESC');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq('d');
expect(objects[1].foo).to.be.eq('c');
expect(objects[2].foo).to.be.eq('b');
expect(objects[3].foo).to.be.eq('a');
});
it('orders in ascending', function () {
const objects = [{foo: 'b'}, {foo: 'c'}, {foo: 'a'}, {foo: 'd'}];
S.sort(objects, 'foo ASC');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq('a');
expect(objects[1].foo).to.be.eq('b');
expect(objects[2].foo).to.be.eq('c');
expect(objects[3].foo).to.be.eq('d');
});
});
});
describe('multiple fields', function () {
it('does not throw an error if multiple fields are not exist', function () {
const objects = [{foo: 1}, {foo: 2}, {foo: 3}, {foo: 4}];
S.sort(objects, ['bar', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
describe('with number values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: 2, bar: 2},
{foo: 2, bar: 3},
{foo: 2, bar: 1},
{foo: 1, bar: 4},
];
S.sort(objects, ['foo', 'bar']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq(4);
expect(objects[1].bar).to.be.eq(1);
expect(objects[2].bar).to.be.eq(2);
expect(objects[3].bar).to.be.eq(3);
});
it('orders in descending', function () {
const objects = [
{foo: 2, bar: 2},
{foo: 2, bar: 3},
{foo: 2, bar: 1},
{foo: 1, bar: 4},
];
S.sort(objects, ['foo DESC', 'bar DESC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq(3);
expect(objects[1].bar).to.be.eq(2);
expect(objects[2].bar).to.be.eq(1);
expect(objects[3].bar).to.be.eq(4);
});
it('orders in ascending', function () {
const objects = [
{foo: 2, bar: 2},
{foo: 2, bar: 3},
{foo: 2, bar: 1},
{foo: 1, bar: 4},
];
S.sort(objects, ['foo ASC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq(4);
expect(objects[1].bar).to.be.eq(1);
expect(objects[2].bar).to.be.eq(2);
expect(objects[3].bar).to.be.eq(3);
});
it('orders with mixed directions', function () {
const objects = [
{foo: 2, bar: 2},
{foo: 2, bar: 4},
{foo: 2, bar: 1},
{foo: 1, bar: 3},
];
S.sort(objects, ['foo DESC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq(1);
expect(objects[1].bar).to.be.eq(2);
expect(objects[2].bar).to.be.eq(4);
expect(objects[3].bar).to.be.eq(3);
});
});
describe('with string values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: 'b', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'b', bar: 'a'},
{foo: 'a', bar: 'd'},
];
S.sort(objects, ['foo', 'bar']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('d');
expect(objects[1].bar).to.be.eq('a');
expect(objects[2].bar).to.be.eq('b');
expect(objects[3].bar).to.be.eq('c');
});
it('orders in descending', function () {
const objects = [
{foo: 'b', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'b', bar: 'a'},
{foo: 'a', bar: 'd'},
];
S.sort(objects, ['foo DESC', 'bar DESC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('c');
expect(objects[1].bar).to.be.eq('b');
expect(objects[2].bar).to.be.eq('a');
expect(objects[3].bar).to.be.eq('d');
});
it('orders in ascending', function () {
const objects = [
{foo: 'b', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'b', bar: 'a'},
{foo: 'a', bar: 'd'},
];
S.sort(objects, ['foo ASC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('d');
expect(objects[1].bar).to.be.eq('a');
expect(objects[2].bar).to.be.eq('b');
expect(objects[3].bar).to.be.eq('c');
});
it('orders with mixed directions', function () {
const objects = [
{foo: 'b', bar: 'b'},
{foo: 'b', bar: 'd'},
{foo: 'b', bar: 'a'},
{foo: 'a', bar: 'c'},
];
S.sort(objects, ['foo DESC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('a');
expect(objects[1].bar).to.be.eq('b');
expect(objects[2].bar).to.be.eq('d');
expect(objects[3].bar).to.be.eq('c');
});
});
describe('with number and string values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: 2, bar: 'd'},
{foo: 2, bar: 'b'},
{foo: 2, bar: 'a'},
{foo: 1, bar: 'c'},
];
S.sort(objects, ['foo', 'bar']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('c');
expect(objects[1].bar).to.be.eq('a');
expect(objects[2].bar).to.be.eq('b');
expect(objects[3].bar).to.be.eq('d');
});
it('orders in descending', function () {
const objects = [
{foo: 2, bar: 'd'},
{foo: 2, bar: 'b'},
{foo: 2, bar: 'a'},
{foo: 1, bar: 'c'},
];
S.sort(objects, ['foo DESC', 'bar DESC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('d');
expect(objects[1].bar).to.be.eq('b');
expect(objects[2].bar).to.be.eq('a');
expect(objects[3].bar).to.be.eq('c');
});
it('orders in ascending', function () {
const objects = [
{foo: 2, bar: 'd'},
{foo: 2, bar: 'b'},
{foo: 2, bar: 'a'},
{foo: 1, bar: 'c'},
];
S.sort(objects, ['foo ASC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('c');
expect(objects[1].bar).to.be.eq('a');
expect(objects[2].bar).to.be.eq('b');
expect(objects[3].bar).to.be.eq('d');
});
it('orders in mixed directions', function () {
const objects = [
{foo: 2, bar: 'd'},
{foo: 2, bar: 'b'},
{foo: 2, bar: 'a'},
{foo: 1, bar: 'c'},
];
S.sort(objects, ['foo DESC', 'bar ASC']);
expect(objects).to.have.length(4);
expect(objects[0].bar).to.be.eq('a');
expect(objects[1].bar).to.be.eq('b');
expect(objects[2].bar).to.be.eq('d');
expect(objects[3].bar).to.be.eq('c');
});
});
});
describe('nested single field', function () {
it('does not throw an error if the nested field is not exist', function () {
const objects = [
{foo: 1},
{foo: 2, bar: undefined},
{foo: 3, bar: {baz: undefined}},
{foo: 4, bar: {baz: 1}},
];
S.sort(objects, 'bar.baz');
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
describe('with number values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: {bar: 3}},
{foo: {bar: 4}},
{foo: {bar: 2}},
{foo: {bar: 1}},
];
S.sort(objects, 'foo.bar');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq(1);
expect(objects[1].foo.bar).to.be.eq(2);
expect(objects[2].foo.bar).to.be.eq(3);
expect(objects[3].foo.bar).to.be.eq(4);
});
it('orders in descending', function () {
const objects = [
{foo: {bar: 3}},
{foo: {bar: 4}},
{foo: {bar: 2}},
{foo: {bar: 1}},
];
S.sort(objects, 'foo.bar DESC');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq(4);
expect(objects[1].foo.bar).to.be.eq(3);
expect(objects[2].foo.bar).to.be.eq(2);
expect(objects[3].foo.bar).to.be.eq(1);
});
it('orders in ascending', function () {
const objects = [
{foo: {bar: 3}},
{foo: {bar: 4}},
{foo: {bar: 2}},
{foo: {bar: 1}},
];
S.sort(objects, 'foo.bar ASC');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq(1);
expect(objects[1].foo.bar).to.be.eq(2);
expect(objects[2].foo.bar).to.be.eq(3);
expect(objects[3].foo.bar).to.be.eq(4);
});
});
describe('with string values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: {bar: 'c'}},
{foo: {bar: 'd'}},
{foo: {bar: 'b'}},
{foo: {bar: 'a'}},
];
S.sort(objects, 'foo.bar');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq('a');
expect(objects[1].foo.bar).to.be.eq('b');
expect(objects[2].foo.bar).to.be.eq('c');
expect(objects[3].foo.bar).to.be.eq('d');
});
it('orders in descending', function () {
const objects = [
{foo: {bar: 'c'}},
{foo: {bar: 'd'}},
{foo: {bar: 'b'}},
{foo: {bar: 'a'}},
];
S.sort(objects, 'foo.bar DESC');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq('d');
expect(objects[1].foo.bar).to.be.eq('c');
expect(objects[2].foo.bar).to.be.eq('b');
expect(objects[3].foo.bar).to.be.eq('a');
});
it('orders in ascending', function () {
const objects = [
{foo: {bar: 'c'}},
{foo: {bar: 'd'}},
{foo: {bar: 'b'}},
{foo: {bar: 'a'}},
];
S.sort(objects, 'foo.bar ASC');
expect(objects).to.have.length(4);
expect(objects[0].foo.bar).to.be.eq('a');
expect(objects[1].foo.bar).to.be.eq('b');
expect(objects[2].foo.bar).to.be.eq('c');
expect(objects[3].foo.bar).to.be.eq('d');
});
});
});
describe('nested multiple fields', function () {
it('does not throw an error if nested multiple fields are not exist', function () {
const objects = [
{foo: 1},
{foo: 2, bar: undefined},
{foo: 3, bar: {baz: undefined}},
{foo: 4, bar: {baz: 1}},
];
S.sort(objects, ['bar.baz', 'qux']);
expect(objects).to.have.length(4);
expect(objects[0].foo).to.be.eq(1);
expect(objects[1].foo).to.be.eq(2);
expect(objects[2].foo).to.be.eq(3);
expect(objects[3].foo).to.be.eq(4);
});
describe('with number values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: {bar: 2}, baz: 2},
{foo: {bar: 2}, baz: 1},
{foo: {bar: 2}, baz: 4},
{foo: {bar: 1}, baz: 3},
];
S.sort(objects, ['foo.bar', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(3);
expect(objects[1].baz).to.be.eq(1);
expect(objects[2].baz).to.be.eq(2);
expect(objects[3].baz).to.be.eq(4);
});
it('orders in descending', function () {
const objects = [
{foo: {bar: 2}, baz: 2},
{foo: {bar: 2}, baz: 1},
{foo: {bar: 2}, baz: 4},
{foo: {bar: 1}, baz: 3},
];
S.sort(objects, ['foo.bar DESC', 'baz DESC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(4);
expect(objects[1].baz).to.be.eq(2);
expect(objects[2].baz).to.be.eq(1);
expect(objects[3].baz).to.be.eq(3);
});
it('orders in ascending', function () {
const objects = [
{foo: {bar: 2}, baz: 2},
{foo: {bar: 2}, baz: 1},
{foo: {bar: 2}, baz: 4},
{foo: {bar: 1}, baz: 3},
];
S.sort(objects, ['foo.bar ASC', 'baz ASC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(3);
expect(objects[1].baz).to.be.eq(1);
expect(objects[2].baz).to.be.eq(2);
expect(objects[3].baz).to.be.eq(4);
});
it('orders with mixed directions', function () {
const objects = [
{foo: {bar: 2}, baz: 2},
{foo: {bar: 2}, baz: 1},
{foo: {bar: 2}, baz: 4},
{foo: {bar: 1}, baz: 3},
];
S.sort(objects, ['foo.bar DESC', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(1);
expect(objects[1].baz).to.be.eq(2);
expect(objects[2].baz).to.be.eq(4);
expect(objects[3].baz).to.be.eq(3);
});
});
describe('with string values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: {bar: 'b'}, baz: 'b'},
{foo: {bar: 'b'}, baz: 'a'},
{foo: {bar: 'b'}, baz: 'd'},
{foo: {bar: 'a'}, baz: 'c'},
];
S.sort(objects, ['foo.bar', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq('c');
expect(objects[1].baz).to.be.eq('a');
expect(objects[2].baz).to.be.eq('b');
expect(objects[3].baz).to.be.eq('d');
});
it('orders in descending', function () {
const objects = [
{foo: {bar: 'b'}, baz: 'b'},
{foo: {bar: 'b'}, baz: 'a'},
{foo: {bar: 'b'}, baz: 'd'},
{foo: {bar: 'a'}, baz: 'c'},
];
S.sort(objects, ['foo.bar DESC', 'baz DESC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq('d');
expect(objects[1].baz).to.be.eq('b');
expect(objects[2].baz).to.be.eq('a');
expect(objects[3].baz).to.be.eq('c');
});
it('orders in ascending', function () {
const objects = [
{foo: {bar: 'b'}, baz: 'b'},
{foo: {bar: 'b'}, baz: 'a'},
{foo: {bar: 'b'}, baz: 'd'},
{foo: {bar: 'a'}, baz: 'c'},
];
S.sort(objects, ['foo.bar ASC', 'baz ASC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq('c');
expect(objects[1].baz).to.be.eq('a');
expect(objects[2].baz).to.be.eq('b');
expect(objects[3].baz).to.be.eq('d');
});
it('orders with mixed directions', function () {
const objects = [
{foo: {bar: 'b'}, baz: 'b'},
{foo: {bar: 'b'}, baz: 'a'},
{foo: {bar: 'b'}, baz: 'd'},
{foo: {bar: 'a'}, baz: 'c'},
];
S.sort(objects, ['foo.bar DESC', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq('a');
expect(objects[1].baz).to.be.eq('b');
expect(objects[2].baz).to.be.eq('d');
expect(objects[3].baz).to.be.eq('c');
});
});
describe('with number and string values', function () {
it('orders in ascending by default', function () {
const objects = [
{foo: {bar: 'b'}, baz: 2},
{foo: {bar: 'b'}, baz: 1},
{foo: {bar: 'b'}, baz: 4},
{foo: {bar: 'a'}, baz: 3},
];
S.sort(objects, ['foo.bar', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(3);
expect(objects[1].baz).to.be.eq(1);
expect(objects[2].baz).to.be.eq(2);
expect(objects[3].baz).to.be.eq(4);
});
it('orders in descending', function () {
const objects = [
{foo: {bar: 'b'}, baz: 2},
{foo: {bar: 'b'}, baz: 1},
{foo: {bar: 'b'}, baz: 4},
{foo: {bar: 'a'}, baz: 3},
];
S.sort(objects, ['foo.bar DESC', 'baz DESC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(4);
expect(objects[1].baz).to.be.eq(2);
expect(objects[2].baz).to.be.eq(1);
expect(objects[3].baz).to.be.eq(3);
});
it('orders in ascending', function () {
const objects = [
{foo: {bar: 'b'}, baz: 2},
{foo: {bar: 'b'}, baz: 1},
{foo: {bar: 'b'}, baz: 4},
{foo: {bar: 'a'}, baz: 3},
];
S.sort(objects, ['foo.bar ASC', 'baz ASC']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(3);
expect(objects[1].baz).to.be.eq(1);
expect(objects[2].baz).to.be.eq(2);
expect(objects[3].baz).to.be.eq(4);
});
it('orders with mixed directions', function () {
const objects = [
{foo: {bar: 'b'}, baz: 2},
{foo: {bar: 'b'}, baz: 1},
{foo: {bar: 'b'}, baz: 4},
{foo: {bar: 'a'}, baz: 3},
];
S.sort(objects, ['foo.bar DESC', 'baz']);
expect(objects).to.have.length(4);
expect(objects[0].baz).to.be.eq(1);
expect(objects[1].baz).to.be.eq(2);
expect(objects[2].baz).to.be.eq(4);
expect(objects[3].baz).to.be.eq(3);
});
});
});
});
describe('validateOrderClause', function () {
describe('single field', function () {
it('requires the first argument as a non-empty string', function () {
const throwable = v => () => OrderClauseTool.validateOrderClause(v);
const error = v =>
format(
'The provided option "order" should be a non-empty String ' +
'or an Array of non-empty String, 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'));
expect(throwable({})).to.throw(error('Object'));
throwable('field')();
throwable(undefined)();
throwable(null)();
});
});
describe('multiple fields', function () {
it('requires the first argument as a non-empty string', function () {
const throwable = v => () => OrderClauseTool.validateOrderClause(v);
const error = v =>
format(
'The provided option "order" should be a non-empty String ' +
'or an Array of non-empty String, 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'));
expect(throwable([{}])).to.throw(error('Object'));
expect(throwable([undefined])).to.throw(error('undefined'));
expect(throwable([null])).to.throw(error('null'));
throwable(['field'])();
throwable([])();
});
});
});
describe('normalizeOrderClause', function () {
describe('single field', function () {
it('requires the first argument as a non-empty string', function () {
const throwable = v => () => OrderClauseTool.normalizeOrderClause(v);
const error = v =>
format(
'The provided option "order" should be a non-empty String ' +
'or an Array of non-empty String, 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'));
expect(throwable({})).to.throw(error('Object'));
expect(throwable('field')()).to.be.eql(['field']);
expect(throwable(undefined)()).to.be.undefined;
expect(throwable(null)()).to.be.undefined;
});
it('returns an array of string', function () {
const fn = OrderClauseTool.normalizeOrderClause;
expect(fn('foo')).to.be.eql(['foo']);
});
});
describe('multiple fields', function () {
it('requires the first argument as a non-empty string', function () {
const throwable = v => () => OrderClauseTool.normalizeOrderClause(v);
const error = v =>
format(
'The provided option "order" should be a non-empty String ' +
'or an Array of non-empty String, 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'));
expect(throwable([{}])).to.throw(error('Object'));
expect(throwable([undefined])).to.throw(error('undefined'));
expect(throwable([null])).to.throw(error('null'));
expect(throwable(['field'])()).to.be.eql(['field']);
expect(throwable([])()).to.be.undefined;
});
it('returns an array of strings', function () {
const fn = OrderClauseTool.normalizeOrderClause;
expect(fn(['foo', 'bar'])).to.be.eql(['foo', 'bar']);
});
});
});
});