Skip to content

Warns when type of reducers passed is invalid to avoid silent failure #2636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

jekku
Copy link

@jekku jekku commented Oct 2, 2017

Attempts to solve issue #1398 .

Undefined reducers are still checked for intuitive debugging.
Warnings are now given to the console if a passed reducer is not a function.
Warnings are also given to the console if a whole es module imported via the * syntax is passed to combineReducers.

)

expect(spy.mock.calls[1][0]).toMatch(
/Reducer provided for "broken" is not a function/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation :)

it('warns on props which are not a function and excludes them', () => {
const preSpy = console.error
const spy = jest.fn()
console.error = spy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've overridden console.error, but there's no mechanism here to put it back after the test.

The Jest way to do this is to make a mock of utils/warning to capture any calls to warning().

jest.mock('../src/helpers/warning')

https://facebook.github.io/jest/docs/en/manual-mocks.html has more info :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They can do what we do in other tests. Just add this at the end:

       spy.mockClear()
       console.error = preSpy

Copy link

@rstacruz rstacruz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you go Jekku :)

@rstacruz
Copy link

rstacruz commented Oct 2, 2017

(Maintainers: sorry for the impromptu review; @jekku is a colleague of mine who's asked his coworkers to review his contribution.)

const reducer = combineReducers({
fake: true,
broken: 'string',
another: { nested: 'object' },
stack: (state = []) => state
})

expect(spy.mock.calls[0][0]).toMatch(
Copy link

@rstacruz rstacruz Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another (less-precise, but terser) way to do this is

expect(spy).toHaveBeenCalledWith('Reducer provided for "fake" is not a function')

...which you can use if you're stubbing warning() instead of console.error.

See: https://devhints.io/jest

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! :)

@@ -106,8 +106,11 @@ export default function combineReducers(reducers) {
const key = reducerKeys[i]

if (process.env.NODE_ENV !== 'production') {
if (typeof reducers[key] === 'undefined') {
const reducerUnderInspection = reducers[key]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to extract this out. Just keep using reducers[key]. It's probably not as fast, but this is dev-only code.

@timdorr
Copy link
Member

timdorr commented Oct 2, 2017

Whoops, got a little cocky with those test updates. Serves me right for trying to use the web interface to edit 😄 Feel free to revert that!

@jekku jekku force-pushed the warn-on-invalid-reducer-types branch from 703761f to c169608 Compare October 3, 2017 06:00
@timdorr
Copy link
Member

timdorr commented Oct 3, 2017

One thing to note: We tried this on bindActionCreators and had to revert there as well: #2279

Unfortunately, with most people transpiling modules through Babel, there are side effects when the pattern of import * as reducers from './reducers' is used. Unless we can somehow be rock solid in protecting against this without hacks, I'm not sure this is going to be mergeable.

@jekku
Copy link
Author

jekku commented Oct 3, 2017

@timdorr would throwing out an exception when an import * is invoked to combineReducers, help?

@timdorr
Copy link
Member

timdorr commented Oct 23, 2017

@jekku Sorry for not responding. At least currently, there isn't a rock-solid, cross-platform way of doing that. You can check for __esModule, but that may not come across depending on how folks have their transpilation set up.

Unfortunately, fixing for this kind of issue isn't going to be possible in the current ecosystem. I had to revert a similar warning in a previous release because it caused other sorts of headaches like this.

Unless someone can think up a novel way to resolve it that covers both native and loosely transpiled environments, I'm not sure there's a solution.

@timdorr timdorr closed this Oct 23, 2017
@jekku jekku deleted the warn-on-invalid-reducer-types branch October 23, 2017 01:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants