vitest-dev / vitest-dev/vitest
Add `.some`, `.every` property chain to matcher that expects an array
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 17.1k
- Forks
- 2k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 94
Description
Clear and concise description of the problem
Currently, when testing elements returned as an array (e.g., screen.getAllByRole in Testing Library), matchers cannot be used directly on individual elements within the array. Specifically, there is no built-in way to check if at least one element satisfies a matcher without manually iterating and extracting a boolean value.
This creates several issues:
- Manual boolean extraction: Test authors must manually iterate over the array and convert the matcher result into a boolean value.
- Redundant code: This leads to unnecessary repetition, making tests more verbose.
- Custom matchers as a workaround: While it is possible to define custom matchers to handle these cases, they must be redefined for every assertion type, increasing maintenance overhead.
Current workarounds
Using Array.prototype.some and a manual boolean assertion
expect(screen.getAllByRole("alert").some((it) => it.textContent === message)).toBe(true);
This approach is verbose and does not leverage existing matchers.
Defining a custom matcher (for each assertion type)
expect.extend({
toHaveSomeTextContent(received, expected) {
const pass = received.some((el) => el.textContent === expected);
return pass
? { pass: true, message: () => `Expected at least one element to not have text content ${expected}` }
: { pass: false, message: () => `Expected at least one element to have text content ${expected}` };
}
});
expect(screen.getAllByRole("alert")).toHaveSomeTextContent(message);
This solves the problem, but requires defining a separate matcher for each assertion type, which is not practical for general use.
Also, there is the hassle of checking the implementation if you want to reproduce the matcher of the community.
Suggested solution
Introduce .some and .every as built-in property chains, such as Array.prototype, so that assertions can be verified to satisfy some or all of the array.
Proposed syntax
expect(array).some.toHaveTextContent(message);
expect(array).every.toHaveTextContent(message);
Benefits:
Eliminates manual boolean extraction
Avoids the need to define custom matchers for each assertion type
Improves readability by making the test’s intent clear
Enables direct use of community matchers (e.g., testing-library/jest-dom)
For symmetry, .every could also be introduced to allow assertions to be applied to all elements in an array.
.every is not strictly necessary since the combination of for and Array.prototype.every is already a viable alternative. .every is included in the proposal primarily for consistency with .some.
Alternative
No response
Additional context
The implementation should ensure proper TypeScript support so that .some and .every only appear on arrays.
It should be compatible with expect.extend, allowing custom matchers to work seamlessly.
Performance considerations should be taken into account to avoid unnecessary operations when chaining multiple matchers.
By introducing .some (and optionally .every for symmetry), this feature would eliminate boilerplate, improve test readability, and reduce the need for repetitive custom matchers.
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the expect matcher property-chain entry point and the expect.extend integration. Define how .some and .every should apply existing and custom matchers to arrays, with TypeScript exposing them only for arrays; done means the proposed syntax works with built-in and extended matchers without unnecessary operations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100