Skip to content

Commit

Permalink
fix: allow mocking CJS module with interoped default (#2598)
Browse files Browse the repository at this point in the history
* fix: allow mocking CJS module with interoped default

* chore: cleanup

* chore: cleanup
  • Loading branch information
sheremet-va committed Jan 6, 2023
1 parent 9a29f98 commit 6b3e36d
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 5 deletions.
3 changes: 3 additions & 0 deletions examples/mocks/src/external/default-function.cjs
@@ -0,0 +1,3 @@
module.exports = function () {
return true
}
7 changes: 7 additions & 0 deletions examples/mocks/test/external.test.ts
@@ -1,7 +1,14 @@
import '../src/external/external.mjs'
import { expect, test, vi } from 'vitest'
import axios from 'axios'
import defaultFunc from '../src/external/default-function.cjs'

vi.mock('../src/external/default-function.cjs')

test('axios is mocked', () => {
expect(vi.isMockFunction(axios.get)).toBe(true)
})

test('defaultFunc is mocked', () => {
expect(vi.isMockFunction(defaultFunc)).toBe(true)
})
1 change: 1 addition & 0 deletions examples/mocks/vite.config.ts
Expand Up @@ -25,6 +25,7 @@ export default defineConfig({
environment: 'node',
deps: {
external: [/src\/external/],
interopDefault: true,
},
},
})
15 changes: 11 additions & 4 deletions packages/vite-node/src/client.ts
Expand Up @@ -424,6 +424,14 @@ export class ViteNodeRunner {

const { mod, defaultExport } = interopModule(importedModule)

const modKeys = Reflect.ownKeys(mod)
let defaultKeys = !isPrimitive(defaultExport) ? Reflect.ownKeys(defaultExport) : []
// remove reserved keys from default keys
if (typeof mod !== 'function' && typeof defaultExport === 'function') {
const reservedKeys = ['arguments', 'caller', 'prototype', 'name', 'length']
defaultKeys = defaultKeys.filter(n => typeof n === 'string' && !reservedKeys.includes(n))
}

return new Proxy(mod, {
get(mod, prop) {
if (prop === 'default')
Expand All @@ -436,11 +444,10 @@ export class ViteNodeRunner {
return prop in mod || (defaultExport && prop in defaultExport)
},
// this is needed for mocker to know what is available to mock
ownKeys(mod) {
const keys = Reflect.ownKeys(mod)
ownKeys() {
if (!defaultExport || isPrimitive(defaultExport))
return keys
const allKeys = [...keys, 'default', ...Reflect.ownKeys(defaultExport)]
return modKeys
const allKeys = [...modKeys, 'default', ...defaultKeys]
return Array.from(new Set(allKeys))
},
getOwnPropertyDescriptor(mod, prop) {
Expand Down
4 changes: 3 additions & 1 deletion packages/vitest/src/runtime/execute.ts
Expand Up @@ -73,6 +73,8 @@ export class VitestRunner extends ViteNodeRunner {
}

shouldInterop(path: string, mod: any) {
return this.options.interopDefault ?? (getCurrentEnvironment() !== 'node' && super.shouldInterop(path, mod))
if (this.options.interopDefault === false)
return false
return (this.options.interopDefault || getCurrentEnvironment() !== 'node') && super.shouldInterop(path, mod)
}
}

0 comments on commit 6b3e36d

Please sign in to comment.