Skip to content

Commit

Permalink
fix: correctly normalize mocked path, if file is named like the folder (
Browse files Browse the repository at this point in the history
#1973)

* fix: correctly normalize mocked path, if file is named like the folder

* chore: cleanup
  • Loading branch information
sheremet-va committed Sep 5, 2022
1 parent f55fa26 commit 209ea6b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
31 changes: 30 additions & 1 deletion packages/vite-node/src/utils.ts
@@ -1,6 +1,7 @@
import { fileURLToPath, pathToFileURL } from 'url'
import { resolve } from 'pathe'
import { relative, resolve } from 'pathe'
import type { TransformResult } from 'vite'
import { isNodeBuiltin } from 'mlly'
import type { Arrayable, Nullable } from './types'

export const isWindows = process.platform === 'win32'
Expand Down Expand Up @@ -45,6 +46,34 @@ export function isPrimitive(v: any) {
return v !== Object(v)
}

export function pathFromRoot(root: string, filename: string) {
if (isNodeBuiltin(filename))
return filename

// don't replace with "/" on windows, "/C:/foo" is not a valid path
filename = filename.replace(/^\/@fs\//, isWindows ? '' : '/')

if (!filename.startsWith(root))
return filename

const relativePath = relative(root, filename)
// foo.js -> /foo.js
if (!relativePath.startsWith('/') && !relativePath.startsWith('.'))
return `/${relativePath}`

let index = 0
for (const char of relativePath) {
// ../../foo.js
// ^ returns from here -> /foo.js
if (char !== '.' && char !== '/')
return relativePath.slice(index - 1)

index++
}

return relativePath
}

export function toFilePath(id: string, root: string): string {
let absolute = id.startsWith('/@fs/')
? id.slice(4)
Expand Down
8 changes: 4 additions & 4 deletions packages/vitest/src/runtime/mocker.ts
@@ -1,9 +1,9 @@
import { existsSync, readdirSync } from 'fs'
import { isNodeBuiltin } from 'mlly'
import { basename, dirname, join, resolve } from 'pathe'
import { normalizeRequestId, toFilePath } from 'vite-node/utils'
import { normalizeRequestId, pathFromRoot, toFilePath } from 'vite-node/utils'
import type { ModuleCacheMap } from 'vite-node/client'
import { getAllMockableProperties, getType, getWorkerState, isWindows, mergeSlashes, slash } from '../utils'
import { getAllMockableProperties, getType, getWorkerState, mergeSlashes, slash } from '../utils'
import { distDir } from '../constants'
import type { PendingSuiteMock } from '../types/mocker'
import type { ExecuteOptions } from './execute'
Expand Down Expand Up @@ -142,14 +142,14 @@ export class VitestMocker {
}

public normalizePath(path: string) {
return normalizeRequestId(path.replace(this.root, ''), this.base).replace(/^\/@fs\//, isWindows ? '' : '/')
return pathFromRoot(this.root, normalizeRequestId(path, this.base))
}

public getFsPath(path: string, external: string | null) {
if (external)
return mergeSlashes(`/@fs/${path}`)

return normalizeRequestId(path.replace(this.root, ''))
return normalizeRequestId(path, this.base)
}

public resolveMockPath(mockPath: string, external: string | null) {
Expand Down
1 change: 1 addition & 0 deletions test/vite-config/src/src.ts
@@ -0,0 +1 @@
export const foo = 'foo'
11 changes: 9 additions & 2 deletions test/vite-config/src/test/root.test.ts
@@ -1,5 +1,12 @@
import { it } from 'vitest'
import { expect, it, vi } from 'vitest'
import { foo } from '../src'

vi.mock('../src.ts', () => ({ foo: 'baz' }))

it('should work', () => {
//
expect(1).toBe(1)
})

it('mocking with root works', () => {
expect(foo).toBe('baz')
})

0 comments on commit 209ea6b

Please sign in to comment.