Skip to content

Commit 86f7eea

Browse files
authored
Add check for undefined middleware in configureStore (#959)
1 parent cb0535d commit 86f7eea

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

src/configureStore.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,53 @@ describe('configureStore', () => {
6868
})
6969
})
7070

71+
describe('given undefined middleware', () => {
72+
it('calls createStore with default middleware', () => {
73+
expect(configureStore({ middleware: undefined, reducer })).toBeInstanceOf(
74+
Object
75+
)
76+
expect(redux.applyMiddleware).toHaveBeenCalledWith(
77+
expect.any(Function), // thunk
78+
expect.any(Function), // immutableCheck
79+
expect.any(Function) // serializableCheck
80+
)
81+
expect(devtools.composeWithDevTools).toHaveBeenCalled()
82+
expect(redux.createStore).toHaveBeenCalledWith(
83+
reducer,
84+
undefined,
85+
expect.any(Function)
86+
)
87+
})
88+
})
89+
90+
describe('given a middleware creation function that returns undefined', () => {
91+
it('throws an error', () => {
92+
const invalidBuilder = jest.fn(getDefaultMiddleware => undefined as any)
93+
expect(() =>
94+
configureStore({ middleware: invalidBuilder, reducer })
95+
).toThrow(
96+
'when using a middleware builder function, an array of middleware must be returned'
97+
)
98+
})
99+
})
100+
101+
describe('given a middleware creation function that returns an array with non-functions', () => {
102+
it('throws an error', () => {
103+
const invalidBuilder = jest.fn(getDefaultMiddleware => [true] as any)
104+
expect(() =>
105+
configureStore({ middleware: invalidBuilder, reducer })
106+
).toThrow('each middleware provided to configureStore must be a function')
107+
})
108+
})
109+
110+
describe('given custom middleware that contains non-functions', () => {
111+
it('throws an error', () => {
112+
expect(() =>
113+
configureStore({ middleware: [true] as any, reducer })
114+
).toThrow('each middleware provided to configureStore must be a function')
115+
})
116+
})
117+
71118
describe('given custom middleware', () => {
72119
it('calls createStore with custom middleware and without default middleware', () => {
73120
const thank: redux.Middleware = (_store) => (next) => (action) =>

src/configureStore.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,26 @@ export function configureStore<
153153
)
154154
}
155155

156-
const middlewareEnhancer = applyMiddleware(
157-
...(typeof middleware === 'function'
158-
? middleware(curriedGetDefaultMiddleware)
159-
: middleware)
160-
)
156+
let finalMiddleware = middleware
157+
if (typeof finalMiddleware === 'function') {
158+
finalMiddleware = finalMiddleware(curriedGetDefaultMiddleware)
159+
160+
if (!IS_PRODUCTION && !Array.isArray(finalMiddleware)) {
161+
throw new Error(
162+
'when using a middleware builder function, an array of middleware must be returned'
163+
)
164+
}
165+
}
166+
if (
167+
!IS_PRODUCTION &&
168+
finalMiddleware.some(item => typeof item !== 'function')
169+
) {
170+
throw new Error(
171+
'each middleware provided to configureStore must be a function'
172+
)
173+
}
174+
175+
const middlewareEnhancer = applyMiddleware(...finalMiddleware)
161176

162177
let finalCompose = compose
163178

0 commit comments

Comments
 (0)