Skip to content

Commit f10a8e7

Browse files
committed
tests for unbind
1 parent 7e8eb77 commit f10a8e7

File tree

3 files changed

+134
-5
lines changed

3 files changed

+134
-5
lines changed

src/vuefire.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,21 @@ function bindAsObject (vm, key, source, cancelCallback) {
140140
* @param {string} key
141141
*/
142142
function unbind (vm, key) {
143-
var source = vm._firebaseSources[key]
143+
var source = vm._firebaseSources && vm._firebaseSources[key]
144+
if (!source) {
145+
throw new Error(
146+
'VueFire: unbind failed: "' + key + '" is not bound to ' +
147+
'a Firebase reference.'
148+
)
149+
}
144150
var listeners = vm._firebaseListeners[key]
145151
for (var event in listeners) {
146152
source.off(event, listeners[event])
147153
}
154+
vm[key] = null
155+
vm.$firebaseRefs[key] = null
156+
vm._firebaseSources[key] = null
157+
vm._firebaseListeners[key] = null
148158
}
149159

150160
var VueFireMixin = {
@@ -159,8 +169,11 @@ var VueFireMixin = {
159169
}
160170
},
161171
beforeDestroy: function () {
172+
if (!this.$firebaseRefs) return
162173
for (var key in this.$firebaseRefs) {
163-
unbind(this, key)
174+
if (this.$firebaseRefs[key]) {
175+
this.$unbind(key)
176+
}
164177
}
165178
this.$firebaseRefs = null
166179
this._firebaseSources = null
@@ -176,13 +189,27 @@ var VueFireMixin = {
176189
function install (_Vue) {
177190
Vue = _Vue
178191
Vue.mixin(VueFireMixin)
192+
179193
// use object-based merge strategy
180194
var mergeStrats = Vue.config.optionMergeStrategies
181195
mergeStrats.firebase = mergeStrats.methods
196+
182197
// extend instance methods
183-
Vue.prototype.$bind = function (key, source) {
184-
bind(this, key, source)
198+
Vue.prototype.$bindAsObject = function (key, source, cancelCallback) {
199+
bind(this, key, {
200+
source: source,
201+
asObject: true,
202+
cancelCallback: cancelCallback
203+
})
185204
}
205+
206+
Vue.prototype.$bindAsArray = function (key, source, cancelCallback) {
207+
bind(this, key, {
208+
source: source,
209+
cancelCallback: cancelCallback
210+
})
211+
}
212+
186213
Vue.prototype.$unbind = function (key) {
187214
unbind(this, key)
188215
}

tests/.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"mocha": true
44
},
55
"globals": {
6-
"expect": true
6+
"expect": true,
7+
"sinon": true
78
}
89
}

tests/vuefire.spec.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,4 +691,105 @@ describe('VueFire', function () {
691691
})
692692
})
693693
})
694+
695+
describe('unbind', function () {
696+
it('throws error given unbound key', function () {
697+
var vm = new Vue()
698+
expect(function () {
699+
vm.$unbind('items')
700+
}).to.throw(/not bound to a Firebase reference/)
701+
})
702+
703+
it('unbinds the state bound to Firebase as an array', function (done) {
704+
var vm = new Vue({
705+
firebase: {
706+
items: firebaseRef
707+
}
708+
})
709+
firebaseRef.set({
710+
first: { index: 0 },
711+
second: { index: 1 },
712+
third: { index: 2 }
713+
}, function () {
714+
vm.$unbind('items')
715+
expect(vm.items).to.be.null
716+
expect(vm.$firebaseRefs.items).to.be.null
717+
expect(vm._firebaseSources.items).to.be.null
718+
expect(vm._firebaseListeners.items).to.be.null
719+
done()
720+
})
721+
})
722+
723+
it('unbinds the state bound to Firebase as an object', function (done) {
724+
var vm = new Vue({
725+
firebase: {
726+
items: {
727+
source: firebaseRef,
728+
asObject: true
729+
}
730+
}
731+
})
732+
firebaseRef.set({
733+
first: { index: 0 },
734+
second: { index: 1 },
735+
third: { index: 2 }
736+
}, function () {
737+
vm.$unbind('items')
738+
expect(vm.items).to.be.null
739+
expect(vm.$firebaseRefs.items).to.be.null
740+
expect(vm._firebaseSources.items).to.be.null
741+
expect(vm._firebaseListeners.items).to.be.null
742+
done()
743+
})
744+
})
745+
746+
it('unbinds all bound state when the component unmounts', function (done) {
747+
var vm = new Vue({
748+
firebase: {
749+
item0: firebaseRef,
750+
item1: {
751+
source: firebaseRef,
752+
asObject: true
753+
}
754+
}
755+
})
756+
sinon.spy(vm, '$unbind')
757+
firebaseRef.set({
758+
first: { index: 0 },
759+
second: { index: 1 },
760+
third: { index: 2 }
761+
}, function () {
762+
vm.$destroy()
763+
expect(vm.$unbind).to.have.been.calledTwice
764+
expect(vm.item0).to.be.null
765+
expect(vm.item1).to.be.null
766+
done()
767+
})
768+
})
769+
770+
it('handles already unbound state when the component unmounts', function (done) {
771+
var vm = new Vue({
772+
firebase: {
773+
item0: firebaseRef,
774+
item1: {
775+
source: firebaseRef,
776+
asObject: true
777+
}
778+
}
779+
})
780+
sinon.spy(vm, '$unbind')
781+
firebaseRef.set({
782+
first: { index: 0 },
783+
second: { index: 1 },
784+
third: { index: 2 }
785+
}, function () {
786+
vm.$unbind('item0')
787+
vm.$destroy()
788+
expect(vm.$unbind).to.have.been.calledTwice
789+
expect(vm.item0).to.be.null
790+
expect(vm.item1).to.be.null
791+
done()
792+
})
793+
})
794+
})
694795
})

0 commit comments

Comments
 (0)