Skip to content

Commit

Permalink
fix: vm should be the vm of the tested component
Browse files Browse the repository at this point in the history
It currently returns the vm of the parent element.
With this commit, it now returns the vm of the tested element.
The types have also been tweaked to avoid the need of casting like `(wrapper.vm as any).msg`.
  • Loading branch information
cexbrayat committed Apr 13, 2020
1 parent 7210864 commit a5f6e9b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
15 changes: 11 additions & 4 deletions src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
Plugin,
Directive,
Component,
reactive
reactive,
ComponentPublicInstance
} from 'vue'

import { createWrapper } from './vue-wrapper'
Expand Down Expand Up @@ -37,7 +38,10 @@ interface MountingOptions {
stubs?: Record<string, any>
}

export function mount(originalComponent: any, options?: MountingOptions) {
export function mount<T extends ComponentPublicInstance>(
originalComponent: new () => T,
options?: MountingOptions
) {
const component = { ...originalComponent }

// Reset the document.body
Expand All @@ -63,7 +67,10 @@ export function mount(originalComponent: any, options?: MountingOptions) {
// override component data with mounting options data
if (options?.data) {
const dataMixin = createDataMixin(options.data())
component.mixins = [...(component.mixins || []), dataMixin]
;(component as any).mixins = [
...((component as any).mixins || []),
dataMixin
]
}

// we define props as reactive so that way when we update them with `setProps`
Expand Down Expand Up @@ -136,5 +143,5 @@ export function mount(originalComponent: any, options?: MountingOptions) {
// mount the app!
const app = vm.mount(el)

return createWrapper(app, events, setProps)
return createWrapper<T>(app, events, setProps)
}
17 changes: 9 additions & 8 deletions src/vue-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { WrapperAPI } from './types'
import { ErrorWrapper } from './error-wrapper'
import { MOUNT_ELEMENT_ID } from './constants'

export class VueWrapper implements WrapperAPI {
private componentVM: ComponentPublicInstance
export class VueWrapper<T extends ComponentPublicInstance>
implements WrapperAPI {
private componentVM: T
private __emitted: Record<string, unknown[]> = {}
private __vm: ComponentPublicInstance
private __setProps: (props: Record<string, any>) => void
Expand All @@ -19,7 +20,7 @@ export class VueWrapper implements WrapperAPI {
) {
this.__vm = vm
this.__setProps = setProps
this.componentVM = this.vm.$refs['VTU_COMPONENT'] as ComponentPublicInstance
this.componentVM = this.__vm.$refs['VTU_COMPONENT'] as T
this.__emitted = events
}

Expand All @@ -41,8 +42,8 @@ export class VueWrapper implements WrapperAPI {
return this.hasMultipleRoots ? this.parentElement : this.componentVM.$el
}

get vm(): ComponentPublicInstance {
return this.__vm
get vm(): T {
return this.componentVM
}

classes(className?: string) {
Expand Down Expand Up @@ -104,10 +105,10 @@ export class VueWrapper implements WrapperAPI {
}
}

export function createWrapper(
export function createWrapper<T extends ComponentPublicInstance>(
vm: ComponentPublicInstance,
events: Record<string, unknown[]>,
setProps: (props: Record<string, any>) => void
): VueWrapper {
return new VueWrapper(vm, events, setProps)
): VueWrapper<T> {
return new VueWrapper<T>(vm, events, setProps)
}
26 changes: 26 additions & 0 deletions tests/vm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineComponent, ref } from 'vue'

import { mount } from '../src'

describe('vm', () => {
it('returns the component vm', () => {
const Component = defineComponent({
template: '<div>{{ msg }}</div>',
setup() {
const msg = 'hello'
const isEnabled = ref(true)
const toggle = () => (isEnabled.value = !isEnabled.value)
return { msg, isEnabled, toggle }
}
})

const wrapper = mount(Component)

expect(wrapper.vm.msg).toBe('hello')
expect(wrapper.vm.isEnabled).toBe(true)

wrapper.vm.toggle()

expect(wrapper.vm.isEnabled).toBe(false)
})
})

0 comments on commit a5f6e9b

Please sign in to comment.