diff --git a/packages/create-instance/create-instance.js b/packages/create-instance/create-instance.js
index fb7cfc292..d1bc01657 100644
--- a/packages/create-instance/create-instance.js
+++ b/packages/create-instance/create-instance.js
@@ -11,7 +11,7 @@ import createScopedSlots from './create-scoped-slots'
import { createStubsFromStubsObject } from './create-component-stubs'
import { patchCreateElement } from './patch-create-element'
-function createContext(options, scopedSlots) {
+function createContext(options, scopedSlots, currentProps) {
const on = {
...(options.context && options.context.on),
...options.listeners
@@ -21,7 +21,7 @@ function createContext(options, scopedSlots) {
...options.attrs,
// pass as attrs so that inheritAttrs works correctly
// propsData should take precedence over attrs
- ...options.propsData
+ ...currentProps
},
...(options.context || {}),
on,
@@ -98,10 +98,16 @@ export default function createInstance(
parentComponentOptions._provided = options.provide
parentComponentOptions.$_doNotStubChildren = true
parentComponentOptions._isFunctionalContainer = componentOptions.functional
+ const originalDataFn = parentComponentOptions.data
+ parentComponentOptions.data = function() {
+ const originalData = originalDataFn ? originalDataFn() : {}
+ originalData.vueTestUtils_childProps = { ...options.propsData }
+ return originalData
+ }
parentComponentOptions.render = function(h) {
return h(
Constructor,
- createContext(options, scopedSlots),
+ createContext(options, scopedSlots, this.vueTestUtils_childProps),
createChildren(this, h, options)
)
}
diff --git a/packages/test-utils/src/create-local-vue.js b/packages/test-utils/src/create-local-vue.js
index 6c81f93b4..798b221c3 100644
--- a/packages/test-utils/src/create-local-vue.js
+++ b/packages/test-utils/src/create-local-vue.js
@@ -1,6 +1,7 @@
// @flow
import Vue from 'vue'
+import config from './config'
import cloneDeep from 'lodash/cloneDeep'
function createLocalVue(_Vue: Component = Vue): Component {
@@ -22,7 +23,10 @@ function createLocalVue(_Vue: Component = Vue): Component {
}
})
- // config is not enumerable
+ // Merge in the (possibly) modified config.
+ // It needs to be done on the prototype for it to actually work throughout the runtime
+ Object.assign(Vue.config, config)
+
instance.config = cloneDeep(Vue.config)
instance.config.errorHandler = Vue.config.errorHandler
diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js
index b8beeca16..b2be36f9a 100644
--- a/packages/test-utils/src/wrapper.js
+++ b/packages/test-utils/src/wrapper.js
@@ -1,10 +1,8 @@
// @flow
-import Vue from 'vue'
import pretty from 'pretty'
import getSelector from './get-selector'
import { REF_SELECTOR, FUNCTIONAL_OPTIONS, VUE_VERSION } from 'shared/consts'
-import config from './config'
import WrapperArray from './wrapper-array'
import ErrorWrapper from './error-wrapper'
import { throwError, getCheckedEvent, isPhantomJS } from 'shared/util'
@@ -478,8 +476,6 @@ export default class Wrapper implements BaseWrapper {
* Sets vm props
*/
setProps(data: Object): void {
- const originalConfig = Vue.config.silent
- Vue.config.silent = config.silent
if (this.isFunctionalComponent) {
throwError(
`wrapper.setProps() cannot be called on a functional component`
@@ -531,10 +527,13 @@ export default class Wrapper implements BaseWrapper {
// $FlowIgnore : Need to call this twice to fix watcher bug in 2.0.x
this.vm[key] = data[key]
}
+
+ if (this.vm && this.vm.$parent) {
+ this.vm.$parent.vueTestUtils_childProps[key] = data[key]
+ }
})
// $FlowIgnore : Problem with possibly null this.vm
this.vm.$forceUpdate()
- Vue.config.silent = originalConfig
}
/**
diff --git a/test/resources/components/component-with-watch-immediate.vue b/test/resources/components/component-with-watch-immediate.vue
new file mode 100644
index 000000000..a660b9865
--- /dev/null
+++ b/test/resources/components/component-with-watch-immediate.vue
@@ -0,0 +1,22 @@
+
+
+ test
+
diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js
index 660aafabc..aaf0febb1 100644
--- a/test/specs/config.spec.js
+++ b/test/specs/config.spec.js
@@ -69,9 +69,7 @@ describeWithShallowAndMount('config', mountingMethod => {
localVue
})
expect(wrapper.vm.prop1).to.equal('example')
- wrapper.setProps({
- prop1: 'new value'
- })
+ wrapper.vm.prop1 = 'new value'
expect(console.error).not.calledWith(sandbox.match('[Vue warn]'))
})
diff --git a/test/specs/wrapper/setProps.spec.js b/test/specs/wrapper/setProps.spec.js
index de74807dd..92afc7f6a 100644
--- a/test/specs/wrapper/setProps.spec.js
+++ b/test/specs/wrapper/setProps.spec.js
@@ -1,6 +1,7 @@
import { compileToFunctions } from 'vue-template-compiler'
import ComponentWithProps from '~resources/components/component-with-props.vue'
import ComponentWithWatch from '~resources/components/component-with-watch.vue'
+import ComponentWithWatchImmediate from '~resources/components/component-with-watch-immediate.vue'
import { describeWithShallowAndMount, vueVersion } from '~resources/utils'
import { itDoNotRunIf } from 'conditional-specs'
import Vue from 'vue'
@@ -244,6 +245,14 @@ describeWithShallowAndMount('setProps', mountingMethod => {
expect(wrapper.vm.propA).to.equal('value')
})
+ it('correctly sets props in async mode when component has immediate watchers', async () => {
+ const wrapper = mountingMethod(ComponentWithWatchImmediate)
+ const prop1 = 'testest'
+ wrapper.setProps({ prop1 })
+ await Vue.nextTick()
+ expect(wrapper.vm.prop1).to.equal(prop1)
+ })
+
it('throws an error if node is not a Vue instance', () => {
const message = 'wrapper.setProps() can only be called on a Vue instance'
const compiled = compileToFunctions('