1
1
/**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
3
3
*
4
4
* This source code is licensed under the Apache-2.0 license found in the
5
5
* LICENSE file in the root directory of this source tree.
6
6
*/
7
7
8
- import { sortRows , defaultSortRow } from '../sorting' ;
8
+ import { compare , defaultSortRow , sortRows } from '../sorting' ;
9
9
import { sortStates } from '../../state/sorting' ;
10
10
11
- describe ( 'sortRow ' , ( ) => {
11
+ describe ( 'sortRows ' , ( ) => {
12
12
const rowIds = [ 'row2' , 'row1' ] ;
13
13
const cellsById = {
14
14
'row1:header1' : { value : 'cell11' } ,
@@ -53,6 +53,91 @@ describe('sortRow', () => {
53
53
} )
54
54
) . toEqual ( [ 'row2' , 'row1' ] ) ;
55
55
} ) ;
56
+
57
+ it ( 'should sort React elements correctly' , ( ) => {
58
+ const reactCells1 = {
59
+ 'row1:header1' : { value : { props : { children : 'Apple' } } } ,
60
+ 'row2:header1' : { value : { props : { children : 'Banana' } } } ,
61
+ } ;
62
+ const reactCells2 = {
63
+ 'row1:header1' : { value : { props : { children : 1000 } } } ,
64
+ 'row2:header1' : { value : { props : { children : 'hmm' } } } ,
65
+ } ;
66
+
67
+ expect (
68
+ sortRows ( {
69
+ rowIds,
70
+ cellsById : reactCells1 ,
71
+ sortDirection : sortStates . ASC ,
72
+ key : 'header1' ,
73
+ locale : 'en' ,
74
+ sortRow : defaultSortRow ,
75
+ } )
76
+ ) . toEqual ( [ 'row1' , 'row2' ] ) ;
77
+ expect (
78
+ sortRows ( {
79
+ rowIds,
80
+ cellsById : reactCells2 ,
81
+ sortDirection : sortStates . ASC ,
82
+ key : 'header1' ,
83
+ locale : 'en' ,
84
+ sortRow : defaultSortRow ,
85
+ } )
86
+ ) . toEqual ( [ 'row2' , 'row1' ] ) ;
87
+ } ) ;
88
+
89
+ it ( 'should sort numeric strings as numbers' , ( ) => {
90
+ const cells = {
91
+ 'row1:header1' : { value : '10' } ,
92
+ 'row2:header1' : { value : '2' } ,
93
+ } ;
94
+
95
+ expect (
96
+ sortRows ( {
97
+ rowIds,
98
+ cellsById : cells ,
99
+ sortDirection : sortStates . ASC ,
100
+ key : 'header1' ,
101
+ locale : 'en' ,
102
+ } )
103
+ ) . toEqual ( [ 'row2' , 'row1' ] ) ;
104
+ } ) ;
105
+
106
+ it ( 'should handle a custom `sortRow` function' , ( ) => {
107
+ const customSortRow = ( a , b ) => a . length - b . length ;
108
+
109
+ const customCells = {
110
+ 'row1:header1' : { value : 'short' } ,
111
+ 'row2:header1' : { value : 'longerstring' } ,
112
+ } ;
113
+
114
+ expect (
115
+ sortRows ( {
116
+ rowIds,
117
+ cellsById : customCells ,
118
+ sortDirection : sortStates . ASC ,
119
+ key : 'header1' ,
120
+ sortRow : customSortRow ,
121
+ } )
122
+ ) . toEqual ( [ 'row1' , 'row2' ] ) ;
123
+ } ) ;
124
+
125
+ it ( 'should maintain order for equal values' , ( ) => {
126
+ const cells = {
127
+ 'row1:header1' : { value : 'same' } ,
128
+ 'row2:header1' : { value : 'same' } ,
129
+ } ;
130
+
131
+ expect ( rowIds ) . toEqual ( [ 'row2' , 'row1' ] ) ;
132
+ expect (
133
+ sortRows ( {
134
+ rowIds,
135
+ cellsById : cells ,
136
+ sortDirection : sortStates . ASC ,
137
+ key : 'header1' ,
138
+ } )
139
+ ) . toEqual ( [ 'row2' , 'row1' ] ) ;
140
+ } ) ;
56
141
} ) ;
57
142
58
143
describe ( 'defaultSortRow' , ( ) => {
@@ -76,3 +161,65 @@ describe('defaultSortRow', () => {
76
161
expect ( defaultSortRow ( '1' , '2' , sortProps ) ) . toBeGreaterThan ( 0 ) ;
77
162
} ) ;
78
163
} ) ;
164
+
165
+ describe ( 'compare' , ( ) => {
166
+ it ( 'should treat null as empty string' , ( ) => {
167
+ expect ( compare ( null , 'abc' ) ) . toEqual ( - 1 ) ;
168
+ expect ( compare ( null , null ) ) . toEqual ( 0 ) ;
169
+ expect ( compare ( 'abc' , null ) ) . toEqual ( 1 ) ;
170
+ } ) ;
171
+
172
+ it ( 'should compare numbers correctly' , ( ) => {
173
+ expect ( compare ( 10 , 5 ) ) . toEqual ( 5 ) ;
174
+ expect ( compare ( 3 , 3 ) ) . toEqual ( 0 ) ;
175
+ expect ( compare ( 1 , 10 ) ) . toEqual ( - 9 ) ;
176
+ } ) ;
177
+
178
+ it ( 'should compare mixed strings and numbers as strings' , ( ) => {
179
+ expect ( compare ( '5' , 10 ) ) . toEqual ( - 1 ) ;
180
+ expect ( compare ( 20 , '10' ) ) . toEqual ( 1 ) ;
181
+ } ) ;
182
+
183
+ it ( 'should compare React elements whose `props.children` are strings' , ( ) => {
184
+ const a = { props : { children : 'Apple' } } ;
185
+ const b = { props : { children : 'Banana' } } ;
186
+
187
+ expect ( compare ( a , b ) ) . toEqual ( - 1 ) ;
188
+ } ) ;
189
+
190
+ it ( 'should fallback to string comparison when `props.children` is not a string' , ( ) => {
191
+ const a = { props : { children : 123 } } ;
192
+ const b = { props : { children : 'banana' } } ;
193
+
194
+ expect ( compare ( a , b ) ) . toEqual ( 0 ) ;
195
+ } ) ;
196
+
197
+ it ( 'should fallback to string comparison for non-matching types' , ( ) => {
198
+ expect ( compare ( { } , 1 ) ) . toEqual ( - 1 ) ;
199
+ expect ( compare ( true , 'false' ) ) . toEqual ( 1 ) ;
200
+ } ) ;
201
+
202
+ it ( 'should treat `undefined` as a string when comparing' , ( ) => {
203
+ expect ( compare ( undefined , 'abc' ) ) . toEqual ( 1 ) ;
204
+ expect ( compare ( undefined , undefined ) ) . toEqual ( 0 ) ;
205
+ expect ( compare ( 'abc' , undefined ) ) . toEqual ( - 1 ) ;
206
+ } ) ;
207
+
208
+ it ( 'should use locale for string comparison' , ( ) => {
209
+ expect ( compare ( 'ä' , 'z' , 'sv-SE' ) ) . toEqual ( 1 ) ;
210
+ expect ( compare ( 'z' , 'ä' , 'sv-SE' ) ) . toEqual ( - 1 ) ;
211
+ expect ( compare ( 'ä' , 'z' , 'en-US' ) ) . toEqual ( - 1 ) ;
212
+ expect ( compare ( 'z' , 'ä' , 'en-US' ) ) . toEqual ( 1 ) ;
213
+ expect ( compare ( 'ä' , 'z' , 'de-DE' ) ) . toEqual ( - 1 ) ;
214
+ expect ( compare ( 'z' , 'ä' , 'de-DE' ) ) . toEqual ( 1 ) ;
215
+ } ) ;
216
+
217
+ it ( 'should compare falsy values correctly' , ( ) => {
218
+ expect ( compare ( false , true ) ) . toEqual ( - 1 ) ;
219
+ expect ( compare ( true , false ) ) . toEqual ( 1 ) ;
220
+ expect ( compare ( 0 , false ) ) . toEqual ( - 1 ) ;
221
+ expect ( compare ( false , 0 ) ) . toEqual ( 1 ) ;
222
+ expect ( compare ( null , undefined ) ) . toEqual ( - 1 ) ;
223
+ expect ( compare ( undefined , null ) ) . toEqual ( 1 ) ;
224
+ } ) ;
225
+ } ) ;
0 commit comments