Skip to content

Commit

Permalink
fix(browser): fix browser mock factory event race condition (#6530)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Sep 25, 2024
1 parent b553c7d commit f131f93
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 20 deletions.
3 changes: 3 additions & 0 deletions packages/browser/src/client/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,19 @@ export interface IframeMockingDoneEvent {

export interface IframeMockFactoryRequestEvent {
type: 'mock-factory:request'
eventId: string
id: string
}

export interface IframeMockFactoryResponseEvent {
type: 'mock-factory:response'
eventId: string
exports: string[]
}

export interface IframeMockFactoryErrorEvent {
type: 'mock-factory:error'
eventId: string
error: any
}

Expand Down
8 changes: 5 additions & 3 deletions packages/browser/src/client/tester/mocker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IframeChannelOutgoingEvent } from '@vitest/browser/client'
import type { IframeChannelOutgoingEvent, IframeMockFactoryErrorEvent, IframeMockFactoryResponseEvent } from '@vitest/browser/client'
import { channel } from '@vitest/browser/client'
import { ModuleMocker } from '@vitest/mocker/browser'
import { getBrowserState } from '../utils'
Expand All @@ -14,18 +14,20 @@ export class VitestBrowserClientMocker extends ModuleMocker {
const exports = Object.keys(module)
channel.postMessage({
type: 'mock-factory:response',
eventId: e.data.eventId,
exports,
})
} satisfies IframeMockFactoryResponseEvent)
}
catch (err: any) {
channel.postMessage({
type: 'mock-factory:error',
eventId: e.data.eventId,
error: {
name: err.name,
message: err.message,
stack: err.stack,
},
})
} satisfies IframeMockFactoryErrorEvent)
}
}
},
Expand Down
10 changes: 7 additions & 3 deletions packages/browser/src/client/tester/msw.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { channel } from '@vitest/browser/client'
import type {
IframeChannelEvent,
IframeMockFactoryRequestEvent,
IframeMockingDoneEvent,
} from '@vitest/browser/client'
import type { MockedModuleSerialized } from '@vitest/mocker'
import { ManualMockedModule } from '@vitest/mocker'
import { ModuleMockerMSWInterceptor } from '@vitest/mocker/browser'
import { nanoid } from '@vitest/utils'

export class VitestBrowserModuleMockerInterceptor extends ModuleMockerMSWInterceptor {
override async register(event: MockedModuleSerialized): Promise<void> {
Expand Down Expand Up @@ -42,19 +44,21 @@ export function createModuleMockerInterceptor() {
}

function getFactoryExports(id: string) {
const eventId = nanoid()
channel.postMessage({
type: 'mock-factory:request',
eventId,
id,
})
} satisfies IframeMockFactoryRequestEvent)
return new Promise<string[]>((resolve, reject) => {
channel.addEventListener(
'message',
function onMessage(e: MessageEvent<IframeChannelEvent>) {
if (e.data.type === 'mock-factory:response') {
if (e.data.type === 'mock-factory:response' && e.data.eventId === eventId) {
resolve(e.data.exports)
channel.removeEventListener('message', onMessage)
}
if (e.data.type === 'mock-factory:error') {
if (e.data.type === 'mock-factory:error' && e.data.eventId === eventId) {
reject(e.data.error)
channel.removeEventListener('message', onMessage)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ export type {
SerializedError,
TestError,
} from './types'

export { nanoid } from './nanoid'
12 changes: 12 additions & 0 deletions packages/utils/src/nanoid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// port from nanoid
// https://github.com/ai/nanoid
const urlAlphabet
= 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
export function nanoid(size = 21): string {
let id = ''
let i = size
while (i--) {
id += urlAlphabet[(Math.random() * 64) | 0]
}
return id
}
15 changes: 1 addition & 14 deletions packages/vitest/src/utils/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Arrayable, Nullable } from '../types/general'

export { notNullish, getCallLastIndex } from '@vitest/utils'
export { notNullish, getCallLastIndex, nanoid } from '@vitest/utils'

export interface GlobalConstructors {
Object: ObjectConstructor
Expand Down Expand Up @@ -203,16 +203,3 @@ export function wildcardPatternToRegExp(pattern: string): RegExp {
'i',
)
}

// port from nanoid
// https://github.com/ai/nanoid
const urlAlphabet
= 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
export function nanoid(size = 21) {
let id = ''
let i = size
while (i--) {
id += urlAlphabet[(Math.random() * 64) | 0]
}
return id
}
13 changes: 13 additions & 0 deletions test/browser/fixtures/mocking/mocked-factory.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test, vi } from 'vitest'
import { calculator, mocked } from './src/mocks_factory'
import factoryMany from './src/mocks_factory_many'

vi.mock(import('./src/mocks_factory'), () => {
return {
Expand All @@ -8,7 +9,19 @@ vi.mock(import('./src/mocks_factory'), () => {
}
})

vi.mock(import('./src/mocks_factory_many_dep1'), () => ({
dep1: "dep1-mocked"
}))
vi.mock(import('./src/mocks_factory_many_dep2'), () => ({
dep2: "dep2-mocked"
}))

test('adds', () => {
expect(mocked).toBe(true)
expect(calculator('plus', 1, 2)).toBe(1166)

expect(factoryMany).toEqual({
"dep1": "dep1-mocked",
"dep2": "dep2-mocked",
})
})
4 changes: 4 additions & 0 deletions test/browser/fixtures/mocking/src/mocks_factory_many.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { dep1 } from "./mocks_factory_many_dep1";
import { dep2 } from "./mocks_factory_many_dep2";

export default { dep1, dep2 }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const dep1: string = "dep1"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const dep2: string = "dep2"

0 comments on commit f131f93

Please sign in to comment.