-
Notifications
You must be signed in to change notification settings - Fork 664
Description
What problem does this feature solve?
Situation
The component (Component
) has children components (Child
), one and one only of type X
that is conditionally rendered.
I need to test this component in severaI cases and so it's common to retrieve the component like this:
const findX = wrapper.findAll(Child).filter(isX).at(0);
Complication
I know the element is rendered conditionally, so I want to test the case when this element does not exist. But when I try:
expect(findX().exists()).toBe(false);
surprisingly enough, I get the following error no item exists at 0
.
I know the option would be not to add at(0)
to my findX()
method. But that's not what I would expect form a method that applies to an Array, for the following reasons:
A) The signature
at()
is defined as at(index: number): Wrapper<V>;
. Throwing clearly does not mean the signature is wrong but what I argue is that the error is thrown for the wrong reason.
B) The semantics
If I change the case slightly and now I have only one Child
component, I could write findX()
as findComponent(Child)
. Testing the case where it is not rendered I would be able to use exists()
properly. It seems to me there is nothing inherently wrong though in sticking to the wrapper.findAll(Child).filter(isX).at(0)
implementation also when I only have one Child
component. Therefore I would expect the same result, that is a BaseWrapper
to which I could ask if the element exists or not;
C) The similarity with filter()
Not only my findX()
implementation is contingent but also at()
's one. It could easily be implemented as a filter function on the given index
as they're both trying to individuate an element in an array based on some condition:
wrapper.filter((_, index) => index === 0)
In this case, if the predicate fails to verify for every element, I would get an empty array.
Returning an empty array from at()
is not what we want – at()
seems to be somehow similar to Array.prototype.find
which would, in the case explored here, return undefined
.
Solution
Given find()
is already taken and that we do not want to return undefined
, my proposal is to return an ErrorWrapper
on which I could call the exists()
method as easily as when I do it with find()
.
What does the proposed API look like?
The API of at()
would not change, instead its internal implementation would.
It could be something along the lines of:
at(index) {
const normalizedIndex = index < 0 ? this.length
return this.wrappers[normalizedIndex] || new ErrorWrapper('')
}