Skip to content

Commit

Permalink
fix: order watchers after trigger (#510)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyerburgh committed Apr 2, 2018
1 parent 21fe83d commit 8fee45a
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
33 changes: 33 additions & 0 deletions packages/test-utils/src/order-watchers.js
@@ -0,0 +1,33 @@
let i = 0

function orderDeps (watcher) {
watcher.deps.forEach(dep => {
if (dep._sortedId === i) {
return
}
dep._sortedId = i
dep.subs.forEach(orderDeps)
dep.subs = dep.subs.sort((a, b) => a.id - b.id)
})
}

function orderVmWatchers (vm) {
if (vm._watchers) {
vm._watchers.forEach(orderDeps)
}

if (vm._computedWatchers) {
Object.keys(vm._computedWatchers).forEach((computedWatcher) => {
orderDeps(vm._computedWatchers[computedWatcher])
})
}

orderDeps(vm._watcher)

vm.$children.forEach(orderVmWatchers)
}

export function orderWatchers (vm) {
orderVmWatchers(vm)
i++
}
1 change: 0 additions & 1 deletion packages/test-utils/src/set-watchers-to-sync.js
@@ -1,5 +1,4 @@
function setDepsSync (dep) {
dep.subs = dep.subs.sort((a, b) => a.id - b.id)
dep.subs.forEach(setWatcherSync)
}

Expand Down
2 changes: 2 additions & 0 deletions packages/test-utils/src/vue-wrapper.js
Expand Up @@ -2,6 +2,7 @@

import Wrapper from './wrapper'
import { setWatchersToSync } from './set-watchers-to-sync'
import { orderWatchers } from './order-watchers'

export default class VueWrapper extends Wrapper implements BaseWrapper {
constructor (vm: Component, options: WrapperOptions) {
Expand All @@ -20,6 +21,7 @@ export default class VueWrapper extends Wrapper implements BaseWrapper {
this.vm = vm
if (options.sync) {
setWatchersToSync(vm)
orderWatchers(vm)
}
this.isVueComponent = true
this.isFunctionalComponent = vm.$options._isFunctionalContainer
Expand Down
6 changes: 6 additions & 0 deletions packages/test-utils/src/wrapper.js
Expand Up @@ -21,6 +21,9 @@ import {
} from 'shared/util'
import findAll from './find'
import createWrapper from './create-wrapper'
import {
orderWatchers
} from './order-watchers'

export default class Wrapper implements BaseWrapper {
vnode: VNode | null;
Expand Down Expand Up @@ -621,6 +624,9 @@ export default class Wrapper implements BaseWrapper {
}

this.element.dispatchEvent(eventObject)
if (this.vnode) {
orderWatchers(this.vm || this.vnode.context.$root)
}
}

update () {
Expand Down
57 changes: 57 additions & 0 deletions test/specs/mounting-options/snyc.spec.js
Expand Up @@ -31,6 +31,63 @@ describeWithShallowAndMount('options.sync', (mountingMethod) => {
expect(wrapper.text()).to.equal('world')
})

it('handles methods that update watchers', () => {
const TestComponent = {
template: `
<div id="app">
<div v-if="open">
<div>
<pre>data.text: <em>{{ text }}</em></pre>
</div>
<!-- Tests fail in 1.0.0-beta.13 with .fails portion of the code -->
<div class="fails">
<pre>computed.text: <em>{{ computedText }}</em></pre>
</div>
</div>
</div>
`,
data () {
return {
open: false,
text: '',
basket: []
}
},
computed: {
computedText () {
return this.text
}
},
created () {
window.addEventListener('click', this.clickHandler)
},
destroyed () {
window.removeEventListener('click', this.clickHandler)
},
watch: {
text () {
this.basket.push(this.computedText)
}
},
methods: {
clickHandler () {
this.open = !this.open
}
}
}

const wrapper = mountingMethod(TestComponent, {
attachToDocument: true
})
wrapper.trigger('click')
expect(wrapper.vm.text).to.equal('')
expect(wrapper.vm.basket.length).to.equal(0)
wrapper.setData({ text: 'foo' })
expect(wrapper.vm.text).to.equal('foo')
expect(wrapper.vm.computedText).to.equal('foo')
expect(wrapper.vm.basket[0]).to.equal('foo')
})

it('does not set watchers to sync if set to false', (done) => {
const TestComponent = {
template: '<div>{{someData}}</div>',
Expand Down

0 comments on commit 8fee45a

Please sign in to comment.