@@ -4,55 +4,71 @@ import undoable, { ActionCreators, excludeAction, includeAction, isHistory } fro
44
55const decrementActions = [ 'DECREMENT' ]
66
7- const testConfigZero = {
8- FOR_TEST_ONLY_includeActions : decrementActions ,
9- filter : includeAction ( decrementActions )
10- }
11-
12- const testConfigOne = {
13- limit : 100 ,
14- initTypes : 'RE-INITIALIZE' ,
15- FOR_TEST_ONLY_excludedActions : decrementActions ,
16- filter : excludeAction ( decrementActions )
17- }
18- const initialStateOne = {
19- past : [ 0 , 1 , 2 , 3 ] ,
20- present : 4 ,
21- future : [ 5 , 6 , 7 ]
22- }
23-
24- const testConfigTwo = {
25- limit : 1024 ,
26- initTypes : 'RE-INITIALIZE'
27- }
28- const initialStateTwo = {
29- past : [ 123 ] ,
30- present : 5 ,
31- future : [ - 1 , - 2 , - 3 ]
32- }
33-
34- const testConfigThree = {
35- limit : - 1 ,
36- initTypes : [ ]
37- }
38- const initialStateThree = {
39- past : [ 5 , { } , 3 , null , 1 ] ,
40- present : Math . pow ( 2 , 32 ) ,
41- future : [ ]
42- }
43-
44- runTestWithConfig ( undefined , undefined , 'Default config' )
45- runTestWithConfig ( { initTypes : [ ] } , undefined , 'No Init types' )
46- runTestWithConfig ( { limit : 200 } , 100 , 'Initial State equals 100' )
47- runTestWithConfig ( { } , { 'present' : 0 } , 'Initial State that looks like a history' )
48- runTestWithConfig ( testConfigZero , undefined , 'Filter (Include Actions)' )
49- runTestWithConfig ( testConfigOne , initialStateOne , 'Initial History and Filter (Exclude Actions)' )
50- runTestWithConfig ( testConfigTwo , initialStateTwo , 'Initial State and Init types' )
51- runTestWithConfig ( testConfigThree , initialStateThree , 'Erroneous configuration' )
7+ runTests ( 'Default config' )
8+ runTests ( 'No Init types' , {
9+ undoableConfig : {
10+ initTypes : [ ]
11+ }
12+ } )
13+ runTests ( 'Initial State equals 100' , {
14+ undoableConfig : {
15+ limit : 200
16+ } ,
17+ initialStoreState : 100
18+ } )
19+ runTests ( 'Initial State that looks like a history' , {
20+ undoableConfig : { } ,
21+ initialStoreState : { 'present' : 0 }
22+ } )
23+ runTests ( 'Filter (Include Actions)' , {
24+ undoableConfig : {
25+ filter : includeAction ( decrementActions )
26+ } ,
27+ testConfig : {
28+ includeActions : decrementActions
29+ }
30+ } )
31+ runTests ( 'Initial History and Filter (Exclude Actions)' , {
32+ undoableConfig : {
33+ limit : 100 ,
34+ initTypes : 'RE-INITIALIZE' ,
35+ filter : excludeAction ( decrementActions )
36+ } ,
37+ initialStoreState : {
38+ past : [ 0 , 1 , 2 , 3 ] ,
39+ present : 4 ,
40+ future : [ 5 , 6 , 7 ]
41+ } ,
42+ testConfig : {
43+ excludedActions : decrementActions
44+ }
45+ } )
46+ runTests ( 'Initial State and Init types' , {
47+ undoableConfig : {
48+ limit : 1024 ,
49+ initTypes : 'RE-INITIALIZE'
50+ } ,
51+ initialStoreState : {
52+ past : [ 123 ] ,
53+ present : 5 ,
54+ future : [ - 1 , - 2 , - 3 ]
55+ }
56+ } )
57+ runTests ( 'Erroneous configuration' , {
58+ undoableConfig : {
59+ limit : - 1 ,
60+ initTypes : [ ]
61+ } ,
62+ initialStoreState : {
63+ past : [ 5 , { } , 3 , null , 1 ] ,
64+ present : Math . pow ( 2 , 32 ) ,
65+ future : [ ]
66+ }
67+ } )
5268
5369// Test undoable reducers as a function of a configuration object
5470// `label` describes the nature of the configuration object used to run a test
55- function runTestWithConfig ( testConfig , initialStoreState , label ) {
71+ function runTests ( label , { undoableConfig , initialStoreState, testConfig } = { } ) {
5672 describe ( 'Undoable: ' + label , ( ) => {
5773 const countReducer = ( state = 0 , action = { } ) => {
5874 switch ( action . type ) {
@@ -65,25 +81,14 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
6581 }
6682 }
6783
68- const tenfoldReducer = ( state = 10 , action = { } ) => {
69- switch ( action . type ) {
70- case 'INCREMENT' :
71- return state + 10
72- case 'DECREMENT' :
73- return state - 10
74- default :
75- return state
76- }
77- }
78-
7984 let mockUndoableReducer
8085 let mockInitialState
8186 let incrementedState
8287 let store
8388
8489 before ( 'setup mock reducers and states' , ( ) => {
85- // testConfig .debug = true
86- mockUndoableReducer = undoable ( countReducer , testConfig )
90+ // undoableConfig .debug = true
91+ mockUndoableReducer = undoable ( countReducer , undoableConfig )
8792 store = createStore ( mockUndoableReducer , initialStoreState )
8893
8994 mockInitialState = mockUndoableReducer ( undefined , { } )
@@ -123,8 +128,18 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
123128 } )
124129
125130 describe ( 'Replace reducers on the fly' , ( ) => {
131+ const tenfoldReducer = ( state = 10 , action = { } ) => {
132+ switch ( action . type ) {
133+ case 'INCREMENT' :
134+ return state + 10
135+ case 'DECREMENT' :
136+ return state - 10
137+ default :
138+ return state
139+ }
140+ }
126141 it ( 'should preserve state when reducers are replaced' , ( ) => {
127- store . replaceReducer ( undoable ( tenfoldReducer , testConfig ) )
142+ store . replaceReducer ( undoable ( tenfoldReducer , undoableConfig ) )
128143 expect ( store . getState ( ) ) . to . deep . equal ( mockInitialState )
129144
130145 // swap back for other tests
@@ -133,7 +148,7 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
133148 } )
134149
135150 it ( 'should use replaced reducer for new actions' , ( ) => {
136- store . replaceReducer ( undoable ( tenfoldReducer , testConfig ) )
151+ store . replaceReducer ( undoable ( tenfoldReducer , undoableConfig ) )
137152
138153 // Increment and check result
139154 let expectedResult = tenfoldReducer ( store . getState ( ) . present , { type : 'INCREMENT' } )
@@ -152,9 +167,9 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
152167
153168 describe ( 'Actions' , ( ) => {
154169 it ( 'should not record unwanted actions' , ( ) => {
155- if ( testConfig && testConfig . FOR_TEST_ONLY_excludedActions ) {
156- const excludedAction = { type : testConfig . FOR_TEST_ONLY_excludedActions [ 0 ] }
157- const notFilteredReducer = undoable ( countReducer , { ...testConfig , filter : null } )
170+ if ( testConfig && testConfig . excludedActions ) {
171+ const excludedAction = { type : testConfig . excludedActions [ 0 ] }
172+ const notFilteredReducer = undoable ( countReducer , { ...undoableConfig , filter : null } )
158173 let expected = {
159174 ...notFilteredReducer ( mockInitialState , excludedAction ) ,
160175 // because action is filtered, this state should be indicated as filtered
@@ -172,13 +187,13 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
172187 expect ( actual ) . to . deep . equal ( expected )
173188 }
174189
175- if ( testConfig && testConfig . FOR_TEST_ONLY_includeActions ) {
190+ if ( testConfig && testConfig . includeActions ) {
176191 // should record this action's state in history
177- const includedAction = { type : testConfig . FOR_TEST_ONLY_includeActions [ 0 ] }
192+ const includedAction = { type : testConfig . includeActions [ 0 ] }
178193 const excludedAction = { type : 'INCREMENT' }
179194 const commonInitialState = mockUndoableReducer ( mockInitialState , includedAction )
180195
181- const notFilteredReducer = undoable ( countReducer , { ...testConfig , filter : null } )
196+ const notFilteredReducer = undoable ( countReducer , { ...undoableConfig , filter : null } )
182197 let expected = notFilteredReducer ( commonInitialState , excludedAction )
183198 expected = {
184199 ...expected ,
@@ -210,9 +225,9 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
210225
211226 it ( 'should reset upon init actions' , ( ) => {
212227 let reInitializedState
213- if ( testConfig && testConfig . initTypes ) {
214- if ( testConfig && testConfig . initTypes . length ) {
215- let initType = Array . isArray ( testConfig . initTypes ) ? testConfig . initTypes [ 0 ] : testConfig . initTypes
228+ if ( undoableConfig && undoableConfig . initTypes ) {
229+ if ( undoableConfig . initTypes . length > 0 ) {
230+ let initType = Array . isArray ( undoableConfig . initTypes ) ? undoableConfig . initTypes [ 0 ] : undoableConfig . initTypes
216231 reInitializedState = mockUndoableReducer ( incrementedState , { type : initType } )
217232 expect ( reInitializedState ) . to . deep . equal ( mockInitialState )
218233 } else {
@@ -240,31 +255,31 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
240255 } )
241256
242257 it ( 'should change present state back by one action' , ( ) => {
243- if ( testConfig && testConfig . limit >= 0 ) {
258+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
244259 expect ( undoState . present ) . to . equal ( mockInitialState . present )
245260 }
246261 } )
247262
248263 it ( 'should change present state to last element of \'past\'' , ( ) => {
249- if ( testConfig && testConfig . limit >= 0 ) {
264+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
250265 expect ( undoState . present ) . to . equal ( incrementedState . past [ incrementedState . past . length - 1 ] )
251266 }
252267 } )
253268
254269 it ( 'should add a new element to \'future\' from last state' , ( ) => {
255- if ( testConfig && testConfig . limit >= 0 ) {
270+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
256271 expect ( undoState . future [ 0 ] ) . to . equal ( incrementedState . present )
257272 }
258273 } )
259274
260275 it ( 'should decrease length of \'past\' by one' , ( ) => {
261- if ( testConfig && testConfig . limit >= 0 ) {
276+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
262277 expect ( undoState . past . length ) . to . equal ( incrementedState . past . length - 1 )
263278 }
264279 } )
265280
266281 it ( 'should increase length of \'future\' by one' , ( ) => {
267- if ( testConfig && testConfig . limit >= 0 ) {
282+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
268283 expect ( undoState . future . length ) . to . equal ( incrementedState . future . length + 1 )
269284 }
270285 } )
@@ -277,8 +292,8 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
277292 } )
278293
279294 it ( 'should undo to last not filtered state' , ( ) => {
280- if ( testConfig && testConfig . FOR_TEST_ONLY_excludedActions ) {
281- const excludedAction = { type : testConfig . FOR_TEST_ONLY_excludedActions [ 0 ] }
295+ if ( testConfig && testConfig . excludedActions ) {
296+ const excludedAction = { type : testConfig . excludedActions [ 0 ] }
282297 const includedAction = { type : 'INCREMENT' }
283298 // handle excluded action on a not filtered initial state
284299 let state = mockUndoableReducer ( mockInitialState , excludedAction )
@@ -305,31 +320,31 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
305320 it ( 'should change present state to equal state before undo' , ( ) => {
306321 // skip this test if steps are filtered out,
307322 // because the action might have been was filtered it won't redo to it's state
308- if ( testConfig && ! testConfig . FOR_TEST_ONLY_includeActions ) {
323+ if ( testConfig && ! testConfig . includeActions ) {
309324 expect ( redoState . present ) . to . equal ( incrementedState . present )
310325 }
311326 } )
312327
313328 it ( 'should change present state to first element of \'future\'' , ( ) => {
314- if ( testConfig && testConfig . limit >= 0 ) {
329+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
315330 expect ( redoState . present ) . to . equal ( undoState . future [ 0 ] )
316331 }
317332 } )
318333
319334 it ( 'should add a new element to \'past\' from last state' , ( ) => {
320- if ( testConfig && testConfig . limit >= 0 ) {
335+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
321336 expect ( redoState . past [ redoState . past . length - 1 ] ) . to . equal ( undoState . present )
322337 }
323338 } )
324339
325340 it ( 'should decrease length of \'future\' by one' , ( ) => {
326- if ( testConfig && testConfig . limit >= 0 ) {
341+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
327342 expect ( redoState . future . length ) . to . equal ( undoState . future . length - 1 )
328343 }
329344 } )
330345
331346 it ( 'should increase length of \'past\' by one' , ( ) => {
332- if ( testConfig && testConfig . limit >= 0 ) {
347+ if ( undoableConfig && undoableConfig . limit >= 0 ) {
333348 expect ( redoState . past . length ) . to . equal ( undoState . past . length + 1 )
334349 }
335350 } )
@@ -342,8 +357,8 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
342357 } )
343358
344359 it ( 'should not redo to filtered state' , ( ) => {
345- if ( testConfig && testConfig . FOR_TEST_ONLY_excludedActions ) {
346- const excludedAction = { type : testConfig . FOR_TEST_ONLY_excludedActions [ 0 ] }
360+ if ( testConfig && testConfig . excludedActions ) {
361+ const excludedAction = { type : testConfig . excludedActions [ 0 ] }
347362 // handle excluded action on a not filtered initial state
348363 let state = mockUndoableReducer ( mockInitialState , excludedAction )
349364 // undo
@@ -378,7 +393,7 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
378393 it ( 'should increase the length of future if successful' , ( ) => {
379394 // skip this test if steps are filtered out,
380395 // because the action might have been was filtered it won't be added to the future
381- if ( testConfig && ! testConfig . FOR_TEST_ONLY_includeActions ) {
396+ if ( testConfig && ! testConfig . includeActions ) {
382397 if ( incrementedState . past . length > jumpToPastIndex ) {
383398 expect ( jumpToPastState . future . length ) . to . be . above ( incrementedState . future . length )
384399 }
@@ -452,7 +467,7 @@ function runTestWithConfig (testConfig, initialStoreState, label) {
452467 it ( '-2 steps should result in same state as two times undo' , ( ) => {
453468 // skip this test if steps are filtered out,
454469 // because the double undo would be out of bounds and thus ignored
455- if ( testConfig && ! testConfig . FOR_TEST_ONLY_includeActions ) {
470+ if ( testConfig && ! testConfig . includeActions ) {
456471 expect ( doubleUndoState ) . to . deep . equal ( jumpToPastState )
457472 }
458473 } )
0 commit comments