Update todomvc dispatcher to match docs, add AppDispatcher test
Joshua Ma committed
May 17, 2014 at 22:01 UTC
de1f7831883e8c438ecaaf2918044ce73bd92383
3 files changed
+90
-29
examples/todomvc-flux/js/dispatcher/Dispatcher.js
+22
-28
@@ -27,28 +27,6 @@ var merge = require('react/lib/merge');
27
var _callbacks = [];
28
var _promises = [];
29
30
-/**
31
- * Add a promise to the queue of callback invocation promises.
32
- * @param {function} callback The Store's registered callback.
33
- * @param {object} payload The data from the Action.
34
- */
35
-var _addPromise = function(callback, payload) {
36
- _promises.push(new Promise(function(resolve, reject) {
37
- if (callback(payload)) {
38
- resolve(payload);
39
- } else {
40
- reject(new Error('Dispatcher callback unsuccessful'));
41
- }
42
- }));
43
-};
44
-
45
-/**
46
- * Empty the queue of callback invocation promises.
47
- */
48
-var _clearPromises = function() {
49
- _promises = [];
50
-};
51
-
30
var Dispatcher = function() {};
31
Dispatcher.prototype = merge(Dispatcher.prototype, {
32
@@ -67,10 +45,26 @@ Dispatcher.prototype = merge(Dispatcher.prototype, {
45
* @param {object} payload The data from the action.
46
*/
47
dispatch: function(payload) {
70
- _callbacks.forEach(function(callback) {
71
- _addPromise(callback, payload);
48
+ // First create array of promises for callbacks to reference.
49
+ var _resolves = [];
50
+ var _rejects = [];
51
+ _promises = _callbacks.map(function(_, i) {
52
+ return new Promise(function(resolve, reject) {
53
+ _resolves[i] = resolve;
54
+ _rejects[i] = reject;
55
+ });
56
+ });
57
+ // Dispatch to callbacks and resolve/reject promises.
58
+ _callbacks.forEach(function(callback, i) {
59
+ // Callback can return an obj, to resolve, or a promise, to chain.
60
+ // See waitFor() for why this might be useful.
61
+ Promise.resolve(callback(payload)).then(function() {
62
+ _resolves[i](payload);
63
+ }, function() {
64
+ _rejects[i](new Error('Dispatcher callback unsuccessful'));
65
+ });
66
});
73
- Promise.all(_promises).then(_clearPromises);
67
+ _promises = [];
68
},
69
70
/**
@@ -108,10 +102,10 @@ Dispatcher.prototype = merge(Dispatcher.prototype, {
102
* A more robust Dispatcher would issue a warning in this scenario.
103
*/
104
waitFor: function(/*array*/ promiseIndexes, /*function*/ callback) {
111
- var selectedPromises = _promises.filter(function(/*object*/ _, /*number*/ j) {
112
- return promiseIndexes.indexOf(j) !== -1;
105
+ var selectedPromises = promiseIndexes.map(function(index) {
106
+ return _promises[index];
107
});
114
- Promise.all(selectedPromises).then(callback);
108
+ return Promise.all(selectedPromises).then(callback);
109
}
110
111
});
examples/todomvc-flux/js/dispatcher/__tests__/AppDispatcher-test.js
new
+66
@@ -0,0 +1,66 @@
1
+"use strict";
2
+
3
+jest.autoMockOff();
4
+
5
+describe('AppDispatcher', function() {
6
+ var AppDispatcher;
7
+
8
+ beforeEach(function() {
9
+ AppDispatcher = require('../AppDispatcher.js');
10
+ });
11
+
12
+ it('sends actions to subscribers', function() {
13
+ var listener = jest.genMockFunction();
14
+ AppDispatcher.register(listener);
15
+
16
+ var payload = {};
17
+ AppDispatcher.dispatch(payload);
18
+ expect(listener.mock.calls.length).toBe(1);
19
+ expect(listener.mock.calls[0][0]).toBe(payload);
20
+ });
21
+
22
+ it.only('waits with chained dependencies properly', function() {
23
+ var payload = {};
24
+
25
+ var listener1Done = false;
26
+ var listener1 = function(pl) {
27
+ return AppDispatcher.waitFor([index2], function() {
28
+ // Second and third listeners should have now been called
29
+ expect(listener2Done).toBe(true);
30
+ expect(listener3Done).toBe(true);
31
+ listener1Done = true;
32
+ });
33
+ };
34
+ var index1 = AppDispatcher.register(listener1);
35
+
36
+ var listener2Done = false;
37
+ var listener2 = function(pl) {
38
+ return AppDispatcher.waitFor([index3], function() {
39
+ expect(listener3Done).toBe(true);
40
+ listener2Done = true;
41
+ });
42
+ };
43
+ var index2 = AppDispatcher.register(listener2);
44
+
45
+ var listener3Done = false;
46
+ var listener3 = function(pl) {
47
+ listener3Done = true;
48
+ return true;
49
+ };
50
+ var index3 = AppDispatcher.register(listener3);
51
+
52
+ runs(function() {
53
+ AppDispatcher.dispatch(payload);
54
+ });
55
+
56
+ waitsFor(function() {
57
+ return listener1Done;
58
+ }, "Not all subscribers were properly called", 500);
59
+
60
+ runs(function() {
61
+ expect(listener1Done).toBe(true);
62
+ expect(listener2Done).toBe(true);
63
+ expect(listener3Done).toBe(true);
64
+ });
65
+ });
66
+});
examples/todomvc-flux/package.json
+2
-1
@@ -13,7 +13,8 @@
13
"reactify": "~0.4.0",
14
"statics": "~0.1.0",
15
"uglify-js": "~2.4.13",
16
- "watchify": "~0.4.1"
16
+ "watchify": "~0.4.1",
17
+ "jest-cli": "~0.1.5"
18
},
19
"scripts": {
20
"start": "STATIC_ROOT=./static watchify -o js/bundle.js -v -d .",