From a415d0375afa4c3726174d8f87db340ca20a428c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fenfels?= <10491533+tim-we@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:38:19 +0100 Subject: [PATCH] feat(expect): add Set support to toBeOneOf (#8906) Co-authored-by: Vladimir --- docs/api/expect.md | 8 ++++++-- packages/expect/src/custom-matchers.ts | 22 ++++++++++++++-------- packages/expect/src/types.ts | 4 ++-- test/core/test/jest-expect.test.ts | 6 ++++++ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/docs/api/expect.md b/docs/api/expect.md index f7237002a..c5a0a290d 100644 --- a/docs/api/expect.md +++ b/docs/api/expect.md @@ -379,9 +379,13 @@ test('getApplesCount has some unusual side effects...', () => { ## toBeOneOf -- **Type:** `(sample: Array) => any` +- **Type:** `(sample: Array | Set) => any` -`toBeOneOf` asserts if a value matches any of the values in the provided array. +`toBeOneOf` asserts if a value matches any of the values in the provided array or set. + +::: warning EXPERIMENTAL +Providing a `Set` is an experimental feature and may change in a future release. +::: ```ts import { expect, test } from 'vitest' diff --git a/packages/expect/src/custom-matchers.ts b/packages/expect/src/custom-matchers.ts index 18ede7c46..5eaf5366e 100644 --- a/packages/expect/src/custom-matchers.ts +++ b/packages/expect/src/custom-matchers.ts @@ -27,21 +27,27 @@ ${printReceived(actual)}`, } }, - toBeOneOf(actual: unknown, expected: Array) { + toBeOneOf(actual: unknown, expected: Array | Set) { const { equals, customTesters } = this const { printReceived, printExpected, matcherHint } = this.utils - if (!Array.isArray(expected)) { + let pass: boolean + + if (Array.isArray(expected)) { + pass = expected.length === 0 + || expected.some(item => + equals(item, actual, customTesters), + ) + } + else if (expected instanceof Set) { + pass = expected.size === 0 || expected.has(actual) || [...expected].some(item => equals(item, actual, customTesters)) + } + else { throw new TypeError( - `You must provide an array to ${matcherHint('.toBeOneOf')}, not '${typeof expected}'.`, + `You must provide an array or set to ${matcherHint('.toBeOneOf')}, not '${typeof expected}'.`, ) } - const pass = expected.length === 0 - || expected.some(item => - equals(item, actual, customTesters), - ) - return { pass, message: () => diff --git a/packages/expect/src/types.ts b/packages/expect/src/types.ts index ef004ed76..ae0954015 100644 --- a/packages/expect/src/types.ts +++ b/packages/expect/src/types.ts @@ -129,14 +129,14 @@ interface CustomMatcher { toSatisfy: (matcher: (value: any) => boolean, message?: string) => any /** - * Matches if the received value is one of the values in the expected array. + * Matches if the received value is one of the values in the expected array or set. * * @example * expect(1).toBeOneOf([1, 2, 3]) * expect('foo').toBeOneOf([expect.any(String)]) * expect({ a: 1 }).toEqual({ a: expect.toBeOneOf(['1', '2', '3']) }) */ - toBeOneOf: (sample: Array) => any + toBeOneOf: (sample: Array | Set) => any } export interface AsymmetricMatchersContaining extends CustomMatcher { diff --git a/test/core/test/jest-expect.test.ts b/test/core/test/jest-expect.test.ts index dba00dd27..8e3a2c9d9 100644 --- a/test/core/test/jest-expect.test.ts +++ b/test/core/test/jest-expect.test.ts @@ -636,7 +636,9 @@ describe('toBeOneOf()', () => { expect(0).toBeOneOf([0, 1, 2]) expect(0).toBeOneOf([expect.any(Number)]) expect('apple').toBeOneOf(['apple', 'banana', 'orange']) + expect('apple').toBeOneOf(new Set(['apple', 'banana', 'orange'])) expect('apple').toBeOneOf([expect.any(String)]) + expect('apple').toBeOneOf(new Set([expect.any(String)])) expect(true).toBeOneOf([true, false]) expect(true).toBeOneOf([expect.any(Boolean)]) expect(null).toBeOneOf([expect.any(Object)]) @@ -647,7 +649,9 @@ describe('toBeOneOf()', () => { expect(3).not.toBeOneOf([0, 1, 2]) expect(3).not.toBeOneOf([expect.any(String)]) expect('mango').not.toBeOneOf(['apple', 'banana', 'orange']) + expect('mango').not.toBeOneOf(new Set(['apple', 'banana', 'orange'])) expect('mango').not.toBeOneOf([expect.any(Number)]) + expect('mango').not.toBeOneOf(new Set([expect.any(Number)])) expect(null).not.toBeOneOf([undefined]) }) @@ -655,7 +659,9 @@ describe('toBeOneOf()', () => { expect(3).toBeOneOf([0, 1, 2]) expect(3).toBeOneOf([expect.any(String)]) expect('mango').toBeOneOf(['apple', 'banana', 'orange']) + expect('mango').toBeOneOf(new Set(['apple', 'banana', 'orange'])) expect('mango').toBeOneOf([expect.any(Number)]) + expect('mango').toBeOneOf(new Set([expect.any(Number)])) expect(null).toBeOneOf([undefined]) }) -- 2.51.2