diff --git a/docs/api/config.md b/docs/api/config.md
index 23a83c784..03083cddb 100644
--- a/docs/api/config.md
+++ b/docs/api/config.md
@@ -89,3 +89,50 @@ import { config } from '@vue/test-utils'
config.silent = false
```
+
+### `autoDestroy`
+
+- type: `boolean | Function`
+- default: `false`
+
+This allows you to call `wrapper.destroy()` automatically—either when creating a new wrapper or by passing a hook function.
+
+Please note that setting `autoDestroy: true` only destroys existing instances when a new instance is created which result in one wrapper instance remaining.
+Therefore passing a hook function is usually a better idea.
+
+Examples:
+
+```js
+import { config, mount } from '@vue/test-utils'
+
+config.autoDestroy = true
+
+const Component = {
+ template: '
come ponente
'
+}
+
+const firstWrapper = mount(Component)
+expect(firstWrapper.text()).not.toBe('come levant')
+
+const secondWrapper = mount(Component) // this will call firstWrapper.destroy()
+expect(firstWrapper.text()).not.toBe('come sirocco')
+```
+
+```js
+import { config, mount } from '@vue/test-utils'
+
+config.autoDestroy = afterEach // will call wrapper.destroy() after each test case
+
+const Component = {
+ template: 'come ponente
'
+}
+
+describe('my component', () => {
+ it('is not East wind', () => {
+ const wrapper = mount(Component)
+ expect(wrapper.text()).not.toBe('levant')
+
+ // wrapper.destroy() is called after this
+ })
+})
+```
diff --git a/flow/config.flow.js b/flow/config.flow.js
index 3b8ca796f..f152304e2 100644
--- a/flow/config.flow.js
+++ b/flow/config.flow.js
@@ -3,5 +3,6 @@ declare type Config = {
mocks?: Object,
methods?: { [name: string]: Function },
provide?: Object,
- silent?: boolean
+ silent?: boolean,
+ autoDestroy?: boolean | Function
}
diff --git a/packages/test-utils/src/config.js b/packages/test-utils/src/config.js
index e70ea7c20..9d2a47542 100644
--- a/packages/test-utils/src/config.js
+++ b/packages/test-utils/src/config.js
@@ -3,5 +3,6 @@ export default {
mocks: {},
methods: {},
provide: {},
- silent: true
+ silent: true,
+ autoDestroy: false
}
diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js
index 60346ce9a..465e1f285 100644
--- a/packages/test-utils/src/wrapper.js
+++ b/packages/test-utils/src/wrapper.js
@@ -15,6 +15,13 @@ import { matches } from './matches'
import createDOMEvent from './create-dom-event'
import { throwIfInstancesThrew } from './error'
+const wrapperInstances = []
+
+const destroyAllInstances = () => {
+ wrapperInstances.forEach(wrapper => wrapper.destroy())
+ wrapperInstances.length = 0
+}
+
export default class Wrapper implements BaseWrapper {
+vnode: VNode | null
+vm: Component | void
@@ -67,6 +74,17 @@ export default class Wrapper implements BaseWrapper {
) {
this.isFunctionalComponent = true
}
+
+ const { autoDestroy } = config
+ if (autoDestroy) {
+ if (autoDestroy instanceof Function) {
+ autoDestroy(destroyAllInstances)
+ } else {
+ destroyAllInstances()
+ }
+
+ wrapperInstances.push(this)
+ }
}
at(): void {
diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js
index dc078413d..c0f8201e9 100644
--- a/test/specs/config.spec.js
+++ b/test/specs/config.spec.js
@@ -1,4 +1,5 @@
import { describeWithShallowAndMount } from '~resources/utils'
+import Component from '~resources/components/component.vue'
import ComponentWithProps from '~resources/components/component-with-props.vue'
import { itDoNotRunIf } from 'conditional-specs'
import { config, createLocalVue } from '~vue/test-utils'
@@ -109,4 +110,44 @@ describeWithShallowAndMount('config', mountingMethod => {
})
expect(console.error).calledWith(sandbox.match('[Vue warn]'))
})
+
+ describe('autoDestroy', () => {
+ it('does not destroy wrapper when autoDestroy is set to false', () => {
+ config.autoDestroy = false
+ const localVue = createLocalVue()
+ const wrapper = mountingMethod(Component, { localVue })
+ sandbox.spy(wrapper, 'destroy')
+
+ mountingMethod(Component, { localVue })
+
+ expect(wrapper.destroy).not.called
+ })
+
+ it('destroys wrapper when autoDestroy is set to true', () => {
+ config.autoDestroy = true
+ const localVue = createLocalVue()
+ const wrapper = mountingMethod(Component, { localVue })
+ sandbox.spy(wrapper, 'destroy')
+
+ mountingMethod(Component, { localVue })
+
+ expect(wrapper.destroy).called
+ })
+
+ it('destroys wrapper when autoDestroy hook is called', () => {
+ let destroyCallback
+ config.autoDestroy = callback => {
+ destroyCallback = callback
+ }
+ const localVue = createLocalVue()
+ const wrapper = mountingMethod(Component, { localVue })
+ sandbox.spy(wrapper, 'destroy')
+
+ mountingMethod(Component, { localVue })
+
+ expect(wrapper.destroy).not.called
+ destroyCallback()
+ expect(wrapper.destroy).called
+ })
+ })
})