@@ -7,128 +7,155 @@ import { act, renderHook, waitFor } from "@testing-library/react";
77
88const expectSelectedItems = ( actualIds : number [ ] , expectedIds : number [ ] ) => {
99 expect ( actualIds . length ) . toBe ( expectedIds . length ) ;
10- expect ( expectedIds . every ( id => actualIds . includes ( id ) ) ) . toBe ( true ) ;
10+ expect ( actualIds ) . toEqual ( expect . arrayContaining ( expectedIds ) ) ;
11+ } ;
12+
13+ type Click = {
14+ id : number ;
15+ isShiftPressed : boolean ;
16+ } ;
17+
18+ type TestConfig = {
19+ clicks : Click [ ] ;
20+ expectedItems : number [ ] ;
21+ } ;
22+
23+ const testSelection = async ( config : TestConfig ) => {
24+ const result = setup ( ) ;
25+
26+ config . clicks . forEach ( ( { id, isShiftPressed } ) => {
27+ act ( ( ) => {
28+ result . current . selectItem ( { id, isShiftPressed } ) ;
29+ } ) ;
30+ } ) ;
31+
32+ await waitFor ( ( ) => {
33+ expectSelectedItems ( result . current . selectedItemIds , config . expectedItems ) ;
34+ } ) ;
1135} ;
1236
1337describe ( useListSelection . name , ( ) => {
1438 it ( "should not explode for an empty list" , ( ) => {
15- const hook = setup ( { ids : [ ] } ) ;
16-
17- expect ( hook . selectedItemIds ) . toEqual ( [ ] ) ;
39+ const result = setup ( { ids : [ ] } ) ;
40+ expect ( result . current . selectedItemIds ) . toEqual ( [ ] ) ;
1841 } ) ;
1942
20- [
21- {
22- name : "can set a single item as selected" ,
43+ it ( "can set a single item as selected" , async ( ) => {
44+ await testSelection ( {
2345 clicks : [ { id : 2 , isShiftPressed : false } ] ,
2446 expectedItems : [ 2 ]
25- } ,
26- {
27- name : "can select multiple items, toggling back and forth" ,
47+ } ) ;
48+ } ) ;
49+
50+ it ( "can select multiple items, toggling back and forth" , async ( ) => {
51+ await testSelection ( {
2852 clicks : [
2953 { id : 2 , isShiftPressed : false } ,
3054 { id : 3 , isShiftPressed : false } ,
3155 { id : 4 , isShiftPressed : false } ,
3256 { id : 3 , isShiftPressed : false }
3357 ] ,
3458 expectedItems : [ 2 , 4 ]
35- } ,
36- {
37- name : "can shift-select first item" ,
59+ } ) ;
60+ } ) ;
61+
62+ it ( "can shift-select first item" , async ( ) => {
63+ await testSelection ( {
3864 clicks : [ { id : 2 , isShiftPressed : true } ] ,
3965 expectedItems : [ 2 ]
40- } ,
41- {
42- name : "can shift-select items down" ,
66+ } ) ;
67+ } ) ;
68+
69+ it ( "can shift-select items down" , async ( ) => {
70+ await testSelection ( {
4371 clicks : [
4472 { id : 2 , isShiftPressed : false } ,
4573 { id : 4 , isShiftPressed : true }
4674 ] ,
4775 expectedItems : [ 2 , 3 , 4 ]
48- } ,
49- {
50- name : "can shift-select items up" ,
76+ } ) ;
77+ } ) ;
78+
79+ it ( "can shift-select items up" , async ( ) => {
80+ await testSelection ( {
5181 clicks : [
5282 { id : 4 , isShiftPressed : false } ,
5383 { id : 2 , isShiftPressed : true }
5484 ] ,
5585 expectedItems : [ 2 , 3 , 4 ]
56- } ,
57- {
58- name : "can shift-select down and then up" ,
86+ } ) ;
87+ } ) ;
88+
89+ it ( "can shift-select down and then up" , async ( ) => {
90+ await testSelection ( {
5991 clicks : [
6092 { id : 2 , isShiftPressed : false } ,
6193 { id : 4 , isShiftPressed : true } ,
6294 { id : 0 , isShiftPressed : true }
6395 ] ,
6496 expectedItems : [ 0 , 1 , 2 , 3 , 4 ]
65- } ,
66- {
67- name : "can shift-select up and then down" ,
97+ } ) ;
98+ } ) ;
99+
100+ it ( "can shift-select up and then down" , async ( ) => {
101+ await testSelection ( {
68102 clicks : [
69103 { id : 2 , isShiftPressed : false } ,
70104 { id : 0 , isShiftPressed : true } ,
71105 { id : 4 , isShiftPressed : true }
72106 ] ,
73107 expectedItems : [ 0 , 1 , 2 , 3 , 4 ]
74- } ,
75- {
76- name : "can deselect the whole range up" ,
108+ } ) ;
109+ } ) ;
110+
111+ it ( "can deselect the whole range up" , async ( ) => {
112+ await testSelection ( {
77113 clicks : [
78114 { id : 2 , isShiftPressed : false } ,
79115 { id : 4 , isShiftPressed : true } ,
80116 { id : 2 , isShiftPressed : true }
81117 ] ,
82118 expectedItems : [ ]
83- } ,
84- {
85- name : "can deselect the whole range down" ,
119+ } ) ;
120+ } ) ;
121+
122+ it ( "can deselect the whole range down" , async ( ) => {
123+ await testSelection ( {
86124 clicks : [
87125 { id : 4 , isShiftPressed : false } ,
88126 { id : 2 , isShiftPressed : true } ,
89127 { id : 4 , isShiftPressed : true }
90128 ] ,
91129 expectedItems : [ ]
92- } ,
93- {
94- name : "can mark even more items down" ,
130+ } ) ;
131+ } ) ;
132+
133+ it ( "can mark even more items down" , async ( ) => {
134+ await testSelection ( {
95135 clicks : [
96136 { id : 2 , isShiftPressed : false } ,
97137 { id : 4 , isShiftPressed : true } ,
98138 { id : 0 , isShiftPressed : true } ,
99139 { id : 6 , isShiftPressed : true }
100140 ] ,
101141 expectedItems : [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ]
102- } ,
103- {
104- name : "can mark even more items up" ,
142+ } ) ;
143+ } ) ;
144+
145+ it ( "can mark even more items up" , async ( ) => {
146+ await testSelection ( {
105147 clicks : [
106148 { id : 4 , isShiftPressed : false } ,
107149 { id : 6 , isShiftPressed : true } ,
108150 { id : 2 , isShiftPressed : true } ,
109151 { id : 0 , isShiftPressed : true }
110152 ] ,
111153 expectedItems : [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ]
112- }
113- ] . forEach ( ( { name, clicks, expectedItems } ) => {
114- it ( name , async ( ) => {
115- const { result } = renderHook ( ( ) => useListSelection ( { ids : range ( 0 , 10 ) } ) ) ;
116-
117- clicks . forEach ( ( { id, isShiftPressed } ) => {
118- act ( ( ) => {
119- result . current . onSelectItem ( { id, isShiftPressed } ) ;
120- } ) ;
121- } ) ;
122-
123- await waitFor ( ( ) => {
124- expectSelectedItems ( result . current . selectedItemIds , expectedItems ) ;
125- } ) ;
126154 } ) ;
127155 } ) ;
128-
129- function setup ( { ids } : UseListSelectionProps < number > = { ids : range ( 0 , 10 ) } ) {
130- const res = renderHook ( ( ) => useListSelection ( { ids } ) ) ;
131-
132- return res . result . current ;
133- }
134156} ) ;
157+
158+ function setup ( { ids } : UseListSelectionProps < number > = { ids : range ( 0 , 10 ) } ) {
159+ const { result } = renderHook ( ( ) => useListSelection ( { ids } ) ) ;
160+ return result ;
161+ }
0 commit comments