From e59974d644433d6deb9a34078a69aa705e4e9e8d Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 8 May 2019 17:50:41 +0200 Subject: [PATCH 1/2] refactor(lodash): replace orderBy I generated this code: 1. take original lodash code 2. inline imports 3. inline helpers 4. remove edge-case helpers (string instead of array arguments, path instead of element, Symbol support, NaN support etc.) 5. copy tests from lodash 6. change tests to work in Jest 7. remove one test that no longer would have passed This probably can be simplified a bit more here and there, but likely isn't that important --- .../generate-hierarchical-tree.js | 3 +- src/SearchResults/index.js | 3 +- src/functions/orderBy.js | 79 +++++++++++++++++++ test/spec/functions/orderBy.js | 55 +++++++++++++ 4 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 src/functions/orderBy.js create mode 100644 test/spec/functions/orderBy.js diff --git a/src/SearchResults/generate-hierarchical-tree.js b/src/SearchResults/generate-hierarchical-tree.js index e36f660c6..e4e8b1691 100644 --- a/src/SearchResults/generate-hierarchical-tree.js +++ b/src/SearchResults/generate-hierarchical-tree.js @@ -2,8 +2,7 @@ module.exports = generateTrees; -var orderBy = require('lodash/orderBy'); - +var orderBy = require('../functions/orderBy'); var find = require('../functions/find'); var prepareHierarchicalFacetSortBy = require('../functions/formatSort'); diff --git a/src/SearchResults/index.js b/src/SearchResults/index.js index 518d89b46..4a88f6557 100644 --- a/src/SearchResults/index.js +++ b/src/SearchResults/index.js @@ -1,7 +1,5 @@ 'use strict'; -var orderBy = require('lodash/orderBy'); - var merge = require('lodash/merge'); var isFunction = require('lodash/isFunction'); @@ -10,6 +8,7 @@ var partial = require('lodash/partial'); var partialRight = require('lodash/partialRight'); var defaultsPure = require('../functions/defaultsPure'); +var orderBy = require('../functions/orderBy'); var compact = require('../functions/compact'); var find = require('../functions/find'); var findIndex = require('../functions/findIndex'); diff --git a/src/functions/orderBy.js b/src/functions/orderBy.js new file mode 100644 index 000000000..995eb9cee --- /dev/null +++ b/src/functions/orderBy.js @@ -0,0 +1,79 @@ +'use strict'; + +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined; + var valIsNull = value === null; + + var othIsDefined = other !== undefined; + var othIsNull = other === null; + + if ( + (!othIsNull && value > other) || + (valIsNull && othIsDefined) || + !valIsDefined + ) { + return 1; + } + if ( + (!valIsNull && value < other) || + (othIsNull && valIsDefined) || + !othIsDefined + ) { + return -1; + } + } + return 0; +} + +/** + * @param {Array} collection object with keys in attributes + * @param {Array} iteratees attributes + * @param {Array} orders asc | desc + */ +function orderBy(collection, iteratees, orders) { + if (!Array.isArray(collection)) { + return []; + } + + if (!Array.isArray(orders)) { + orders = []; + } + + var result = collection.map(function(value, index) { + return { + criteria: iteratees.map(function(iteratee) { + return value[iteratee]; + }), + index: index, + value: value + }; + }); + + result.sort(function comparer(object, other) { + var index = -1; + + while (++index < object.criteria.length) { + var res = compareAscending(object.criteria[index], other.criteria[index]); + if (res) { + if (index >= orders.length) { + return res; + } + if (orders[index] === 'desc') { + return -res; + } + return res; + } + } + + // This ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + }); + + return result.map(function(res) { + return res.value; + }); +} + +module.exports = orderBy; diff --git a/test/spec/functions/orderBy.js b/test/spec/functions/orderBy.js new file mode 100644 index 000000000..1419e216f --- /dev/null +++ b/test/spec/functions/orderBy.js @@ -0,0 +1,55 @@ +'use strict'; + +var orderBy = require('../../../src/functions/orderBy'); + +var objects = [ + {a: 'x', b: 3}, + {a: 'y', b: 4}, + {a: 'x', b: 1}, + {a: 'y', b: 2} +]; + +it('should sort by a single property by a specified order', function() { + expect(orderBy(objects, ['a'], ['desc'])).toEqual([ + objects[1], + objects[3], + objects[0], + objects[2] + ]); +}); + +it('should sort by multiple properties by specified orders', function() { + expect(orderBy(objects, ['a', 'b'], ['desc', 'asc'])).toEqual([ + objects[3], + objects[1], + objects[2], + objects[0] + ]); +}); + +it('should sort by a property in ascending order when its order is not specified', function() { + expect(orderBy(objects, ['a', 'b'])).toEqual([ + objects[2], + objects[0], + objects[3], + objects[1] + ]); + + expect(orderBy(objects, ['a', 'b'], ['desc'])).toEqual([ + objects[3], + objects[1], + objects[2], + objects[0] + ]); + + [null, undefined, false, 0, NaN, ''].forEach(function(order) { + expect(orderBy(objects, ['a', 'b'], ['desc', order])).toEqual([ + objects[3], + objects[1], + objects[2], + objects[0] + ]); + }); +}); + + From 2e987de56feb7a4b903b2a84bcbd3e40ebc7fb88 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 9 May 2019 10:48:26 +0200 Subject: [PATCH 2/2] test(orderBy): test empty use case --- test/spec/functions/orderBy.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/spec/functions/orderBy.js b/test/spec/functions/orderBy.js index 1419e216f..e0e314e7b 100644 --- a/test/spec/functions/orderBy.js +++ b/test/spec/functions/orderBy.js @@ -52,4 +52,9 @@ it('should sort by a property in ascending order when its order is not specified }); }); - +it('should return an empty array when collections is no array', function() { + expect(orderBy(undefined)).toEqual([]); + expect(orderBy(false)).toEqual([]); + expect(orderBy({})).toEqual([]); + expect(orderBy({}, [], [])).toEqual([]); +});