/
utils.ts
51 lines (43 loc) · 1.56 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { processError } from '@vitest/utils/error'
import type { Test } from '@vitest/runner/types'
import { GLOBAL_EXPECT } from './constants'
import { getState } from './state'
import type { Assertion, MatcherState } from './types'
export function recordAsyncExpect(test: any, promise: Promise<any> | PromiseLike<any>) {
// record promise for test, that resolves before test ends
if (test && promise instanceof Promise) {
// if promise is explicitly awaited, remove it from the list
promise = promise.finally(() => {
const index = test.promises.indexOf(promise)
if (index !== -1)
test.promises.splice(index, 1)
})
// record promise
if (!test.promises)
test.promises = []
test.promises.push(promise)
}
return promise
}
export function wrapSoft(utils: Chai.ChaiUtils, fn: (this: Chai.AssertionStatic & Assertion, ...args: any[]) => void) {
return function (this: Chai.AssertionStatic & Assertion, ...args: any[]) {
const test: Test = utils.flag(this, 'vitest-test')
// @ts-expect-error local is untyped
const state: MatcherState = test?.context._local
? test.context.expect.getState()
: getState((globalThis as any)[GLOBAL_EXPECT])
if (!state.soft)
return fn.apply(this, args)
if (!test)
throw new Error('expect.soft() can only be used inside a test')
try {
return fn.apply(this, args)
}
catch (err) {
test.result ||= { state: 'fail' }
test.result.state = 'fail'
test.result.errors ||= []
test.result.errors.push(processError(err))
}
}
}