From f4ea3fd1ff6802cb1fd756a72510b1a059b5f897 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Fri, 22 Mar 2019 10:42:47 -0300 Subject: [PATCH] feat(wrapper): allow destroy() method to work with functional components (#1188) --- docs/api/options.md | 3 +++ docs/api/wrapper/destroy.md | 5 +++++ packages/test-utils/src/wrapper.js | 16 +++++++++++----- test/specs/wrapper/destroy.spec.js | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/api/options.md b/docs/api/options.md index 39ac9178d..13f9f7788 100644 --- a/docs/api/options.md +++ b/docs/api/options.md @@ -206,6 +206,9 @@ expect(wrapper.vm.$route).toBeInstanceOf(Object) Component will be attached to DOM when rendered if set to `true`. +When attaching to the DOM, you should call `wrapper.destroy()` at the end of your test to +remove the rendered elements from the document and destroy the component instance. + ## attrs - type: `Object` diff --git a/docs/api/wrapper/destroy.md b/docs/api/wrapper/destroy.md index 1825ca7a0..5857c1867 100644 --- a/docs/api/wrapper/destroy.md +++ b/docs/api/wrapper/destroy.md @@ -17,3 +17,8 @@ mount({ }).destroy() expect(spy.calledOnce).toBe(true) ``` + +if `attachToDocument` was set to `true` when mounted, the component DOM elements will +also be removed from the document. + +For functional components, `destroy` only removes the rendered DOM elements from the document. diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index c2eece65f..561674b48 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -124,16 +124,22 @@ export default class Wrapper implements BaseWrapper { * Calls destroy on vm */ destroy(): void { - if (!this.isVueInstance()) { - throwError(`wrapper.destroy() can only be called on a Vue instance`) + if (!this.isVueInstance() && !this.isFunctionalComponent) { + throwError( + `wrapper.destroy() can only be called on a Vue instance or ` + + `functional component.` + ) } if (this.element.parentNode) { this.element.parentNode.removeChild(this.element) } - // $FlowIgnore - this.vm.$destroy() - throwIfInstancesThrew(this.vm) + + if (this.isVueInstance()) { + // $FlowIgnore + this.vm.$destroy() + throwIfInstancesThrew(this.vm) + } } /** diff --git a/test/specs/wrapper/destroy.spec.js b/test/specs/wrapper/destroy.spec.js index a326339db..3b698f834 100644 --- a/test/specs/wrapper/destroy.spec.js +++ b/test/specs/wrapper/destroy.spec.js @@ -40,6 +40,21 @@ describeWithShallowAndMount('destroy', mountingMethod => { expect(wrapper.vm.$el.parentNode).to.be.null }) + it('removes functional component element from document.body', () => { + const wrapper = mountingMethod( + { + functional: true, + render: h => { + return h('div', {}, []) + } + }, + { attachToDocument: true } + ) + expect(wrapper.element.parentNode).to.equal(document.body) + wrapper.destroy() + expect(wrapper.element.parentNode).to.be.null + }) + it('throws if component throws during destroy', () => { const TestComponent = { template: '
',