Skip to content

Commit 7dd4d1d

Browse files
committed
feat: Introduce enableAutoDestroy() helper function
1 parent 7c7b949 commit 7dd4d1d

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed

docs/api/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
!!!include(docs/api/createLocalVue.md)!!!
99
!!!include(docs/api/createWrapper.md)!!!
1010
!!!include(docs/api/config.md)!!!
11+
!!!include(docs/api/enableAutoDestroy.md)!!!

docs/api/enableAutoDestroy.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## enableAutoDestroy(hook)
2+
3+
- **Arguments:**
4+
5+
- `{Function} hook`
6+
7+
- **Usage:**
8+
9+
`enableAutoDestroy` allows to destroy all created `Wrapper` instances using the passed hook function (for example [`afterEach`](https://jestjs.io/docs/en/api#aftereachfn-timeout)).
10+
11+
```js
12+
import { enableAutoDestroy, mount } from '@vue/test-utils'
13+
import Foo from './Foo.vue'
14+
15+
// calls wrapper.destroy() after each test
16+
enableAutoDestroy(afterEach)
17+
18+
describe('Foo', () => {
19+
it('renders a div', () => {
20+
const wrapper = mount(Foo)
21+
expect(wrapper.contains('div')).toBe(true)
22+
// no need to call wrapper.destroy() here
23+
})
24+
})
25+
```

packages/test-utils/src/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import mount from './mount'
33
import createLocalVue from './create-local-vue'
44
import RouterLinkStub from './components/RouterLinkStub'
55
import createWrapper from './create-wrapper'
6-
import Wrapper from './wrapper'
6+
import Wrapper, { enableAutoDestroy } from './wrapper'
77
import WrapperArray from './wrapper-array'
88
import config from './config'
99
import { warn } from 'shared/util'
@@ -20,6 +20,7 @@ export default {
2020
createLocalVue,
2121
createWrapper,
2222
config,
23+
enableAutoDestroy,
2324
mount,
2425
shallow,
2526
shallowMount,

packages/test-utils/src/wrapper.js

+25
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export default class Wrapper implements BaseWrapper {
2525
isFunctionalComponent: boolean
2626
rootNode: VNode | Element
2727
selector: Selector | void
28+
static _instances: ?Array<Wrapper>
2829

2930
constructor(
3031
node: VNode | Element,
@@ -68,6 +69,10 @@ export default class Wrapper implements BaseWrapper {
6869
) {
6970
this.isFunctionalComponent = true
7071
}
72+
73+
if (Wrapper._instances) {
74+
Wrapper._instances.push(this)
75+
}
7176
}
7277

7378
at(): void {
@@ -603,3 +608,23 @@ export default class Wrapper implements BaseWrapper {
603608
this.element.dispatchEvent(event)
604609
}
605610
}
611+
612+
export const enableAutoDestroy = (hook: Function) => {
613+
if (Wrapper._instances) {
614+
throwError('enableAutoDestroy cannot be called more than once')
615+
}
616+
617+
Wrapper._instances = []
618+
619+
hook(() => {
620+
const { _instances } = Wrapper
621+
if (!_instances) {
622+
return
623+
}
624+
625+
while (_instances.length > 0) {
626+
const wrapper = _instances.pop()
627+
wrapper.destroy()
628+
}
629+
})
630+
}

test/specs/wrapper.spec.js

+38
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { describeWithShallowAndMount } from '~resources/utils'
2+
import { Wrapper, enableAutoDestroy } from '~vue/test-utils'
23

34
describeWithShallowAndMount('Wrapper', mountingMethod => {
45
;['vnode', 'element', 'vm', 'options'].forEach(property => {
@@ -15,4 +16,41 @@ describeWithShallowAndMount('Wrapper', mountingMethod => {
1516
.with.property('message', message)
1617
})
1718
})
19+
20+
describe('enableAutoDestroy', () => {
21+
const sandbox = sinon.createSandbox()
22+
23+
beforeEach(() => {
24+
Wrapper._instances = undefined
25+
})
26+
27+
it('calls the hook function', () => {
28+
const hookSpy = sandbox.spy()
29+
30+
enableAutoDestroy(hookSpy)
31+
32+
expect(hookSpy).calledOnce
33+
})
34+
35+
it('uses the hook function to destroy wrappers', () => {
36+
let hookCallback
37+
enableAutoDestroy(callback => {
38+
hookCallback = callback
39+
})
40+
const wrapper = mountingMethod({ template: '<p>con tent</p>' })
41+
sandbox.spy(wrapper, 'destroy')
42+
43+
hookCallback()
44+
45+
expect(wrapper.destroy).calledOnce
46+
})
47+
48+
it('cannot be called twice', () => {
49+
const noop = () => {}
50+
51+
enableAutoDestroy(noop)
52+
53+
expect(() => enableAutoDestroy(noop)).to.throw()
54+
})
55+
})
1856
})

0 commit comments

Comments
 (0)