Skip to content

Commit 85a972c

Browse files
authoredFeb 3, 2019
feat: stop auto stubbing transition and transition-group (#1127)
1 parent b3ad782 commit 85a972c

File tree

11 files changed

+117
-58
lines changed

11 files changed

+117
-58
lines changed
 

‎flow/options.flow.js

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ declare type Options = {
1818
shouldProxy?: boolean
1919
}
2020

21+
declare type NormalizedOptions = {
22+
attachToDocument?: boolean,
23+
propsData?: Object,
24+
mocks: Object,
25+
methods: { [key: string]: Function },
26+
slots?: SlotsObject,
27+
scopedSlots?: { [key: string]: string | Function },
28+
localVue?: Component,
29+
provide?: Object | Function,
30+
stubs: { [name: string]: Component | true | string } | boolean,
31+
context?: Object,
32+
attrs?: { [key: string]: string },
33+
listeners?: { [key: string]: Function | Array<Function> },
34+
parentComponent?: Object,
35+
logModifiedComponents?: boolean,
36+
sync: boolean,
37+
shouldProxy?: boolean
38+
}
39+
2140
declare type SlotValue = Component | string | Array<Component | string>
2241

2342
declare type SlotsObject = { [name: string]: SlotValue }

‎package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@
6868
"sinon-chai": "^2.10.0",
6969
"typescript": "^3.0.1",
7070
"vee-validate": "^2.1.3",
71-
"vue": "2.5.21",
71+
"vue": "^2.5.22",
7272
"vue-class-component": "^6.1.2",
7373
"vue-loader": "^13.6.2",
7474
"vue-router": "^3.0.1",
75-
"vue-server-renderer": "2.5.21",
76-
"vue-template-compiler": "2.5.21",
75+
"vue-server-renderer": "^2.5.22",
76+
"vue-template-compiler": "^2.5.22",
7777
"vuepress": "^0.14.2",
7878
"vuepress-theme-vue": "^1.0.3",
7979
"vuex": "^3.0.1",

‎packages/create-instance/create-instance.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function createChildren(vm, h, { slots, context }) {
4141

4242
export default function createInstance(
4343
component: Component,
44-
options: Options,
44+
options: NormalizedOptions,
4545
_Vue: Component
4646
): Component {
4747
const componentOptions = isConstructor(component)

‎packages/shared/merge-options.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,27 @@ function getOption(option, config?: Object): any {
1919
}
2020
}
2121

22-
export function mergeOptions(options: Options, config: Config): Options {
22+
function getStubs(stubs, configStubs): Object {
23+
const normalizedStubs = normalizeStubs(stubs)
24+
const normalizedConfigStubs = normalizeStubs(configStubs)
25+
return getOption(normalizedStubs, normalizedConfigStubs)
26+
}
27+
28+
export function mergeOptions(
29+
options: Options,
30+
config: Config
31+
): NormalizedOptions {
2332
const mocks = (getOption(options.mocks, config.mocks): Object)
2433
const methods = (getOption(options.methods, config.methods): {
2534
[key: string]: Function
2635
})
2736
const provide = (getOption(options.provide, config.provide): Object)
37+
const stubs = (getStubs(options.stubs, config.stubs): Object)
38+
// $FlowIgnore
2839
return {
2940
...options,
3041
provide: normalizeProvide(provide),
31-
stubs: getOption(normalizeStubs(options.stubs), config.stubs),
42+
stubs,
3243
mocks,
3344
methods,
3445
sync: !!(options.sync || options.sync === undefined)

‎packages/test-utils/src/config.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
import TransitionStub from './components/TransitionStub'
2-
import TransitionGroupStub from './components/TransitionGroupStub'
3-
41
export default {
5-
stubs: {
6-
transition: TransitionStub,
7-
'transition-group': TransitionGroupStub
8-
},
2+
stubs: {},
93
mocks: {},
104
methods: {},
115
provide: {},

‎packages/test-utils/src/mount.js

+31-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
// @flow
2-
31
import Vue from 'vue'
4-
import VueWrapper from './vue-wrapper'
52
import createInstance from 'create-instance'
63
import createElement from './create-element'
74
import { throwIfInstancesThrew, addGlobalErrorHandler } from './error'
@@ -14,6 +11,8 @@ import { warn } from 'shared/util'
1411
import semver from 'semver'
1512
import { COMPAT_SYNC_MODE } from 'shared/consts'
1613
import { validateOptions } from 'shared/validate-options'
14+
import TransitionGroupStub from './components/TransitionGroupStub'
15+
import TransitionStub from './components/TransitionStub'
1716

1817
Vue.config.productionTip = false
1918
Vue.config.devtools = false
@@ -45,20 +44,45 @@ function getSyncOption(syncOption) {
4544
return true
4645
}
4746

48-
export default function mount(
49-
component: Component,
50-
options: Options = {}
51-
): VueWrapper | Wrapper {
47+
function addTransitionStubs(options) {
48+
if (config.stubs === false) {
49+
return
50+
}
51+
if (
52+
options.stubs &&
53+
options.stubs.transition !== false &&
54+
!options.stubs.transition
55+
) {
56+
options.stubs.transition = TransitionStub
57+
}
58+
if (
59+
options.stubs &&
60+
options.stubs['transition-group'] !== false &&
61+
!options.stubs['transition-group']
62+
) {
63+
options.stubs['transition-group'] = TransitionGroupStub
64+
}
65+
}
66+
67+
export default function mount(component, options = {}) {
5268
warnIfNoWindow()
5369

5470
addGlobalErrorHandler(Vue)
5571

5672
const _Vue = createLocalVue(options.localVue)
5773

5874
const mergedOptions = mergeOptions(options, config)
75+
const sync = getSyncOption(mergedOptions.sync)
5976

6077
validateOptions(mergedOptions, component)
6178

79+
// Stub transition and transition-group if in compat sync mode to keep old
80+
// behavior
81+
// TODO: Remove when compat sync mode is removed
82+
if (sync === COMPAT_SYNC_MODE) {
83+
addTransitionStubs(mergedOptions)
84+
}
85+
6286
const parentVm = createInstance(component, mergedOptions, _Vue)
6387

6488
const el = options.attachToDocument ? createElement() : undefined
@@ -67,7 +91,6 @@ export default function mount(
6791
component._Ctor = {}
6892

6993
throwIfInstancesThrew(vm)
70-
const sync = getSyncOption(mergedOptions.sync)
7194

7295
const wrapperOptions = {
7396
attachedToDocument: !!mergedOptions.attachToDocument,

‎test/resources/components/component-with-transition-group.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<transition-group>
3-
<div>{{ a }}</div>
4-
<div></div>
3+
<div key="123">{{ a }}</div>
4+
<div key="124"></div>
55
</transition-group>
66
</template>
77

‎test/specs/components/TransitionGroupStub.spec.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ComponentWithTransitionGroup from '~resources/components/component-with-transition-group.vue'
22
import { TransitionGroupStub } from '~vue/test-utils'
3-
import { describeWithShallowAndMount } from '~resources/utils'
3+
import { describeWithShallowAndMount, vueVersion } from '~resources/utils'
4+
import { itDoNotRunIf } from 'conditional-specs'
45

56
describeWithShallowAndMount('TransitionGroupStub', mountingMethod => {
67
it('update synchronously when used as stubs for Transition', () => {
@@ -14,6 +15,18 @@ describeWithShallowAndMount('TransitionGroupStub', mountingMethod => {
1415
expect(wrapper.text()).contains('b')
1516
})
1617

18+
itDoNotRunIf(
19+
vueVersion < 2.5,
20+
'does not stub TransitionGroup, but applies synchronously in Vue > 2.5.18',
21+
() => {
22+
const wrapper = mountingMethod(ComponentWithTransitionGroup)
23+
expect(wrapper.find(TransitionGroupStub).exists()).to.equal(false)
24+
expect(wrapper.text()).contains('a')
25+
wrapper.setData({ a: 'b' })
26+
expect(wrapper.text()).contains('b')
27+
}
28+
)
29+
1730
it('updates watchers', () => {
1831
const TestComponent = {
1932
data: () => ({

‎test/specs/components/TransitionStub.spec.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ComponentWithTransition from '~resources/components/component-with-transition.vue'
2-
import { describeWithShallowAndMount } from '~resources/utils'
2+
import { describeWithShallowAndMount, vueVersion } from '~resources/utils'
33
import { TransitionStub } from '~vue/test-utils'
4+
import { itDoNotRunIf } from 'conditional-specs'
45

56
describeWithShallowAndMount('TransitionStub', mountingMethod => {
67
let consoleError
@@ -24,6 +25,18 @@ describeWithShallowAndMount('TransitionStub', mountingMethod => {
2425
expect(wrapper.text()).contains('b')
2526
})
2627

28+
itDoNotRunIf(
29+
vueVersion < 2.5,
30+
'does not stub Transition, but applies synchronously in Vue > 2.5.18',
31+
() => {
32+
const wrapper = mountingMethod(ComponentWithTransition)
33+
expect(wrapper.find(TransitionStub).exists()).to.equal(false)
34+
expect(wrapper.text()).contains('a')
35+
wrapper.setData({ a: 'b' })
36+
expect(wrapper.text()).contains('b')
37+
}
38+
)
39+
2740
it('does not add v-leave class to children', () => {
2841
const TestComponent = {
2942
template: `

‎test/specs/config.spec.js

-14
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,6 @@ describeWithShallowAndMount('config', mountingMethod => {
122122
expect(wrapper.contains(TransitionStub)).to.equal(false)
123123
})
124124

125-
it("doesn't stub transition when config.stubs is set to a string", () => {
126-
config.stubs = 'a string'
127-
const testComponent = {
128-
template: `
129-
<div>
130-
<transition-group><p /><p /></transition-group>
131-
</div>
132-
`
133-
}
134-
const wrapper = mountingMethod(testComponent)
135-
expect(wrapper.contains(TransitionGroupStub)).to.equal(false)
136-
expect(wrapper.contains(TransitionStub)).to.equal(false)
137-
})
138-
139125
it("doesn't throw Vue warning when silent is set to true", () => {
140126
config.silent = true
141127
const localVue = createLocalVue()

‎yarn.lock

+19-19
Original file line numberDiff line numberDiff line change
@@ -9823,10 +9823,9 @@ vue-router@^3.0.1:
98239823
version "3.0.1"
98249824
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.1.tgz#d9b05ad9c7420ba0f626d6500d693e60092cc1e9"
98259825

9826-
vue-server-renderer@2.5.21:
9827-
version "2.5.21"
9828-
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.21.tgz#7c2b611d2e8558359cdb84dcd3080845c07121b4"
9829-
integrity sha512-bAkOYZ5DnmQKv3RboNbmCB4LReF2tIE20EgUeWrz/87aVkpMihf3FVK+8DT45nyN4k9iSQOhsyem49fq++cF8w==
9826+
vue-server-renderer@^2.5.16:
9827+
version "2.5.16"
9828+
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.16.tgz#279ef8e37e502a0de3a9ae30758cc04a472eaac0"
98309829
dependencies:
98319830
chalk "^1.1.3"
98329831
hash-sum "^1.0.2"
@@ -9837,9 +9836,10 @@ vue-server-renderer@2.5.21:
98379836
serialize-javascript "^1.3.0"
98389837
source-map "0.5.6"
98399838

9840-
vue-server-renderer@^2.5.16:
9841-
version "2.5.16"
9842-
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.16.tgz#279ef8e37e502a0de3a9ae30758cc04a472eaac0"
9839+
vue-server-renderer@^2.5.22:
9840+
version "2.5.22"
9841+
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.22.tgz#f119efef289c865adc22fda0ae7595299bedbdcf"
9842+
integrity sha512-PQ0PubA6b2MyZud/gepWeiUuDFSbRfa6h1qYINcbwXRr4Z3yLTHprEQuFnWikdkTkZpeLFYUqZrDxPbDcJ71mA==
98439843
dependencies:
98449844
chalk "^1.1.3"
98459845
hash-sum "^1.0.2"
@@ -9864,17 +9864,17 @@ vue-style-loader@^4.1.0:
98649864
hash-sum "^1.0.2"
98659865
loader-utils "^1.0.2"
98669866

9867-
vue-template-compiler@2.5.21:
9868-
version "2.5.21"
9869-
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a"
9870-
integrity sha512-Vmk5Cv7UcmI99B9nXJEkaK262IQNnHp5rJYo+EwYpe2epTAXqcVyExhV6pk8jTkxQK2vRc8v8KmZBAwdmUZvvw==
9867+
vue-template-compiler@^2.5.16:
9868+
version "2.5.16"
9869+
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb"
98719870
dependencies:
98729871
de-indent "^1.0.2"
98739872
he "^1.1.0"
98749873

9875-
vue-template-compiler@^2.5.16:
9876-
version "2.5.16"
9877-
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb"
9874+
vue-template-compiler@^2.5.22:
9875+
version "2.5.22"
9876+
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.22.tgz#c3d3c02c65f1908205c4fbd3b0ef579e51239955"
9877+
integrity sha512-1VTw/NPTUeHNiwhkq6NkFzO7gYLjFCueBN0FX8NEiQIemd5EUMQ5hxrF7O0zCPo5tae+U9S/scETPea+hIz8Eg==
98789878
dependencies:
98799879
de-indent "^1.0.2"
98809880
he "^1.1.0"
@@ -9883,15 +9883,15 @@ vue-template-es2015-compiler@^1.6.0:
98839883
version "1.6.0"
98849884
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
98859885

9886-
vue@2.5.21:
9887-
version "2.5.21"
9888-
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
9889-
integrity sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ==
9890-
98919886
vue@^2.5.16:
98929887
version "2.5.16"
98939888
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
98949889

9890+
vue@^2.5.22:
9891+
version "2.5.22"
9892+
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.22.tgz#3bf88041af08b8539c37b268b70ca79245e9cc30"
9893+
integrity sha512-pxY3ZHlXNJMFQbkjEgGVMaMMkSV1ONpz+4qB55kZuJzyJOhn6MSy/YZdzhdnumegNzVTL/Dn3Pp4UrVBYt1j/g==
9894+
98959895
vuepress-html-webpack-plugin@^3.2.0:
98969896
version "3.2.0"
98979897
resolved "https://registry.yarnpkg.com/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz#219be272ad510faa8750d2d4e70fd028bfd1c16e"

0 commit comments

Comments
 (0)
Please sign in to comment.