Skip to content

Commit 8fee45a

Browse files
authoredApr 2, 2018
fix: order watchers after trigger (#510)
1 parent 21fe83d commit 8fee45a

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed
 
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
let i = 0
2+
3+
function orderDeps (watcher) {
4+
watcher.deps.forEach(dep => {
5+
if (dep._sortedId === i) {
6+
return
7+
}
8+
dep._sortedId = i
9+
dep.subs.forEach(orderDeps)
10+
dep.subs = dep.subs.sort((a, b) => a.id - b.id)
11+
})
12+
}
13+
14+
function orderVmWatchers (vm) {
15+
if (vm._watchers) {
16+
vm._watchers.forEach(orderDeps)
17+
}
18+
19+
if (vm._computedWatchers) {
20+
Object.keys(vm._computedWatchers).forEach((computedWatcher) => {
21+
orderDeps(vm._computedWatchers[computedWatcher])
22+
})
23+
}
24+
25+
orderDeps(vm._watcher)
26+
27+
vm.$children.forEach(orderVmWatchers)
28+
}
29+
30+
export function orderWatchers (vm) {
31+
orderVmWatchers(vm)
32+
i++
33+
}

‎packages/test-utils/src/set-watchers-to-sync.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
function setDepsSync (dep) {
2-
dep.subs = dep.subs.sort((a, b) => a.id - b.id)
32
dep.subs.forEach(setWatcherSync)
43
}
54

‎packages/test-utils/src/vue-wrapper.js

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import Wrapper from './wrapper'
44
import { setWatchersToSync } from './set-watchers-to-sync'
5+
import { orderWatchers } from './order-watchers'
56

67
export default class VueWrapper extends Wrapper implements BaseWrapper {
78
constructor (vm: Component, options: WrapperOptions) {
@@ -20,6 +21,7 @@ export default class VueWrapper extends Wrapper implements BaseWrapper {
2021
this.vm = vm
2122
if (options.sync) {
2223
setWatchersToSync(vm)
24+
orderWatchers(vm)
2325
}
2426
this.isVueComponent = true
2527
this.isFunctionalComponent = vm.$options._isFunctionalContainer

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

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import {
2121
} from 'shared/util'
2222
import findAll from './find'
2323
import createWrapper from './create-wrapper'
24+
import {
25+
orderWatchers
26+
} from './order-watchers'
2427

2528
export default class Wrapper implements BaseWrapper {
2629
vnode: VNode | null;
@@ -621,6 +624,9 @@ export default class Wrapper implements BaseWrapper {
621624
}
622625

623626
this.element.dispatchEvent(eventObject)
627+
if (this.vnode) {
628+
orderWatchers(this.vm || this.vnode.context.$root)
629+
}
624630
}
625631

626632
update () {

‎test/specs/mounting-options/snyc.spec.js

+57
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,63 @@ describeWithShallowAndMount('options.sync', (mountingMethod) => {
3131
expect(wrapper.text()).to.equal('world')
3232
})
3333

34+
it('handles methods that update watchers', () => {
35+
const TestComponent = {
36+
template: `
37+
<div id="app">
38+
<div v-if="open">
39+
<div>
40+
<pre>data.text: <em>{{ text }}</em></pre>
41+
</div>
42+
<!-- Tests fail in 1.0.0-beta.13 with .fails portion of the code -->
43+
<div class="fails">
44+
<pre>computed.text: <em>{{ computedText }}</em></pre>
45+
</div>
46+
</div>
47+
</div>
48+
`,
49+
data () {
50+
return {
51+
open: false,
52+
text: '',
53+
basket: []
54+
}
55+
},
56+
computed: {
57+
computedText () {
58+
return this.text
59+
}
60+
},
61+
created () {
62+
window.addEventListener('click', this.clickHandler)
63+
},
64+
destroyed () {
65+
window.removeEventListener('click', this.clickHandler)
66+
},
67+
watch: {
68+
text () {
69+
this.basket.push(this.computedText)
70+
}
71+
},
72+
methods: {
73+
clickHandler () {
74+
this.open = !this.open
75+
}
76+
}
77+
}
78+
79+
const wrapper = mountingMethod(TestComponent, {
80+
attachToDocument: true
81+
})
82+
wrapper.trigger('click')
83+
expect(wrapper.vm.text).to.equal('')
84+
expect(wrapper.vm.basket.length).to.equal(0)
85+
wrapper.setData({ text: 'foo' })
86+
expect(wrapper.vm.text).to.equal('foo')
87+
expect(wrapper.vm.computedText).to.equal('foo')
88+
expect(wrapper.vm.basket[0]).to.equal('foo')
89+
})
90+
3491
it('does not set watchers to sync if set to false', (done) => {
3592
const TestComponent = {
3693
template: '<div>{{someData}}</div>',

0 commit comments

Comments
 (0)
Please sign in to comment.