Skip to content

wip: shallow #21

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

Closed
wants to merge 3 commits into from
Closed
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
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,9 @@
"*.ts": [
"prettier --parser=typescript --write"
]
},
"dependencies": {
"@types/lodash": "^4.14.149",
"lodash": "^4.17.15"
}
}
33 changes: 33 additions & 0 deletions src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import {
createApp,
VNode,
defineComponent,
transformVNodeArgs,
VNodeNormalizedChildren,
VNodeProps,
ComponentOptions,
Plugin,
Directive,
Component
} from 'vue'
import { isEqual, kebabCase } from 'lodash'

import { VueWrapper, createWrapper } from './vue-wrapper'
import { createEmitMixin } from './emitMixin'
Expand All @@ -20,6 +22,7 @@ type Slot = VNode | string

interface MountingOptions<Props> {
data?: () => Record<string, unknown>
shallow?: boolean
props?: Props
slots?: {
default?: Slot
Expand Down Expand Up @@ -61,8 +64,10 @@ export function mount<P>(
}

// create the wrapper component
const PARENT_NAME = 'VTU_PARENT'
const Parent = (props?: VNodeProps) =>
defineComponent({
name: PARENT_NAME,
render() {
return h(component, { ...props, ref: 'VTU_COMPONENT' }, slots)
}
Expand Down Expand Up @@ -99,6 +104,34 @@ export function mount<P>(
}
}

if (options?.shallow) {
transformVNodeArgs((args, instance) => {
// VTU Root node. Keep this or there won't be anything to render!
if (typeof args[0] === 'object' && args[0]['name'] === PARENT_NAME) {
return args
}

// original component we are mounting - don't stub that!
if (isEqual(args[0], originalComponent)) {
return args
}

// regular HTML tags
if (typeof args[0] === 'string') {
return args
}

// don't care about comments/fragments
if (typeof args[0] === 'symbol') {
return args
}

// must be a custom component. Stub!
const name = kebabCase(args[0]['name'] || 'anonymous')
return [`${name}-stub`]
Copy link
Member

Choose a reason for hiding this comment

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

I love how clean getting a stubbed version of the component looks like. It might get dirtier at some point, but this is a great starting point 👌

})
}

// add tracking for emitted events
const { emitMixin, events } = createEmitMixin()
vm.mixin(emitMixin)
Expand Down
49 changes: 49 additions & 0 deletions tests/mountingOptions/shallow.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { h } from 'vue'

import { mount } from '../../src'

describe('mounting options: shallow', () => {
it('stubs everything with a single root node', async () => {
Copy link
Member

@afontcu afontcu Apr 1, 2020

Choose a reason for hiding this comment

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

Suggested change
it('stubs everything with a single root node', async () => {
it('stubs child components when rendering a single root node', () => {

const Bar = {
name: 'Bar',
render() {
return h('div', { id: 'bar' }, 'Bar')
}
}
const Foo = {
name: 'Foo',
render() {
return h('div', [h('p', 'hello'), h(Bar)])
}
}

const wrapper = mount(Foo, {
shallow: true
})

expect(wrapper.html()).toBe('<div><p>hello</p><bar-stub></bar-stub></div>')
expect(wrapper.find('bar-stub').exists()).toBeTruthy()
})

it('stubs everything with a single root node', async () => {
Copy link
Member

@afontcu afontcu Apr 1, 2020

Choose a reason for hiding this comment

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

Suggested change
it('stubs everything with a single root node', async () => {
it('stubs child components when rendering several root nodes', () => {

const Bar = {
name: 'Bar',
render() {
return h('div', { id: 'bar' }, 'Bar')
}
}
const Foo = {
name: 'Foo',
render() {
return [h(Bar), h(Bar)]
}
}

const wrapper = mount(Foo, {
shallow: true
})

expect(wrapper.html()).toBe('<bar-stub></bar-stub><bar-stub></bar-stub>')
expect(wrapper.find('bar-stub').exists()).toBeTruthy()
})
})
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,11 @@
dependencies:
jest-diff "^24.3.0"

"@types/lodash@^4.14.149":
version "4.14.149"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440"
integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==

"@types/node@*":
version "13.7.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.4.tgz#76c3cb3a12909510f52e5dc04a6298cdf9504ffd"
Expand Down