diff --git a/app/common/SortFunc.ts b/app/common/SortFunc.ts index 1bfc7098..36fb7598 100644 --- a/app/common/SortFunc.ts +++ b/app/common/SortFunc.ts @@ -38,11 +38,15 @@ function naturalCompare(val1: any, val2: any) { /** * Empty comparator will treat empty values as last. */ -const emptyCompare = (next: Comparator) => (val1: any, val2: any) => { - if (!val1 && typeof val1 !== 'number') { - return 1; +export const emptyCompare = (next: Comparator) => (val1: any, val2: any) => { + const isEmptyValue1 = !val1 && typeof val1 !== 'number'; + const isEmptyValue2 = !val2 && typeof val2 !== 'number'; + + // If both values are empty values, rely on next to compare. + if (isEmptyValue1 && !isEmptyValue2) { + return 1; } - if (!val2 && typeof val2 !== 'number') { + if (isEmptyValue2 && !isEmptyValue1) { return -1; } return next(val1, val2); diff --git a/test/common/SortFunc.ts b/test/common/SortFunc.ts index bb722de2..4f5ff4b5 100644 --- a/test/common/SortFunc.ts +++ b/test/common/SortFunc.ts @@ -1,4 +1,4 @@ -import {typedCompare} from 'app/common/SortFunc'; +import {emptyCompare, typedCompare} from 'app/common/SortFunc'; import {assert} from 'chai'; import {format} from 'util'; @@ -26,4 +26,43 @@ describe('SortFunc', function() { } } }); + + it('typedCompare should treat empty values as equal', function() { + assert.equal(typedCompare(null, null), 0); + assert.equal(typedCompare('', ''), 0); + }); + + describe('emptyCompare', function() { + + it('should work correctly ', function() { + const comparator = emptyCompare(typedCompare); + assert.equal(comparator(null, null), 0); + assert.equal(comparator('', ''), 0); + + assert.equal(comparator(null, 0), 1); + assert.equal(comparator(null, -1), 1); + assert.equal(comparator(null, 1), 1); + assert.equal(comparator(null, 'a'), 1); + assert.equal(comparator(null, 'z'), 1); + + assert.equal(comparator(0, null), -1); + assert.equal(comparator(-1, null), -1); + assert.equal(comparator(1, null), -1); + assert.equal(comparator('a', null), -1); + assert.equal(comparator('z', null), -1); + }); + + it('should keep sorting order consistent amongst empty values', function() { + // values1 and values2 have same values but in different order. Sorting them with emptyCompare + // function should yield same results. + const values1 = ['', null, undefined, 2, 3, 4]; + const values2 = [undefined, null, '', 2, 3, 4]; + const comparator = emptyCompare(typedCompare); + values1.sort(comparator); + values2.sort(comparator); + assert.deepEqual(values1, values2); + }); + + }); + });