mirror of
https://github.com/vitest-dev/vitest.git
synced 2026-02-01 17:36:51 +00:00
feat: add resolveSnapshotPath option (#1101)
This commit is contained in:
parent
6f552751df
commit
5cc592be97
@ -431,3 +431,18 @@ Overrides Vite mode.
|
||||
Run tests only against changed files. If no value is provided, it will run tests against uncomitted changes (includes staged and unstaged).
|
||||
|
||||
To run tests against changes made in last commit, you can use `--changed HEAD~1`. You can also pass commit hash or branch name.
|
||||
|
||||
### resolveSnapshotPath
|
||||
|
||||
- **Type**: `(testPath: string, snapExtension: string) => string`
|
||||
- **Default**: stores snapshot files in `__snapshots__` directory
|
||||
|
||||
Overrides default snapshot path. For example, to store snapshots next to test files:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
test: {
|
||||
resolveSnapshotPath: (testPath, snapExtension) => testPath + snapExtension,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import path from 'pathe'
|
||||
import { expect } from 'chai'
|
||||
import type { SnapshotResult, Test } from '../../types'
|
||||
import { rpc } from '../../runtime/rpc'
|
||||
@ -13,18 +12,12 @@ export interface Context {
|
||||
fullTitle?: string
|
||||
}
|
||||
|
||||
const resolveSnapshotPath = (testPath: string) =>
|
||||
path.join(
|
||||
path.join(path.dirname(testPath), '__snapshots__'),
|
||||
`${path.basename(testPath)}.snap`,
|
||||
)
|
||||
|
||||
export class SnapshotClient {
|
||||
test: Test | undefined
|
||||
testFile = ''
|
||||
snapshotState: SnapshotState | undefined
|
||||
|
||||
setTest(test: Test) {
|
||||
async setTest(test: Test) {
|
||||
this.test = test
|
||||
|
||||
if (this.testFile !== this.test.file!.filepath) {
|
||||
@ -33,7 +26,7 @@ export class SnapshotClient {
|
||||
|
||||
this.testFile = this.test!.file!.filepath
|
||||
this.snapshotState = new SnapshotState(
|
||||
resolveSnapshotPath(this.testFile),
|
||||
await rpc().resolveSnapshotPath(this.testFile),
|
||||
getWorkerState().config.snapshotOptions,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,19 +1,33 @@
|
||||
import type { ResolvedConfig, SnapshotResult, SnapshotStateOptions, SnapshotSummary } from '../../types'
|
||||
import { basename, dirname, join } from 'pathe'
|
||||
import type { SnapshotResult, SnapshotStateOptions, SnapshotSummary } from '../../types'
|
||||
|
||||
export class SnapshotManager {
|
||||
summary: SnapshotSummary = undefined!
|
||||
extension = '.snap'
|
||||
|
||||
constructor(public config: ResolvedConfig) {
|
||||
constructor(public options: SnapshotStateOptions) {
|
||||
this.clear()
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.summary = emptySummary(this.config.snapshotOptions)
|
||||
this.summary = emptySummary(this.options)
|
||||
}
|
||||
|
||||
add(result: SnapshotResult) {
|
||||
addSnapshotResult(this.summary, result)
|
||||
}
|
||||
|
||||
resolvePath(testPath: string) {
|
||||
const resolver = this.options.resolveSnapshotPath || (() => {
|
||||
return join(
|
||||
join(
|
||||
dirname(testPath), '__snapshots__'),
|
||||
`${basename(testPath)}${this.extension}`,
|
||||
)
|
||||
})
|
||||
|
||||
return resolver(testPath, this.extension)
|
||||
}
|
||||
}
|
||||
|
||||
export function emptySummary(options: SnapshotStateOptions): SnapshotSummary {
|
||||
|
||||
@ -110,8 +110,12 @@ export function resolveConfig(
|
||||
: UPDATE_SNAPSHOT
|
||||
? 'all'
|
||||
: 'new',
|
||||
resolveSnapshotPath: options.resolveSnapshotPath,
|
||||
}
|
||||
|
||||
if (options.resolveSnapshotPath)
|
||||
delete (resolved as UserConfig).resolveSnapshotPath
|
||||
|
||||
if (process.env.VITEST_MAX_THREADS)
|
||||
resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS)
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ export class Vitest {
|
||||
this.server = server
|
||||
this.config = resolved
|
||||
this.state = new StateManager()
|
||||
this.snapshot = new SnapshotManager(resolved)
|
||||
this.snapshot = new SnapshotManager({ ...resolved.snapshotOptions })
|
||||
this.reporters = resolved.reporters
|
||||
.map((i) => {
|
||||
if (typeof i === 'string') {
|
||||
@ -91,6 +91,11 @@ export class Vitest {
|
||||
const hasCustomReporter = toArray(this.config.reporters)
|
||||
.some(reporter => typeof reporter !== 'string')
|
||||
|
||||
// cannot be serialized for sending to workers
|
||||
// reimplemented on rpc
|
||||
if (this.config.snapshotOptions.resolveSnapshotPath)
|
||||
this.config.snapshotOptions.resolveSnapshotPath = undefined
|
||||
|
||||
if (!hasCustomReporter && !this.configOverride)
|
||||
return this.config
|
||||
|
||||
|
||||
@ -118,6 +118,9 @@ function createChannel(ctx: Vitest) {
|
||||
snapshotSaved(snapshot) {
|
||||
ctx.snapshot.add(snapshot)
|
||||
},
|
||||
resolveSnapshotPath(testPath: string) {
|
||||
return ctx.snapshot.resolvePath(testPath)
|
||||
},
|
||||
async getSourceMap(id, force) {
|
||||
if (force) {
|
||||
const mod = ctx.server.moduleGraph.getModuleById(id)
|
||||
|
||||
@ -78,7 +78,7 @@ export async function runTest(test: Test) {
|
||||
|
||||
clearModuleMocks()
|
||||
|
||||
getSnapshotClient().setTest(test)
|
||||
await getSnapshotClient().setTest(test)
|
||||
|
||||
const workerState = getWorkerState()
|
||||
|
||||
|
||||
@ -290,6 +290,11 @@ export interface InlineConfig {
|
||||
* Format options for snapshot testing.
|
||||
*/
|
||||
snapshotFormat?: PrettyFormatOptions
|
||||
|
||||
/**
|
||||
* Resolve custom snapshot path
|
||||
*/
|
||||
resolveSnapshotPath?: (path: string, extension: string) => string
|
||||
}
|
||||
|
||||
export interface UserConfig extends InlineConfig {
|
||||
@ -338,7 +343,7 @@ export interface UserConfig extends InlineConfig {
|
||||
changed?: boolean | string
|
||||
}
|
||||
|
||||
export interface ResolvedConfig extends Omit<Required<UserConfig>, 'config' | 'filters' | 'coverage' | 'testNamePattern' | 'related' | 'api' | 'reporters'> {
|
||||
export interface ResolvedConfig extends Omit<Required<UserConfig>, 'config' | 'filters' | 'coverage' | 'testNamePattern' | 'related' | 'api' | 'reporters' | 'resolveSnapshotPath'> {
|
||||
base?: string
|
||||
|
||||
config?: string
|
||||
|
||||
@ -8,6 +8,7 @@ export interface SnapshotStateOptions {
|
||||
updateSnapshot: SnapshotUpdateState
|
||||
expand?: boolean
|
||||
snapshotFormat?: PrettyFormatOptions
|
||||
resolveSnapshotPath?: (path: string, extension: string) => string
|
||||
}
|
||||
|
||||
export interface SnapshotMatchOptions {
|
||||
|
||||
@ -29,6 +29,7 @@ export interface WorkerRPC {
|
||||
onTaskUpdate: (pack: TaskResultPack[]) => void
|
||||
|
||||
snapshotSaved: (snapshot: SnapshotResult) => void
|
||||
resolveSnapshotPath: (testPath: string) => string
|
||||
}
|
||||
|
||||
export interface WorkerGlobalState {
|
||||
|
||||
5
test/core/test/moved-snapshot.test.ts
Normal file
5
test/core/test/moved-snapshot.test.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { expect, test } from 'vitest'
|
||||
|
||||
test('snapshot is stored close to file', () => {
|
||||
expect('moved snapshot').toMatchSnapshot()
|
||||
})
|
||||
3
test/core/test/moved-snapshot.test.ts.snap
Normal file
3
test/core/test/moved-snapshot.test.ts.snap
Normal file
@ -0,0 +1,3 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`snapshot is stored close to file 1`] = `"moved snapshot"`;
|
||||
@ -1,4 +1,4 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { basename, dirname, join, resolve } from 'pathe'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
@ -45,5 +45,10 @@ export default defineConfig({
|
||||
coverage: {
|
||||
reporter: ['text', 'html'],
|
||||
},
|
||||
resolveSnapshotPath: (path, extension) => {
|
||||
if (path.includes('moved-snapshot'))
|
||||
return path + extension
|
||||
return join(dirname(path), '__snapshots__', `${basename(path)}${extension}`)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user