Your IP : 172.71.120.3


Current Path : /var/www/element/data/www/revenuestory.ru/bitrix/js/main/core/test/collection/
Upload File :
Current File : /var/www/element/data/www/revenuestory.ru/bitrix/js/main/core/test/collection/ordered-array.test.js

import OrderedArray from '../../src/lib/collections/ordered-array';
import Type from '../../src/lib/type';

const compareItems = (
	itemA,
	itemB,
	orderProperty: string,
	ascOrdering: boolean,
	nullsOrdering: boolean
) => {

	const valueA = itemA[orderProperty];
	const valueB = itemB[orderProperty];

	let result = 0;

	if (valueA !== null && valueB === null)
	{
		result = nullsOrdering ? -1 : 1;
	}
	else if (valueA === null && valueB !== null)
	{
		result = nullsOrdering ? 1 : -1;
	}
	else if (valueA === null && valueB === null)
	{
		result = ascOrdering ? -1 : 1;
	}
	else
	{
		if (Type.isString(valueA))
		{
			result = valueA.localeCompare(valueB);
		}
		else
		{
			result = valueA - valueB;
		}
	}

	const sortOrder = ascOrdering ? 1 : -1;

	return result * sortOrder;
};

const makeMultipleComparator = (order: {[key: string]: 'asc' | 'desc' }) => {

	const props = Object.keys(order);
	const directions: Array<{ ascOrdering: boolean, nullsOrdering: boolean }> = [];
	Object.values(order).forEach((element) => {

		const direction = element.toLowerCase().trim();

		// Default sorting: 'asc' || 'asc nulls last'
		let ascOrdering = true;
		let nullsOrdering = true;

		if (direction === 'desc' || direction === 'desc nulls first')
		{
			ascOrdering = false;
		}
		else if (direction === 'asc nulls first')
		{
			nullsOrdering = false;
		}
		else if (direction === 'desc nulls last')
		{
			ascOrdering = false;
			nullsOrdering = false;
		}

		directions.push({ ascOrdering, nullsOrdering });
	});

	const numberOfProperties = props.length;

	return (itemA, itemB) => {
		let i = 0;
		let result = 0;

		while (result === 0 && i < numberOfProperties)
		{
			const property = props[i];
			const direction = directions[i];

			result = compareItems(itemA, itemB, property, direction.ascOrdering, direction.nullsOrdering);
			i += 1;
		}

		return result;
	};
};

const sortByName = function(a, b) {
	const nameA = a.name.toUpperCase(); // ignore upper and lowercase
	const nameB = b.name.toUpperCase(); // ignore upper and lowercase
	if (nameA < nameB)
	{
		return -1;
	}

	if (nameA > nameB)
	{
		return 1;
	}

	return 0;
};

const sortByNumber = (a, b) => {
	return a.sort - b.sort;
};

