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