@@ -7,190 +7,220 @@ import { mount } from 'enzyme';
77import useRootClose from '../src/useRootClose' ;
88
99const escapeKeyCode = 27 ;
10+ const configs = [
11+ {
12+ description : '' ,
13+ useShadowRoot : false ,
14+ } ,
15+ {
16+ description : 'with shadow root' ,
17+ useShadowRoot : true ,
18+ } ,
19+ ] ;
20+ // Wrap simulant's created event to add composed: true, which is the default
21+ // for most events.
22+ const fire = ( node , event , params ) => {
23+ const simulatedEvent = simulant ( event , params ) ;
24+ const fixedEvent = new simulatedEvent . constructor ( simulatedEvent . type , {
25+ bubbles : simulatedEvent . bubbles ,
26+ button : simulatedEvent . button ,
27+ cancelable : simulatedEvent . cancelable ,
28+ composed : true ,
29+ } ) ;
30+ fixedEvent . keyCode = simulatedEvent . keyCode ;
31+ node . dispatchEvent ( fixedEvent ) ;
32+ return fixedEvent ;
33+ } ;
34+
35+ configs . map ( ( config ) =>
36+ // eslint-disable-next-line mocha/no-setup-in-describe
37+ describe ( `useRootClose ${ config . description } ` , ( ) => {
38+ let attachTo , renderRoot , myDiv ;
39+
40+ beforeEach ( ( ) => {
41+ renderRoot = document . createElement ( 'div' ) ;
42+ if ( config . useShadowRoot ) {
43+ renderRoot . attachShadow ( { mode : 'open' } ) ;
44+ }
45+ document . body . appendChild ( renderRoot ) ;
46+ attachTo = config . useShadowRoot ? renderRoot . shadowRoot : renderRoot ;
47+ myDiv = ( ) => attachTo . querySelector ( '#my-div' ) ;
48+ } ) ;
1049
11- describe ( 'useRootClose' , ( ) => {
12- let attachTo ;
50+ afterEach ( ( ) => {
51+ ReactDOM . unmountComponentAtNode ( renderRoot ) ;
52+ document . body . removeChild ( renderRoot ) ;
53+ } ) ;
1354
14- beforeEach ( ( ) => {
15- attachTo = document . createElement ( 'div' ) ;
16- document . body . appendChild ( attachTo ) ;
17- } ) ;
55+ describe ( 'using default event' , ( ) => {
56+ // eslint-disable-next-line mocha/no-setup-in-describe
57+ shouldCloseOn ( undefined , 'click' ) ;
58+ } ) ;
1859
19- afterEach ( ( ) => {
20- ReactDOM . unmountComponentAtNode ( attachTo ) ;
21- document . body . removeChild ( attachTo ) ;
22- } ) ;
60+ describe ( 'using click event' , ( ) => {
61+ // eslint-disable-next-line mocha/no-setup-in-describe
62+ shouldCloseOn ( 'click' , 'click' ) ;
63+ } ) ;
2364
24- describe ( 'using default event' , ( ) => {
25- // eslint-disable-next-line mocha/no-setup-in-describe
26- shouldCloseOn ( undefined , 'click ' ) ;
27- } ) ;
65+ describe ( 'using mousedown event' , ( ) => {
66+ // eslint-disable-next-line mocha/no-setup-in-describe
67+ shouldCloseOn ( 'mousedown' , 'mousedown ' ) ;
68+ } ) ;
2869
29- describe ( 'using click event' , ( ) => {
30- // eslint-disable-next-line mocha/no-setup-in-describe
31- shouldCloseOn ( 'click' , 'click' ) ;
32- } ) ;
70+ function shouldCloseOn ( clickTrigger , eventName ) {
71+ function Wrapper ( { onRootClose, disabled } ) {
72+ const ref = useRef ( ) ;
73+ useRootClose ( ref , onRootClose , {
74+ disabled,
75+ clickTrigger,
76+ } ) ;
3377
34- describe ( 'using mousedown event' , ( ) => {
35- // eslint-disable-next-line mocha/no-setup-in-describe
36- shouldCloseOn ( 'mousedown' , 'mousedown' ) ;
37- } ) ;
78+ return (
79+ < div ref = { ref } id = "my-div" >
80+ hello there
81+ </ div >
82+ ) ;
83+ }
84+
85+ it ( 'should close when clicked outside' , ( ) => {
86+ let spy = sinon . spy ( ) ;
87+
88+ mount ( < Wrapper onRootClose = { spy } /> , { attachTo } ) ;
3889
39- function shouldCloseOn ( clickTrigger , eventName ) {
40- function Wrapper ( { onRootClose, disabled } ) {
41- const ref = useRef ( ) ;
42- useRootClose ( ref , onRootClose , {
43- disabled,
44- clickTrigger,
90+ fire ( myDiv ( ) , eventName ) ;
91+
92+ expect ( spy ) . to . not . have . been . called ;
93+
94+ fire ( document . body , eventName ) ;
95+
96+ expect ( spy ) . to . have . been . calledOnce ;
97+
98+ expect ( spy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . oneOf ( [ 'click' , 'mousedown' ] ) ;
4599 } ) ;
46100
47- return (
48- < div ref = { ref } id = "my-div" >
49- hello there
50- </ div >
51- ) ;
52- }
101+ it ( 'should not close when right-clicked outside' , ( ) => {
102+ let spy = sinon . spy ( ) ;
103+ mount ( < Wrapper onRootClose = { spy } /> , { attachTo } ) ;
53104
54- it ( 'should close when clicked outside' , ( ) => {
55- let spy = sinon . spy ( ) ;
105+ fire ( myDiv ( ) , eventName , { button : 1 } ) ;
56106
57- mount ( < Wrapper onRootClose = { spy } /> , { attachTo } ) ;
107+ expect ( spy ) . to . not . have . been . called ;
58108
59- simulant . fire ( document . getElementById ( 'my-div' ) , eventName ) ;
109+ fire ( document . body , eventName , { button : 1 } ) ;
60110
61- expect ( spy ) . to . not . have . been . called ;
111+ expect ( spy ) . to . not . have . been . called ;
112+ } ) ;
62113
63- simulant . fire ( document . body , eventName ) ;
114+ it ( 'should not close when disabled' , ( ) => {
115+ let spy = sinon . spy ( ) ;
116+ mount ( < Wrapper onRootClose = { spy } disabled /> , { attachTo } ) ;
64117
65- expect ( spy ) . to . have . been . calledOnce ;
118+ fire ( myDiv ( ) , eventName ) ;
66119
67- expect ( spy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . oneOf ( [ 'click' , 'mousedown' ] ) ;
68- } ) ;
120+ expect ( spy ) . to . not . have . been . called ;
69121
70- it ( 'should not close when right-clicked outside' , ( ) => {
71- let spy = sinon . spy ( ) ;
72- mount ( < Wrapper onRootClose = { spy } /> , { attachTo } ) ;
122+ fire ( document . body , eventName ) ;
73123
74- simulant . fire ( document . getElementById ( 'my-div' ) , eventName , {
75- button : 1 ,
124+ expect ( spy ) . to . not . have . been . called ;
76125 } ) ;
77126
78- expect ( spy ) . to . not . have . been . called ;
127+ it ( 'should close when inside another RootCloseWrapper' , ( ) => {
128+ let outerSpy = sinon . spy ( ) ;
129+ let innerSpy = sinon . spy ( ) ;
79130
80- simulant . fire ( document . body , eventName , { button : 1 } ) ;
131+ function Inner ( ) {
132+ const ref = useRef ( ) ;
133+ useRootClose ( ref , innerSpy , { clickTrigger } ) ;
81134
82- expect ( spy ) . to . not . have . been . called ;
83- } ) ;
135+ return (
136+ < div ref = { ref } id = "my-other-div" >
137+ hello there
138+ </ div >
139+ ) ;
140+ }
84141
85- it ( 'should not close when disabled' , ( ) => {
86- let spy = sinon . spy ( ) ;
87- mount ( < Wrapper onRootClose = { spy } disabled /> , { attachTo } ) ;
142+ function Outer ( ) {
143+ const ref = useRef ( ) ;
144+ useRootClose ( ref , outerSpy , { clickTrigger } ) ;
88145
89- simulant . fire ( document . getElementById ( 'my-div' ) , eventName ) ;
146+ return (
147+ < div ref = { ref } >
148+ < div id = "my-div" > hello there</ div >
149+ < Inner />
150+ </ div >
151+ ) ;
152+ }
90153
91- expect ( spy ) . to . not . have . been . called ;
154+ mount ( < Outer /> , { attachTo } ) ;
92155
93- simulant . fire ( document . body , eventName ) ;
156+ fire ( myDiv ( ) , eventName ) ;
94157
95- expect ( spy ) . to . not . have . been . called ;
96- } ) ;
158+ expect ( outerSpy ) . to . have . not . been . called ;
159+ expect ( innerSpy ) . to . have . been . calledOnce ;
97160
98- it ( 'should close when inside another RootCloseWrapper' , ( ) => {
99- let outerSpy = sinon . spy ( ) ;
100- let innerSpy = sinon . spy ( ) ;
161+ expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . oneOf ( [
162+ 'click' ,
163+ 'mousedown' ,
164+ ] ) ;
165+ } ) ;
166+ }
101167
102- function Inner ( ) {
168+ describe ( 'using keyup event' , ( ) => {
169+ function Wrapper ( { children, onRootClose, event : clickTrigger } ) {
103170 const ref = useRef ( ) ;
104- useRootClose ( ref , innerSpy , { clickTrigger } ) ;
171+ useRootClose ( ref , onRootClose , { clickTrigger } ) ;
105172
106173 return (
107- < div ref = { ref } id = "my-other- div" >
108- hello there
174+ < div ref = { ref } id = "my-div" >
175+ { children }
109176 </ div >
110177 ) ;
111178 }
112179
113- function Outer ( ) {
114- const ref = useRef ( ) ;
115- useRootClose ( ref , outerSpy , { clickTrigger } ) ;
116-
117- return (
118- < div ref = { ref } >
180+ it ( 'should close when escape keyup' , ( ) => {
181+ let spy = sinon . spy ( ) ;
182+ mount (
183+ < Wrapper onRootClose = { spy } >
119184 < div id = "my-div" > hello there</ div >
120- < Inner />
121- </ div >
185+ </ Wrapper > ,
122186 ) ;
123- }
124-
125- mount ( < Outer /> , { attachTo } ) ;
126-
127- simulant . fire ( document . getElementById ( 'my-div' ) , eventName ) ;
128187
129- expect ( outerSpy ) . to . have . not . been . called ;
130- expect ( innerSpy ) . to . have . been . calledOnce ;
188+ expect ( spy ) . to . not . have . been . called ;
131189
132- expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . oneOf ( [
133- 'click' ,
134- 'mousedown' ,
135- ] ) ;
136- } ) ;
137- }
138-
139- describe ( 'using keyup event' , ( ) => {
140- function Wrapper ( { children, onRootClose, event : clickTrigger } ) {
141- const ref = useRef ( ) ;
142- useRootClose ( ref , onRootClose , { clickTrigger } ) ;
143-
144- return (
145- < div ref = { ref } id = "my-div" >
146- { children }
147- </ div >
148- ) ;
149- }
150-
151- it ( 'should close when escape keyup' , ( ) => {
152- let spy = sinon . spy ( ) ;
153- mount (
154- < Wrapper onRootClose = { spy } >
155- < div id = "my-div" > hello there</ div >
156- </ Wrapper > ,
157- ) ;
158-
159- expect ( spy ) . to . not . have . been . called ;
190+ fire ( document . body , 'keyup' , { keyCode : escapeKeyCode } ) ;
160191
161- simulant . fire ( document . body , 'keyup' , { keyCode : escapeKeyCode } ) ;
162-
163- expect ( spy ) . to . have . been . calledOnce ;
164-
165- expect ( spy . getCall ( 0 ) . args . length ) . to . be . equal ( 1 ) ;
166- expect ( spy . getCall ( 0 ) . args [ 0 ] . keyCode ) . to . be . equal ( escapeKeyCode ) ;
167- expect ( spy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . equal ( 'keyup' ) ;
168- } ) ;
192+ expect ( spy ) . to . have . been . calledOnce ;
169193
170- it ( 'should close when inside another RootCloseWrapper' , ( ) => {
171- let outerSpy = sinon . spy ( ) ;
172- let innerSpy = sinon . spy ( ) ;
194+ expect ( spy . getCall ( 0 ) . args . length ) . to . be . equal ( 1 ) ;
195+ expect ( spy . getCall ( 0 ) . args [ 0 ] . keyCode ) . to . be . equal ( escapeKeyCode ) ;
196+ expect ( spy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . equal ( 'keyup' ) ;
197+ } ) ;
173198
174- mount (
175- < Wrapper onRootClose = { outerSpy } >
176- < div >
177- < div id = "my-div" > hello there</ div >
178- < Wrapper onRootClose = { innerSpy } >
179- < div id = "my-other-div" > hello there</ div >
180- </ Wrapper >
181- </ div >
182- </ Wrapper > ,
183- ) ;
199+ it ( 'should close when inside another RootCloseWrapper' , ( ) => {
200+ let outerSpy = sinon . spy ( ) ;
201+ let innerSpy = sinon . spy ( ) ;
202+
203+ mount (
204+ < Wrapper onRootClose = { outerSpy } >
205+ < div >
206+ < div id = "my-div" > hello there</ div >
207+ < Wrapper onRootClose = { innerSpy } >
208+ < div id = "my-other-div" > hello there</ div >
209+ </ Wrapper >
210+ </ div >
211+ </ Wrapper > ,
212+ ) ;
184213
185- simulant . fire ( document . body , 'keyup' , { keyCode : escapeKeyCode } ) ;
214+ fire ( document . body , 'keyup' , { keyCode : escapeKeyCode } ) ;
186215
187- // TODO: Update to match expectations.
188- // expect(outerSpy).to.have.not.been.called;
189- expect ( innerSpy ) . to . have . been . calledOnce ;
216+ // TODO: Update to match expectations.
217+ // expect(outerSpy).to.have.not.been.called;
218+ expect ( innerSpy ) . to . have . been . calledOnce ;
190219
191- expect ( innerSpy . getCall ( 0 ) . args . length ) . to . be . equal ( 1 ) ;
192- expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . keyCode ) . to . be . equal ( escapeKeyCode ) ;
193- expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . equal ( 'keyup' ) ;
220+ expect ( innerSpy . getCall ( 0 ) . args . length ) . to . be . equal ( 1 ) ;
221+ expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . keyCode ) . to . be . equal ( escapeKeyCode ) ;
222+ expect ( innerSpy . getCall ( 0 ) . args [ 0 ] . type ) . to . be . equal ( 'keyup' ) ;
223+ } ) ;
194224 } ) ;
195- } ) ;
196- } ) ;
225+ } ) ,
226+ ) ;
0 commit comments