forked from brianmhunt/knockout
-
Notifications
You must be signed in to change notification settings - Fork 0
/
subscribableBehaviors.js
156 lines (128 loc) · 6.57 KB
/
subscribableBehaviors.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
describe('Subscribable', function() {
it('Should declare that it is subscribable', function () {
var instance = new ko.subscribable();
expect(ko.isSubscribable(instance)).toEqual(true);
});
it('isSubscribable should return false for undefined', function () {
expect(ko.isSubscribable(undefined)).toEqual(false);
});
it('isSubscribable should return false for null', function () {
expect(ko.isSubscribable(null)).toEqual(false);
});
it('Should be able to notify subscribers', function () {
var instance = new ko.subscribable();
var notifiedValue;
instance.subscribe(function (value) { notifiedValue = value; });
instance.notifySubscribers(123);
expect(notifiedValue).toEqual(123);
});
it('Should be able to unsubscribe', function () {
var instance = new ko.subscribable();
var notifiedValue;
var subscription = instance.subscribe(function (value) { notifiedValue = value; });
subscription.dispose();
instance.notifySubscribers(123);
expect(notifiedValue).toEqual(undefined);
});
it('Should be able to specify a \'this\' pointer for the callback', function () {
var model = {
someProperty: 123,
myCallback: function (arg) { expect(arg).toEqual('notifiedValue'); expect(this.someProperty).toEqual(123); }
};
var instance = new ko.subscribable();
instance.subscribe(model.myCallback, model);
instance.notifySubscribers('notifiedValue');
});
it('Should not notify subscribers after unsubscription, even if the unsubscription occurs midway through a notification cycle', function() {
// This spec represents the unusual case where during notification, subscription1's callback causes subscription2 to be disposed.
// Since subscription2 was still active at the start of the cycle, it is scheduled to be notified. This spec verifies that
// even though it is scheduled to be notified, it does not get notified, because the unsubscription just happened.
var instance = new ko.subscribable();
var subscription1 = instance.subscribe(function() {
subscription2.dispose();
});
var subscription2wasNotified = false;
var subscription2 = instance.subscribe(function() {
subscription2wasNotified = true;
});
instance.notifySubscribers('ignored');
expect(subscription2wasNotified).toEqual(false);
});
it('Should be able to notify subscribers for a specific \'event\'', function () {
var instance = new ko.subscribable();
var notifiedValue = undefined;
instance.subscribe(function (value) { notifiedValue = value; }, null, "myEvent");
instance.notifySubscribers(123, "unrelatedEvent");
expect(notifiedValue).toEqual(undefined);
instance.notifySubscribers(456, "myEvent");
expect(notifiedValue).toEqual(456);
});
it('Should be able to unsubscribe for a specific \'event\'', function () {
var instance = new ko.subscribable();
var notifiedValue;
var subscription = instance.subscribe(function (value) { notifiedValue = value; }, null, "myEvent");
subscription.dispose();
instance.notifySubscribers(123, "myEvent");
expect(notifiedValue).toEqual(undefined);
});
it('Should be able to subscribe for a specific \'event\' without being notified for the default event', function () {
var instance = new ko.subscribable();
var notifiedValue;
var subscription = instance.subscribe(function (value) { notifiedValue = value; }, null, "myEvent");
instance.notifySubscribers(123);
expect(notifiedValue).toEqual(undefined);
});
it('Should be able to retrieve the number of active subscribers', function() {
var instance = new ko.subscribable();
var sub1 = instance.subscribe(function() { });
var sub2 = instance.subscribe(function() { }, null, "someSpecificEvent");
expect(instance.getSubscriptionsCount()).toEqual(2);
expect(instance.getSubscriptionsCount("change")).toEqual(1);
expect(instance.getSubscriptionsCount("someSpecificEvent")).toEqual(1);
expect(instance.getSubscriptionsCount("nonexistentEvent")).toEqual(0);
sub1.dispose();
expect(instance.getSubscriptionsCount()).toEqual(1);
expect(instance.getSubscriptionsCount("change")).toEqual(0);
expect(instance.getSubscriptionsCount("someSpecificEvent")).toEqual(1);
sub2.dispose();
expect(instance.getSubscriptionsCount()).toEqual(0);
expect(instance.getSubscriptionsCount("change")).toEqual(0);
expect(instance.getSubscriptionsCount("someSpecificEvent")).toEqual(0);
});
it('Should be possible to replace notifySubscribers with a custom handler', function() {
var instance = new ko.subscribable();
var interceptedNotifications = [];
instance.subscribe(function() { throw new Error("Should not notify subscribers by default once notifySubscribers is overridden") });
instance.notifySubscribers = function(newValue, eventName) {
interceptedNotifications.push({ eventName: eventName, value: newValue });
};
instance.notifySubscribers(123, "myEvent");
expect(interceptedNotifications.length).toEqual(1);
expect(interceptedNotifications[0].eventName).toEqual("myEvent");
expect(interceptedNotifications[0].value).toEqual(123);
});
it('Should inherit any properties defined on ko.subscribable.fn', function() {
this.after(function() {
delete ko.subscribable.fn.customProp;
delete ko.subscribable.fn.customFunc;
});
ko.subscribable.fn.customProp = 'some value';
ko.subscribable.fn.customFunc = function() { return this; };
var instance = new ko.subscribable();
expect(instance.customProp).toEqual('some value');
expect(instance.customFunc()).toEqual(instance);
});
it('Should have access to functions added to "fn" on existing instances on supported browsers', function () {
// On unsupported browsers, there's nothing to test
if (!jasmine.browserSupportsProtoAssignment) {
return;
}
this.after(function() {
delete ko.subscribable.fn.customFunction;
});
var subscribable = new ko.subscribable();
var customFunction = function () {};
ko.subscribable.fn.customFunction = customFunction;
expect(subscribable.customFunction).toBe(customFunction);
});
});