Skip to content

Commit

Permalink
feat: move matcher types to Vi namespace (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jan 22, 2022
1 parent 2509e06 commit 64f07e2
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 39 deletions.
19 changes: 9 additions & 10 deletions packages/vitest/src/index.ts
Expand Up @@ -16,8 +16,6 @@ export * from './integrations/vi'
export * from './types'
export * from './api/types'

export type { Spy, SpyFn } from 'tinyspy'

declare module 'vite' {
interface UserConfig {
/**
Expand All @@ -43,9 +41,10 @@ type Promisify<O> = {
}

declare global {
namespace Chai {
interface ExpectStatic extends AsymmetricMatchersContaining {
<T>(actual: T, message?: string): VitestAssertion<T>
namespace Vi {

interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining {
<T>(actual: T, message?: string): Vi.Assertion<T>

extend(expects: MatchersObject): void
assertions(expected: number): void
Expand Down Expand Up @@ -117,16 +116,16 @@ declare global {
}

type VitestifyAssertion<A> = {
[K in keyof A]: A[K] extends Assertion
? VitestAssertion<any>
[K in keyof A]: A[K] extends Chai.Assertion
? Assertion<any>
: A[K] extends (...args: any[]) => any
? A[K] // not converting function since they may contain overload
: VitestifyAssertion<A[K]>
}

interface VitestAssertion<T = any> extends VitestifyAssertion<Assertion>, JestAssertion<T> {
resolves: Promisify<VitestAssertion<T>>
rejects: Promisify<VitestAssertion<T>>
interface Assertion<T = any> extends VitestifyAssertion<Chai.Assertion>, JestAssertion<T> {
resolves: Promisify<Assertion<T>>
rejects: Promisify<Assertion<T>>

chaiEqual<E>(expected: E): void
}
Expand Down
6 changes: 3 additions & 3 deletions packages/vitest/src/integrations/chai/index.ts
Expand Up @@ -3,11 +3,11 @@ import { getState, setState } from './jest-expect'

export { assert, should } from 'chai'

const expect = ((value: any, message?: string): Chai.VitestAssertion => {
const expect = ((value: any, message?: string): Vi.Assertion => {
const { assertionCalls } = getState()
setState({ assertionCalls: assertionCalls + 1 })
return chai.expect(value, message)
}) as Chai.ExpectStatic
return chai.expect(value, message) as unknown as Vi.Assertion
}) as Vi.ExpectStatic
expect.getState = getState
expect.setState = setState

Expand Down
Expand Up @@ -294,7 +294,8 @@ export const JestAsymmetricMatchers: ChaiPlugin = (chai, utils) => {
(expected: any) => new StringMatching(expected),
)

chai.expect.not = {
// defineProperty does not work
;(chai.expect as any).not = {
stringContaining: (expected: string) => new StringContaining(expected, true),
objectContaining: (expected: any) => new ObjectContaining(expected, true),
arrayContaining: (expected: unknown[]) => new ArrayContaining(expected, true),
Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/integrations/chai/jest-expect.ts
Expand Up @@ -34,8 +34,8 @@ export const setState = <State extends MatcherState = MatcherState>(

// Jest Expect Compact
export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
function def(name: keyof Chai.VitestAssertion | (keyof Chai.VitestAssertion)[], fn: ((this: Chai.AssertionStatic & Chai.VitestAssertion, ...args: any[]) => any)) {
const addMethod = (n: keyof Chai.VitestAssertion) => {
function def(name: keyof Vi.Assertion | (keyof Vi.Assertion)[], fn: ((this: Chai.AssertionStatic & Vi.Assertion, ...args: any[]) => any)) {
const addMethod = (n: keyof Vi.Assertion) => {
utils.addMethod(chai.Assertion.prototype, n, fn)
}

Expand Down
34 changes: 17 additions & 17 deletions packages/vitest/src/integrations/jest-mock.ts
Expand Up @@ -36,7 +36,7 @@ type Classes<T> = {
[K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never
}[keyof T] & string

export interface JestMockCompat<TArgs extends any[] = any[], TReturns = any> {
export interface SpyInstance<TArgs extends any[] = any[], TReturns = any> {
getMockName(): string
mockName(n: string): this
mock: JestMockCompatContext<TArgs, TReturns>
Expand All @@ -55,14 +55,14 @@ export interface JestMockCompat<TArgs extends any[] = any[], TReturns = any> {
mockRejectedValueOnce(obj: any): this
}

export interface JestMockCompatFn<TArgs extends any[] = any, TReturns = any> extends JestMockCompat<TArgs, TReturns> {
export interface SpyInstanceFn<TArgs extends any[] = any, TReturns = any> extends SpyInstance<TArgs, TReturns> {
(...args: TArgs): TReturns
}

export type MaybeMockedConstructor<T> = T extends new (
...args: Array<any>
) => infer R
? JestMockCompatFn<ConstructorParameters<T>, R>
? SpyInstanceFn<ConstructorParameters<T>, R>
: T
export type MockedFunction<T extends Procedure> = MockWithArgs<T> & {
[K in keyof T]: T[K];
Expand Down Expand Up @@ -91,15 +91,15 @@ export type MaybeMocked<T> = T extends Procedure
? MockedObject<T>
: T

export type EnhancedSpy<TArgs extends any[] = any[], TReturns = any> = JestMockCompat<TArgs, TReturns> & SpyImpl<TArgs, TReturns>
export type EnhancedSpy<TArgs extends any[] = any[], TReturns = any> = SpyInstance<TArgs, TReturns> & SpyImpl<TArgs, TReturns>

export interface MockWithArgs<T extends Procedure>
extends JestMockCompatFn<Parameters<T>, ReturnType<T>> {
extends SpyInstanceFn<Parameters<T>, ReturnType<T>> {
new (...args: T extends new (...args: any) => any ? ConstructorParameters<T> : never): T
(...args: Parameters<T>): ReturnType<T>
}

export const spies = new Set<JestMockCompat>()
export const spies = new Set<SpyInstance>()

export function isMockFunction(fn: any): fn is EnhancedSpy {
return typeof fn === 'function'
Expand All @@ -111,28 +111,28 @@ export function spyOn<T, S extends Properties<Required<T>>>(
obj: T,
methodName: S,
accesType: 'get',
): JestMockCompat<[], T[S]>
): SpyInstance<[], T[S]>
export function spyOn<T, G extends Properties<Required<T>>>(
obj: T,
methodName: G,
accesType: 'set',
): JestMockCompat<[T[G]], void>
): SpyInstance<[T[G]], void>
export function spyOn<T, M extends Classes<Required<T>>>(
object: T,
method: M
): Required<T>[M] extends new (...args: infer A) => infer R
? JestMockCompat<A, R>
? SpyInstance<A, R>
: never
export function spyOn<T, M extends Methods<Required<T>>>(
obj: T,
methodName: M,
mock?: T[M]
): Required<T>[M] extends (...args: infer A) => infer R ? JestMockCompat<A, R> : never
): Required<T>[M] extends (...args: infer A) => infer R ? SpyInstance<A, R> : never
export function spyOn<T, K extends keyof T>(
obj: T,
method: K,
accessType?: 'get' | 'set',
): JestMockCompat {
): SpyInstance {
const dictionary = {
get: 'getter',
set: 'setter',
Expand All @@ -141,14 +141,14 @@ export function spyOn<T, K extends keyof T>(

const stub = tinyspy.spyOn(obj, objMethod as any)

return enhanceSpy(stub) as JestMockCompat
return enhanceSpy(stub) as SpyInstance
}

let callOrder = 0

function enhanceSpy<TArgs extends any[], TReturns>(
spy: SpyImpl<TArgs, TReturns>,
): JestMockCompat<TArgs, TReturns> {
): SpyInstance<TArgs, TReturns> {
const stub = spy as unknown as EnhancedSpy<TArgs, TReturns>

let implementation: ((...args: TArgs) => TReturns) | undefined
Expand Down Expand Up @@ -249,12 +249,12 @@ function enhanceSpy<TArgs extends any[], TReturns>(
return stub as any
}

export function fn<TArgs extends any[] = any[], R = any>(): JestMockCompatFn<TArgs, R>
export function fn<TArgs extends any[] = any[], R = any>(): SpyInstanceFn<TArgs, R>
export function fn<TArgs extends any[] = any[], R = any>(
implementation: (...args: TArgs) => R
): JestMockCompatFn<TArgs, R>
): SpyInstanceFn<TArgs, R>
export function fn<TArgs extends any[] = any[], R = any>(
implementation?: (...args: TArgs) => R,
): JestMockCompatFn<TArgs, R> {
return enhanceSpy(tinyspy.spyOn({ fn: implementation || (() => {}) }, 'fn')) as unknown as JestMockCompatFn
): SpyInstanceFn<TArgs, R> {
return enhanceSpy(tinyspy.spyOn({ fn: implementation || (() => {}) }, 'fn')) as unknown as SpyInstanceFn
}
2 changes: 1 addition & 1 deletion packages/vitest/src/integrations/snapshot/client.ts
Expand Up @@ -54,7 +54,7 @@ export class SnapshotClient {
try {
const pass = equals(received, properties, [iterableEquality, subsetEquality])
if (!pass)
expect(received).toBe(properties)
expect(received).equals(properties)
else
received = deepMergeSnapshot(received, properties)
}
Expand Down
10 changes: 5 additions & 5 deletions packages/vitest/src/integrations/timers.ts
@@ -1,7 +1,7 @@
// TODO setImmediate, nextTick, requestAnimationFrame, cancelAnimationFrame
// TODO async timers

import type { JestMockCompat } from './jest-mock'
import type { SpyInstance } from './jest-mock'
import { spyOn } from './jest-mock'

const originalSetTimeout = global.setTimeout
Expand Down Expand Up @@ -57,11 +57,11 @@ const getNodeTimeout = (id: number): NodeJS.Timeout => {
}

export class FakeTimers {
private _setTimeout!: JestMockCompat<Arguments, NodeJS.Timeout>
private _setInterval!: JestMockCompat<Arguments, NodeJS.Timeout>
private _setTimeout!: SpyInstance<Arguments, NodeJS.Timeout>
private _setInterval!: SpyInstance<Arguments, NodeJS.Timeout>

private _clearTimeout!: JestMockCompat<[NodeJS.Timeout], void>
private _clearInterval!: JestMockCompat<[NodeJS.Timeout], void>
private _clearTimeout!: SpyInstance<[NodeJS.Timeout], void>
private _clearInterval!: SpyInstance<[NodeJS.Timeout], void>

private _advancedTime = 0
private _nestedTime: Record<string, number> = {}
Expand Down

0 comments on commit 64f07e2

Please sign in to comment.