diff --git a/src/utils/comparator/Comparator.js b/src/utils/comparator/Comparator.js new file mode 100644 index 00000000..a2c71527 --- /dev/null +++ b/src/utils/comparator/Comparator.js @@ -0,0 +1,46 @@ +export default class Comparator { + /** + * @param {function(a: *, b: *)} [compareFunction] + */ + constructor(compareFunction) { + this.compare = compareFunction || Comparator.defaultCompareFunction; + } + + /** + * @param {(string|number)} a + * @param {(string|number)} b + * @returns {number} + */ + static defaultCompareFunction(a, b) { + if (a === b) { + return 0; + } + + return a < b ? -1 : 1; + } + + equal(a, b) { + return this.compare(a, b) === 0; + } + + lessThen(a, b) { + return this.compare(a, b) < 0; + } + + greaterThen(a, b) { + return this.compare(a, b) > 0; + } + + lessThenOrEqual(a, b) { + return this.lessThen(a, b) || this.equal(a, b); + } + + greaterThenOrEqual(a, b) { + return this.greaterThen(a, b) || this.equal(a, b); + } + + reverse() { + const compareOriginal = this.compare; + this.compare = (a, b) => compareOriginal(b, a); + } +} diff --git a/src/utils/comparator/__test__/Comparator.test.js b/src/utils/comparator/__test__/Comparator.test.js new file mode 100644 index 00000000..4bd83754 --- /dev/null +++ b/src/utils/comparator/__test__/Comparator.test.js @@ -0,0 +1,50 @@ +import Comparator from '../Comparator'; + +describe('Comparator', () => { + it('should compare with default comparator function', () => { + const comparator = new Comparator(); + + expect(comparator.equal(0, 0)).toBeTruthy(); + expect(comparator.equal(0, 1)).toBeFalsy(); + expect(comparator.equal('a', 'a')).toBeTruthy(); + expect(comparator.lessThen(1, 2)).toBeTruthy(); + expect(comparator.lessThen(-1, 2)).toBeTruthy(); + expect(comparator.lessThen('a', 'b')).toBeTruthy(); + expect(comparator.lessThen('a', 'ab')).toBeTruthy(); + expect(comparator.lessThen(10, 2)).toBeFalsy(); + expect(comparator.lessThenOrEqual(10, 2)).toBeFalsy(); + expect(comparator.lessThenOrEqual(1, 1)).toBeTruthy(); + expect(comparator.lessThenOrEqual(0, 0)).toBeTruthy(); + expect(comparator.greaterThen(0, 0)).toBeFalsy(); + expect(comparator.greaterThen(10, 0)).toBeTruthy(); + expect(comparator.greaterThenOrEqual(10, 0)).toBeTruthy(); + expect(comparator.greaterThenOrEqual(10, 10)).toBeTruthy(); + expect(comparator.greaterThenOrEqual(0, 10)).toBeFalsy(); + }); + + it('should compare with custom comparator function', () => { + const comparator = new Comparator((a, b) => { + if (a.length === b.length) { + return 0; + } + + return a.length < b.length ? -1 : 1; + }); + + expect(comparator.equal('a', 'b')).toBeTruthy(); + expect(comparator.equal('a', '')).toBeFalsy(); + expect(comparator.lessThen('b', 'aa')).toBeTruthy(); + expect(comparator.greaterThenOrEqual('a', 'aa')).toBeFalsy(); + expect(comparator.greaterThenOrEqual('aa', 'a')).toBeTruthy(); + expect(comparator.greaterThenOrEqual('a', 'a')).toBeTruthy(); + + comparator.reverse(); + + expect(comparator.equal('a', 'b')).toBeTruthy(); + expect(comparator.equal('a', '')).toBeFalsy(); + expect(comparator.lessThen('b', 'aa')).toBeFalsy(); + expect(comparator.greaterThenOrEqual('a', 'aa')).toBeTruthy(); + expect(comparator.greaterThenOrEqual('aa', 'a')).toBeFalsy(); + expect(comparator.greaterThenOrEqual('a', 'a')).toBeTruthy(); + }); +});