diff --git a/package.json b/package.json index deb7325..cc76de5 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,6 @@ "pre-commit": "npm run lint" } }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "name": "dva-toolkit", "author": "Bay", "module": "dist/dva-toolkit.esm.js", diff --git a/src/actions.ts b/src/actions.ts index 9ee17e6..845498b 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -16,7 +16,7 @@ export type ActionCreatorDvaCaseReducer = : ActionCreatorWithoutPayload /** - * dva action need + * dva reducer actions creator * * @public */ @@ -25,7 +25,7 @@ export type ActionCreatorDvaReducers = { } /** - * dva + * dva reducer actions * * @public */ @@ -35,6 +35,11 @@ export type DvaReducersAction< ? ActionCreatorDvaReducers : never +/** + * dva effects actions creator + * + * @public + */ export type ActionCreatorDvaEffect = E extends (action: infer Action, effects: any) => any ? Action extends { payload: infer P } @@ -42,6 +47,11 @@ export type ActionCreatorDvaEffect = : ActionCreatorWithoutPayload : ActionCreatorWithoutPayload +/** + * dva effects actions + * + * @public + */ export type DvaEffectsAction< CE extends DvaSliceCaseEffects > = { @@ -50,6 +60,11 @@ export type DvaEffectsAction< : ActionCreatorDvaEffect } +/** + * dva actions + * + * @public + */ export type DvaCaseAction< CR extends DvaSliceCaseReducers, CE extends DvaSliceCaseEffects diff --git a/src/effects.ts b/src/effects.ts index 72a54f2..8c9fb70 100644 --- a/src/effects.ts +++ b/src/effects.ts @@ -3,7 +3,7 @@ import type { call, put, take, select, cancel } from 'redux-saga/effects' import type { PayloadAction } from '@reduxjs/toolkit' /** - * dva 支持的 saga command 列表 + * saga effects supported by dva * * @public */ @@ -17,7 +17,7 @@ export type SagaEffectsCommandMap = { } /** - * effect 方法 + * pure effect method * * @public */ @@ -25,17 +25,22 @@ export type DvaCaseEffects = (action: PayloadAction, effects: SagaEffectsCommandMap) => Generator /** - * 有 effect 类型的 effect 方法 + * effect with saga config * * @public */ export type DvaCaseEffectWithType = [DvaCaseEffects, {type: EffectType}] +/** + * all effect case + * + * @public + */ export type DvaCaseEffectValue = DvaCaseEffects | DvaCaseEffectWithType /** - * dva 配置中 effects 列表的类型 + * effects in dva config * * @public */ diff --git a/src/reducers.ts b/src/reducers.ts index abd8653..99c78d7 100644 --- a/src/reducers.ts +++ b/src/reducers.ts @@ -37,7 +37,7 @@ export type DvaSliceCaseReducers< > = DvaReducersWithEnhancer | Reducers /** - * 没看懂,但加上去就对了 + * valid dva reducers case * * TODO: try to understand this func */ diff --git a/src/slice.ts b/src/slice.ts index 39622bc..9327406 100644 --- a/src/slice.ts +++ b/src/slice.ts @@ -40,6 +40,11 @@ export type CreateDvaSliceOption< subscriptions?: SubscriptionsMapObject, } +/** + * dva slice result, `model` is dva model, `action` is typed action generator + * + * @public + */ export type DvaSlice< State = any, CR extends DvaSliceCaseReducers = DvaSliceCaseReducers, diff --git a/test/effects.test.ts b/test/effects.test.ts index 8d52da7..50780e3 100644 --- a/test/effects.test.ts +++ b/test/effects.test.ts @@ -7,816 +7,70 @@ declare module 'dva' { } } -const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout)) +const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout)) describe('effects', () => { it('put action', done => { const app = create() - app.model({ + const { model, action: { addDelay } } = createDvaSlice({ namespace: 'count', state: 0, reducers: { - add (state, { payload }) { - return state + payload || 1 + add (state, { payload }: PayloadAction) { + return state + (payload || 1) } }, effects: { - * addDelay ({ payload }, { put, call }) { + * addDelay ({ payload }: PayloadAction, { put, call }) { yield call(delay, 100) yield put({ type: 'add', payload }) } } }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'count/addDelay', payload: 2 }) - expect(app._store.getState().count).toEqual(0) - setTimeout(() => { - expect(app._store.getState().count).toEqual(2) - done() - }, 200) - }) - - function testAppCreator (opts?: any) { - const app = create(opts) - const { model } = createDvaSlice({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }: PayloadAction) { - return state + payload || 1 - } - }, - effects: { - * putWithNamespace ({ payload }: PayloadAction, { put }) { - yield put({ type: 'count/add', payload }) - }, - * putWithoutNamespace ({ payload }: PayloadAction, { put }) { - yield put({ type: 'add', payload }) - } - } - }) app.model(model) - return app - } - - it('put action with namespace will get a warning', () => { - const app = testAppCreator() - const logs = [] - - app.router(() => ({})) - app.start() - expect(app._store.getState().count).toEqual(0) - expect(logs.length).toEqual(0) - app._store.dispatch({ type: 'count/putWithNamespace', payload: 2 }) - expect(logs.length).toEqual(1) - expect(logs[0]).toEqual( - 'Warning: [sagaEffects.put] count/add should not be prefixed with namespace count' - ) - app._store.dispatch({ type: 'count/putWithoutNamespace', payload: 2 }) - expect(logs.length).toEqual(1) - expect(app._store.getState().count).toEqual(4) - }) - - it('test disable namespacePrefixWarning', () => { - const app = testAppCreator({ namespacePrefixWarning: false }) - const logs = [] app.router(() => ({})) app.start() + app._store.dispatch(addDelay(2)) expect(app._store.getState().count).toEqual(0) - expect(logs.length).toEqual(0) - app._store.dispatch({ type: 'count/putWithNamespace', payload: 2 }) - expect(logs.length).toEqual(0) - app._store.dispatch({ type: 'count/putWithoutNamespace', payload: 2 }) - expect(logs.length).toEqual(0) - expect(app._store.getState().count).toEqual(4) - }) - - it('put multi effects in order', done => { - const app = create() - app.model({ - namespace: 'counter', - state: { - count: 0, - resolveCount: 0 - }, - reducers: { - dump (state, { payload }) { - return { - ...state, - ...payload - } - } - }, - effects: { - * changeCountDelay ({ payload }, { put, call }) { - yield call(delay, 200) - yield put({ type: 'dump', payload: { count: payload } }) - }, - * process ({ payload }, { put, select }) { - yield put({ type: 'changeCountDelay', payload }) - const count = yield select(state => state.counter.count) - yield put({ type: 'dump', payload: { resolveCount: count } }) - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'counter/process', payload: 1 }).then(() => { - expect(app._store.getState().counter.resolveCount).toEqual(1) - done() - }) - expect(app._store.getState().counter.resolveCount).toEqual(0) - }) - - it('take', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - * addDelay ({ payload }, { put, call }) { - yield call(delay, payload.delay || 100) - yield put({ type: 'add', payload: payload.amount }) - }, - * test (_, { put, select, take }) { - yield put({ type: 'addDelay', payload: { amount: 2 } }) - yield take('addDelay/@@end') - const count = yield select(state => state.count) - yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } }) - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'count/test' }) setTimeout(() => { - expect(app._store.getState().count).toEqual(4) + expect(app._store.getState().count).toEqual(2) done() - }, 300) - }) - - it('take with array of actions', () => { - const app = create() - let takenCount = 0 - app.model({ - namespace: 'count', - state: null, - reducers: { - addRequest () { - return 1 - }, - addFailure () { - return -1 - }, - addSuccess () { - return 0 - } - }, - effects: { - * add (action, { put }) { - yield put({ type: 'addRequest' }) - if (action.amount > 0.5) { - yield put({ type: 'addSuccess' }) - } else { - yield put({ type: 'addFailure' }) - } - }, - * test (action, { put, take }) { - yield put({ type: 'add', amount: action.amount }) - yield take(['addSuccess', 'addFailure']) - takenCount += 1 - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'count/test', amount: 0 }) - expect(app._store.getState().count).toEqual(-1) - app._store.dispatch({ type: 'count/test', amount: 1 }) - expect(app._store.getState().count).toEqual(0) - expect(takenCount).toEqual(2) - }) - - it('dispatch action for other models', () => { - const app = create() - app.model({ - namespace: 'loading', - state: false, - reducers: { - show () { - return true - } - } - }) - app.model({ - namespace: 'count', - state: 0, - effects: { - * addDelay (_, { put }) { - yield put({ type: 'loading/show' }) - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'count/addDelay' }) - expect(app._store.getState().loading).toEqual(true) - }) - - it('onError', () => { - const errors = [] - const app = create({ - onError: (error: any, dispatch) => { - error.preventDefault() - errors.push(error.message as never) - dispatch({ type: 'count/add' }) - } - }) - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - * addDelay ({ payload }, { put }) { - if (!payload) { - throw new Error('effect error') - } else { - yield put({ type: 'add', payload }) - } - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ type: 'count/addDelay' }) - expect(errors).toEqual(['effect error']) - expect(app._store.getState().count).toEqual(1) - app._store.dispatch({ type: 'count/addDelay', payload: 2 }) - expect(app._store.getState().count).toEqual(3) - }) - - it('onError: extension', () => { - const app = create({ - // @ts-ignore - onError (err: any, dispatch: any, extension:any) { - err.preventDefault() - dispatch({ - type: 'err/append', - payload: extension - }) - } - }) - app.model({ - namespace: 'err', - state: [], - reducers: { - append (state, action) { - return [...state, action.payload] - } - }, - effects: { - // eslint-disable-next-line - *generate() { - throw new Error('Effect error') - } - } - }) - app.router(() => ({})) - app.start() - app._store.dispatch({ - type: 'err/generate', - payload: 'err.payload' - }) - expect(app._store.getState().err.length).toEqual(1) - expect(app._store.getState().err[0].key).toEqual('err/generate') - expect(app._store.getState().err[0].effectArgs[0].type).toEqual('err/generate') - expect(app._store.getState().err[0].effectArgs[0].payload).toEqual('err.payload') + }, 200) }) it('type: takeLatest', done => { const app = create() - const takeLatest = { type: 'takeLatest' } - app.model({ + + const { model, action: { addDelay } } = createDvaSlice({ namespace: 'count', state: 0, reducers: { - add (state, { payload }) { - return state + payload || 1 + add (state, { payload }: PayloadAction) { + return state + (payload || 1) } }, effects: { addDelay: [ - function * ({ payload }, { call, put }) { + function * ({ payload }: PayloadAction, { call, put }) { yield call(delay, 100) yield put({ type: 'add', payload }) }, - // @ts-ignore - takeLatest + { type: 'takeLatest' } ] } }) + app.model(model) app.router(() => ({})) app.start() // Only catch the last one. - app._store.dispatch({ type: 'count/addDelay', payload: 2 }) - app._store.dispatch({ type: 'count/addDelay', payload: 3 }) + app._store.dispatch(addDelay(2)) + app._store.dispatch(addDelay(3)) setTimeout(() => { expect(app._store.getState().count).toEqual(3) done() }, 200) }) - - xit('type: throttle throw error if no ms', () => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - effects: { - addDelay: [ - function * () { - yield console.log(1) - }, - { type: 'throttle' } - ] - } - }) - expect(() => { - app.router(() => ({})) - app.start() - }).toThrow(/app.start: opts.ms should be defined if type is throttle/) - }) - - it('type: throttle', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - addDelay: [ - function * ({ payload }, { call, put }) { - yield call(delay, 120) - yield put({ type: 'add', payload }) - }, - // @ts-ignore - { type: 'throttle', ms: 100 } - ] - } - }) - app.router(() => ({})) - app.start() - - // Only catch the last one. - app._store.dispatch({ type: 'count/addDelay', payload: 2 }) - app._store.dispatch({ type: 'count/addDelay', payload: 3 }) - - setTimeout(() => { - expect(app._store.getState().count).toEqual(2) - done() - }, 200) - }) - - it('type: watcher', done => { - const watcher = { type: 'watcher' } - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - addWatcher: [ - function * ({ take, put, call }) { - while (true) { - const { payload } = yield take('addWatcher') - yield call(delay, 100) - yield put({ type: 'add', payload }) - } - }, - // @ts-ignore - watcher - ] - } - }) - app.router(() => ({})) - app.start() - - // Only catch the first one. - app._store.dispatch({ type: 'count/addWatcher', payload: 2 }) - app._store.dispatch({ type: 'count/addWatcher', payload: 3 }) - - setTimeout(() => { - expect(app._store.getState().count).toEqual(2) - done() - }, 200) - }) - - it('type: poll', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * (_, { put }) { - yield put({ type: 'add', payload: 1 }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start' }) - - setTimeout(() => { - app._store.dispatch({ type: 'count/pollAdd-stop' }) - expect(app._store.getState().count).toEqual(2) - done() - }, 2000) - }) - - it('type: poll and stop', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * (_, { put }) { - yield put({ type: 'add', payload: 1 }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start' }) - // should work one time - app._store.dispatch({ type: 'count/pollAdd-stop' }) - - setTimeout(() => { - expect(app._store.getState().count).toEqual(1) - done() - }, 200) - }) - - it('type: poll with payload', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * ({ payload }, { put }) { - yield put({ type: 'add', payload }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start', payload: 2 }) - - setTimeout(() => { - app._store.dispatch({ type: 'count/pollAdd-stop' }) - expect(app._store.getState().count).toEqual(4) - done() - }, 2000) - }) - - it('type: poll, start many time', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * ({ payload }, { put }) { - yield put({ type: 'add', payload }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start', payload: 2 }) - - setTimeout(() => { - // second start should not work - app._store.dispatch({ type: 'count/pollAdd-start', payload: 3 }) - app._store.dispatch({ type: 'count/pollAdd-stop' }) - expect(app._store.getState().count).toEqual(6) - done() - }, 3000) - }) - - it('type: poll, start many time 2', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * (_, { put }) { - yield put({ type: 'add', payload: 1 }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start' }) - // second start should not work - app._store.dispatch({ type: 'count/pollAdd-start' }) - - setTimeout(() => { - app._store.dispatch({ type: 'count/pollAdd-stop' }) - expect(app._store.getState().count).toEqual(3) - done() - }, 3000) - }) - - it('type: poll, start and stop many time', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - pollAdd: [ - function * (_, { put }) { - yield put({ type: 'add', payload: 1 }) - }, - // @ts-ignore - { type: 'poll', delay: 1000 } - ] - } - }) - app.router(() => ({})) - app.start() - - app._store.dispatch({ type: 'count/pollAdd-start' }) - app._store.dispatch({ type: 'count/pollAdd-stop' }) - app._store.dispatch({ type: 'count/pollAdd-start' }) - - setTimeout(() => { - app._store.dispatch({ type: 'count/pollAdd-stop' }) - expect(app._store.getState().count).toEqual(3) - done() - }, 2000) - }) - - xit('nonvalid type', () => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - effects: { - addDelay: [ - function * () { - yield console.log(1) - }, - // @ts-ignore - { type: 'nonvalid' } - ] - } - }) - - expect(() => { - app.router(() => ({})) - app.start() - }).toThrow(/app.start: effect type should be takeEvery, takeLatest, throttle or watcher/) - }) - - it('onEffect', done => { - const SHOW = '@@LOADING/SHOW' - const HIDE = '@@LOADING/HIDE' - - const app = create() - - // Test model should be accessible - let modelNamespace = null - // Test onEffect should be run orderly - let count = 0 - let expectedKey = null - - app.use({ - extraReducers: { - loading (state = false, action) { - switch (action.type) { - case SHOW: - return true - case HIDE: - return false - default: - return state - } - } - }, - // @ts-ignore - onEffect (effect, { put }, model, key) { - expectedKey = key - modelNamespace = model.namespace - return function * (...args) { - count *= 2 - yield put({ type: SHOW }) - yield effect(...args) - yield put({ type: HIDE }) - } - } - }) - - app.use({ - // @ts-ignore - onEffect (effect) { - return function * (...args) { - count += 2 - yield effect(...args) - count += 1 - } - } - }) - - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state) { - return state + 1 - } - }, - effects: { - * addRemote (_, { put }) { - yield delay(100) - yield put({ type: 'add' }) - } - } - }) - - app.router(() => ({})) - app.start() - - expect(app._store.getState().loading).toEqual(false) - - app._store.dispatch({ type: 'count/addRemote' }) - expect(app._store.getState().loading).toEqual(true) - expect(modelNamespace).toEqual('count') - expect(expectedKey).toEqual('count/addRemote') - - setTimeout(() => { - expect(app._store.getState().loading).toEqual(false) - expect(app._store.getState().count).toEqual(1) - expect(count).toEqual(5) - done() - }, 200) - }) - - it('return Promise', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - * addDelay ({ payload }, { put, call, select }) { - yield call(delay, payload.delay || 100) - yield put({ type: 'add', payload: payload.amount }) - return yield select(state => state.count) - } - } - }) - app.router(() => ({})) - app.start() - const p1 = app._store.dispatch({ - type: 'count/addDelay', - payload: { amount: 2 } - }) - const p2 = app._store.dispatch({ - type: 'count/add', - payload: 2 - }) - expect(p1 instanceof Promise).toEqual(true) - expect(p2).toEqual({ type: 'count/add', payload: 2 }) - expect(app._store.getState().count).toEqual(2) - p1.then(count => { - expect(count).toEqual(4) - expect(app._store.getState().count).toEqual(4) - done() - }) - }) - - it('return Promises when trigger the same effect multiple times', done => { - const app = create() - app.model({ - namespace: 'count', - state: 0, - reducers: { - add (state, { payload }) { - return state + payload || 1 - } - }, - effects: { - * addDelay ({ payload }, { put, call, select }) { - yield call(delay, payload.delay || 100) - yield put({ type: 'add', payload: payload.amount }) - return yield select(state => state.count) - } - } - }) - app.router(() => ({})) - app.start() - - const p1 = app._store.dispatch({ - type: 'count/addDelay', - payload: { delay: 100, amount: 1 } - }) - const p2 = app._store.dispatch({ - type: 'count/add', - payload: 2 - }) - const p3 = app._store.dispatch({ - type: 'count/addDelay', - payload: { delay: 200, amount: 3 } - }) - expect(p1 instanceof Promise).toEqual(true) - expect(p2).toEqual({ type: 'count/add', payload: 2 }) - expect(app._store.getState().count).toEqual(2) - p1.then(count => { - expect(count).toEqual(3) - expect(app._store.getState().count).toEqual(3) - p3.then(count => { - expect(count).toEqual(6) - expect(app._store.getState().count).toEqual(6) - done() - }) - }) - }) }) diff --git a/test/reducers.test.ts b/test/reducers.test.ts index e4030f2..fb7b27c 100644 --- a/test/reducers.test.ts +++ b/test/reducers.test.ts @@ -9,6 +9,24 @@ declare module 'dva' { } describe('reducers', () => { + it('basic', () => { + const app = create() + const { model, action: { add } } = createDvaSlice({ + namespace: 'hello', + state: 0, + reducers: { + add (state, { payload }: PayloadAction) { + return state + (payload || 1) + } + } + }) + app.model(model) + app.router(() => ({})) + app.start() + app._store.dispatch(add(2)) + expect(app._store.getState().hello).toEqual(2) + }) + it('enhancer', () => { const app = create() @@ -42,131 +60,4 @@ describe('reducers', () => { app._store.dispatch(add()) expect(app._store.getState().count).toEqual(10) }) - - it('extraReducers', () => { - const reducers = { - count: (state: any, { type }: any) => { - if (type === 'add') { - return state + 1 - } - // default state - return 0 - } - } - const app = create({ - extraReducers: reducers - }) - - app.router(() => ({})) - app.start() - - expect(app._store.getState().count).toEqual(0) - app._store.dispatch({ type: 'add' }) - expect(app._store.getState().count).toEqual(1) - }) - - // core 没有 routing 这个 reducer,所以用例无效了 - xit('extraReducers: throw error if conflicts', () => { - const app = create({ - extraReducers: { routing () {} } - }) - expect(() => { - app.start() - }).toThrow(/\[app\.start\] extraReducers is conflict with other reducers/) - }) - - it('onReducer with saveAndLoad', () => { - let savedState: any = null - const saveAndLoad = (r: any) => (state: any, action: any) => { - const newState = r(state, action) - if (action.type === 'save') { - savedState = newState - } - if (action.type === 'load') { - return savedState - } - return newState - } - const app = create({ - onReducer: saveAndLoad - }) - - const { model, action: { add } } = createDvaSlice({ - namespace: 'count', - state: 0, - reducers: { - add (state) { - return state + 1 - } - } - }) - app.model(model) - app.router(() => ({})) - app.start() - - app._store.dispatch(add()) - expect(app._store.getState().count).toEqual(1) - app._store.dispatch({ type: 'save' }) - expect(app._store.getState().count).toEqual(1) - app._store.dispatch(add()) - app._store.dispatch({ type: 'count/add' }) - expect(app._store.getState().count).toEqual(3) - app._store.dispatch({ type: 'load' }) - expect(app._store.getState().count).toEqual(1) - }) - - it('onReducer', () => { - const undo = (r: any) => (state: any, action: any) => { - const newState = r(state, action) - return { present: newState, routing: newState.routing } - } - const app = create({ - onReducer: undo - }) - app.model({ - namespace: 'count', - state: 0, - reducers: { - update (state) { - return state + 1 - } - } - }) - - app.router(() => ({})) - app.start() - - expect(app._store.getState().present.count).toEqual(0) - }) - - it('effects put reducers when reducers is array', () => { - const app = create() - const { model, action: { putSetState } } = createDvaSlice({ - namespace: 'count', - state: 0, - effects: { - * putSetState (_: PayloadAction, { put }) { - yield put({ type: 'setState' }) - } - }, - reducers: [ - { - setState (state) { - return state + 1 - } - }, - (r) => (state, action) => { - const newState = r(state, action) - return newState - } - ] - }) - app.model(model) - app.router(() => ({})) - app.start() - const putSetStateAction = putSetState() - - app._store.dispatch(putSetStateAction) - expect(app._store.getState().count).toEqual(1) - }) }) diff --git a/tsconfig.json b/tsconfig.json index c94fab8..2c85b2d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,6 +31,5 @@ "forceConsistentCasingInFileNames": true, // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` "noEmit": true, - "noImplicitAny": false } }