@samitouri / QOS-React-2 / commits / de1f783188

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 .",