Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: opt-out of stubbing by passing false as stub #702

Merged
merged 1 commit into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions docs/guide/advanced/stubs-shallow-mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,45 @@ test('shallow stubs out all child components', () => {
If you used VTU V1, you may remember this as `shallowMount`. That method is still available, too - it's the same as writing `shallow: true`.
:::

## Stubbing all children components with exceptions

Sometimes you want to stub out _all_ the custom components, _except_ specific one. Let's consider an example:

```js
const ComplexA = {
template: '<h2>Hello from real component!</h2>'
}

const ComplexComponent = {
components: { ComplexA, ComplexB, ComplexC },
template: `
<h1>Welcome to Vue.js 3</h1>
<ComplexA />
<ComplexB />
<ComplexC />
`
}
```

By using `shallow` mounting option that will automatically stub out all the child components. If we want to explicitly opt-out of stubbing specific component, we could provide its name in `stubs` with value set to `false`

```js {3}
test('shallow allows opt-out of stubbing specific component', () => {
const wrapper = mount(ComplexComponent, {
shallow: true,
stubs: { ComplexA: false }
})

console.log(wrapper.html())
/*
<h1>Welcome to Vue.js 3</h1>
<h2>Hello from real component!</h2>
<complex-b-stub></complex-b-stub>
<complex-c-stub></complex-c-stub>
*/
})
```

## Stubbing an async component

In case you want to stub out an async component, then there are two behaviours. For example, you might have components like this:
Expand Down
5 changes: 5 additions & 0 deletions src/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ export function stubComponents(
return [stubs[name], props, children, patchFlag, dynamicProps]
}

if (stub === false) {
// we explicitly opt out of stubbing this component
return args
}

// we return a stub by matching Vue's `h` function
// where the signature is h(Component, props, slots)
// case 1: default stub
Expand Down
22 changes: 22 additions & 0 deletions tests/shallowMount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ describe('shallowMount', () => {
)
})

it('stubs all components, but allows disabling stub by passing false', () => {
const wrapper = mount(ComponentWithChildren, {
shallow: true,
global: {
stubs: {
Hello: false
}
}
})
expect(wrapper.html()).toEqual(
'<div class="ComponentWithChildren">\n' +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can use the inlineSnapshot feature from Jest here? Or do you think the string assertion is easier to read?

Thanks for all these PRs - let's do a release as soon as they are all merged up.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to keep this as it is for now - just for consistency with style of other tests here. We could probably address it in separate clean-up MR

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit offtopic, regarding release. I believe I have some more (~5-10 MR coming) somewhere in next two days. I'm working (for fun) on building a prototype migration of gitlab-ui to Vue3 using compat build and it is surprisingly satisfying.

With new plugin system in play I was able to mimic a huge precent of old VTU v1 behavior in pretty clean manner (for now we would like to have tests which run on both versions of VTU and)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, happy to keep this as-is.

If you have 5-10 more PRs coming, we can wait until they are all merged up before doing a release.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmiller1990 Sure, I'll drop a comment in "last PR" for letting you know. thank you for acting super-fast

' <div id="root">\n' +
' <div id="msg">Hello world</div>\n' +
' </div>\n' +
' <component-with-input-stub></component-with-input-stub>\n' +
' <component-without-name-stub></component-without-name-stub>\n' +
' <script-setup-stub></script-setup-stub>\n' +
' <with-props-stub></with-props-stub>\n' +
'</div>'
)
})

it('stubs all components in a script setup component', () => {
const wrapper = mount(ScriptSetupWithChildren, {
shallow: true,
Expand Down