Content-Length: 414795 | pFad | https://redirect.github.com/vitest-dev/vitest/commit/0ad2860b

7E feat: add `describe.for` (#7253) · vitest-dev/vitest@0ad2860 · GitHub
Skip to content

Commit

Permalink
feat: add describe.for (#7253)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Jan 15, 2025
1 parent d4ea0b5 commit 0ad2860
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
36 changes: 36 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,11 @@ describe.todo('unimplemented suite')

- **Alias:** `suite.each`

::: tip
While `describe.each` is provided for Jest compatibility,
Vitest also has [`describe.for`](#describe-for) which simplifies argument types and aligns with [`test.for`](#test-for).
:::

Use `describe.each` if you have more than one test that depends on the same data.

```ts
Expand Down Expand Up @@ -998,6 +1003,37 @@ describe.each`
You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
:::

### describe.for

- **Alias:** `suite.for`

The difference from `describe.each` is how array case is provided in the arguments.
Other non array case (including template string usage) works exactly same.

```ts
// `each` spreads array case
describe.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --]
test('test', () => {
expect(a + b).toBe(expected)
})
})

// `for` doesn't spread array case
describe.for([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++]
test('test', () => {
expect(a + b).toBe(expected)
})
})
```

## Setup and Teardown

These functions allow you to hook into the life cycle of tests to avoid repeating setup and teardown code. They apply to the current context: the file if they are used at the top-level or the current suite if they are inside a `describe` block. These hooks are not called, when you are running Vitest as a type checker.
Expand Down
25 changes: 25 additions & 0 deletions packages/runner/src/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,31 @@ function createSuite() {
}
}

suiteFn.for = function <T>(
this: {
withContext: () => SuiteAPI
setContext: (key: string, value: boolean | undefined) => SuiteAPI
},
cases: ReadonlyArray<T>,
...args: any[]
) {
if (Array.isArray(cases) && args.length) {
cases = formatTemplateString(cases, args)
}

return (
name: string | Function,
optionsOrFn: ((...args: T[]) => void) | TestOptions,
fnOrOptions?: ((...args: T[]) => void) | number | TestOptions,
) => {
const name_ = formatName(name)
const { options, handler } = parseArguments(optionsOrFn, fnOrOptions)
cases.forEach((item, idx) => {
suite(formatTitle(name_, toArray(item), idx), options, () => handler(item))
})
}
}

suiteFn.skipIf = (condition: any) =>
(condition ? suite.skip : suite) as SuiteAPI
suiteFn.runIf = (condition: any) =>
Expand Down
6 changes: 6 additions & 0 deletions packages/runner/src/types/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ interface TestForFunction<ExtraContext> {
>
}

interface SuiteForFunction {
<T>(cases: ReadonlyArray<T>): EachFunctionReturn<[T]>
(...args: [TemplateStringsArray, ...any]): EachFunctionReturn<any[]>
}

interface TestCollectorCallable<C = object> {
/**
* @deprecated Use options as the second argument instead
Expand Down Expand Up @@ -525,6 +530,7 @@ type ChainableSuiteAPI<ExtraContext = object> = ChainableFunction<
SuiteCollectorCallable<ExtraContext>,
{
each: TestEachFunction
for: SuiteForFunction
}
>

Expand Down
45 changes: 45 additions & 0 deletions test/core/test/__snapshots__/test-for-suite.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`add(1, 1) > test 1`] = `2`;

exports[`add(1, 2) > test 1`] = `3`;

exports[`add(2, 1) > test 1`] = `3`;

exports[`basic case1 > test 1`] = `
{
"args": [
"case1",
],
}
`;

exports[`basic case2 > test 1`] = `
{
"args": [
"case2",
],
}
`;

exports[`template 'x' true > test 1`] = `
{
"args": [
{
"a": "x",
"b": true,
},
],
}
`;

exports[`template 'y' false > test 1`] = `
{
"args": [
{
"a": "y",
"b": false,
},
],
}
`;
35 changes: 35 additions & 0 deletions test/core/test/test-for-suite.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, expect, expectTypeOf, test } from 'vitest'

describe.for(['case1', 'case2'])(
'basic %s',
(...args) => {
test('test', () => {
expectTypeOf(args).toEqualTypeOf<[string]>()
expect({ args }).matchSnapshot()
})
},
)

describe.for`
a | b
${'x'} | ${true}
${'y'} | ${false}
`(
'template $a $b',
(...args) => {
test('test', () => {
expectTypeOf(args).toEqualTypeOf<any[]>()
expect({ args }).toMatchSnapshot()
})
},
)

describe.for([
[1, 1],
[1, 2],
[2, 1],
])('add(%i, %i)', ([a, b]) => {
test('test', () => {
expect(a + b).matchSnapshot()
})
})

0 comments on commit 0ad2860

Please sign in to comment.








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://redirect.github.com/vitest-dev/vitest/commit/0ad2860b

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy