diff --git a/frontend_tests/node_tests/list_render.js b/frontend_tests/node_tests/list_render.js index 516f346221..9860479d41 100644 --- a/frontend_tests/node_tests/list_render.js +++ b/frontend_tests/node_tests/list_render.js @@ -541,3 +541,25 @@ run_test('errors', () => { }); blueslip.reset(); }); + +run_test('sort helpers', () => { + /* + We mostly test our sorting helpers using the + actual widget, but this test gets us a bit + more line coverage. + */ + const alice2 = {name: 'alice', id: 2}; + const alice10 = {name: 'alice', id: 10}; + const bob2 = {name: 'bob', id: 2}; + const bob10 = {name: 'bob', id: 10}; + + const alpha_cmp = list_render.alphabetic_sort('name'); + const num_cmp = list_render.numeric_sort('id'); + + assert.equal(alpha_cmp(alice2, alice10), 0); + assert.equal(alpha_cmp(alice2, bob2), -1); + assert.equal(alpha_cmp(bob2, alice10), 1); + assert.equal(num_cmp(alice2, bob2), 0); + assert.equal(num_cmp(alice2, bob10), -1); + assert.equal(num_cmp(alice10, bob2), 1); +}); diff --git a/static/js/list_render.js b/static/js/list_render.js index 59fc1a4c9a..30b3e7e6c4 100644 --- a/static/js/list_render.js +++ b/static/js/list_render.js @@ -25,6 +25,34 @@ exports.filter = (value, list, opts) => { }); }; +exports.alphabetic_sort = (prop) => { + return function (a, b) { + // The conversion to uppercase helps make the sorting case insensitive. + const str1 = a[prop].toUpperCase(); + const str2 = b[prop].toUpperCase(); + + if (str1 === str2) { + return 0; + } else if (str1 > str2) { + return 1; + } + + return -1; + }; +}; + +exports.numeric_sort = (prop) => { + return function (a, b) { + if (parseFloat(a[prop]) > parseFloat(b[prop])) { + return 1; + } else if (parseFloat(a[prop]) === parseFloat(b[prop])) { + return 0; + } + + return -1; + }; +}; + exports.valid_filter_opts = (opts) => { if (!opts.filter) { return true; @@ -67,7 +95,10 @@ exports.create = function ($container, list, opts) { const meta = { sorting_function: null, sorting_functions: new Map(), - generic_sorting_functions: new Map(), + generic_sorting_functions: { + alphabetic: exports.alphabetic_sort, + numeric: exports.numeric_sort, + }, offset: 0, list: list, filtered_list: list, @@ -156,19 +187,13 @@ exports.create = function ($container, list, opts) { } else if (typeof sorting_function === "string") { if (typeof prop === "string") { /* eslint-disable max-len */ - meta.sorting_function = meta.generic_sorting_functions.get(sorting_function)(prop); + meta.sorting_function = meta.generic_sorting_functions[sorting_function](prop); } else { meta.sorting_function = meta.sorting_functions.get(sorting_function); } } }; - // generic sorting functions are ones that will use a specified prop - // and perform a sort on it with the given sorting function. - widget.add_generic_sort_function = function (name, sorting_function) { - meta.generic_sorting_functions.set(name, sorting_function); - }; - widget.set_up_event_handlers = function () { meta.scroll_container = scroll_util.get_list_scrolling_container($container); @@ -235,35 +260,6 @@ exports.create = function ($container, list, opts) { widget.hard_redraw(); }; - // add built-in generic sort functions. - widget.add_generic_sort_function("alphabetic", function (prop) { - return function (a, b) { - // The conversion to uppercase helps make the sorting case insensitive. - const str1 = a[prop].toUpperCase(); - const str2 = b[prop].toUpperCase(); - - if (str1 === str2) { - return 0; - } else if (str1 > str2) { - return 1; - } - - return -1; - }; - }); - - widget.add_generic_sort_function("numeric", function (prop) { - return function (a, b) { - if (parseFloat(a[prop]) > parseFloat(b[prop])) { - return 1; - } else if (parseFloat(a[prop]) === parseFloat(b[prop])) { - return 0; - } - - return -1; - }; - }); - widget.set_up_event_handlers(); if (opts.sort_fields) {