1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var test_1 = require("../test");
|
5 | var rxjs_1 = require("rxjs");
|
6 | var _1 = require(".");
|
7 | var initial = { count: 0, foo: { list: [] } };
|
8 | describe('Store', function () {
|
9 | describe('lifecycle', function () {
|
10 | it('constructs', function () {
|
11 | var store = _1.Store.create({ initial: initial });
|
12 | test_1.expect(store.isDisposed).to.eql(false);
|
13 | test_1.expect(store.state).to.not.equal(initial);
|
14 | test_1.expect(store.state).to.eql(initial);
|
15 | });
|
16 | it('disposes', function () {
|
17 | var store = _1.Store.create({ initial: initial });
|
18 | var count = 0;
|
19 | store.dispose$.subscribe(function () { return count++; });
|
20 | store.dispose();
|
21 | store.dispose();
|
22 | test_1.expect(store.isDisposed).to.eql(true);
|
23 | test_1.expect(count).to.eql(1);
|
24 | });
|
25 | it('takes event$ at creation', function () {
|
26 | var event$ = new rxjs_1.Subject();
|
27 | var store = _1.Store.create({ initial: initial, event$: event$ });
|
28 | test_1.expect(store._event$).to.equal(event$);
|
29 | });
|
30 | });
|
31 | describe('state', function () {
|
32 | it('returns new immutable object from [state] property', function () {
|
33 | var store = _1.Store.create({ initial: initial });
|
34 | var state1 = store.state;
|
35 | var state2 = store.state;
|
36 | test_1.expect(store.state).to.eql(initial);
|
37 | test_1.expect(store.state).to.not.equal(initial);
|
38 | test_1.expect(state1).to.eql(store.state);
|
39 | test_1.expect(state1).to.eql(initial);
|
40 | test_1.expect(state1).to.not.equal(state2);
|
41 | test_1.expect(store.state).to.not.equal(initial);
|
42 | });
|
43 | });
|
44 | describe('dispatch', function () {
|
45 | it('returns the state object', function () {
|
46 | var state = _1.Store.create({ initial: initial });
|
47 | var res = state.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
48 | test_1.expect(res).to.equal(res);
|
49 | });
|
50 | it('fires dispatch event', function () {
|
51 | var store = _1.Store.create({ initial: initial });
|
52 | var events = [];
|
53 | store.event$.subscribe(function (e) { return events.push(e); });
|
54 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
55 | store.dispatch({ type: 'TEST/decrement', payload: { by: 2 } });
|
56 | test_1.expect(events.length).to.eql(2);
|
57 | test_1.expect(events[0].type).to.eql('TEST/increment');
|
58 | test_1.expect(events[1].type).to.eql('TEST/decrement');
|
59 | });
|
60 | it('fires (via injected event$)', function () {
|
61 | var event$ = new rxjs_1.Subject();
|
62 | var store = _1.Store.create({ initial: initial, event$: event$ });
|
63 | var events = [];
|
64 | store.event$.subscribe(function (e) { return events.push(e); });
|
65 | event$.next({ type: 'TEST/increment', payload: { by: 1 } });
|
66 | event$.next({ type: 'TEST/decrement', payload: { by: 2 } });
|
67 | test_1.expect(events.length).to.eql(2);
|
68 | test_1.expect(events[0].type).to.eql('TEST/increment');
|
69 | test_1.expect(events[1].type).to.eql('TEST/decrement');
|
70 | });
|
71 | it('returns copy of the current state object on event', function () {
|
72 | var store = _1.Store.create({ initial: initial });
|
73 | var states = [];
|
74 | store.on('TEST/increment').subscribe(function (e) {
|
75 | states.push(e.state);
|
76 | states.push(e.state);
|
77 | });
|
78 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
79 | test_1.expect(states.length).to.eql(2);
|
80 | test_1.expect(states[0]).to.eql(store.state);
|
81 | test_1.expect(states[1]).to.eql(store.state);
|
82 | test_1.expect(states[0]).to.not.equal(store.state);
|
83 | test_1.expect(states[1]).to.not.equal(store.state);
|
84 | test_1.expect(states[0]).to.not.equal(states[1]);
|
85 | });
|
86 | it('changes the current state (via {...object})', function () {
|
87 | var store = _1.Store.create({ initial: initial });
|
88 | test_1.expect(store.state.count).to.eql(0);
|
89 | store.on('TEST/increment').subscribe(function (e) {
|
90 | var count = e.state.count + e.payload.by;
|
91 | var next = tslib_1.__assign(tslib_1.__assign({}, e.state), { count: count });
|
92 | e.change(next);
|
93 | });
|
94 | store.on('TEST/decrement').subscribe(function (e) {
|
95 | var count = e.state.count - e.payload.by;
|
96 | var next = tslib_1.__assign(tslib_1.__assign({}, e.state), { count: count });
|
97 | e.change(next);
|
98 | });
|
99 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
100 | test_1.expect(store.state.count).to.eql(1);
|
101 | store.dispatch({ type: 'TEST/decrement', payload: { by: 2 } });
|
102 | test_1.expect(store.state.count).to.eql(-1);
|
103 | });
|
104 | it('changes the current state (via immutable function)', function () {
|
105 | var store = _1.Store.create({
|
106 | initial: tslib_1.__assign(tslib_1.__assign({}, initial), { bar: { msg: 'hello' } }),
|
107 | });
|
108 | var before = store.state;
|
109 | test_1.expect(before.count).to.eql(0);
|
110 | store.on('TEST/increment').subscribe(function (e) {
|
111 | e.change(function (draft) {
|
112 | draft.count += e.payload.by;
|
113 | });
|
114 | });
|
115 | store.on('TEST/changeFoo').subscribe(function (e) {
|
116 | e.change(function (draft) {
|
117 | draft.foo.list.push(123);
|
118 | var foo = draft.foo;
|
119 | foo.msg = 'hello';
|
120 | });
|
121 | });
|
122 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
123 | var after1 = store.state;
|
124 | test_1.expect(before).to.not.equal(after1);
|
125 | test_1.expect(after1.count).to.eql(1);
|
126 | test_1.expect(after1.foo).to.equal(before.foo);
|
127 | test_1.expect(after1.bar).to.equal(before.bar);
|
128 | store.dispatch({ type: 'TEST/changeFoo', payload: {} });
|
129 | var after2 = store.state;
|
130 | test_1.expect(after2.foo.list).to.eql([123]);
|
131 | test_1.expect(after2.foo.msg).to.eql('hello');
|
132 | test_1.expect(after2).to.not.equal(after1);
|
133 | test_1.expect(after2.foo).to.not.equal(after1.foo);
|
134 | test_1.expect(after2.foo.list).to.not.equal(after1.foo.list);
|
135 | });
|
136 | it('fires [changing] event', function () {
|
137 | var store = _1.Store.create({ initial: initial });
|
138 | var events = [];
|
139 | store.changing$.subscribe(function (e) { return events.push(e); });
|
140 | store.on('TEST/increment').subscribe(function (e) { return e.change(e.state); });
|
141 | store
|
142 | .on('TEST/changeFoo')
|
143 | .subscribe(function (e) { return e.change(function (draft) { return (draft.foo.list = [1, 2, 3]); }); });
|
144 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
145 | test_1.expect(events.length).to.eql(1);
|
146 | test_1.expect(events[0].isCancelled).to.eql(false);
|
147 | test_1.expect(events[0].change.type).to.eql('TEST/increment');
|
148 | store.dispatch({ type: 'TEST/changeFoo', payload: {} });
|
149 | test_1.expect(events.length).to.eql(2);
|
150 | test_1.expect(events[1].isCancelled).to.eql(false);
|
151 | test_1.expect(events[1].change.type).to.eql('TEST/changeFoo');
|
152 | });
|
153 | it('cancels change', function () {
|
154 | var store = _1.Store.create({ initial: initial });
|
155 | var cancel = false;
|
156 | store.changing$.subscribe(function (e) {
|
157 | if (cancel) {
|
158 | e.cancel();
|
159 | }
|
160 | });
|
161 | store.on('TEST/increment').subscribe(function (e) {
|
162 | if (e.payload.by > 0) {
|
163 | var count = e.state.count + e.payload.by;
|
164 | var next = tslib_1.__assign(tslib_1.__assign({}, e.state), { count: count });
|
165 | e.change(next);
|
166 | }
|
167 | });
|
168 | store
|
169 | .on('TEST/changeFoo')
|
170 | .subscribe(function (e) { return e.change(function (draft) { return (draft.foo.list = [1, 2, 3]); }); });
|
171 | test_1.expect(store.state.count).to.eql(0);
|
172 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
173 | test_1.expect(store.state.count).to.eql(1);
|
174 | cancel = true;
|
175 | store.dispatch({ type: 'TEST/increment', payload: { by: 99 } });
|
176 | test_1.expect(store.state.count).to.eql(1);
|
177 | store.dispatch({ type: 'TEST/changeFoo', payload: {} });
|
178 | test_1.expect(store.state.foo.list).to.eql([]);
|
179 | cancel = false;
|
180 | store.dispatch({ type: 'TEST/changeFoo', payload: {} });
|
181 | test_1.expect(store.state.foo.list).to.eql([1, 2, 3]);
|
182 | });
|
183 | it('fires [changed] event', function () {
|
184 | var store = _1.Store.create({ initial: initial });
|
185 | var events = [];
|
186 | store.changed$.subscribe(function (e) { return events.push(e); });
|
187 | store.on('TEST/increment').subscribe(function (e) {
|
188 | if (e.payload.by > 0) {
|
189 | var count = e.state.count + e.payload.by;
|
190 | var next = tslib_1.__assign(tslib_1.__assign({}, e.state), { count: count });
|
191 | e.change(next);
|
192 | }
|
193 | });
|
194 | store.dispatch({ type: 'TEST/increment', payload: { by: 90 } });
|
195 | store.dispatch({ type: 'TEST/increment', payload: { by: 0 } });
|
196 | store.dispatch({ type: 'TEST/increment', payload: { by: 2 } });
|
197 | test_1.expect(events.length).to.eql(2);
|
198 | var change1 = events[0];
|
199 | var change2 = events[1];
|
200 | test_1.expect(change1.type).to.eql('TEST/increment');
|
201 | test_1.expect(change1.event.type).to.eql('TEST/increment');
|
202 | test_1.expect(change1.event.payload.by).to.eql(90);
|
203 | test_1.expect(change2.type).to.eql('TEST/increment');
|
204 | test_1.expect(change2.event.type).to.eql('TEST/increment');
|
205 | test_1.expect(change2.event.payload.by).to.eql(2);
|
206 | test_1.expect(change1.from.count).to.eql(0);
|
207 | test_1.expect(change1.to.count).to.eql(90);
|
208 | test_1.expect(change2.from.count).to.eql(90);
|
209 | test_1.expect(change2.to.count).to.eql(92);
|
210 | });
|
211 | });
|
212 | describe('epics', function () {
|
213 | it('dispatches a follow-on event (sync)', function () {
|
214 | var store = _1.Store.create({ initial: initial });
|
215 | var events = [];
|
216 | store.event$.subscribe(function (e) { return events.push(e); });
|
217 | store.on('TEST/increment').subscribe(function (e) {
|
218 | e.dispatch({ type: 'TEST/decrement', payload: { by: 2 } });
|
219 | });
|
220 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
221 | test_1.expect(events.length).to.eql(2);
|
222 | test_1.expect(events[0].type).to.eql('TEST/increment');
|
223 | test_1.expect(events[1].type).to.eql('TEST/decrement');
|
224 | });
|
225 | it('dispatches a follow-on event (async)', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
226 | var store, events;
|
227 | return tslib_1.__generator(this, function (_a) {
|
228 | switch (_a.label) {
|
229 | case 0:
|
230 | store = _1.Store.create({ initial: initial });
|
231 | events = [];
|
232 | store.event$.subscribe(function (e) { return events.push(e); });
|
233 | store.on('TEST/increment').subscribe(function (e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
234 | return tslib_1.__generator(this, function (_a) {
|
235 | switch (_a.label) {
|
236 | case 0: return [4, test_1.time.wait(3)];
|
237 | case 1:
|
238 | _a.sent();
|
239 | e.dispatch({ type: 'TEST/decrement', payload: { by: 2 } });
|
240 | return [2];
|
241 | }
|
242 | });
|
243 | }); });
|
244 | test_1.expect(events.length).to.eql(0);
|
245 | store.dispatch({ type: 'TEST/increment', payload: { by: 1 } });
|
246 | test_1.expect(events.length).to.eql(1);
|
247 | return [4, test_1.time.wait(10)];
|
248 | case 1:
|
249 | _a.sent();
|
250 | test_1.expect(events.length).to.eql(2);
|
251 | return [2];
|
252 | }
|
253 | });
|
254 | }); });
|
255 | });
|
256 | });
|