11import { describe , expect , it , vi } from "vitest" ;
2- import { swap , defaultCompare , sortProducts , ProductTuple } from "./sort" ;
2+ import { swap , ProductTuple , sortProducts , compareStrings , Compare } from "./sort" ;
33
44describe ( "swap" , ( ) => {
55 it ( "should swap two items in an array" , ( ) => {
@@ -9,61 +9,43 @@ describe("swap", () => {
99 } ) ;
1010} ) ;
1111
12- describe ( "defaultCompare" , ( ) => {
13- it ( "should return -1 if a < b" , ( ) => {
14- const result = defaultCompare ( 1 , 2 ) ;
15- expect ( result ) . toBe ( - 1 ) ;
16- } ) ;
17- it ( "should return 1 if a > b" , ( ) => {
18- const result = defaultCompare ( 2 , 1 ) ;
19- expect ( result ) . toBe ( 1 ) ;
20- } ) ;
21- it ( "should return 0 if a === b" , ( ) => {
22- const result = defaultCompare ( 1 , 1 ) ;
23- expect ( result ) . toBe ( 0 ) ;
24- } ) ;
25- } ) ;
26-
2712describe ( "array sort" , ( ) => {
28- it ( "should sort an array of numbers" , ( ) => {
29- const array = [ 4 , 2 , 3 , 1 , 5 ] ;
30- const result = array . sort ( ( a , b ) => defaultCompare ( a , b ) ) ;
31- expect ( result ) . toEqual ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
32- } ) ;
33-
3413 it ( "should sort an array of strings" , ( ) => {
3514 const array = [ "a" , "z" , "ag" , "ac" , "ab" , "ae" , "ba" ] ;
36- const result = array . sort ( ( a , b ) => defaultCompare ( a , b ) ) ;
37- expect ( result ) . toEqual ( [ "a" , "ab" , "ac" , "ae" , "ag" , "ba" , "z "] ) ;
15+ const result = array . sort ( ( a , b ) => compareStrings ( a , b ) ) ;
16+ expect ( result ) . toEqual ( [ "a" , "z" , " ab", "ac" , "ae" , "ag" , "ba" ] ) ;
3817 } ) ;
18+
3919 it ( "should sort an array of strings that are numbers" , ( ) => {
4020 const array = [ "5" , "4" , "3" , "2" , "1" ] ;
41- const result = array . sort ( ( a , b ) => defaultCompare ( a , b ) ) ;
21+ const result = array . sort ( ( a , b ) => compareStrings ( a , b ) ) ;
4222 expect ( result ) . toEqual ( [ "1" , "2" , "3" , "4" , "5" ] ) ;
4323 } ) ;
4424} ) ;
4525
4626describe ( "sortProducts" , ( ) => {
47- it ( "should sort an array of products by pick location" , ( ) => {
27+ it ( "should sort an array of products by pick location in ascending order from A 1 to A 10 " , ( ) => {
4828 const data : ProductTuple [ ] = [
4929 [ "product_code" , "quantity" , "pick_location" ] ,
50- [ "B1234" , "2" , "A3" ] ,
51- [ "B1235" , "3" , "A2" ] ,
52- [ "B1236" , "4" , "A1" ]
30+ [ "B1237" , "2" , "A 10" ] ,
31+ [ "B1234" , "2" , "A 3" ] ,
32+ [ "B1235" , "3" , "A 2" ] ,
33+ [ "B1236" , "4" , "A 1" ]
5334 ] ;
5435 const [ columns , ...rows ] = data ;
5536
56- const sortedRows = sortProducts ( rows ) ;
37+ const sortedRows = sortProducts ( rows , "ascending" ) ;
5738 const result = [ columns , ...sortedRows ] ;
5839
5940 expect ( result ) . toEqual ( [
6041 [ "product_code" , "quantity" , "pick_location" ] ,
61- [ "B1236" , "4" , "A1" ] ,
62- [ "B1235" , "3" , "A2" ] ,
63- [ "B1234" , "2" , "A3" ]
42+ [ "B1236" , "4" , "A 1" ] ,
43+ [ "B1235" , "3" , "A 2" ] ,
44+ [ "B1234" , "2" , "A 3" ] ,
45+ [ "B1237" , "2" , "A 10" ]
6446 ] ) ;
6547 } ) ;
66- it ( "should sort an array of products by bay and shelf height in ascending order" , ( ) => {
48+ it ( "should sort an array of products by pick location ( bay and shelf height) in ascending order" , ( ) => {
6749 const data : ProductTuple [ ] = [
6850 [ "product_code" , "quantity" , "pick_location" ] ,
6951 [ "A" , "10" , "Z 1" ] ,
@@ -73,7 +55,7 @@ describe("sortProducts", () => {
7355 ] ;
7456 const [ columns , ...rows ] = data ;
7557
76- const sortedRows = sortProducts ( rows ) ;
58+ const sortedRows = sortProducts ( rows , "ascending" ) ;
7759 const result = [ columns , ...sortedRows ] ;
7860
7961 expect ( result ) . toEqual ( [
@@ -90,19 +72,245 @@ describe("sortProducts", () => {
9072 [ "E" , "1" , "AB 1" ] ,
9173 [ "F" , "1" , "AB 10" ] ,
9274 [ "H" , "1" , "AB 9" ] ,
93- [ "H " , "1" , "AB 7" ]
75+ [ "J " , "1" , "AB 7" ]
9476 ] ;
9577 const [ columns , ...rows ] = data ;
9678
97- const sortedRows = sortProducts ( rows ) ;
79+ const sortedRows = sortProducts ( rows , "ascending" ) ;
9880 const result = [ columns , ...sortedRows ] ;
9981
10082 expect ( result ) . toEqual ( [
10183 [ "product_code" , "quantity" , "pick_location" ] ,
10284 [ "E" , "1" , "AB 1" ] ,
103- [ "H " , "1" , "AB 7" ] ,
85+ [ "J " , "1" , "AB 7" ] ,
10486 [ "H" , "1" , "AB 9" ] ,
10587 [ "F" , "1" , "AB 10" ]
10688 ] ) ;
10789 } ) ;
90+
91+ it ( "should sort by shelf height if the bays are not the same" , ( ) => {
92+ const data : ProductTuple [ ] = [
93+ [ "product_code" , "quantity" , "pick_location" ] ,
94+ [ "B1237" , "2" , "A 10" ] ,
95+ [ "B1237" , "2" , "A 10" ] ,
96+ [ "B12311" , "2" , "Z 10" ] ,
97+ [ "B1234" , "2" , "Z 3" ] ,
98+ [ "B1235" , "2" , "A 3" ] ,
99+ [ "B1236" , "3" , "Z 2" ] ,
100+ [ "B1238" , "4" , "Z 1" ] ,
101+ [ "B1239" , "3" , "A 2" ] ,
102+ [ "B12310" , "4" , "A 1" ]
103+ ] ;
104+
105+ const [ columns , ...rows ] = data ;
106+
107+ const sortedRows = sortProducts ( rows , "ascending" ) ;
108+ const result = [ columns , ...sortedRows ] ;
109+ expect ( result ) . toEqual ( [
110+ [ "product_code" , "quantity" , "pick_location" ] ,
111+ [ "B12310" , "4" , "A 1" ] ,
112+ [ "B1239" , "3" , "A 2" ] ,
113+ [ "B1235" , "2" , "A 3" ] ,
114+ [ "B1237" , "4" , "A 10" ] ,
115+ [ "B1238" , "4" , "Z 1" ] ,
116+ [ "B1236" , "3" , "Z 2" ] ,
117+ [ "B1234" , "2" , "Z 3" ] ,
118+ [ "B12311" , "2" , "Z 10" ]
119+ ] ) ;
120+ } ) ;
121+ } ) ;
122+
123+ describe ( "sortProducts" , ( ) => {
124+ const data : ProductTuple [ ] = [
125+ [ "product_code" , "quantity" , "pick_location" ] ,
126+ [ "1" , "1" , "AB 1" ] ,
127+ [ "2" , "1" , "AB 10" ] ,
128+ [ "3" , "1" , "AB 9" ] ,
129+ [ "4" , "1" , "AB 7" ]
130+ ] ;
131+
132+ it ( "should sort products with the same bay by shelf height" , ( ) => {
133+ const [ , ...rows ] = data ;
134+ const result = sortProducts ( rows , "ascending" ) ;
135+ expect ( result ) . toEqual ( [
136+ [ "1" , "1" , "AB 1" ] ,
137+ [ "4" , "1" , "AB 7" ] ,
138+ [ "3" , "1" , "AB 9" ] ,
139+ [ "2" , "1" , "AB 10" ]
140+ ] ) ;
141+ } ) ;
142+
143+ it ( 'should reverse the results if the method is "descending"' , ( ) => {
144+ const [ , ...rows ] = data ;
145+ const result = sortProducts ( rows , "descending" ) ;
146+ expect ( result ) . toEqual ( [
147+ [ "2" , "1" , "AB 10" ] ,
148+ [ "3" , "1" , "AB 9" ] ,
149+ [ "4" , "1" , "AB 7" ] ,
150+ [ "1" , "1" , "AB 1" ]
151+ ] ) ;
152+ } ) ;
153+
154+ it ( "should deduplicate products by id and add their qty" , ( ) => {
155+ const data : ProductTuple [ ] = [
156+ [ "product_code" , "quantity" , "pick_location" ] ,
157+ [ "1" , "1" , "AB 1" ] ,
158+ [ "1" , "1" , "AB 1" ] ,
159+ [ "2" , "1" , "AB 10" ] ,
160+ [ "3" , "1" , "AB 9" ] ,
161+ [ "4" , "1" , "AB 7" ]
162+ ] ;
163+ const [ , ...rows ] = data ;
164+ const result = sortProducts ( rows , "descending" ) ;
165+ expect ( result ) . toEqual ( [
166+ [ "2" , "1" , "AB 10" ] ,
167+ [ "3" , "1" , "AB 9" ] ,
168+ [ "4" , "1" , "AB 7" ] ,
169+ [ "1" , "2" , "AB 1" ]
170+ ] ) ;
171+ } ) ;
172+
173+ it ( "should sort products that do not have the same bay by bay and then by shelf height" , ( ) => {
174+ const data : ProductTuple [ ] = [
175+ [ "product_code" , "quantity" , "pick_location" ] ,
176+ [ "3" , "1" , "AB 10" ] ,
177+ [ "4" , "1" , "AB 9" ] ,
178+ [ "5" , "1" , "AB 7" ] ,
179+ [ "6" , "1" , "AZ 1" ] ,
180+ [ "7" , "1" , "AZ 10" ] ,
181+ [ "8" , "1" , "AZ 9" ] ,
182+ [ "9" , "1" , "AZ 7" ]
183+ ] ;
184+ const [ , ...rows ] = data ;
185+ const result = sortProducts ( rows , "ascending" ) ;
186+ expect ( result ) . toEqual ( [
187+ [ "5" , "1" , "AB 7" ] ,
188+ [ "4" , "1" , "AB 9" ] ,
189+ [ "3" , "1" , "AB 10" ] ,
190+ [ "6" , "1" , "AZ 1" ] ,
191+ [ "9" , "1" , "AZ 7" ] ,
192+ [ "8" , "1" , "AZ 9" ] ,
193+ [ "7" , "1" , "AZ 10" ]
194+ ] ) ;
195+ } ) ;
196+
197+ it ( "should sort an array of products by pick location in ascending order from A 1 to AZ 10" , ( ) => {
198+ const data : ProductTuple [ ] = [
199+ [ "product_code" , "quantity" , "pick_location" ] ,
200+ [ "1" , "1" , "A 1" ] ,
201+ [ "2" , "1" , "Z 1" ] ,
202+ [ "3" , "1" , "AB 10" ] ,
203+ [ "9" , "1" , "AZ 7" ]
204+ ] ;
205+ const [ , ...rows ] = data ;
206+ const result = sortProducts ( rows , "ascending" ) ;
207+ expect ( result ) . toEqual ( [
208+ [ "1" , "1" , "A 1" ] ,
209+ [ "2" , "1" , "Z 1" ] ,
210+ [ "3" , "1" , "AB 10" ] ,
211+ [ "9" , "1" , "AZ 7" ]
212+ ] ) ;
213+ } ) ;
214+ } ) ;
215+
216+ describe ( "compareStrings" , ( ) => {
217+ it ( "should throw an error if the string is more than two characters" , ( ) => {
218+ expect ( ( ) => compareStrings ( "ABC" , "ABC" ) ) . toThrowError ( ) ;
219+ expect ( ( ) => compareStrings ( "ABC" , "AB" ) ) . toThrowError ( ) ;
220+ expect ( ( ) => compareStrings ( "AB" , "ABC" ) ) . toThrowError ( ) ;
221+ expect ( ( ) => compareStrings ( "AB" , "AB" ) ) . not . toThrowError ( ) ;
222+ } ) ;
223+ describe ( "single char" , ( ) => {
224+ // Case 1: A, A - single chars, both match
225+ it ( "should return EQUALS if single chars, both match" , ( ) => {
226+ const data = [ "A" , "A" ] ;
227+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
228+ expect ( result ) . toEqual ( Compare . EQUALS ) ;
229+ } ) ;
230+
231+ // Case 2: A, Z || Z, A - single chars, no match
232+ it ( "should return BIGGER THAN if single chars, no match" , ( ) => {
233+ const data = [ "Z" , "A" ] ;
234+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
235+ expect ( result ) . toEqual ( Compare . BIGGER_THAN ) ;
236+ } ) ;
237+
238+ it ( "should return LESS THAN if single chars, no match" , ( ) => {
239+ const data = [ "A" , "Z" ] ;
240+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
241+ expect ( result ) . toEqual ( Compare . LESS_THAN ) ;
242+ } ) ;
243+ } ) ;
244+
245+ describe ( "multiple chars" , ( ) => {
246+ // Case 3: AA, AA - multiple chars, both match
247+ it ( "should return EQUALS if the first and second letters are the same" , ( ) => {
248+ const data = [ "AA" , "AA" ] ;
249+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
250+ expect ( result ) . toEqual ( Compare . EQUALS ) ;
251+ } ) ;
252+
253+ // Case 4: AA, AZ - multiple chars, only first letters match
254+ it ( "should return LESS THAN if the first letters match but the second char is lower" , ( ) => {
255+ const data = [ "AA" , "AB" ] ;
256+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
257+ expect ( result ) . toEqual ( Compare . LESS_THAN ) ;
258+ } ) ;
259+
260+ it ( "should return BIGGER THAN if the first letters match but the second char is higher" , ( ) => {
261+ const data = [ "AB" , "AA" ] ;
262+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
263+ expect ( result ) . toEqual ( Compare . BIGGER_THAN ) ;
264+ } ) ;
265+
266+ // Case 5: ZA, AA - multiple chars, only second letters match
267+ it ( "should return LESS THAN if the first letters dont match and only second letters match" , ( ) => {
268+ const data = [ "AA" , "BA" ] ;
269+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
270+ expect ( result ) . toEqual ( Compare . LESS_THAN ) ;
271+ } ) ;
272+
273+ it ( "should return BIGGER THAN if the first letters dont match and only second letters match" , ( ) => {
274+ const data = [ "BA" , "AA" ] ;
275+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
276+ expect ( result ) . toEqual ( Compare . BIGGER_THAN ) ;
277+ } ) ;
278+
279+ // Case 6: ZA, AZ - multiple chars, no match
280+ it ( "should return BIGGER THAN if no chars match and the first char is lower" , ( ) => {
281+ const data = [
282+ [ "ZA" , "AZ" ] ,
283+ [ "XY" , "AK" ]
284+ ] ;
285+ data . forEach ( ( [ a , b ] ) => {
286+ const result = compareStrings ( a , b ) ;
287+ expect ( result ) . toEqual ( Compare . BIGGER_THAN ) ;
288+ } ) ;
289+ } ) ;
290+
291+ it ( "should return LESS THAN if no chars match and the first char is higher" , ( ) => {
292+ const data = [
293+ [ "AZ" , "ZA" ] ,
294+ [ "KA" , "XY" ]
295+ ] ;
296+ data . forEach ( ( [ a , b ] ) => {
297+ const result = compareStrings ( a , b ) ;
298+ expect ( result ) . toEqual ( Compare . LESS_THAN ) ;
299+ } ) ;
300+ } ) ;
301+
302+ // Case 7: AA, Z - multiple chars, and single char
303+ it ( "should return BIGGER THAN if the first string is multiple chars and the second is a single char" , ( ) => {
304+ const data = [ "AA" , "Z" ] ;
305+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
306+ expect ( result ) . toEqual ( Compare . BIGGER_THAN ) ;
307+ } ) ;
308+
309+ // Case 8: Z, AA - single char, and multiple chars
310+ it ( "should return LESS THAN if the first string is a single char and second is multiple" , ( ) => {
311+ const data = [ "Z" , "AA" ] ;
312+ const result = compareStrings ( data [ 0 ] , data [ 1 ] ) ;
313+ expect ( result ) . toEqual ( Compare . LESS_THAN ) ;
314+ } ) ;
315+ } ) ;
108316} ) ;
0 commit comments