Skip to content

Commit

Permalink
feat: add parameter for test name of each (#1031)
Browse files Browse the repository at this point in the history
* feat: add parameter for test name of each api

* fix: each test name escaped case

* fix: add a judgment
  • Loading branch information
ouduidui committed Mar 26, 2022
1 parent 05b3b77 commit 4210c39
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 21 deletions.
43 changes: 27 additions & 16 deletions docs/api/index.md
Expand Up @@ -121,22 +121,33 @@ For compatibility with Jest, `TestFunction` can also be of type `(done: DoneCall
- **Type:** `(cases: ReadonlyArray<T>) => void`
- **Alias:** `it.each`

Use `test.each` when you need to run the same test with different variables.
You can use `%i` or `%s` in the test name in the order of the test function parameters.
```ts
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected)
})

// this will return
// √ add(1, 1) -> 2
// √ add(1, 2) -> 3
// √ add(2, 1) -> 3
```
Use `test.each` when you need to run the same test with different variables.
You can inject parameters with [printf formmatting](https://nodejs.org/api/util.html#util_util_format_format_args) in the test name in the order of the test function parameters.

- `%s`: string
- `%d`: number
- `%i`: integer
- `%f`: floating point value
- `%j`: json
- `$o`: object
- `%#`: index of the test case
- `%%`: single precent sign ('%')

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

// this will return
// √ add(1, 1) -> 2
// √ add(1, 2) -> 3
// √ add(2, 1) -> 3
```

## describe

When you use `test` in the top level of file, they are collected as part of the implicit suite for it. Using `describe` you can define a new suite in the current context, as a set of related tests and other nested suites. A suite lets you organize your tests so reports are more clear.
Expand Down
18 changes: 13 additions & 5 deletions packages/vitest/src/runtime/suite.ts
Expand Up @@ -14,7 +14,15 @@ export const test = createTest(
},
)

function formatTitle(template: string, items: any[]) {
function formatTitle(template: string, items: any[], idx: number) {
if (template.includes('%#')) {
// '%#' match index of the test case
template = template
.replace(/%%/g, '__vitest_escaped_%__')
.replace(/%#/g, `${idx}`)
.replace(/__vitest_escaped_%__/g, '%%')
}

const count = template.split('%').length - 1
let formatted = format(template, ...items.slice(0, count))
if (isObject(items[0])) {
Expand Down Expand Up @@ -146,9 +154,9 @@ function createSuite() {

suite.each = <T>(cases: ReadonlyArray<T>) => {
return (name: string, fn: (...args: T[]) => void) => {
cases.forEach((i) => {
cases.forEach((i, idx) => {
const items = toArray(i) as any
suite(formatTitle(name, items), () => fn(...items))
suite(formatTitle(name, items, idx), () => fn(...items))
})
}
}
Expand All @@ -164,9 +172,9 @@ function createTest(fn: ((this: Record<'concurrent'| 'skip'| 'only'| 'todo'| 'fa

test.each = <T>(cases: ReadonlyArray<T>) => {
return (name: string, fn: (...args: T[]) => void) => {
cases.forEach((i) => {
cases.forEach((i, idx) => {
const items = toArray(i) as any
test(formatTitle(name, items), () => fn(...items))
test(formatTitle(name, items, idx), () => fn(...items))
})
}
}
Expand Down
8 changes: 8 additions & 0 deletions test/core/test/each.test.ts
Expand Up @@ -75,3 +75,11 @@ describe.each([1, 2, 0])('%s (describe.each 1d)', (num) => {
expect(typeof num).toEqual('number')
})
})

test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('the index of the test case is %#', (a, b, expected) => {
expect(a + b).toBe(expected)
})

0 comments on commit 4210c39

Please sign in to comment.