Skip to content

Commit

Permalink
fix(browser): correctly import optimized module in vi.importActual (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jul 25, 2024
1 parent 9069bdc commit 804ff2f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 8 deletions.
13 changes: 10 additions & 3 deletions packages/browser/src/client/tester/mocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,19 @@ export class VitestBrowserClientMocker {
)
}
const ext = extname(resolved.id)
const url = new URL(`/@id/${resolved.id}`, location.href)
const query = `_vitest_original&ext.${ext}`
const url = new URL(resolved.url, location.href)
const query = `_vitest_original&ext${ext}`
const actualUrl = `${url.pathname}${
url.search ? `${url.search}&${query}` : `?${query}`
}${url.hash}`
return getBrowserState().wrapModule(() => import(/* @vite-ignore */ actualUrl))
return getBrowserState().wrapModule(() => import(/* @vite-ignore */ actualUrl)).then((mod) => {
if (!resolved.optimized || typeof mod.default === 'undefined') {
return mod
}
// vite injects this helper for optimized modules, so we try to follow the same behavior
const m = mod.default
return m?.__esModule ? m : { ...((typeof m === 'object' && !Array.isArray(m)) || typeof m === 'function' ? m : {}), default: m }
})
}

public async importMock(rawId: string, importer: string) {
Expand Down
47 changes: 43 additions & 4 deletions packages/browser/src/node/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { existsSync, promises as fs } from 'node:fs'
import { dirname } from 'pathe'
import { dirname, isAbsolute, join } from 'pathe'
import { createBirpc } from 'birpc'
import { parse, stringify } from 'flatted'
import type { WebSocket } from 'ws'
Expand All @@ -8,11 +8,12 @@ import type { BrowserCommandContext } from 'vitest/node'
import { createDebugger, isFileServingAllowed } from 'vitest/node'
import type { WebSocketBrowserEvents, WebSocketBrowserHandlers } from './types'
import type { BrowserServer } from './server'
import { resolveMock } from './resolveMock'
import { cleanUrl, resolveMock } from './resolveMock'

const debug = createDebugger('vitest:browser:api')

const BROWSER_API_PATH = '/__vitest_browser_api__'
const VALID_ID_PREFIX = '/@id/'

export function setupBrowserRpc(
server: BrowserServer,
Expand Down Expand Up @@ -118,14 +119,44 @@ export function setupBrowserRpc(
ctx.cancelCurrentRun(reason)
},
async resolveId(id, importer) {
const result = await project.server.pluginContainer.resolveId(
const resolved = await vite.pluginContainer.resolveId(
id,
importer,
{
ssr: false,
},
)
return result
if (!resolved) {
return null
}
const isOptimized = resolved.id.startsWith(withTrailingSlash(vite.config.cacheDir))
let url: string
// normalise the URL to be acceptible by the browser
// https://github.com/vitejs/vite/blob/e833edf026d495609558fd4fb471cf46809dc369/packages/vite/src/node/plugins/importAnalysis.ts#L335
const root = vite.config.root
if (resolved.id.startsWith(withTrailingSlash(root))) {
url = resolved.id.slice(root.length)
}
else if (
resolved.id !== '/@react-refresh'
&& isAbsolute(resolved.id)
&& existsSync(cleanUrl(resolved.id))
) {
url = join('/@fs/', resolved.id)
}
else {
url = resolved.id
}
if (url[0] !== '.' && url[0] !== '/') {
url = id.startsWith(VALID_ID_PREFIX)
? id
: VALID_ID_PREFIX + id.replace('\0', '__x00__')
}
return {
id: resolved.id,
url,
optimized: isOptimized,
}
},
debug(...args) {
ctx.logger.console.debug(...args)
Expand Down Expand Up @@ -242,3 +273,11 @@ export function stringifyReplace(key: string, value: any) {
return value
}
}

function withTrailingSlash(path: string): string {
if (path[path.length - 1] !== '/') {
return `${path}/`
}

return path
}
2 changes: 1 addition & 1 deletion packages/browser/src/node/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface WebSocketBrowserHandlers {
resolveId: (
id: string,
importer?: string
) => Promise<{ id: string } | null>
) => Promise<{ id: string; url: string; optimized: boolean } | null>
triggerCommand: <T>(
contextId: string,
command: string,
Expand Down
14 changes: 14 additions & 0 deletions test/browser/fixtures/mocking/import-actual-dep.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { a, b } from '@vitest/cjs-lib'
import { expect, test, vi } from 'vitest'

vi.mock(import('@vitest/cjs-lib'), async (importOriginal) => {
const original = await importOriginal()
return {
...await importOriginal(),
}
})

test('mocking works correctly', () => {
expect(a).toBe('a')
expect(b).toBe('b')
})
1 change: 1 addition & 0 deletions test/browser/specs/mocking.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ test.each([true, false])('mocking works correctly - isolated %s', async (isolate
expect(result.stdout).toContain('import-actual-query.test.ts')
expect(result.stdout).toContain('import-mock.test.ts')
expect(result.stdout).toContain('mocked-do-mock-factory.test.ts')
expect(result.stdout).toContain('import-actual-dep.test.ts')
expect(result.exitCode).toBe(0)
})

Expand Down

0 comments on commit 804ff2f

Please sign in to comment.