@@ -7,18 +7,22 @@ describe('Statemachine', () => {
77
88 test ( 'should set initial state' , ( ) => {
99
10- type States = {
10+ type States = {
1111 state : 'FOO'
12+ string : string
1213 } | {
1314 state : 'BAR'
15+ number : number
1416 }
1517
1618 const state = statemachine < States > ( {
1719 FOO : [ 'BAR' ] ,
1820 BAR : [ 'FOO' ]
1921 } , {
20- state : 'FOO'
22+ state : 'FOO' ,
23+ string : 'hey'
2124 } )
25+
2226 const config = {
2327 state,
2428 }
@@ -27,6 +31,7 @@ describe('Statemachine', () => {
2731
2832 expect ( overmind . state . state ) . toBe ( 'FOO' )
2933 } )
34+
3035 test ( 'should transition state' , ( ) => {
3136 type States = {
3237 state : 'FOO'
@@ -38,10 +43,10 @@ describe('Statemachine', () => {
3843 FOO : [ 'BAR' ] ,
3944 BAR : [ 'FOO' ]
4045 } , {
41- state : 'FOO'
46+ state : 'FOO' ,
4247 } )
4348 const transition : Action = ( { state } ) => {
44- state . transition ( 'BAR' )
49+ state . transition ( 'BAR' , { } )
4550 }
4651
4752 const config = {
@@ -54,9 +59,12 @@ describe('Statemachine', () => {
5459 interface Action extends IAction < typeof config , void , void > { }
5560
5661 const overmind = createOvermindMock ( config )
62+
63+
5764 overmind . actions . transition ( )
5865 expect ( overmind . state . state ) . toBe ( 'BAR' )
5966 } )
67+
6068 test ( 'should ignore transition to invalid state' , ( ) => {
6169
6270 type States = {
@@ -72,7 +80,7 @@ describe('Statemachine', () => {
7280 state : 'FOO'
7381 } )
7482 const transition : Action = ( { state } ) => {
75- state . transition ( 'BAR' )
83+ state . transition ( 'BAR' , { } )
7684 }
7785
7886 const config = {
@@ -88,6 +96,7 @@ describe('Statemachine', () => {
8896 overmind . actions . transition ( )
8997 expect ( overmind . state . state ) . toBe ( 'FOO' )
9098 } )
99+
91100 test ( 'should run entry and exit transition' , async ( ) => {
92101 expect . assertions ( 3 )
93102 type States = {
@@ -103,12 +112,13 @@ describe('Statemachine', () => {
103112 state : 'FOO'
104113 } )
105114
106- const transition : Action = ( { state } ) => {
107- if ( state . transition ( 'BAR' ) ) {
108- expect ( state . state ) . toBe ( 'BAR' )
109- state . transition ( 'FOO' )
110- expect ( state . state ) . toBe ( 'FOO' )
111- }
115+ const transition : Action = async ( { state } ) => {
116+ state . transition ( 'BAR' , { } , ( barState ) => {
117+ expect ( barState . state ) . toBe ( 'BAR' )
118+ state . transition ( 'FOO' , { } , ( fooState ) => {
119+ expect ( fooState . state ) . toBe ( 'FOO' )
120+ } )
121+ } )
112122 }
113123
114124 const config = {
@@ -121,9 +131,11 @@ describe('Statemachine', () => {
121131 interface Action extends IAction < typeof config , void , void | Promise < void > > { }
122132
123133 const overmind = createOvermindMock ( config )
134+
124135 await overmind . actions . transition ( )
125136 expect ( overmind . state . state ) . toBe ( 'FOO' )
126137 } )
138+
127139 test ( 'should flush changes to transitions' , ( ) => {
128140 expect . assertions ( 1 )
129141
@@ -141,7 +153,7 @@ describe('Statemachine', () => {
141153 } )
142154
143155 const transition : Action = ( { state } ) => {
144- state . transition ( 'BAR' )
156+ state . transition ( 'BAR' , { } )
145157 }
146158
147159 const config = {
@@ -159,7 +171,7 @@ describe('Statemachine', () => {
159171 } )
160172 overmind . actions . transition ( )
161173 } )
162-
174+
163175 test ( 'should error when mutating async in transitions' , async ( ) => {
164176 expect . assertions ( 1 )
165177
@@ -176,10 +188,10 @@ describe('Statemachine', () => {
176188 state : 'FOO'
177189 } )
178190 const transition : Action = async ( { state } ) => {
179- if ( state . transition ( 'BAR' ) ) {
191+ await state . transition ( 'BAR' , { } , async ( ) => {
180192 await Promise . resolve ( )
181193 expect ( state [ PROXY_TREE ] . master . mutationTree . isBlocking ) . toBe ( true )
182- }
194+ } )
183195 }
184196
185197 const config = {
@@ -195,6 +207,7 @@ describe('Statemachine', () => {
195207
196208 return overmind . actions . transition ( )
197209 } )
210+
198211 test ( 'should enable mutations after new async matching or transition' , async ( ) => {
199212 expect . assertions ( 3 )
200213
@@ -211,19 +224,18 @@ describe('Statemachine', () => {
211224 state : 'FOO' ,
212225 } )
213226 const transition : Action = async ( { state } ) => {
214- if ( state . transition ( 'BAR' ) ) {
227+ await state . transition ( 'BAR' , { } , async ( ) => {
215228 await Promise . resolve ( )
216229 expect ( state [ PROXY_TREE ] . master . mutationTree . isBlocking ) . toBe ( true )
217230 if ( state . matches ( 'BAR' ) ) {
218231 expect ( state [ PROXY_TREE ] . master . mutationTree . isBlocking ) . toBe ( false )
219232 await Promise . resolve ( )
220- if ( state . transition ( 'FOO' ) ) {
233+ state . transition ( 'FOO' , { } , ( ) => {
221234 expect ( state [ PROXY_TREE ] . master . mutationTree . isBlocking ) . toBe ( false )
222- }
235+ } )
223236 }
224- }
237+ } )
225238 }
226-
227239
228240
229241 const config = {
@@ -239,6 +251,7 @@ describe('Statemachine', () => {
239251
240252 return overmind . actions . transition ( )
241253 } )
254+
242255 test ( 'should make copy of statemachine during tests' , ( ) => {
243256
244257 type States = {
@@ -282,4 +295,102 @@ describe('Statemachine', () => {
282295
283296 expect ( overmind2 . state . obj . foo ) . toBe ( 'bar' )
284297 } )
298+ test ( 'should have base state' , ( ) => {
299+
300+ type States = {
301+ state : 'FOO'
302+ } | {
303+ state : 'BAR'
304+ }
305+
306+ type Base = {
307+ obj : {
308+ foo : string
309+ }
310+ }
311+
312+ const state = statemachine < States , Base > ( {
313+ FOO : [ 'BAR' ] ,
314+ BAR : [ 'FOO' ]
315+ } , {
316+ state : 'FOO' ,
317+ } , {
318+ obj : {
319+ foo : 'bar'
320+ }
321+ } )
322+
323+ const config = {
324+ state,
325+ actions : {
326+ changeFoo ( { state } ) {
327+ state . obj . foo = 'bar2'
328+ }
329+ }
330+ }
331+
332+ const overmind = createOvermindMock ( config )
333+
334+ // @ts -ignore
335+ overmind . actions . changeFoo ( )
336+ expect ( overmind . state . obj . foo ) . toBe ( 'bar2' )
337+
338+
339+ const overmind2 = createOvermindMock ( config )
340+
341+ expect ( overmind2 . state . obj . foo ) . toBe ( 'bar' )
342+ } )
343+ test ( 'should delete existing state and merge in new state, keep base' , ( ) => {
344+
345+ type States = {
346+ state : 'FOO'
347+ foo : string
348+ } | {
349+ state : 'BAR'
350+ bar : number
351+ }
352+
353+ type Base = {
354+ baz : boolean
355+ }
356+
357+ const state = statemachine < States , Base > ( {
358+ FOO : [ 'BAR' ] ,
359+ BAR : [ 'FOO' ]
360+ } , {
361+ state : 'FOO' ,
362+ foo : 'bar'
363+ } , {
364+ baz : true
365+ } )
366+
367+ const transition : Action = async ( { state } ) => {
368+ await state . transition ( 'BAR' , {
369+ bar : 123 ,
370+ } , async ( barState ) => {
371+ expect ( barState . bar ) . toBe ( 123 )
372+ await Promise . resolve ( )
373+ await state . transition ( 'FOO' , {
374+ foo : '123'
375+ } , async ( fooState ) => {
376+ expect ( fooState . foo ) . toBe ( '123' )
377+ await Promise . resolve ( )
378+ } )
379+ } )
380+
381+ }
382+
383+ const config = {
384+ state,
385+ actions : {
386+ transition
387+ }
388+ }
389+
390+ interface Action extends IAction < typeof config , void , Promise < void > > { }
391+
392+ const overmind = createOvermindMock ( config )
393+
394+ overmind . actions . transition ( )
395+ } )
285396} )
0 commit comments