-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
add disableLifecycleMethods for shallow #789
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should still have some code to ensure that users aren't passing flags both to enable and disable the methods, and throws in that case.
Added some validation. |
src/ShallowWrapper.js
Outdated
function validateOptions(options) { | ||
if ( | ||
options.lifecycleExperimental != null && | ||
options.lifecycleExperimental === options.disableLifecycleMethods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this comparison should probably just ‼
both options, and throw if they're the same, as long as both of them aren't == null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, done
test/ShallowWrapper-spec.jsx
Outdated
expect(() => shallow(<div />, { | ||
lifecycleExperimental: false, | ||
disableLifecycleMethods: false, | ||
})).to.throw(/same value/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's also add tests where both are omitted, and where either aren't a boolean (ie, it should throw if a non-boolean non-undefined value is provided)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
['componentWillReceiveProps'], | ||
['shouldComponentUpdate'], | ||
['componentWillUpdate'], | ||
['render'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure whether componentDidUpdate
is supposed to be called here, but it's not currently. If this behavior is correct it's going to make this flag + documentation pretty confusing since, per next test down, setState does trigger componentDidUpdate
for shallow rendered components (even without enzyme in the picture).
The flag is looking more like it should be disableDidMountAllTheTimeAndDidUpdateSomeOfTheTime. 😅
cc @koba04 any thoughts on correctness here? Note this is all without lifecycleExperimental set to true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jwbay
Currently, lifecycleExperimental
does complement lifecycle methods that ShallowRenderer is missing, which are componentDidMount
and componentDidUpdate
in setProps
and setContext
#318 (comment).
In setState
, componentDidUpdate
is always called because ShallowWrapper calls instance.setState()
directly. 😅
To be clear, if disableLifecycleMethods
set to true, componentDidMount
and componentDidUpdate
(in setProps
and setContext
) are not called on the component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is looking great, but let's get more reviewers to take a look before merging.
src/ShallowWrapper.js
Outdated
const { lifecycleExperimental, disableLifecycleMethods } = options; | ||
if ( | ||
typeof lifecycleExperimental !== 'undefined' && | ||
lifecycleExperimental !== !!lifecycleExperimental |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof lifecycleExperimental !== 'boolean'
is more explicitly?
}); | ||
}); | ||
|
||
describeIf(REACT014, 'setContext', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad we're testing this on all React versions - could you elaborate on why componentWillReceiveProps
fires in 13 and 15, but not 14?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In React 13 and 14, the check for whether willReceiveProps is called is just a strict equality check in ReactCompositeComponent between the previous and next elements. In React 15, they added an additional equality check between previous and next context.
willReceiveProps is called in 13 because Enzyme clones the element on each render in react-compat's createRendererCompatible, failing the equality check.
It's not called in 14 because the elements are equal. createRendererCompatible is only used for React 13.
It's called in 15 because of the new check for context.
2fd4aee
to
027d5a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see the advantage of adding a no-op flag in a minor release, @ljharb can you clarify why we'd want that? It feels like it will just be ignored anyway if it's a no-op.
But otherwise this implementation LGTM if we want this.
@aweary because then people who depend on the |
It just sounds unlikely that anyone is going enable a no-op flag from a minor release when their tests are all working as they would expect. What's more likely is that they upgrade to the next major release, have breakage, and then enable the flag. But either way, it's not like this change will hurt anyone so 👍 |
I envision "upgrade, breakage, downgrade, gradually migrate their tests to use an explicit flag, upgrade smoothly later" :-) |
Sooo. Sounds like this is good to merge then? @jwbay mind rebasing? |
027d5a2
to
4f34542
Compare
@blainekasten rebased |
4f34542
to
765ec95
Compare
cc @ljharb do you want these all rebased down to 1 commit or is this fine? |
This is fine, as long as there's no merge commits :-) |
Thanks for the work on this @jwbay ! This is big! |
As part of the plan to switch on all lifecycle methods for
shallow
in the next major, introduce a no-op flag ahead of time that turns that off.Ref: #678 (comment)
Since there's no options validation, I'm not sure any code changes are necessary.(added) It may be confusing if someone sets this flag to explicitly false and expects their lifecycle methods to be called. Should we set lifecycleExperimental to true in that case?I didn't prefix the option with
deprecated
because it seemed this flag is going to be sticking around as the official, inverted version of lifecycleExperimental. I may have misunderstood something though.The name feels a bit off since it's not disabling all the lifecycle methods, just two of them. Should it be something like
disableFullLifecycle
?