Skip to content

Commit

Permalink
fix(setprops): allowed for setProps to be synced with nextTick intervals
Browse files Browse the repository at this point in the history
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
  • Loading branch information
AtofStryker committed Jul 31, 2020
1 parent ef6f166 commit fa669fa
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, reject) => {
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 fa669fa

Please sign in to comment.