Skip to content

Commit e91df73

Browse files
fix(overmind): make copy of statemachines during mocking
1 parent 3586efa commit e91df73

File tree

3 files changed

+60
-8
lines changed

3 files changed

+60
-8
lines changed

packages/node_modules/overmind/src/statemachine.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,47 @@ describe('Statemachine', () => {
239239

240240
return overmind.actions.transition()
241241
})
242+
test('should make copy of statemachine during tests', () => {
243+
244+
type States = {
245+
state: 'FOO'
246+
obj: {
247+
foo: string
248+
}
249+
} | {
250+
state: 'BAR'
251+
obj: {
252+
foo: string
253+
}
254+
}
255+
256+
const state = statemachine<States>({
257+
FOO: ['BAR'],
258+
BAR: ['FOO']
259+
}, {
260+
state: 'FOO',
261+
obj: {
262+
foo: 'bar'
263+
}
264+
})
265+
const config = {
266+
state,
267+
actions: {
268+
changeFoo({ state }) {
269+
state.obj.foo = 'bar2'
270+
}
271+
}
272+
}
273+
274+
const overmind = createOvermindMock(config)
275+
276+
// @ts-ignore
277+
overmind.actions.changeFoo()
278+
expect(overmind.state.obj.foo).toBe('bar2')
279+
280+
281+
const overmind2 = createOvermindMock(config)
282+
283+
expect(overmind2.state.obj.foo).toBe('bar')
284+
})
242285
})

packages/node_modules/overmind/src/statemachine.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PROXY_TREE, VALUE } from 'proxy-state-tree'
2-
2+
import { deepCopy } from './utils'
33
import { IState } from '.'
44

55
type TStates = IState & {
@@ -25,14 +25,20 @@ export type Statemachine<States extends TStates, State extends TStates = States>
2525

2626
const INITIAL_STATE = Symbol('INITIAL_STATE')
2727
const TRANSITIONS = Symbol('TRANSITIONS')
28+
const STATE = Symbol('STATE')
2829

29-
class StateMachine<States extends TStates, State extends TStates = States> {
30+
export class StateMachine<States extends TStates, State extends TStates = States> {
3031
state: State["state"]
3132
private [INITIAL_STATE]: State["state"]
32-
constructor(transitions: StatemachineTransitions<States>, definition: States) {
33-
this[INITIAL_STATE] = definition.state
33+
private [STATE]: any
34+
private clone() {
35+
return new StateMachine(this[TRANSITIONS], deepCopy(this[STATE]))
36+
}
37+
constructor(transitions: StatemachineTransitions<States>, state: States) {
38+
this[STATE] = state
39+
this[INITIAL_STATE] = state.state
3440
this[TRANSITIONS] = transitions
35-
Object.assign(this, definition)
41+
Object.assign(this, state)
3642
}
3743
transition(state) {
3844
const transitions = this[VALUE][TRANSITIONS]
@@ -60,6 +66,6 @@ class StateMachine<States extends TStates, State extends TStates = States> {
6066
}
6167
}
6268

63-
export function statemachine<States extends TStates>(definition: StatemachineTransitions<States>, state: States): Statemachine<States> {
64-
return new StateMachine(definition, state) as any
69+
export function statemachine<States extends TStates>(transitions: StatemachineTransitions<States>, state: States): Statemachine<States> {
70+
return new StateMachine(transitions, state) as any
6571
}

packages/node_modules/overmind/src/utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import isPlainObject from 'is-plain-obj'
22
import { IMutation, IS_PROXY, VALUE } from 'proxy-state-tree'
3+
import { StateMachine } from './statemachine'
34

45
export const IS_TEST = process.env.NODE_ENV === 'test'
56
export const IS_OPERATOR = Symbol('operator')
@@ -62,7 +63,9 @@ export function getFunctionName(func: Function) {
6263
}
6364

6465
export function deepCopy(obj) {
65-
if (isPlainObject(obj)) {
66+
if (obj instanceof StateMachine) {
67+
return (obj as any).clone()
68+
} else if (isPlainObject(obj)) {
6669
return Object.keys(obj).reduce((aggr: any, key) => {
6770
if (key === '__esModule') {
6871
return aggr

0 commit comments

Comments
 (0)