Skip to content

Commit

Permalink
feat(overmind): createOvermindMock accepts an initial state callback
Browse files Browse the repository at this point in the history
  • Loading branch information
christianalfoni committed Jan 23, 2021
1 parent ee06ac2 commit 8f7ecf6
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 43 deletions.
59 changes: 21 additions & 38 deletions packages/node_modules/overmind/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { EventType, IAction, Overmind, SERIALIZE, createOvermindMock, rehydrate } from './'
import {
EventType,
IAction,
Overmind,
SERIALIZE,
createOvermindMock,
rehydrate,
} from './'
import { namespaced } from './config'

function toJSON(obj) {
Expand All @@ -10,7 +17,7 @@ class StateValue {
toJSON() {
return {
[SERIALIZE]: true,
value: this.value
value: this.value,
}
}
static fromJSON(json: { value: string }) {
Expand All @@ -26,7 +33,7 @@ function createDefaultOvermind() {
item: {
isAwesome: true,
},
value: null as unknown as StateValue
value: (null as unknown) as StateValue,
}
const changeFoo: Action<void, string> = (context) => {
context.state.foo = 'bar2'
Expand Down Expand Up @@ -68,7 +75,7 @@ function createDefaultOvermind() {
changeFooWithEffect,
changeValue,
waitAndChangeFoo,
rehydrateAction
rehydrateAction,
}
const effects = {
hello() {
Expand Down Expand Up @@ -170,14 +177,14 @@ describe('Overmind', () => {
})
app.eventHub.once(EventType.ACTION_START, (data) => {
expect(toJSON(data)).toEqual({
actionId:'doThis',
actionId: 'doThis',
actionName: 'doThis',
isRunning: true,
namespacePath: [],
executionId: 0,
operatorId: 0,
path: [],
type: 'action'
type: 'action',
})
})
app.eventHub.once(EventType.ACTION_END, (data) => {
Expand Down Expand Up @@ -242,7 +249,7 @@ describe('Overmind', () => {
method: 'set',
path: 'foo',
hasChangedValue: true,
delimiter: '.'
delimiter: '.',
},
],
executionId: 0,
Expand All @@ -268,7 +275,7 @@ describe('Overmind', () => {
method: 'set',
path: 'foo',
hasChangedValue: true,
delimiter: '.'
delimiter: '.',
},
],
executionId: 0,
Expand All @@ -294,7 +301,7 @@ describe('Overmind', () => {
method: 'set',
path: 'foo',
hasChangedValue: true,
delimiter: '.'
delimiter: '.',
},
],
executionId: 0,
Expand Down Expand Up @@ -388,8 +395,8 @@ describe('Overmind', () => {
expect(app.state.foo).toBe('bar2')
app.reconfigure({
state: {
foo: 'bar'
}
foo: 'bar',
},
})
expect(app.state.foo).toBe('bar2')
})
Expand All @@ -399,41 +406,17 @@ describe('Overmind', () => {
const changeFoo = app.actions.changeFoo
app.reconfigure({
state: {
foo: 'bar2'
foo: 'bar2',
},
actions: {
changeFoo(context) {
context.state.foo = 'replaced!'
}
}
},
},
})

expect(app.state.foo).toBe('bar2')
changeFoo()
expect(app.state.foo).toBe('replaced!')
})
})

describe('Overmind mock', () => {
test('should preserve getters', async (done) => {
expect.assertions(1)
const state = {
value: 0,
get valuePlusTwo() {
return this.value + 2
},
}
const updateValue: Action = (context) => {
context.state.value = 15
}
const actions = { updateValue }
const config = { state, actions }
type Config = typeof config
interface Action<Value = void> extends IAction<Config, Value> {}

const mock = createOvermindMock(config)
await mock.actions.updateValue()
expect(mock.state.valuePlusTwo).toEqual(17)
done()
})
})
42 changes: 38 additions & 4 deletions packages/node_modules/overmind/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,44 @@ export interface OvermindMock<Config extends IConfiguration>
mutations: IMutation[]
}

export function createOvermindMock<Config extends IConfiguration>(
config: Config
): OvermindMock<Config>
export function createOvermindMock<Config extends IConfiguration>(
config: Config,
setInitialState: (state: Config['state']) => void
): OvermindMock<Config>
export function createOvermindMock<Config extends IConfiguration>(
config: Config,
mockedEffects: NestedPartial<Config['effects']>
): OvermindMock<Config>
export function createOvermindMock<Config extends IConfiguration>(
config: Config,
mockedEffects?: NestedPartial<Config['effects']>
mockedEffects: NestedPartial<Config['effects']>,
setInitialState: (state: Config['state']) => void
): OvermindMock<Config>
export function createOvermindMock<Config extends IConfiguration>(
...args:
| [Config]
| [Config, (state: Config['state']) => void]
| [Config, NestedPartial<Config['effects']>]
| [
Config,
NestedPartial<Config['effects']>,
(state: Config['state']) => void
]
): OvermindMock<Config> {
const setState = typeof args[1] === 'function' ? args[1] : args[2]
const mockedEffects = typeof args[1] === 'function' ? undefined : args[1]

const state = deepCopy(args[0].state)

if (setState) {
;(setState as any)(state)
}
const mock = new Overmind(
Object.assign({}, config, {
state: deepCopy(config.state),
Object.assign({}, args[0], {
state,
}),
{
devtools: false,
Expand All @@ -167,7 +198,10 @@ export function createOvermindMock<Config extends IConfiguration>(
} as TestMode
) as OvermindMock<Config>

const action = (mock as any).createAction('onInitialize', config.onInitialize)
const action = (mock as any).createAction(
'onInitialize',
args[0].onInitialize
)

mock.onInitialize = () => action(mock)
mock.mutations = []
Expand Down
68 changes: 67 additions & 1 deletion packages/node_modules/overmind/src/mock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,74 @@ describe('Mock', () => {
path: 'foo',
args: ['bar!'],
hasChangedValue: true,
delimiter: '.',
delimiter: '.',
},
])
})
test('should preserve getters', async (done) => {
expect.assertions(1)
const state = {
value: 0,
get valuePlusTwo() {
return this.value + 2
},
}
const updateValue: Action = (context) => {
context.state.value = 15
}
const actions = { updateValue }
const config = { state, actions }
type Config = typeof config
interface Action<Value = void> extends IAction<Config, Value> {}

const mock = createOvermindMock(config)
await mock.actions.updateValue()
expect(mock.state.valuePlusTwo).toEqual(17)
done()
})
test('should allow setting initial state', async () => {
expect.assertions(1)
const state = {
value: 0,
}
const config = { state }

const mock = createOvermindMock(config, (state) => {
state.value = 1
})
expect(mock.state.value).toBe(1)
})
test('should allow setting initial and mock effect', async () => {
expect.assertions(2)
const state = {
value: 0,
}
const config = {
state,
actions: {
runFoo({ effects }) {
return effects.foo()
},
},
effects: {
foo() {
return 'bar'
},
},
}

const mock = createOvermindMock(
config,
{
foo() {
return 'bar2'
},
},
(state) => {
state.value = 1
}
)
expect(mock.state.value).toBe(1)
expect(mock.actions.runFoo()).toBe('bar2')
})
})

0 comments on commit 8f7ecf6

Please sign in to comment.