Skip to content

Commit 3508a16

Browse files
committed
fix: delete any recursive components in shallow
1 parent 9ab8d43 commit 3508a16

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

src/lib/util.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,17 @@ export function throwError (msg: string): void {
77
export function warn (msg: string): void {
88
console.error(`[vue-test-utils]: ${msg}`)
99
}
10+
11+
const camelizeRE = /-(\w)/g
12+
export const camelize = (str: string): string => str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
13+
14+
/**
15+
* Capitalize a string.
16+
*/
17+
export const capitalize = (str: string): string => str.charAt(0).toUpperCase() + str.slice(1)
18+
19+
/**
20+
* Hyphenate a camelCase string.
21+
*/
22+
const hyphenateRE = /\B([A-Z])/g
23+
export const hyphenate = (str: string): string => str.replace(hyphenateRE, '-$1').toLowerCase()

src/shallow.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,27 @@ import {
88
} from './lib/stub-components'
99
import mount from './mount'
1010
import type VueWrapper from './wrappers/vue-wrapper'
11+
import {
12+
camelize,
13+
capitalize,
14+
hyphenate
15+
} from './lib/util'
1116

1217
export default function shallow (
1318
component: Component,
1419
options: Options = {}
1520
): VueWrapper {
1621
const vue = options.localVue || Vue
22+
23+
// remove any recursive components added to the constructor
24+
// in vm._init from previous tests
25+
if (component.name && component.components) {
26+
delete component.components[capitalize(camelize(component.name))]
27+
delete component.components[hyphenate(component.name)]
28+
}
29+
1730
const stubbedComponents = createComponentStubsForAll(component)
1831
const stubbedGlobalComponents = createComponentStubsForGlobals(vue)
19-
2032
return mount(component, {
2133
...options,
2234
components: {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<template>
2+
<div>
3+
<recursive-component
4+
v-for="item in items"
5+
:key="item"
6+
:items="items ? items[0] : []"
7+
>{{something}}</recursive-component>
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
name: 'recursive-component',
14+
props: ['items'],
15+
computed: {
16+
something () {
17+
return 'value'
18+
}
19+
}
20+
}
21+
</script>

test/unit/specs/shallow.spec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ComponentWithChild from '~resources/components/component-with-child.vue'
66
import ComponentWithNestedChildren from '~resources/components/component-with-nested-children.vue'
77
import ComponentWithLifecycleHooks from '~resources/components/component-with-lifecycle-hooks.vue'
88
import ComponentWithoutName from '~resources/components/component-without-name.vue'
9+
import RecursiveComponent from '~resources/components/recursive-component.vue'
910

1011
describe('shallow', () => {
1112
let info
@@ -108,6 +109,28 @@ describe('shallow', () => {
108109
expect(wrapper.findAll(Component).length).to.equal(1)
109110
})
110111

112+
it('works correctly with find on recursive components', () => {
113+
// this is for a bug that I've been unable to replicate.
114+
// Sometimes components mutate their components, in this line—
115+
RecursiveComponent.components = {
116+
RecursiveComponent: { render: h => h('div') }
117+
}
118+
119+
expect(shallow(RecursiveComponent, {
120+
propsData: {
121+
items: ['', '']
122+
}
123+
}).findAll(RecursiveComponent).length).to.equal(2)
124+
RecursiveComponent.components = {
125+
'recursive-component': { render: h => h('div') }
126+
}
127+
expect(shallow(RecursiveComponent, {
128+
propsData: {
129+
items: ['', '']
130+
}
131+
}).findAll(RecursiveComponent).length).to.equal(2)
132+
})
133+
111134
it('throws an error when the component fails to mount', () => {
112135
expect(() => shallow({
113136
template: '<div></div>',

0 commit comments

Comments
 (0)