Skip to content

Commit

Permalink
wip: deal with concurrent
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Oct 31, 2024
1 parent 861c58b commit 44eadd6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 10 deletions.
13 changes: 5 additions & 8 deletions packages/snapshot/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { RawSnapshotInfo } from './port/rawSnapshot'
import type { SnapshotResult, SnapshotStateOptions } from './types'
import SnapshotState from './port/state'
import { deepMergeSnapshot, DefaultMap } from './port/utils'
import { deepMergeSnapshot, DefaultMap, PromiseMap } from './port/utils'

function createMismatchError(
message: string,
Expand Down Expand Up @@ -83,7 +83,7 @@ export class SnapshotClient {

private fileToTestIds = new DefaultMap<string, Set<string>>(() => new Set())
private testIdToSnapshotPath = new Map<string, string>()
private snapshotPathToState = new Map<string, SnapshotState>()
private snapshotPathToState = new PromiseMap<string, SnapshotState>()

// resolve snapshot file for each test and reuse state for same snapshot file
// TODO: concurrent safe
Expand All @@ -95,13 +95,10 @@ export class SnapshotClient {
this.fileToTestIds.get(filepath).add(testId)
const snapshotPath = await options.snapshotEnvironment.resolvePath(filepath)
this.testIdToSnapshotPath.set(testId, snapshotPath)
// share same snapshot state for same snapshot path
let state = this.snapshotPathToState.get(snapshotPath)
if (!state) {
const state = await this.snapshotPathToState.getOrCreate(snapshotPath, async () => {
const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath)
state = new SnapshotState(filepath, snapshotPath, content, options)
this.snapshotPathToState.set(snapshotPath, state)
}
return new SnapshotState(filepath, snapshotPath, content, options)
})
state.clearTest(testId)
return state
}
Expand Down
16 changes: 16 additions & 0 deletions packages/snapshot/src/port/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,19 @@ export class CounterMap<K> extends Map<K, number> {
return total
}
}

export class PromiseMap<K, V> extends Map<K, V> {
private inner = new Map<K, Promise<V>>()

getOrCreate(key: K, createFn: () => Promise<V>): Promise<V> {
let promise = this.inner.get(key)
if (!promise) {
promise = createFn().then((value) => {
this.set(key, value)
return value
})
this.inner.set(key, promise)
}
return promise
}
}
6 changes: 4 additions & 2 deletions test/core/test/nested-test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ test('nested test should throw error', () => {
})

describe('parallel tests', () => {
test.concurrent('parallel test 1 with nested test', () => {
test.concurrent('parallel test 1 with nested test', ({ expect }) => {
expect(() => {
test('test inside test', () => {})
}).toThrowErrorMatchingInlineSnapshot(`[Error: Calling the test function inside another test function is not allowed. Please put it inside "describe" or "suite" so it can be properly collected.]`)
})
test.concurrent('parallel test 2 without nested test', () => {})
test.concurrent('parallel test 3 without nested test', () => {})
test.concurrent('parallel test 4 with nested test', () => {
// TODO: the error is not guaranteed since getCurrentTest can be already cleared
// https://stackblitz.com/edit/vitest-dev-vitest-44ezrs?file=test%2Fbasic.test.ts
test.skip.concurrent('parallel test 4 with nested test', () => {
expect(() => {
test('test inside test', () => {})
}).toThrowErrorMatchingInlineSnapshot(`[Error: Calling the test function inside another test function is not allowed. Please put it inside "describe" or "suite" so it can be properly collected.]`)
Expand Down

0 comments on commit 44eadd6

Please sign in to comment.