Skip to content

Commit

Permalink
fix(setprops): allowed for setProps to be synced with nextTick interv…
Browse files Browse the repository at this point in the history
…als (#1618)

* fix(setprops): allowed for setProps to be synced with nextTick intervals

setProps in certain cases was being blown away by nextTick intervals. If the property is not up to
date, setProps will be called again to sync the changes.

fix #1419

* Update packages/test-utils/src/wrapper.js

Co-authored-by: Bill Glesias <[email protected]>

Co-authored-by: Lachlan <[email protected]>
  • Loading branch information
AtofStryker and lmiller1990 authored Aug 1, 2020
1 parent cc4619e commit 9a3e6f9
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
12 changes: 11 additions & 1 deletion packages/test-utils/src/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,17 @@ export default class Wrapper implements BaseWrapper {

// $FlowIgnore : Problem with possibly null this.vm
this.vm.$forceUpdate()
return nextTick()
return new Promise(resolve => {
nextTick().then(() => {
const isUpdated = Object.keys(data).some(key => {
return (
// $FlowIgnore : Problem with possibly null this.vm
this.vm[key] === data[key] || this.vm.$attrs[key] === data[key]
)
})
return !isUpdated ? this.setProps(data).then(resolve()) : resolve()
})
})
} catch (err) {
throw err
} finally {
Expand Down
75 changes: 75 additions & 0 deletions test/specs/wrapper/setProps.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,81 @@ describeWithShallowAndMount('setProps', mountingMethod => {
await wrapper.setProps({ prop1 })
expect(wrapper.vm.prop2).to.equal(prop1)
})

it('invokes watchers with immediate set to "true"', async () => {
const callback = sinon.spy()
const TestComponent = {
template: '<div />',
props: ['propA'],
mounted() {
this.$watch(
'propA',
function() {
callback()
},
{ immediate: true }
)
}
}
const wrapper = mountingMethod(TestComponent, {
propsData: { propA: 'none' }
})

expect(callback.calledOnce)
callback.resetHistory()

await wrapper.setProps({ propA: 'value' })
expect(wrapper.props().propA).to.equal('value')
expect(callback.calledOnce)
})

it('invokes watchers with immediate set to "true" with deep objects', async () => {
const callback = sinon.spy()
const TestComponent = {
template: '<div />',
props: ['propA'],
mounted() {
this.$watch(
'propA',
function() {
callback()
},
{ immediate: true }
)
}
}
const wrapper = mountingMethod(TestComponent, {
propsData: {
propA: {
key: {
nestedKey: 'value'
},
key2: 'value2'
}
}
})

expect(callback.calledOnce)
callback.resetHistory()

await wrapper.setProps({
propA: {
key: {
nestedKey: 'newValue',
anotherNestedKey: 'value'
},
key2: 'value2'
}
})
expect(wrapper.props().propA).to.deep.equal({
key: {
nestedKey: 'newValue',
anotherNestedKey: 'value'
},
key2: 'value2'
})
expect(callback.calledOnce)
})
})

it('props and setProps should return the same reference when called with same object', () => {
Expand Down

0 comments on commit 9a3e6f9

Please sign in to comment.