Skip to content

Commit

Permalink
fix: make globalThis more compatible with jest (vitest-dev#1956)
Browse files Browse the repository at this point in the history
* fix: make globalThis more compatible with jest

* chore: oops

* chore: cleanup

* chore: cleanup
  • Loading branch information
sheremet-va authored and antfu committed Sep 4, 2022
1 parent 69153c0 commit 709c694
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/vitest/src/integrations/chai/constants.ts
@@ -1,2 +1,3 @@
export const GLOBAL_EXPECT = Symbol.for('expect-global')
export const MATCHERS_OBJECT = Symbol.for('matchers-object')
export const JEST_MATCHERS_OBJECT = Symbol.for('$$jest-matchers-object')
Expand Up @@ -16,6 +16,7 @@ export abstract class AsymmetricMatcher<
T,
State extends MatcherState = MatcherState,
> implements AsymmetricMatcherInterface {
// should have "jest" to be compatible with its ecosystem
$$typeof = Symbol.for('jest.asymmetricMatcher')

constructor(protected sample: T, protected inverse = false) {}
Expand Down
14 changes: 12 additions & 2 deletions packages/vitest/src/integrations/chai/jest-expect.ts
Expand Up @@ -10,11 +10,20 @@ import type { ChaiPlugin, MatcherState } from '../../types/chai'
import { arrayBufferEquality, generateToBeMessage, iterableEquality, equals as jestEquals, sparseArrayEquality, subsetEquality, typeEquality } from './jest-utils'
import type { AsymmetricMatcher } from './jest-asymmetric-matchers'
import { stringify } from './jest-matcher-utils'
import { MATCHERS_OBJECT } from './constants'
import { GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, MATCHERS_OBJECT } from './constants'

if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
const globalState = new WeakMap<Vi.ExpectStatic, MatcherState>()
const matchers = Object.create(null)
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
value: new WeakMap<Vi.ExpectStatic, MatcherState>(),
get: () => globalState,
})
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
configurable: true,
get: () => ({
state: globalState.get((globalThis as any)[GLOBAL_EXPECT]),
matchers,
}),
})
}

Expand All @@ -36,6 +45,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
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)
utils.addMethod((globalThis as any)[JEST_MATCHERS_OBJECT].matchers, n, fn)
}

if (Array.isArray(name))
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/integrations/chai/jest-extend.ts
Expand Up @@ -6,6 +6,7 @@ import type {
SyncExpectationResult,
} from '../../types/chai'
import { getSnapshotClient } from '../snapshot/chai'
import { JEST_MATCHERS_OBJECT } from './constants'
import { AsymmetricMatcher } from './jest-asymmetric-matchers'
import { getState } from './jest-expect'

Expand Down Expand Up @@ -79,6 +80,7 @@ function JestExtendPlugin(expect: Vi.ExpectStatic, matchers: MatchersObject): Ch

const expectAssertionWrapper = isAsyncFunction(expectAssertion) ? expectAsyncWrapper : expectSyncWrapper

utils.addMethod((globalThis as any)[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectAssertionWrapper)
utils.addMethod(c.Assertion.prototype, expectAssertionName, expectAssertionWrapper)

class CustomMatcher extends AsymmetricMatcher<[unknown, ...unknown[]]> {
Expand Down
12 changes: 12 additions & 0 deletions test/core/test/jest-expect.test.ts
Expand Up @@ -603,4 +603,16 @@ describe('async expect', () => {
})
})

it('compatible with jest', () => {
expect.extend({
someObject() {
return { pass: true, message: () => '' }
},
})
const { matchers, state } = (globalThis as any)[Symbol.for('$$jest-matchers-object')]
expect(matchers).toHaveProperty('someObject')
expect(matchers).toHaveProperty('toBe')
expect(state.assertionCalls).toBe(2)
})

it('timeout', () => new Promise(resolve => setTimeout(resolve, 500)))

0 comments on commit 709c694

Please sign in to comment.