Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80632 views
1
/*
2
* Copyright (c) 2014-2015, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*/
9
10
jest.dontMock('../Dispatcher');
11
jest.dontMock('../invariant');
12
__DEV__ = true; // simulate dev environment to test if errors are thrown
13
14
describe('Dispatcher', function() {
15
16
var Dispatcher = require('../Dispatcher');
17
var dispatcher;
18
var callbackA;
19
var callbackB;
20
21
beforeEach(function() {
22
dispatcher = new Dispatcher();
23
callbackA = jest.genMockFunction();
24
callbackB = jest.genMockFunction();
25
});
26
27
it('should execute all subscriber callbacks', function() {
28
dispatcher.register(callbackA);
29
dispatcher.register(callbackB);
30
31
var payload = {};
32
dispatcher.dispatch(payload);
33
34
expect(callbackA.mock.calls.length).toBe(1);
35
expect(callbackA.mock.calls[0][0]).toBe(payload);
36
37
expect(callbackB.mock.calls.length).toBe(1);
38
expect(callbackB.mock.calls[0][0]).toBe(payload);
39
40
dispatcher.dispatch(payload);
41
42
expect(callbackA.mock.calls.length).toBe(2);
43
expect(callbackA.mock.calls[1][0]).toBe(payload);
44
45
expect(callbackB.mock.calls.length).toBe(2);
46
expect(callbackB.mock.calls[1][0]).toBe(payload);
47
});
48
49
it('should wait for callbacks registered earlier', function() {
50
var tokenA = dispatcher.register(callbackA);
51
52
dispatcher.register(function(payload) {
53
dispatcher.waitFor([tokenA]);
54
expect(callbackA.mock.calls.length).toBe(1);
55
expect(callbackA.mock.calls[0][0]).toBe(payload);
56
callbackB(payload);
57
});
58
59
var payload = {};
60
dispatcher.dispatch(payload);
61
62
expect(callbackA.mock.calls.length).toBe(1);
63
expect(callbackA.mock.calls[0][0]).toBe(payload);
64
65
expect(callbackB.mock.calls.length).toBe(1);
66
expect(callbackB.mock.calls[0][0]).toBe(payload);
67
});
68
69
it('should wait for callbacks registered later', function() {
70
dispatcher.register(function(payload) {
71
dispatcher.waitFor([tokenB]);
72
expect(callbackB.mock.calls.length).toBe(1);
73
expect(callbackB.mock.calls[0][0]).toBe(payload);
74
callbackA(payload);
75
});
76
77
var tokenB = dispatcher.register(callbackB);
78
79
var payload = {};
80
dispatcher.dispatch(payload);
81
82
expect(callbackA.mock.calls.length).toBe(1);
83
expect(callbackA.mock.calls[0][0]).toBe(payload);
84
85
expect(callbackB.mock.calls.length).toBe(1);
86
expect(callbackB.mock.calls[0][0]).toBe(payload);
87
});
88
89
it('should throw if dispatch() while dispatching', function() {
90
dispatcher.register(function(payload) {
91
dispatcher.dispatch(payload);
92
callbackA();
93
});
94
95
var payload = {};
96
expect(function() {
97
dispatcher.dispatch(payload);
98
}).toThrow();
99
100
expect(callbackA.mock.calls.length).toBe(0);
101
});
102
103
it('should throw if waitFor() while not dispatching', function() {
104
var tokenA = dispatcher.register(callbackA);
105
106
expect(function() {
107
dispatcher.waitFor([tokenA]);
108
}).toThrow();
109
110
expect(callbackA.mock.calls.length).toBe(0);
111
});
112
113
it('should throw if waitFor() with invalid token', function() {
114
var invalidToken = 1337;
115
116
dispatcher.register(function() {
117
dispatcher.waitFor([invalidToken]);
118
});
119
120
var payload = {};
121
expect(function() {
122
dispatcher.dispatch(payload);
123
}).toThrow();
124
});
125
126
it('should throw on self-circular dependencies', function() {
127
var tokenA = dispatcher.register(function(payload) {
128
dispatcher.waitFor([tokenA]);
129
callbackA(payload);
130
});
131
132
var payload = {};
133
expect(function() {
134
dispatcher.dispatch(payload);
135
}).toThrow();
136
137
expect(callbackA.mock.calls.length).toBe(0);
138
});
139
140
it('should throw on multi-circular dependencies', function() {
141
var tokenA = dispatcher.register(function(payload) {
142
dispatcher.waitFor([tokenB]);
143
callbackA(payload);
144
});
145
146
var tokenB = dispatcher.register(function(payload) {
147
dispatcher.waitFor([tokenA]);
148
callbackB(payload);
149
});
150
151
var payload = {};
152
expect(function() {
153
dispatcher.dispatch(payload);
154
}).toThrow();
155
156
expect(callbackA.mock.calls.length).toBe(0);
157
expect(callbackB.mock.calls.length).toBe(0);
158
});
159
160
it('should remain in a consistent state after a failed dispatch', function() {
161
dispatcher.register(callbackA);
162
dispatcher.register(function(payload) {
163
if (payload.shouldThrow) {
164
throw new Error();
165
}
166
callbackB();
167
});
168
169
expect(function() {
170
dispatcher.dispatch({shouldThrow: true});
171
}).toThrow();
172
173
// Cannot make assumptions about a failed dispatch.
174
var callbackACount = callbackA.mock.calls.length;
175
176
dispatcher.dispatch({shouldThrow: false});
177
178
expect(callbackA.mock.calls.length).toBe(callbackACount + 1);
179
expect(callbackB.mock.calls.length).toBe(1);
180
});
181
182
it('should properly unregister callbacks', function() {
183
dispatcher.register(callbackA);
184
185
var tokenB = dispatcher.register(callbackB);
186
187
var payload = {};
188
dispatcher.dispatch(payload);
189
190
expect(callbackA.mock.calls.length).toBe(1);
191
expect(callbackA.mock.calls[0][0]).toBe(payload);
192
193
expect(callbackB.mock.calls.length).toBe(1);
194
expect(callbackB.mock.calls[0][0]).toBe(payload);
195
196
dispatcher.unregister(tokenB);
197
198
dispatcher.dispatch(payload);
199
200
expect(callbackA.mock.calls.length).toBe(2);
201
expect(callbackA.mock.calls[1][0]).toBe(payload);
202
203
expect(callbackB.mock.calls.length).toBe(1);
204
});
205
206
});
207
208