Skip to content

Commit

Permalink
fix(mount): pass unknown options to $options on mount
Browse files Browse the repository at this point in the history
  • Loading branch information
xanf committed Nov 16, 2021
1 parent 4975415 commit 3d2f9b2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
42 changes: 34 additions & 8 deletions src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,34 @@ import { trackInstance } from './utils/autoUnmount'
// NOTE this should come from `vue`
type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps

const MOUNT_OPTIONS: Array<keyof MountingOptions<any>> = [
'attachTo',
'attrs',
'data',
'props',
'slots',
'global',
'shallow'
]

function getInstanceOptions(
options: MountingOptions<any> & Record<string, any>
): Record<string, any> {
const resultOptions = { ...options }
for (const key of Object.keys(options)) {
if (MOUNT_OPTIONS.includes(key as keyof MountingOptions<any>)) {
delete resultOptions[key]
}
}
return resultOptions
}
// Class component - no props
export function mount<V>(
originalComponent: {
new (...args: any[]): V
registerHooks(keys: string[]): void
},
options?: MountingOptions<any>
options?: MountingOptions<any> & Record<string, any>
): VueWrapper<ComponentPublicInstance<V>>

// Class component - props
Expand All @@ -66,13 +87,13 @@ export function mount<V, P>(
props(Props: P): any
registerHooks(keys: string[]): void
},
options?: MountingOptions<P & PublicProps>
options?: MountingOptions<P & PublicProps> & Record<string, any>
): VueWrapper<ComponentPublicInstance<V>>

// Functional component with emits
export function mount<Props, E extends EmitsOptions = {}>(
originalComponent: FunctionalComponent<Props, E>,
options?: MountingOptions<Props & PublicProps>
options?: MountingOptions<Props & PublicProps> & Record<string, any>
): VueWrapper<ComponentPublicInstance<Props>>

// Component declared with defineComponent
Expand Down Expand Up @@ -107,7 +128,8 @@ export function mount<
options?: MountingOptions<
Partial<Defaults> & Omit<Props & PublicProps, keyof Defaults>,
D
>
> &
Record<string, any>
): VueWrapper<
InstanceType<
DefineComponent<
Expand Down Expand Up @@ -153,7 +175,8 @@ export function mount<
options?: MountingOptions<Props & PublicProps, D>
): VueWrapper<
ComponentPublicInstance<Props, RawBindings, D, C, M, E, VNodeProps & Props>
>
> &
Record<string, any>

// Component declared with { props: [] }
export function mount<
Expand Down Expand Up @@ -226,25 +249,28 @@ export function mount<
// implementation
export function mount(
inputComponent: any,
options?: MountingOptions<any>
options?: MountingOptions<any> & Record<string, any>
): VueWrapper<any> {
// normalise the incoming component
let originalComponent = unwrapLegacyVueExtendComponent(inputComponent)
let component: ConcreteComponent
const instanceOptions = getInstanceOptions(options ?? {})

if (
isFunctionalComponent(originalComponent) ||
isLegacyFunctionalComponent(originalComponent)
) {
component = defineComponent({
compatConfig: { MODE: 3, COMPONENT_FUNCTIONAL: true },
setup:
(_, { attrs, slots }) =>
() =>
h(originalComponent, attrs, slots)
h(originalComponent, attrs, slots),
...instanceOptions
})
addToDoNotStubComponents(originalComponent)
} else if (isObjectComponent(originalComponent)) {
component = { ...originalComponent }
component = { ...originalComponent, ...instanceOptions }
} else {
component = originalComponent
}
Expand Down
13 changes: 13 additions & 0 deletions tests/mountingOptions/options.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineComponent } from 'vue'
import { mount } from '../../src'

describe('mounting options: other', () => {
it('passes other options as $options to component', () => {
const TestComponent = defineComponent({ template: '<div>test</div>' })
const optionContent = {}
const wrapper = mount(TestComponent, {
someUnknownOption: optionContent
})
expect(wrapper.vm.$options.someUnknownOption).toBe(optionContent)
})
})

0 comments on commit 3d2f9b2

Please sign in to comment.