describe('OrderedArray', () => {

	const elements = [
		{ name: 'Blue', sort: 3 },
		{ name: 'Yellow', sort: 4 },
		{ name: 'Orange', sort: 2 },
		{ name: 'White', sort: 6 },
		{ name: 'Black', sort: 5 },
		{ name: 'Red', sort: 1 },
	];

	const elements2 = [
		{ name: 'Blue', sort: 3 },
		{ name: 'Yellow', sort: 4 },
		{ name: 'Orange', sort: 3 },
		{ name: 'White', sort: 6 },
		{ name: 'Black', sort: 4 },
		{ name: 'Red', sort: 1 },
		{ name: 'Pink', sort: 6 },
		{ name: 'Green', sort: 3 },
		{ name: 'Purple', sort: 1 },
		{ name: 'Brown', sort: 6 },
		{ name: 'Grey', sort: 7 },
	];

	const elements3 = [
		{ name: 'Blue', sort: 3, id: 1 },
		{ name: 'Yellow', sort: 4, id: 2 },
		{ name: 'Orange', sort: 3, id: 3 },
		{ name: 'White', sort: 6, id: 4 },
		{ name: 'White', sort: 6, id: 5 },
		{ name: 'Black', sort: 4, id: 6 },
		{ name: 'Red', sort: 1, id: 7 },
		{ name: 'Pink', sort: 6, id: 8 },
		{ name: 'Pink', sort: 6, id: 9 },
		{ name: 'Green', sort: 3, id: 10 },
		{ name: 'Purple', sort: 1, id: 11 },
		{ name: 'Brown', sort: 6, id: 12 },
		{ name: 'Grey', sort: 7, id: 13 },
		{ name: 'Grey', sort: 7, id: 14 },
		{ name: 'Grey', sort: 7, id: 15 },
	];

	const products = [
		{ id: 1, name: 'Bread', sort: 3, nullProperty: null },
		{ id: 2, name: 'Sausage', sort: 4, nullProperty: null },
		{ id: 3, name: 'Bacon', sort: 1, nullProperty: null },
		{ id: 4, name: 'Cheese', sort: null, nullProperty: null },
		{ id: 5, name: 'Milk', sort: 2, nullProperty: null },
		{ id: 6, name: 'Butter', sort: null, nullProperty: null },
		{ id: 7, name: 'Eggs', sort: 5, nullProperty: null },
		{ id: 8, name: 'Cucumber', sort: null, nullProperty: null },
	];

	it('Should behave like a simple array with a comparator', () => {
		const names = new OrderedArray();
		elements.forEach(element => {
			names.add(element);
		});

		assert.equal(
			elements.map(element => element.name).join('|'),
			names.getAll().map(element => element.name).join('|'),
		);
	});

	it('Should sort elements using a comparator', () => {

		const names = new OrderedArray(sortByName);
		elements.forEach(element => {
			names.add(element);
		});

		assert.equal(
			names.getAll().map(element => element.name).join('|'),
			'Black|Blue|Orange|Red|White|Yellow'
		);

		const numbers = new OrderedArray(sortByNumber);
		elements.forEach(element => {
			numbers.add(element);
		});

		assert.equal(
			numbers.getAll().map(element => element.sort).join(''),
			'123456'
		);

		const colors = new OrderedArray(makeMultipleComparator({ sort: 'asc', name: 'asc' }));
		elements2.forEach(element => {
			colors.add(element);
		});

		assert.equal(
			colors.getAll().map(element => element.sort).join(''),
			'11333446667'
		);

		assert.equal(
			colors.getAll().map(element => element.name).join('|'),
			'Purple|Red|Blue|Green|Orange|Black|Yellow|Brown|Pink|White|Grey'
		);

		const colors2 = new OrderedArray(makeMultipleComparator({ sort: 'desc', name: 'desc' }));
		elements2.forEach(element => {
			colors2.add(element);
		});

		assert.equal(
			colors2.getAll().map(element => element.sort).join(''),
			'76664433311'
		);

		assert.equal(
			colors2.getAll().map(element => element.name).join('|'),
			'Grey|White|Pink|Brown|Yellow|Black|Orange|Green|Blue|Red|Purple'
		);
	});

	it('Should resort elements', () => {

		const numbers = new OrderedArray(sortByNumber);
		elements.forEach(element => {
			numbers.add(element);
		});

		assert.equal(numbers.getFirst().name, 'Red');
		assert.equal(numbers.getLast().name, 'White');
		assert.equal(numbers.getByIndex(2).name, 'Blue');

		assert.equal(
			numbers.getAll().map(element => element.sort).join(''),
			'123456'
		);

		numbers.getFirst().sort = 10;
		numbers.getLast().sort = 0;
		numbers.sort();

		assert.equal(numbers.getFirst().name, 'White');
		assert.equal(numbers.getLast().name, 'Red');
		assert.equal(numbers.getByIndex(2).name, 'Blue');

		const colors = new OrderedArray(makeMultipleComparator({ sort: 'asc', name: 'desc' }));
		elements3.forEach(element => {
			colors.add(element);
		});

		assert.equal(
			colors.getAll().map(element => element.sort).join(''),
			'113334466666777'
		);

		assert.equal(
			colors.getAll().map(element => element.id).join('|'),
			'7|11|3|10|1|2|6|5|4|9|8|12|15|14|13'
		);

		assert.equal(
			colors.getAll().map(element => element.name).join('|'),
			'Red|Purple|Orange|Green|Blue|Yellow|Black|White|White|Pink|Pink|Brown|Grey|Grey|Grey'
		);

		colors.getByIndex(0).sort = 8;
		colors.getByIndex(9).sort = 5;
		colors.getByIndex(3).sort = 6;

		colors.sort();

		assert.equal(
			colors.getAll().map(element => element.sort).join(''),
			'133445666667778'
		);

		assert.equal(
			colors.getAll().map(element => element.id).join('|'),
			'11|3|1|2|6|9|5|4|8|10|12|15|14|13|7'
		);

		assert.equal(
			colors.getAll().map(element => element.name).join('|'),
			'Purple|Orange|Blue|Yellow|Black|Pink|White|White|Pink|Green|Brown|Grey|Grey|Grey|Red'
		);

		colors.getByIndex(8).sort = 1;
		colors.getByIndex(5).sort = 3;
		colors.getByIndex(4).sort = 5;

		colors.sort();

		assert.equal(
			colors.getAll().map(element => element.sort).join(''),
			'113334566667778'
		);

		assert.equal(
			colors.getAll().map(element => element.id).join('|'),
			'11|8|9|3|1|2|6|5|4|10|12|15|14|13|7'
		);

		assert.equal(
			colors.getAll().map(element => element.name).join('|'),
			'Purple|Pink|Pink|Orange|Blue|Yellow|Black|White|White|Green|Brown|Grey|Grey|Grey|Red'
		);
	});

	it('Should sort elements with nulls', () => {

		const orderByAsc = new OrderedArray(makeMultipleComparator({ sort: 'asc' }));
		const orderByAsc2 = new OrderedArray(makeMultipleComparator({ sort: 'asc nulls last' }));
		const orderByAsc3 = new OrderedArray(makeMultipleComparator({ sort: 'asc nulls first' }));

		products.forEach(element => {
			orderByAsc.add(element);
			orderByAsc2.add(element);
			orderByAsc3.add(element);
		});

		assert.equal(
			orderByAsc.getAll().map(element => element.name).join('|'),
			'Bacon|Milk|Bread|Sausage|Eggs|Cheese|Butter|Cucumber'
		);

		assert.equal(
			orderByAsc2.getAll().map(element => element.name).join('|'),
			'Bacon|Milk|Bread|Sausage|Eggs|Cheese|Butter|Cucumber'
		);

		assert.equal(
			orderByAsc3.getAll().map(element => element.name).join('|'),
			'Cheese|Butter|Cucumber|Bacon|Milk|Bread|Sausage|Eggs'
		);

		const orderByDesc = new OrderedArray(makeMultipleComparator({ sort: 'desc' }));
		const orderByDesc2 = new OrderedArray(makeMultipleComparator({ sort: 'desc nulls first' }));
		const orderByDesc3 = new OrderedArray(makeMultipleComparator({ sort: 'desc nulls last' }));

		products.forEach(element => {
			orderByDesc.add(element);
			orderByDesc2.add(element);
			orderByDesc3.add(element);
		});

		assert.equal(
			orderByDesc.getAll().map(element => element.name).join('|'),
			'Cheese|Butter|Cucumber|Eggs|Sausage|Bread|Milk|Bacon'
		);

		assert.equal(
			orderByDesc2.getAll().map(element => element.name).join('|'),
			'Cheese|Butter|Cucumber|Eggs|Sausage|Bread|Milk|Bacon'
		);

		assert.equal(
			orderByDesc3.getAll().map(element => element.name).join('|'),
			'Eggs|Sausage|Bread|Milk|Bacon|Cheese|Butter|Cucumber'
		);

		const orderByAscNullable = new OrderedArray(makeMultipleComparator({ nullProperty: 'asc' }));
		const orderByDescNullable = new OrderedArray(makeMultipleComparator({ nullProperty: 'desc' }));

		products.forEach(element => {
			orderByAscNullable.add(element);
			orderByDescNullable.add(element);
		});

		assert.equal(
			orderByAscNullable.getAll().map(element => element.id).join(''),
			'12345678'
		);
		assert.equal(
			orderByDescNullable.getAll().map(element => element.id).join(''),
			'12345678'
		);
	});
});