@@ -19,18 +19,20 @@ function testSorting({
1919 direction,
2020 type,
2121 keepLast,
22+ reverseOutput = true ,
2223} : {
2324 input : unknown [ ] ;
2425 output : unknown [ ] ;
2526 direction : 'asc' | 'desc' ;
2627 type : DatatableColumnType | 'range' ;
2728 keepLast ?: boolean ; // special flag to handle values that should always be last no matter the direction
29+ reverseOutput ?: boolean ;
2830} ) {
2931 const datatable = input . map ( ( v ) => ( {
3032 a : v ,
3133 } ) ) ;
3234 const sorted = output . map ( ( v ) => ( { a : v } ) ) ;
33- if ( direction === 'desc' ) {
35+ if ( direction === 'desc' && reverseOutput ) {
3436 sorted . reverse ( ) ;
3537 if ( keepLast ) {
3638 // Cycle shift of the first element
@@ -64,6 +66,44 @@ describe('Data sorting criteria', () => {
6466 } ) ;
6567 } ) ;
6668 }
69+
70+ it ( `should sort undefined and null to the end` , ( ) => {
71+ const now = Date . now ( ) ;
72+ testSorting ( {
73+ input : [ null , now , 0 , undefined , null , now - 150000 ] ,
74+ output : [ 0 , now - 150000 , now , null , undefined , null ] ,
75+ direction : 'asc' ,
76+ type : 'date' ,
77+ reverseOutput : false ,
78+ } ) ;
79+
80+ testSorting ( {
81+ input : [ null , now , 0 , undefined , null , now - 150000 ] ,
82+ output : [ now , now - 150000 , 0 , null , undefined , null ] ,
83+ direction : 'desc' ,
84+ type : 'date' ,
85+ reverseOutput : false ,
86+ } ) ;
87+ } ) ;
88+
89+ it ( `should sort NaN to the end` , ( ) => {
90+ const now = Date . now ( ) ;
91+ testSorting ( {
92+ input : [ null , now , 0 , undefined , Number . NaN , now - 150000 ] ,
93+ output : [ 0 , now - 150000 , now , null , undefined , Number . NaN ] ,
94+ direction : 'asc' ,
95+ type : 'number' ,
96+ reverseOutput : false ,
97+ } ) ;
98+
99+ testSorting ( {
100+ input : [ null , now , 0 , undefined , Number . NaN , now - 150000 ] ,
101+ output : [ now , now - 150000 , 0 , null , undefined , Number . NaN ] ,
102+ direction : 'desc' ,
103+ type : 'number' ,
104+ reverseOutput : false ,
105+ } ) ;
106+ } ) ;
67107 } ) ;
68108
69109 describe ( 'String or anything else as string' , ( ) => {
@@ -86,6 +126,39 @@ describe('Data sorting criteria', () => {
86126 } ) ;
87127 } ) ;
88128 }
129+
130+ it ( 'should sort undefined and null to the end' , ( ) => {
131+ testSorting ( {
132+ input : [ 'a' , null , 'b' , 'c' , undefined , 'd' , '12' ] ,
133+ output : [ '12' , 'a' , 'b' , 'c' , 'd' , null , undefined ] ,
134+ direction : 'asc' ,
135+ type : 'string' ,
136+ reverseOutput : false ,
137+ } ) ;
138+
139+ testSorting ( {
140+ input : [ 'a' , null , 'b' , 'c' , undefined , 'd' , '12' ] ,
141+ output : [ 'd' , 'c' , 'b' , 'a' , '12' , null , undefined ] ,
142+ direction : 'desc' ,
143+ type : 'string' ,
144+ reverseOutput : false ,
145+ } ) ;
146+
147+ testSorting ( {
148+ input : [ true , null , false , undefined , false ] ,
149+ output : [ false , false , true , null , undefined ] ,
150+ direction : 'asc' ,
151+ type : 'boolean' ,
152+ reverseOutput : false ,
153+ } ) ;
154+ testSorting ( {
155+ input : [ true , null , false , undefined , false ] ,
156+ output : [ true , false , false , null , undefined ] ,
157+ direction : 'desc' ,
158+ type : 'boolean' ,
159+ reverseOutput : false ,
160+ } ) ;
161+ } ) ;
89162 } ) ;
90163
91164 describe ( 'IP sorting' , ( ) => {
@@ -154,6 +227,60 @@ describe('Data sorting criteria', () => {
154227 } ) ;
155228 } ) ;
156229 }
230+
231+ it ( 'should sort undefined and null to the end' , ( ) => {
232+ testSorting ( {
233+ input : [
234+ 'fc00::123' ,
235+ '192.168.1.50' ,
236+ null ,
237+ undefined ,
238+ 'Other' ,
239+ '10.0.1.76' ,
240+ '8.8.8.8' ,
241+ '::1' ,
242+ ] ,
243+ output : [
244+ '::1' ,
245+ '8.8.8.8' ,
246+ '10.0.1.76' ,
247+ '192.168.1.50' ,
248+ 'fc00::123' ,
249+ 'Other' ,
250+ null ,
251+ undefined ,
252+ ] ,
253+ direction : 'asc' ,
254+ type : 'ip' ,
255+ reverseOutput : false ,
256+ } ) ;
257+
258+ testSorting ( {
259+ input : [
260+ 'fc00::123' ,
261+ '192.168.1.50' ,
262+ null ,
263+ undefined ,
264+ 'Other' ,
265+ '10.0.1.76' ,
266+ '8.8.8.8' ,
267+ '::1' ,
268+ ] ,
269+ output : [
270+ 'fc00::123' ,
271+ '192.168.1.50' ,
272+ '10.0.1.76' ,
273+ '8.8.8.8' ,
274+ '::1' ,
275+ 'Other' ,
276+ null ,
277+ undefined ,
278+ ] ,
279+ direction : 'desc' ,
280+ type : 'ip' ,
281+ reverseOutput : false ,
282+ } ) ;
283+ } ) ;
157284 } ) ;
158285
159286 describe ( 'Range sorting' , ( ) => {
@@ -184,5 +311,22 @@ describe('Data sorting criteria', () => {
184311 } ) ;
185312 } ) ;
186313 }
314+
315+ it ( 'should sort undefined and null to the end' , ( ) => {
316+ testSorting ( {
317+ input : [ { gte : 1 , lt : 5 } , undefined , { gte : 0 , lt : 5 } , null , { gte : 0 } ] ,
318+ output : [ { gte : 0 , lt : 5 } , { gte : 0 } , { gte : 1 , lt : 5 } , undefined , null ] ,
319+ direction : 'asc' ,
320+ type : 'range' ,
321+ reverseOutput : false ,
322+ } ) ;
323+ testSorting ( {
324+ input : [ { gte : 1 , lt : 5 } , undefined , { gte : 0 , lt : 5 } , null , { gte : 0 } ] ,
325+ output : [ { gte : 1 , lt : 5 } , { gte : 0 } , { gte : 0 , lt : 5 } , undefined , null ] ,
326+ direction : 'desc' ,
327+ type : 'range' ,
328+ reverseOutput : false ,
329+ } ) ;
330+ } ) ;
187331 } ) ;
188332} ) ;
0 commit comments