Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80522 views
1
'use strict';
2
3
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj['default'] : obj; };
4
5
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
6
7
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
8
9
var _fluxMixin = require('../fluxMixin');
10
11
var fluxMixin = _interopRequire(_fluxMixin);
12
13
var _Flummox$Store$Actions = require('../../Flux');
14
15
var _addContext = require('./addContext');
16
17
var addContext = _interopRequire(_addContext);
18
19
var _sinon = require('sinon');
20
21
var sinon = _interopRequire(_sinon);
22
23
var _React = require('react/addons');
24
25
var React = _interopRequire(_React);
26
27
var PropTypes = React.PropTypes;
28
var TestUtils = React.addons.TestUtils;
29
30
describe('fluxMixin', function () {
31
var TestActions = (function (_Actions) {
32
function TestActions() {
33
_classCallCheck(this, TestActions);
34
35
if (_Actions != null) {
36
_Actions.apply(this, arguments);
37
}
38
}
39
40
_inherits(TestActions, _Actions);
41
42
TestActions.prototype.getSomething = function getSomething(something) {
43
return something;
44
};
45
46
return TestActions;
47
})(_Flummox$Store$Actions.Actions);
48
49
var TestStore = (function (_Store) {
50
function TestStore(flux) {
51
_classCallCheck(this, TestStore);
52
53
_Store.call(this);
54
55
var testActions = flux.getActions('test');
56
this.register(testActions.getSomething, this.handleGetSomething);
57
58
this.state = {
59
something: null
60
};
61
}
62
63
_inherits(TestStore, _Store);
64
65
TestStore.prototype.handleGetSomething = function handleGetSomething(something) {
66
this.setState({ something: something });
67
};
68
69
return TestStore;
70
})(_Flummox$Store$Actions.Store);
71
72
var Flux = (function (_Flummox) {
73
function Flux() {
74
_classCallCheck(this, Flux);
75
76
_Flummox.call(this);
77
78
this.createActions('test', TestActions);
79
this.createStore('test', TestStore, this);
80
this.createStore('test2', TestStore, this);
81
}
82
83
_inherits(Flux, _Flummox);
84
85
return Flux;
86
})(_Flummox$Store$Actions.Flummox);
87
88
var ComponentWithFluxMixin = React.createClass({
89
displayName: 'ComponentWithFluxMixin',
90
91
mixins: [fluxMixin()],
92
93
render: function render() {
94
return null;
95
}
96
});
97
98
it('gets flux from either props or context', function () {
99
var flux = new Flux();
100
var contextComponent = undefined,
101
propsComponent = undefined;
102
103
var ContextComponent = addContext(ComponentWithFluxMixin, { flux: flux }, { flux: React.PropTypes.instanceOf(_Flummox$Store$Actions.Flummox) });
104
105
var tree = TestUtils.renderIntoDocument(React.createElement(ContextComponent, null));
106
107
contextComponent = TestUtils.findRenderedComponentWithType(tree, ComponentWithFluxMixin);
108
109
propsComponent = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { flux: flux }));
110
111
expect(contextComponent.flux).to.be.an['instanceof'](_Flummox$Store$Actions.Flummox);
112
expect(propsComponent.flux).to.be.an['instanceof'](_Flummox$Store$Actions.Flummox);
113
});
114
115
it('exposes flux as context', function () {
116
var flux = new Flux();
117
118
var ChildComponent = React.createClass({
119
displayName: 'ChildComponent',
120
121
contextTypes: {
122
flux: PropTypes.instanceOf(_Flummox$Store$Actions.Flummox) },
123
124
render: function render() {
125
return React.createElement('div', null);
126
}
127
});
128
129
var Component = React.createClass({
130
displayName: 'Component',
131
132
mixins: [fluxMixin()],
133
134
render: function render() {
135
return React.createElement(
136
'div',
137
null,
138
React.createElement(ChildComponent, { key: 'test' })
139
);
140
}
141
});
142
143
var tree = TestUtils.renderIntoDocument(React.createElement(Component, { flux: flux }));
144
145
var childComponent = TestUtils.findRenderedComponentWithType(tree, ChildComponent);
146
147
expect(childComponent.context.flux).to.equal(flux);
148
});
149
150
it('throws error if neither props or context is set', function () {
151
var flux = new Flux();
152
153
expect(TestUtils.renderIntoDocument.bind(null, React.createElement(ComponentWithFluxMixin, null))).to['throw']('fluxMixin: Could not find Flux instance. Ensure that your component ' + 'has either `this.context.flux` or `this.props.flux`.');
154
});
155
156
it('ignores change event after unmounted', function () {
157
var flux = new Flux();
158
flux.getActions('test').getSomething('foo');
159
160
var getterMap = {
161
test: function test(store) {
162
return { something: store.state.something };
163
}
164
};
165
var Component = React.createClass({
166
displayName: 'Component',
167
168
mixins: [fluxMixin(getterMap)],
169
170
render: function render() {
171
return null;
172
}
173
});
174
175
var container = document.createElement('div');
176
var component = React.render(React.createElement(Component, { flux: flux }), container);
177
var listener = flux.getStore('test').listeners('change')[0];
178
179
React.unmountComponentAtNode(container);
180
181
flux.getActions('test').getSomething('bar');
182
listener();
183
184
expect(component.state.something).to.equal('foo');
185
});
186
187
it('uses #connectToStores() to get initial state', function () {
188
var flux = new Flux();
189
190
flux.getActions('test').getSomething('foobar');
191
192
var getterMap = {
193
test: function test(store) {
194
return {
195
something: store.state.something,
196
custom: true };
197
} };
198
199
var mixin = fluxMixin(getterMap);
200
201
var connectToStores = sinon.spy(mixin, 'connectToStores');
202
203
var Component = React.createClass({
204
displayName: 'Component',
205
206
mixins: [mixin],
207
208
getInitialState: function getInitialState() {
209
return {
210
foobar: 'baz' };
211
},
212
213
render: function render() {
214
return null;
215
}
216
});
217
218
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: 'test', flux: flux }));
219
220
expect(connectToStores.calledOnce).to.be['true'];
221
expect(connectToStores.firstCall.args[0]).to.equal(getterMap);
222
223
expect(flux.getStore('test').listeners('change')).to.have.length(1);
224
225
expect(component.state).to.deep.equal({
226
something: 'foobar',
227
custom: true,
228
foobar: 'baz' });
229
});
230
231
describe('#connectToStores', function () {
232
233
it('returns initial state', function () {
234
var flux = new Flux();
235
236
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
237
238
var initialState = component.connectToStores('test');
239
240
expect(initialState).to.deep.equal({
241
something: null });
242
});
243
244
it('merges store state with component state on change', function () {
245
var flux = new Flux();
246
247
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
248
249
component.setState({ otherThing: 'barbaz' });
250
251
component.connectToStores('test');
252
flux.getActions('test').getSomething('foobar');
253
254
expect(component.state).to.deep.equal({
255
something: 'foobar',
256
otherThing: 'barbaz' });
257
});
258
259
it('uses custom state getter, if given', function () {
260
var flux = new Flux();
261
262
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux, bar: 'baz' }));
263
264
component.setState({ otherThing: 'barbaz' });
265
266
component.connectToStores('test', function (store, props) {
267
return {
268
something: store.state.something,
269
barbaz: 'bar' + props.bar };
270
});
271
272
flux.getActions('test').getSomething('foobar');
273
274
expect(component.state).to.deep.equal({
275
something: 'foobar',
276
otherThing: 'barbaz',
277
barbaz: 'barbaz' });
278
});
279
280
it('syncs with store after prop change', function () {
281
var flux = new Flux();
282
283
var Component = React.createClass({
284
displayName: 'Component',
285
286
mixins: [fluxMixin({
287
test: function test(store, props) {
288
return {
289
foo: 'foo is ' + props.foo };
290
} })],
291
292
render: function render() {
293
return null;
294
}
295
});
296
297
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: 'test', flux: flux, foo: 'bar' }));
298
299
expect(component.state.foo).to.equal('foo is bar');
300
301
component.setProps({ foo: 'baz' });
302
303
expect(component.state.foo).to.equal('foo is baz');
304
});
305
306
it('accepts object of keys to state getters', function () {
307
var flux = new Flux();
308
309
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
310
311
component.setState({ otherThing: 'barbaz' });
312
313
component.connectToStores({
314
test: function test(store) {
315
return {
316
something: store.state.something,
317
custom: true };
318
} });
319
320
flux.getActions('test').getSomething('foobar');
321
322
expect(component.state).to.deep.equal({
323
something: 'foobar',
324
otherThing: 'barbaz',
325
custom: true });
326
});
327
328
it('calls default state getter once with array of stores', function () {
329
var flux = new Flux();
330
331
flux.getStore('test2').setState({ otherThing: 'barbaz' });
332
333
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
334
335
component.connectToStores(['test', 'test2']);
336
337
flux.getActions('test').getSomething('foobar');
338
339
expect(component.state).to.deep.equal({
340
something: 'foobar',
341
otherThing: 'barbaz'
342
});
343
});
344
345
it('calls custom state getter once with array of stores', function () {
346
var flux = new Flux();
347
var testStore = flux.getStore('test');
348
var test2Store = flux.getStore('test2');
349
350
testStore._testId = 'test';
351
test2Store._testId = 'test2';
352
353
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
354
355
var stateGetter = sinon.stub().returns({ foo: 'bar' });
356
var state = component.connectToStores(['test', 'test2'], stateGetter);
357
358
expect(stateGetter.calledOnce).to.be['true'];
359
// Use _testId as unique identifier on store.
360
expect(stateGetter.firstCall.args[0][0]._testId).to.equal('test');
361
expect(stateGetter.firstCall.args[0][1]._testId).to.equal('test2');
362
363
expect(state).to.deep.equal({
364
foo: 'bar'
365
});
366
});
367
368
it('uses default getter if null is passed as getter', function () {
369
var flux = new Flux();
370
371
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
372
373
component.setState({ otherThing: 'barbaz' });
374
375
component.connectToStores('test', null);
376
377
flux.getActions('test').getSomething('foobar');
378
379
expect(component.state).to.deep.equal({
380
something: 'foobar',
381
otherThing: 'barbaz' });
382
});
383
384
it('removes listener before unmounting', function () {
385
var flux = new Flux();
386
var div = document.createElement('div');
387
388
var component = React.render(React.createElement(ComponentWithFluxMixin, { flux: flux }), div);
389
390
var store = flux.getStore('test');
391
component.connectToStores('test');
392
393
expect(store.listeners('change').length).to.equal(1);
394
React.unmountComponentAtNode(div);
395
expect(store.listeners('change').length).to.equal(0);
396
});
397
});
398
399
describe('#getStoreState', function () {
400
it('gets combined state of connected stores', function () {
401
var flux = new Flux();
402
403
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
404
405
component.connectToStores({
406
test: function test(store) {
407
return {
408
foo: 'bar' };
409
},
410
test2: function test2(store) {
411
return {
412
bar: 'baz'
413
};
414
}
415
});
416
417
component.setState({ baz: 'foo' });
418
419
expect(component.getStoreState()).to.deep.equal({
420
foo: 'bar',
421
bar: 'baz'
422
});
423
});
424
});
425
});
426