Describe the bug
.exists() returns true when you return null on a component
To Reproduce
function Something () {
return null
}
test('something exists', () => {
const obj = shallow(<Something />)
// throws an error because `obj.exists()` returns true
expect(obj.exists()).toBeFalsy()
})
Expected behavior
.exists() should return false because there's nothing to be rendered
Additional context
The reason it's failing is because it's testing this.length > 0 which returns true because if you log out the private variable of wrapper[NODES] it returns [ null ].
for now I've just overwritten the default .exists() function in my setup until this is resolved
Enzyme.ShallowWrapper.prototype.exists = function exists (selector = null) {
if (arguments.length > 0 && typeof selector !== 'string') {
throw new TypeError('`selector` argument must be a string, if present.')
}
if (typeof selector === 'string') {
return this.find(selector).exists()
}
return this.getNodesInternal().filter(Boolean).length > 0
}
You want .isEmptyRender() instead; .exists() indeed is doing the correct thing - the wrapper exists, whether it renders null or not.
We can either close this ticket, as "answered" or keep it open to discuss how exists should behave in this circumstance. Or close this issue and create a new issue discussing it.
Notes: As per the documentation and conversation with @ljharb https://airbnb.io/enzyme/docs/api/ShallowWrapper/exists.html, when a selector is not passed in, it should return whether or not the node existsReturns whether or not the current node exists. The discussion should be about the definition of exists and how to proceed with this question/bug.
@ljharb any idea on the direction we should go with this?
Thanks
I think if we can confirm that both exists and isEmptyRender are behaving as expected for both shallow and mount (possibly with added test cases), then we should improve the documentation for both to avoid confusion.
Sounds good! IMO, this ticket has been addressed and your recommendation to use isEmptyRender was the right call. Given that, we can update the documentation and add tests like you suggested to avoid confusion.
Via https://airbnb.io/enzyme/docs/api/ReactWrapper/exists.html
Returns whether or not the current node exists.
I could see how you could expect a rendered component that returns null to use .exists() and expect it to return false. Maybe thats one of the aspects we can expand on?
The docs have been updated.
Most helpful comment
Sounds good! IMO, this ticket has been addressed and your recommendation to use isEmptyRender was the right call. Given that, we can update the documentation and add tests like you suggested to avoid confusion.
Via https://airbnb.io/enzyme/docs/api/ReactWrapper/exists.html
I could see how you could expect a rendered component that returns null to use .exists() and expect it to return false. Maybe thats one of the aspects we can expand on?