From 45c5c45ab0b36a0077e318bff1b638829158538f Mon Sep 17 00:00:00 2001 From: yoho Date: Sat, 3 Dec 2022 17:32:58 +0800 Subject: [PATCH] feat: format test tablename (#2405) * feat: custom format test.each named * docs: format title * chore: update * chore: update * chore: update * chore: upadte * docs: update * chore: revert * chore: update * feat: object attr getter * docs: object getter --- docs/api/index.md | 18 ++++++++++++++++++ packages/vitest/src/runtime/suite.ts | 8 ++++---- packages/vitest/src/utils/index.ts | 12 ++++++++++++ test/core/test/each.test.ts | 9 +++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/docs/api/index.md b/docs/api/index.md index d9683428c1d4..706bfd8d0fdf 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -244,6 +244,24 @@ You cannot use this syntax, when using Vitest as [type checker](/guide/testing-t // ✓ add(2, 1) -> 3 ``` + You can also access Object attributes with `.`, if you are using objects as arguments: + + ```ts + test.each` + a | b | expected + ${{ val: 1 }} | ${'b'} | ${'1b'} + ${{ val: 2 }} | ${'b'} | ${'2b'} + ${{ val: 3 }} | ${'b'} | ${'3b'} + `('add($a.val, $b) -> $expected', ({ a, b, expected }) => { + expect(a.val + b).toBe(expected) + }) + + // this will return + // ✓ add(1, b) -> 1b + // ✓ add(2, b) -> 2b + // ✓ add(3, b) -> 3b + ``` + Starting from Vitest 0.25.3, you can also use template string table. diff --git a/packages/vitest/src/runtime/suite.ts b/packages/vitest/src/runtime/suite.ts index db07a6902559..1f217fbdc3d2 100644 --- a/packages/vitest/src/runtime/suite.ts +++ b/packages/vitest/src/runtime/suite.ts @@ -1,6 +1,6 @@ import util from 'util' import type { BenchFunction, BenchOptions, Benchmark, BenchmarkAPI, File, RunMode, Suite, SuiteAPI, SuiteCollector, SuiteFactory, SuiteHooks, Task, Test, TestAPI, TestFunction, TestOptions } from '../types' -import { getWorkerState, isObject, isRunningInBenchmark, isRunningInTest, noop } from '../utils' +import { getWorkerState, isObject, isRunningInBenchmark, isRunningInTest, noop, objectAttr } from '../utils' import { createChainable } from './chain' import { collectTask, collectorContext, createTestContext, runWithSuite, withTimeout } from './context' import { getHooks, setBenchOptions, setFn, setHooks } from './map' @@ -226,6 +226,7 @@ function createTest(fn: ( const arrayOnlyCases = cases.every(Array.isArray) cases.forEach((i, idx) => { const items = Array.isArray(i) ? i : [i] + arrayOnlyCases ? test(formatTitle(name, items, idx), () => fn(...items), options) : test(formatTitle(name, items, idx), () => fn(i), options) @@ -269,12 +270,11 @@ function formatTitle(template: string, items: any[], idx: number) { .replace(/%#/g, `${idx}`) .replace(/__vitest_escaped_%__/g, '%%') } - const count = template.split('%').length - 1 let formatted = util.format(template, ...items.slice(0, count)) if (isObject(items[0])) { - formatted = formatted.replace(/\$([$\w_]+)/g, (_, key) => { - return items[0][key] + formatted = formatted.replace(/\$([$\w_.]+)/g, (_, key) => { + return objectAttr(items[0], key) }) } return formatted diff --git a/packages/vitest/src/utils/index.ts b/packages/vitest/src/utils/index.ts index 15eb87b1b799..7db9215e170b 100644 --- a/packages/vitest/src/utils/index.ts +++ b/packages/vitest/src/utils/index.ts @@ -180,3 +180,15 @@ export function createDefer(): DeferPromise { p.reject = reject! return p } + +export function objectAttr(source: any, path: string, defaultValue = undefined) { + // a[3].b -> a.3.b + const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.') + let result = source + for (const p of paths) { + result = Object(result)[p] + if (result === undefined) + return defaultValue + } + return result +} diff --git a/test/core/test/each.test.ts b/test/core/test/each.test.ts index a54ba8ac4ded..6f61dbf4bbed 100644 --- a/test/core/test/each.test.ts +++ b/test/core/test/each.test.ts @@ -194,6 +194,15 @@ ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'} expect(a + b).toBe(expected) }) +test.each` +a | b | expected +${{ val: 1 }} | ${'b'} | ${'1b'} +${{ val: 2 }} | ${'b'} | ${'2b'} +${{ val: 3 }} | ${'b'} | ${'3b'} +`('returns $expected when $a.val is added $b', ({ a, b, expected }) => { + expect(a.val + b).toBe(expected) +}) + test.each` a | b | expected ${true} | ${true} | ${true}