From d8b0b55e493ea5c5396d96d809816b41c2dcf71e Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 22 Jan 2022 14:54:43 +0300 Subject: [PATCH 1/3] feat: move matcher types to Vi namespace --- packages/vitest/src/index.ts | 21 +++++------- .../vitest/src/integrations/chai/index.ts | 6 ++-- .../src/integrations/chai/jest-expect.ts | 4 +-- packages/vitest/src/integrations/jest-mock.ts | 34 +++++++++---------- packages/vitest/src/integrations/timers.ts | 10 +++--- 5 files changed, 36 insertions(+), 39 deletions(-) diff --git a/packages/vitest/src/index.ts b/packages/vitest/src/index.ts index 48c6aced8d64..9127e21fbf35 100644 --- a/packages/vitest/src/index.ts +++ b/packages/vitest/src/index.ts @@ -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 { /** @@ -43,9 +41,10 @@ type Promisify = { } declare global { - namespace Chai { - interface ExpectStatic extends AsymmetricMatchersContaining { - (actual: T, message?: string): VitestAssertion + namespace Vi { + + interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining { + (actual: T, message?: string): Vi.Assertion extend(expects: MatchersObject): void assertions(expected: number): void @@ -117,18 +116,16 @@ declare global { } type VitestifyAssertion = { - [K in keyof A]: A[K] extends Assertion - ? VitestAssertion + [K in keyof A]: A[K] extends Chai.Assertion + ? Assertion : A[K] extends (...args: any[]) => any ? A[K] // not converting function since they may contain overload : VitestifyAssertion } - interface VitestAssertion extends VitestifyAssertion, JestAssertion { - resolves: Promisify> - rejects: Promisify> - - chaiEqual(expected: E): void + interface Assertion extends VitestifyAssertion, JestAssertion { + resolves: Promisify> + rejects: Promisify> } } } diff --git a/packages/vitest/src/integrations/chai/index.ts b/packages/vitest/src/integrations/chai/index.ts index 2d332bbcbd4f..fce9765a289a 100644 --- a/packages/vitest/src/integrations/chai/index.ts +++ b/packages/vitest/src/integrations/chai/index.ts @@ -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 diff --git a/packages/vitest/src/integrations/chai/jest-expect.ts b/packages/vitest/src/integrations/chai/jest-expect.ts index 95d5ab90ba85..bd2c676d1a95 100644 --- a/packages/vitest/src/integrations/chai/jest-expect.ts +++ b/packages/vitest/src/integrations/chai/jest-expect.ts @@ -34,8 +34,8 @@ export const setState = ( // 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) } diff --git a/packages/vitest/src/integrations/jest-mock.ts b/packages/vitest/src/integrations/jest-mock.ts index 735b3ab20f0a..549116294eb8 100644 --- a/packages/vitest/src/integrations/jest-mock.ts +++ b/packages/vitest/src/integrations/jest-mock.ts @@ -36,7 +36,7 @@ type Classes = { [K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never }[keyof T] & string -export interface JestMockCompat { +export interface SpyInstance { getMockName(): string mockName(n: string): this mock: JestMockCompatContext @@ -55,14 +55,14 @@ export interface JestMockCompat { mockRejectedValueOnce(obj: any): this } -export interface JestMockCompatFn extends JestMockCompat { +export interface SpyInstanceFn extends SpyInstance { (...args: TArgs): TReturns } export type MaybeMockedConstructor = T extends new ( ...args: Array ) => infer R - ? JestMockCompatFn, R> + ? SpyInstanceFn, R> : T export type MockedFunction = MockWithArgs & { [K in keyof T]: T[K]; @@ -91,15 +91,15 @@ export type MaybeMocked = T extends Procedure ? MockedObject : T -export type EnhancedSpy = JestMockCompat & SpyImpl +export type EnhancedSpy = SpyInstance & SpyImpl export interface MockWithArgs - extends JestMockCompatFn, ReturnType> { + extends SpyInstanceFn, ReturnType> { new (...args: T extends new (...args: any) => any ? ConstructorParameters : never): T (...args: Parameters): ReturnType } -export const spies = new Set() +export const spies = new Set() export function isMockFunction(fn: any): fn is EnhancedSpy { return typeof fn === 'function' @@ -111,28 +111,28 @@ export function spyOn>>( obj: T, methodName: S, accesType: 'get', -): JestMockCompat<[], T[S]> +): SpyInstance<[], T[S]> export function spyOn>>( obj: T, methodName: G, accesType: 'set', -): JestMockCompat<[T[G]], void> +): SpyInstance<[T[G]], void> export function spyOn>>( object: T, method: M ): Required[M] extends new (...args: infer A) => infer R - ? JestMockCompat + ? SpyInstance : never export function spyOn>>( obj: T, methodName: M, mock?: T[M] -): Required[M] extends (...args: infer A) => infer R ? JestMockCompat : never +): Required[M] extends (...args: infer A) => infer R ? SpyInstance : never export function spyOn( obj: T, method: K, accessType?: 'get' | 'set', -): JestMockCompat { +): SpyInstance { const dictionary = { get: 'getter', set: 'setter', @@ -141,14 +141,14 @@ export function spyOn( const stub = tinyspy.spyOn(obj, objMethod as any) - return enhanceSpy(stub) as JestMockCompat + return enhanceSpy(stub) as SpyInstance } let callOrder = 0 function enhanceSpy( spy: SpyImpl, -): JestMockCompat { +): SpyInstance { const stub = spy as unknown as EnhancedSpy let implementation: ((...args: TArgs) => TReturns) | undefined @@ -249,12 +249,12 @@ function enhanceSpy( return stub as any } -export function fn(): JestMockCompatFn +export function fn(): SpyInstanceFn export function fn( implementation: (...args: TArgs) => R -): JestMockCompatFn +): SpyInstanceFn export function fn( implementation?: (...args: TArgs) => R, -): JestMockCompatFn { - return enhanceSpy(tinyspy.spyOn({ fn: implementation || (() => {}) }, 'fn')) as unknown as JestMockCompatFn +): SpyInstanceFn { + return enhanceSpy(tinyspy.spyOn({ fn: implementation || (() => {}) }, 'fn')) as unknown as SpyInstanceFn } diff --git a/packages/vitest/src/integrations/timers.ts b/packages/vitest/src/integrations/timers.ts index 610efea80f18..3e64e75ffbb8 100644 --- a/packages/vitest/src/integrations/timers.ts +++ b/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 @@ -57,11 +57,11 @@ const getNodeTimeout = (id: number): NodeJS.Timeout => { } export class FakeTimers { - private _setTimeout!: JestMockCompat - private _setInterval!: JestMockCompat + private _setTimeout!: SpyInstance + private _setInterval!: SpyInstance - 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 = {} From ee4805f51ccd5c62057d542405fe6340f4647143 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 22 Jan 2022 15:01:40 +0300 Subject: [PATCH 2/3] chore: fix types --- packages/vitest/src/index.ts | 2 ++ .../vitest/src/integrations/chai/jest-asymmetric-matchers.ts | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/vitest/src/index.ts b/packages/vitest/src/index.ts index 9127e21fbf35..33924b556352 100644 --- a/packages/vitest/src/index.ts +++ b/packages/vitest/src/index.ts @@ -126,6 +126,8 @@ declare global { interface Assertion extends VitestifyAssertion, JestAssertion { resolves: Promisify> rejects: Promisify> + + chaiEqual(expected: E): void } } } diff --git a/packages/vitest/src/integrations/chai/jest-asymmetric-matchers.ts b/packages/vitest/src/integrations/chai/jest-asymmetric-matchers.ts index 8e445315aae6..a26c28c9b727 100644 --- a/packages/vitest/src/integrations/chai/jest-asymmetric-matchers.ts +++ b/packages/vitest/src/integrations/chai/jest-asymmetric-matchers.ts @@ -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), From 2ad0d05ff460dedc617c313c43f61d7a14094227 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 22 Jan 2022 15:06:25 +0300 Subject: [PATCH 3/3] chore: fix types --- packages/vitest/src/integrations/snapshot/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vitest/src/integrations/snapshot/client.ts b/packages/vitest/src/integrations/snapshot/client.ts index 5b79f5ef4885..2e9acaff33f2 100644 --- a/packages/vitest/src/integrations/snapshot/client.ts +++ b/packages/vitest/src/integrations/snapshot/client.ts @@ -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) }