Skip to content

Commit

Permalink
making automocking aware of symbol indexed methods
Browse files Browse the repository at this point in the history
  • Loading branch information
eleith committed Apr 7, 2022
1 parent e27068b commit 99a0c1f
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 15 deletions.
2 changes: 1 addition & 1 deletion examples/mocks/package.json
Expand Up @@ -14,7 +14,7 @@
"dependencies": {
"@vueuse/integrations": "^8.2.4",
"axios": "^0.26.1",
"tinyspy": "^0.3.0"
"tinyspy": "^0.3.1"
},
"devDependencies": {
"@vitest/ui": "latest",
Expand Down
12 changes: 12 additions & 0 deletions examples/mocks/src/log2.ts
@@ -0,0 +1,12 @@
const sym = Symbol('x')

const logger = {
warn() {
return this[sym]()
},
[sym]() {
return 'hello'
},
}

export default logger
17 changes: 10 additions & 7 deletions examples/mocks/test/automocking.spec.ts
@@ -1,8 +1,9 @@
import type * as exampleModule from '../src/example'

import log from '../src/log'
import log2 from '../src/log2'

vi.mock('../src/log')
vi.mock('../src/log2')

test('all mocked are valid', async() => {
const example = await vi.importMock<typeof exampleModule>('../src/example')
Expand Down Expand Up @@ -40,13 +41,15 @@ test('all mocked are valid', async() => {
expect(example.symbol).toEqual(Symbol.for('a.b.c'))
})

test('automock doesn\'t throw when unmocked', () => {
// logger uses symbols on its prototype
// we are checking here that after unmocking
// these symbols are accessible
test('automock properly restores mock', async() => {
expect(log.warn()).toBeUndefined()
expect(log2.warn()).toBeUndefined()

vi.restoreAllMocks()

expect(() => {
log.warn()
vi.restoreAllMocks()
log.warn()
}).not.toThrow()

expect(log2.warn()).toBe('hello')
})
2 changes: 1 addition & 1 deletion packages/vitest/package.json
Expand Up @@ -85,7 +85,7 @@
"chai": "^4.3.6",
"local-pkg": "^0.4.1",
"tinypool": "^0.1.2",
"tinyspy": "^0.3.0",
"tinyspy": "^0.3.1",
"vite": "^2.9.1"
},
"devDependencies": {
Expand Down
6 changes: 3 additions & 3 deletions packages/vitest/src/integrations/spy.ts
Expand Up @@ -28,13 +28,13 @@ type Procedure = (...args: any[]) => any

type Methods<T> = {
[K in keyof T]: T[K] extends Procedure ? K : never
}[keyof T] & string
}[keyof T] & (string | symbol)
type Properties<T> = {
[K in keyof T]: T[K] extends Procedure ? never : K
}[keyof T] & string
}[keyof T] & (string | symbol)
type Classes<T> = {
[K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never
}[keyof T] & string
}[keyof T] & (string | symbol)

export interface SpyInstance<TArgs extends any[] = any[], TReturns = any> {
getMockName(): string
Expand Down
10 changes: 7 additions & 3 deletions packages/vitest/src/runtime/mocker.ts
Expand Up @@ -15,15 +15,19 @@ function getType(value: unknown): string {
}

function getAllProperties(obj: any) {
const allProps = new Set<string>()
const allProps = new Set<string | symbol>()
let curr = obj
do {
// we don't need propterties from these
if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype)
break
const props = Object.getOwnPropertyNames(curr)
const symbs = Object.getOwnPropertySymbols(curr)

props.forEach(prop => allProps.add(prop))
// eslint-disable-next-line no-cond-assign
symbs.forEach(symb => allProps.add(symb))

// eslint-disable-next-line no-cond-assign
} while (curr = Object.getPrototypeOf(curr))
return Array.from(allProps)
}
Expand Down Expand Up @@ -168,7 +172,7 @@ export class VitestMocker {
else if (type !== 'Object' && type !== 'Module')
return value

const newObj: any = {}
const newObj: Record<string | symbol, any> = {}

const proproperties = getAllProperties(value)

Expand Down

0 comments on commit 99a0c1f

Please sign in to comment.