1
+ import React , { useState } from "react"
2
+ import { render , unmountComponentAtNode } from "react-dom" ;
3
+ import { act } from "react-dom/test-utils" ;
4
+ import TabList from "../tabList/tabList" ;
5
+ import PanelList from "../panelList/panelList.js" ;
6
+ import reducer from "../utils/stateManagement/reducer" ;
7
+ import Api from '../utils/api' ;
8
+ import { ApiContext , StateContext , ForceUpdateContext } from "../utils/context.js" ;
9
+ import useDynTabs from './useDynamicTabs.js' ;
10
+ let container = document . createElement ( "div" ) ;
11
+ let op = '' ; //options
12
+ let renderApp ;
13
+ beforeAll ( ( ) => {
14
+ document . body . appendChild ( container ) ;
15
+ } ) ;
16
+ beforeEach ( ( ) => {
17
+ op = {
18
+ tabs : [ {
19
+ id : '1' ,
20
+ title : 'mock tab 1' ,
21
+ closable : true ,
22
+ panelComponent : < p > tab1 content</ p >
23
+ } , {
24
+ id : '2' ,
25
+ title : 'mock tab 2' ,
26
+ iconClass : 'ui-icon ui-icon-seek-end' ,
27
+ closable : false ,
28
+ panelComponent : < p > tab2 content</ p >
29
+ } , {
30
+ id : '3' ,
31
+ title : 'mock tab 3' ,
32
+ iconClass : 'ui-icon ui-icon-seek-end' ,
33
+ closable : false ,
34
+ panelComponent : < p > tab3 content</ p >
35
+ } ] ,
36
+ selectedTabID : '1' ,
37
+ accessibility : true ,
38
+ onSelect : jest . fn ( function ( ) { } ) ,
39
+ onChange : jest . fn ( function ( ) { } ) ,
40
+ onInit : jest . fn ( function ( ) { } ) ,
41
+ onClose : jest . fn ( function ( ) { } ) ,
42
+ onOpen : jest . fn ( function ( ) { } ) ,
43
+ onLoad : jest . fn ( function ( ) { } ) ,
44
+ beforeClose : jest . fn ( function ( ) { } ) ,
45
+ beforeSelect : jest . fn ( function ( ) { } )
46
+ } ;
47
+ renderApp = ( getDeps , rerender ) => {
48
+ const App = function ( props ) {
49
+ const [ Tablist , Panellist , ready ] = useDynTabs ( getDeps , op ) ;
50
+ return (
51
+ < div >
52
+ < Tablist > </ Tablist >
53
+ < Panellist > </ Panellist >
54
+ </ div >
55
+ ) ;
56
+ } ;
57
+ act ( ( ) => {
58
+ render ( < App > </ App > , container ) ;
59
+ } ) ;
60
+ rerender && act ( ( ) => {
61
+ render ( < App > </ App > , container ) ;
62
+ } ) ;
63
+ } ;
64
+ } ) ;
65
+ afterEach ( ( ) => {
66
+ unmountComponentAtNode ( container ) ;
67
+ container . innerHTML = "" ;
68
+ renderApp = null ;
69
+ } ) ;
70
+ afterAll ( ( ) => {
71
+ document . body . removeChild ( container ) ;
72
+ container = null ;
73
+ } ) ;
74
+ describe ( "checking number of tabs renders : " , ( ) => {
75
+ test ( "each tab should be rendered once initially" , ( ) => {
76
+ let _api ;
77
+ const getApiInstance = function ( op ) {
78
+ const api = new Api ( { options : op } ) ;
79
+ _api = api ;
80
+ api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
81
+ const updateStateRef = api . updateStateRef ;
82
+ api . updateStateRef = jest . fn ( function ( ) { updateStateRef . apply ( api , arguments ) ; return api ; } ) ;
83
+ return api ;
84
+ } ;
85
+ const getDeps = function ( ) {
86
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
87
+ } ;
88
+ renderApp ( getDeps ) ;
89
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
90
+ expect ( _api . updateStateRef . mock . calls . length ) . toBe ( 1 ) ;
91
+ } ) ;
92
+ test ( "tabs should not be rendered when parent component is re-rendered" , ( ) => {
93
+ let _api ;
94
+ const getApiInstance = function ( op ) {
95
+ const api = new Api ( { options : op } ) ;
96
+ _api = api ;
97
+ api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
98
+ const updateStateRef = api . updateStateRef ;
99
+ api . updateStateRef = jest . fn ( function ( ) { updateStateRef . apply ( api , arguments ) ; return api ; } ) ;
100
+ return api ;
101
+ } ;
102
+ const getDeps = function ( ) {
103
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
104
+ } ;
105
+ renderApp ( getDeps , true ) ;
106
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
107
+ expect ( _api . updateStateRef . mock . calls . length ) . toBe ( 2 ) ;
108
+ } ) ;
109
+ test ( "only current selected and previously selected tabs should be rendered after switching" , ( ) => {
110
+ let _api ;
111
+ const getApiInstance = function ( op ) {
112
+ const api = new Api ( { options : op } ) ;
113
+ _api = api ;
114
+ return api ;
115
+ } ;
116
+ const getDeps = function ( ) {
117
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
118
+ } ;
119
+ renderApp ( getDeps ) ;
120
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
121
+ act ( ( ) => { _api . select ( '2' ) ; } ) ;
122
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 2 ) ;
123
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '1' ) ;
124
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 1 ] [ 0 ] ) . toBe ( '2' ) ;
125
+ } ) ;
126
+ test ( "tabs should not be rendered after selecting a tab twice" , ( ) => {
127
+ let _api ;
128
+ const getApiInstance = function ( op ) {
129
+ const api = new Api ( { options : op } ) ;
130
+ _api = api ;
131
+ return api ;
132
+ } ;
133
+ const getDeps = function ( ) {
134
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
135
+ } ;
136
+ renderApp ( getDeps ) ;
137
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
138
+ act ( ( ) => { _api . select ( '1' ) ; } ) ;
139
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 0 ) ;
140
+ } ) ;
141
+ test ( "only opened tab should be rendered after opening a new tab" , ( ) => {
142
+ let _api ;
143
+ const getApiInstance = function ( op ) {
144
+ const api = new Api ( { options : op } ) ;
145
+ _api = api ;
146
+ return api ;
147
+ } ;
148
+ const getDeps = function ( ) {
149
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
150
+ } ;
151
+ renderApp ( getDeps ) ;
152
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
153
+ act ( ( ) => { _api . open ( { id : '4' , title : 'tab4' } ) ; } ) ;
154
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 1 ) ;
155
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '4' ) ;
156
+ } ) ;
157
+ test ( "tabs should not be rendered after closing a none selected tab" , ( ) => {
158
+ let _api ;
159
+ const getApiInstance = function ( op ) {
160
+ const api = new Api ( { options : op } ) ;
161
+ _api = api ;
162
+ return api ;
163
+ } ;
164
+ const getDeps = function ( ) {
165
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
166
+ } ;
167
+ renderApp ( getDeps ) ;
168
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
169
+ act ( ( ) => { _api . close ( '3' ) ; } ) ;
170
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 0 ) ;
171
+ } ) ;
172
+ test ( "only new selected tab should be rendered after closing a selected tab with switching" , ( ) => {
173
+ let _api ;
174
+ const getApiInstance = function ( op ) {
175
+ const api = new Api ( { options : op } ) ;
176
+ _api = api ;
177
+ return api ;
178
+ } ;
179
+ const getDeps = function ( ) {
180
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
181
+ } ;
182
+ renderApp ( getDeps ) ;
183
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
184
+ act ( ( ) => { _api . close ( '1' ) ; } ) ;
185
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 1 ) ;
186
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '2' ) ;
187
+ } ) ;
188
+ test ( 'all tabs should be render after calling refresh method' , ( ) => {
189
+ let _api ;
190
+ const getApiInstance = function ( op ) {
191
+ const api = new Api ( { options : op } ) ;
192
+ _api = api ;
193
+ return api ;
194
+ } ;
195
+ const getDeps = function ( ) {
196
+ return { reducer, getApiInstance, PanelList : props => null , TabList, ApiContext, StateContext, ForceUpdateContext } ;
197
+ } ;
198
+ renderApp ( getDeps ) ;
199
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
200
+ act ( ( ) => { _api . refresh ( ) ; } ) ;
201
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
202
+ } ) ;
203
+ } ) ;
204
+ describe ( "checking number of panels renders : " , ( ) => {
205
+ test ( "each panel should be rendered once initially" , ( ) => {
206
+ let _api ;
207
+ const getApiInstance = function ( op ) {
208
+ const api = new Api ( { options : op } ) ;
209
+ _api = api ;
210
+ api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
211
+ const updateStateRef = api . updateStateRef ;
212
+ api . updateStateRef = jest . fn ( function ( ) { updateStateRef . apply ( api , arguments ) ; return api ; } ) ;
213
+ return api ;
214
+ } ;
215
+ const getDeps = function ( ) {
216
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
217
+ } ;
218
+ renderApp ( getDeps ) ;
219
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
220
+ expect ( _api . updateStateRef . mock . calls . length ) . toBe ( 1 ) ;
221
+ } ) ;
222
+ test ( "panels should not be rendered when parent component is re-rendered" , ( ) => {
223
+ let _api ;
224
+ const getApiInstance = function ( op ) {
225
+ const api = new Api ( { options : op } ) ;
226
+ _api = api ;
227
+ api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
228
+ const updateStateRef = api . updateStateRef ;
229
+ api . updateStateRef = jest . fn ( function ( ) { updateStateRef . apply ( api , arguments ) ; return api ; } ) ;
230
+ return api ;
231
+ } ;
232
+ const getDeps = function ( ) {
233
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
234
+ } ;
235
+ renderApp ( getDeps , true ) ;
236
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
237
+ expect ( _api . updateStateRef . mock . calls . length ) . toBe ( 2 ) ;
238
+ } ) ;
239
+ test ( "only current selected and previously selected panels should be rendered after switching" , ( ) => {
240
+ let _api ;
241
+ const getApiInstance = function ( op ) {
242
+ const api = new Api ( { options : op } ) ;
243
+ _api = api ;
244
+ return api ;
245
+ } ;
246
+ const getDeps = function ( ) {
247
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
248
+ } ;
249
+ renderApp ( getDeps ) ;
250
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
251
+ act ( ( ) => { _api . select ( '2' ) ; } ) ;
252
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 2 ) ;
253
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '1' ) ;
254
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 1 ] [ 0 ] ) . toBe ( '2' ) ;
255
+ } ) ;
256
+ test ( "panels should not be rendered after selecting a tab twice" , ( ) => {
257
+ let _api ;
258
+ const getApiInstance = function ( op ) {
259
+ const api = new Api ( { options : op } ) ;
260
+ _api = api ;
261
+ return api ;
262
+ } ;
263
+ const getDeps = function ( ) {
264
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
265
+ } ;
266
+ renderApp ( getDeps ) ;
267
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
268
+ act ( ( ) => { _api . select ( '1' ) ; } ) ;
269
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 0 ) ;
270
+ } ) ;
271
+ test ( "only panle of opened tab should be rendered after opening a new tab" , ( ) => {
272
+ let _api ;
273
+ const getApiInstance = function ( op ) {
274
+ const api = new Api ( { options : op } ) ;
275
+ _api = api ;
276
+ return api ;
277
+ } ;
278
+ const getDeps = function ( ) {
279
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
280
+ } ;
281
+ renderApp ( getDeps ) ;
282
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
283
+ act ( ( ) => { _api . open ( { id : '4' , title : 'tab4' } ) ; } ) ;
284
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 1 ) ;
285
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '4' ) ;
286
+ } ) ;
287
+ test ( "panels should not be rendered after closing a none selected tab" , ( ) => {
288
+ let _api ;
289
+ const getApiInstance = function ( op ) {
290
+ const api = new Api ( { options : op } ) ;
291
+ _api = api ;
292
+ return api ;
293
+ } ;
294
+ const getDeps = function ( ) {
295
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
296
+ } ;
297
+ renderApp ( getDeps ) ;
298
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
299
+ act ( ( ) => { _api . close ( '3' ) ; } ) ;
300
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 0 ) ;
301
+ } ) ;
302
+ test ( "only panel of new selected tab should be rendered after closing a selected tab with switching" , ( ) => {
303
+ let _api ;
304
+ const getApiInstance = function ( op ) {
305
+ const api = new Api ( { options : op } ) ;
306
+ _api = api ;
307
+ return api ;
308
+ } ;
309
+ const getDeps = function ( ) {
310
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
311
+ } ;
312
+ renderApp ( getDeps ) ;
313
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
314
+ act ( ( ) => { _api . close ( '1' ) ; } ) ;
315
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 1 ) ;
316
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls [ 0 ] [ 0 ] ) . toBe ( '2' ) ;
317
+ } ) ;
318
+ test ( 'all panels should be render after calling refresh method' , ( ) => {
319
+ let _api ;
320
+ const getApiInstance = function ( op ) {
321
+ const api = new Api ( { options : op } ) ;
322
+ _api = api ;
323
+ return api ;
324
+ } ;
325
+ const getDeps = function ( ) {
326
+ return { reducer, getApiInstance, PanelList, TabList : props => null , ApiContext, StateContext, ForceUpdateContext } ;
327
+ } ;
328
+ renderApp ( getDeps ) ;
329
+ _api . optionsManager . setting . panelIdTemplate = jest . fn ( id => id ) ;
330
+ act ( ( ) => { _api . refresh ( ) ; } ) ;
331
+ expect ( _api . optionsManager . setting . panelIdTemplate . mock . calls . length ) . toBe ( 3 ) ;
332
+ } ) ;
333
+ } ) ;
334
+ describe ( 'output : ' , ( ) => {
335
+ test ( 'it returns TabList, PanelList and ready function with a same referenc after rendering multiple times' , ( ) => {
336
+ let _api ;
337
+ const getApiInstance = function ( op ) {
338
+ const api = new Api ( { options : op } ) ;
339
+ _api = api ;
340
+ return api ;
341
+ } ;
342
+ const getDeps = function ( ) {
343
+ return { reducer, getApiInstance, PanelList, TabList, ApiContext, StateContext, ForceUpdateContext } ;
344
+ } ;
345
+ let counter = 0 , firstReady , secondReady , firstTabList , secondTabList , firstPanelList , secondPanelList ;
346
+ const App = function ( props ) {
347
+ const [ TabList , PanelList , ready ] = useDynTabs ( getDeps , op ) ;
348
+ if ( counter === 0 ) {
349
+ firstPanelList = PanelList ;
350
+ firstReady = ready ;
351
+ firstTabList = TabList ;
352
+ } else {
353
+ secondPanelList = PanelList ;
354
+ secondReady = ready ;
355
+ secondTabList = TabList ;
356
+ }
357
+ counter ++ ;
358
+ return (
359
+ < div >
360
+ < TabList > </ TabList >
361
+ < PanelList > </ PanelList >
362
+ </ div >
363
+ ) ;
364
+ } ;
365
+ act ( ( ) => { render ( < App > </ App > , container ) ; } ) ;
366
+ act ( ( ) => { _api . refresh ( ) ; } ) ;
367
+ expect ( firstTabList ) . toBe ( secondTabList ) ;
368
+ expect ( firstReady ) . toBe ( secondReady ) ;
369
+ expect ( firstPanelList ) . toBe ( secondPanelList ) ;
370
+ } ) ;
371
+ } ) ;
0 commit comments