From d96d5bb8e12801312369bef17c0a9a973bfddf7c Mon Sep 17 00:00:00 2001 From: Illya Klymov Date: Mon, 10 Oct 2022 00:12:34 +0300 Subject: [PATCH] feat(stubs): Allow to stub directives * this adds stubbing directives functionality to @vue/test-utils --- docs/guide/advanced/stubs-shallow-mount.md | 76 ++++++++++++- src/mount.ts | 17 ++- src/stubs.ts | 32 ++++++ src/types.ts | 2 +- src/utils.ts | 46 +++++++- src/utils/find.ts | 15 +-- .../stubComponentsTransformer.ts | 60 +++------- .../stubDirectivesTransformer.ts | 46 ++++++++ src/vnodeTransformers/util.ts | 14 ++- tests/findComponent.spec.ts | 20 ++++ tests/mountingOptions/global.stubs.spec.ts | 104 +++++++++++++++++- 11 files changed, 367 insertions(+), 65 deletions(-) create mode 100644 src/stubs.ts create mode 100644 src/vnodeTransformers/stubDirectivesTransformer.ts diff --git a/docs/guide/advanced/stubs-shallow-mount.md b/docs/guide/advanced/stubs-shallow-mount.md index dc43fe98c..d0aef7d3d 100644 --- a/docs/guide/advanced/stubs-shallow-mount.md +++ b/docs/guide/advanced/stubs-shallow-mount.md @@ -1,6 +1,6 @@ # Stubs and Shallow Mount -Vue Test Utils provides some advanced features for _stubbing_ components. A _stub_ is where you replace an existing implementation of a custom component with a dummy component that doesn't do anything at all, which can simplify an otherwise complex test. Let's see an example. +Vue Test Utils provides some advanced features for _stubbing_ components and directives. A _stub_ is where you replace an existing implementation of a custom component or directive with a dummy one that doesn't do anything at all, which can simplify an otherwise complex test. Let's see an example. ## Stubbing a single child component @@ -238,6 +238,78 @@ test('stubs async component with resolving', async () => { }) ``` +## Stubbing a directive + +Sometimes directives do quite complex things, like perform a lot of DOM manipulation which might result in errors in your tests (due to JSDOM not resembling entire DOM behavior). A common example is tooltip directives from various libraries, which usually rely heavily on measuring DOM nodes position/sizes. + +In this example, we have another `` that renders a message with tooltip + +```js +// tooltip directive declared somewhere, named `Tooltip` + +const App = { + directives: { + Tooltip + }, + template: '

Welcome to Vue.js 3

' +} +``` + +We do not want `Tooltip` directive code to be executed in this test, we just want to assert the message is rendered. In this case, we could use the `stubs`, which appears in the `global` mounting option passing `vTooltip`. + +```js +test('stubs component with custom template', () => { + const wrapper = mount(App, { + global: { + stubs: { + vTooltip: true + } + } + }) + + console.log(wrapper.html()) + //

Welcome to Vue.js 3

+ + expect(wrapper.html()).toContain('Welcome to Vue.js 3') +}) +``` + +::: tip +Usage of `vCustomDirective` naming scheme to differentiate between components and directives is inspired by [same approach](https://vuejs.org/api/sfc-script-setup.html#using-custom-directives) used in `