source: node_modules/immutable/contrib/cursor/__tests__/Cursor.ts.skip

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 13.4 KB
Line 
1/**
2 * Copyright (c) 2014-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8///<reference path='../../../resources/jest.d.ts'/>
9///<reference path='../../../dist/immutable.d.ts'/>
10///<reference path='../index.d.ts'/>
11
12jest.autoMockOff();
13
14import Immutable = require('immutable');
15import Cursor = require('immutable/contrib/cursor');
16
17describe('Cursor', () => {
18
19 beforeEach(function () {
20 this.addMatchers({
21 toValueEqual: function (expected) {
22 var actual = this.actual;
23 if (!Immutable.is(expected, this.actual)) {
24 this.message = 'Expected\n' + this.actual + '\nto equal\n' + expected;
25 return false;
26 }
27 return true;
28 }
29 });
30 });
31
32 var json = { a: { b: { c: 1 } } };
33
34 it('gets from its path', () => {
35 var data = Immutable.fromJS(json);
36 var cursor = Cursor.from(data);
37
38 expect(cursor.deref()).toBe(data);
39
40 var deepCursor = cursor.cursor(['a', 'b']);
41 expect(deepCursor.deref().toJS()).toEqual(json.a.b);
42 expect(deepCursor.deref()).toBe(data.getIn(['a', 'b']));
43 expect(deepCursor.get('c')).toBe(1);
44
45 var leafCursor = deepCursor.cursor('c');
46 expect(leafCursor.deref()).toBe(1);
47
48 var missCursor = leafCursor.cursor('d');
49 expect(missCursor.deref()).toBe(undefined);
50 });
51
52 it('gets return new cursors', () => {
53 var data = Immutable.fromJS(json);
54 var cursor = Cursor.from(data);
55 var deepCursor = cursor.getIn(['a', 'b']);
56 expect(deepCursor.deref()).toBe(data.getIn(['a', 'b']));
57 });
58
59 it('gets return new cursors using List', () => {
60 var data = Immutable.fromJS(json);
61 var cursor = Cursor.from(data);
62 var deepCursor = cursor.getIn(Immutable.fromJS(['a', 'b']));
63 expect(deepCursor.deref()).toBe(data.getIn(Immutable.fromJS(['a', 'b'])));
64 });
65
66 it('cursor return new cursors of correct type', () => {
67 var data = Immutable.fromJS({ a: [1, 2, 3] });
68 var cursor = Cursor.from(data);
69 var deepCursor = <any>cursor.cursor('a');
70 expect(deepCursor.findIndex).toBeDefined();
71 });
72
73 it('can be treated as a value', () => {
74 var data = Immutable.fromJS(json);
75 var cursor = Cursor.from(data, ['a', 'b']);
76 expect(cursor.toJS()).toEqual(json.a.b);
77 expect(cursor).toValueEqual(data.getIn(['a', 'b']));
78 expect(cursor.size).toBe(1);
79 expect(cursor.get('c')).toBe(1);
80 });
81
82 it('can be value compared to a primitive', () => {
83 var data = Immutable.Map({ a: 'A' });
84 var aCursor = Cursor.from(data, 'a');
85 expect(aCursor.size).toBe(undefined);
86 expect(aCursor.deref()).toBe('A');
87 expect(Immutable.is(aCursor, 'A')).toBe(true);
88 });
89
90 it('updates at its path', () => {
91 var onChange = jest.genMockFunction();
92
93 var data = Immutable.fromJS(json);
94 var aCursor = Cursor.from(data, 'a', onChange);
95
96 var deepCursor = aCursor.cursor(['b', 'c']);
97 expect(deepCursor.deref()).toBe(1);
98
99 // cursor edits return new cursors:
100 var newDeepCursor = deepCursor.update(x => x + 1);
101 expect(newDeepCursor.deref()).toBe(2);
102 var call1 = onChange.mock.calls[0];
103 expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
104 expect(call1[1]).toBe(data);
105 expect(call1[2]).toEqual(['a', 'b', 'c']);
106
107 var newestDeepCursor = newDeepCursor.update(x => x + 1);
108 expect(newestDeepCursor.deref()).toBe(3);
109 var call2 = onChange.mock.calls[1];
110 expect(call2[0]).toValueEqual(Immutable.fromJS({a:{b:{c:3}}}));
111 expect(call2[1]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
112 expect(call2[2]).toEqual(['a', 'b', 'c']);
113
114 // meanwhile, data is still immutable:
115 expect(data.toJS()).toEqual(json);
116
117 // as is the original cursor.
118 expect(deepCursor.deref()).toBe(1);
119 var otherNewDeepCursor = deepCursor.update(x => x + 10);
120 expect(otherNewDeepCursor.deref()).toBe(11);
121 var call3 = onChange.mock.calls[2];
122 expect(call3[0]).toValueEqual(Immutable.fromJS({a:{b:{c:11}}}));
123 expect(call3[1]).toBe(data);
124 expect(call3[2]).toEqual(['a', 'b', 'c']);
125
126 // and update has been called exactly thrice.
127 expect(onChange.mock.calls.length).toBe(3);
128 });
129
130 it('updates with the return value of onChange', () => {
131 var onChange = jest.genMockFunction();
132
133 var data = Immutable.fromJS(json);
134 var deepCursor = Cursor.from(data, ['a', 'b', 'c'], onChange);
135
136 onChange.mockReturnValueOnce(undefined);
137 // onChange returning undefined has no effect
138 var newCursor = deepCursor.update(x => x + 1);
139 expect(newCursor.deref()).toBe(2);
140 var call1 = onChange.mock.calls[0];
141 expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
142 expect(call1[1]).toBe(data);
143 expect(call1[2]).toEqual(['a', 'b', 'c']);
144
145 onChange.mockReturnValueOnce(Immutable.fromJS({a:{b:{c:11}}}));
146 // onChange returning something else has an effect
147 newCursor = newCursor.update(x => 999);
148 expect(newCursor.deref()).toBe(11);
149 var call2 = onChange.mock.calls[1];
150 expect(call2[0]).toValueEqual(Immutable.fromJS({a:{b:{c:999}}}));
151 expect(call2[1]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
152 expect(call2[2]).toEqual(['a', 'b', 'c']);
153
154 // and update has been called exactly twice
155 expect(onChange.mock.calls.length).toBe(2);
156 });
157
158 it('has map API for update shorthand', () => {
159 var onChange = jest.genMockFunction();
160
161 var data = Immutable.fromJS(json);
162 var aCursor = Cursor.from(data, 'a', onChange);
163 var bCursor = aCursor.cursor('b');
164 var cCursor = bCursor.cursor('c');
165
166 expect(bCursor.set('c', 10).deref()).toValueEqual(
167 Immutable.fromJS({ c: 10 })
168 );
169
170 var call1 = onChange.mock.calls[0];
171 expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
172 expect(call1[1]).toBe(data);
173 expect(call1[2]).toEqual(['a', 'b', 'c']);
174 });
175
176 it('creates maps as necessary', () => {
177 var data = Immutable.Map();
178 var cursor = Cursor.from(data, ['a', 'b', 'c']);
179 expect(cursor.deref()).toBe(undefined);
180 cursor = cursor.set('d', 3);
181 expect(cursor.deref()).toValueEqual(Immutable.Map({d: 3}));
182 });
183
184 it('can set undefined', () => {
185 var data = Immutable.Map();
186 var cursor = Cursor.from(data, ['a', 'b', 'c']);
187 expect(cursor.deref()).toBe(undefined);
188 cursor = cursor.set('d', undefined);
189 expect(cursor.toJS()).toEqual({d: undefined});
190 });
191
192 it('has the sequence API', () => {
193 var data = Immutable.Map({a: 1, b: 2, c: 3});
194 var cursor = Cursor.from(data);
195 expect(cursor.map((x: number) => x * x)).toValueEqual(Immutable.Map({a: 1, b: 4, c: 9}));
196 });
197
198 it('can push values on a List', () => {
199 var onChange = jest.genMockFunction();
200 var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
201 var cursor = Cursor.from(data, ['a', 'b'], onChange);
202
203 expect(cursor.push(3,4)).toValueEqual(Immutable.List([0, 1, 2, 3, 4]));
204
205 var call = onChange.mock.calls[0];
206 expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [0, 1, 2, 3, 4]}}));
207 expect(call[1]).toBe(data);
208 expect(call[2]).toEqual(['a', 'b']);
209 });
210
211 it('can pop values of a List', () => {
212 var onChange = jest.genMockFunction();
213 var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
214 var cursor = Cursor.from(data, ['a', 'b'], onChange);
215
216 expect(cursor.pop()).toValueEqual(Immutable.List([0, 1]));
217
218 var call = onChange.mock.calls[0];
219 expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [0, 1]}}));
220 expect(call[1]).toBe(data);
221 expect(call[2]).toEqual(['a', 'b']);
222 });
223
224 it('can unshift values on a List', () => {
225 var onChange = jest.genMockFunction();
226 var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
227 var cursor = Cursor.from(data, ['a', 'b'], onChange);
228
229 expect(cursor.unshift(-2, -1)).toValueEqual(Immutable.List([-2, -1, 0, 1, 2]));
230
231 var call = onChange.mock.calls[0];
232 expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [-2, -1, 0, 1, 2]}}));
233 expect(call[1]).toBe(data);
234 expect(call[2]).toEqual(['a', 'b']);
235 });
236
237 it('can shift values of a List', () => {
238 var onChange = jest.genMockFunction();
239 var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
240 var cursor = Cursor.from(data, ['a', 'b'], onChange);
241
242 expect(cursor.shift()).toValueEqual(Immutable.List([1, 2]));
243
244 var call = onChange.mock.calls[0];
245 expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [1, 2]}}));
246 expect(call[1]).toBe(data);
247 expect(call[2]).toEqual(['a', 'b']);
248 });
249
250
251 it('returns wrapped values for sequence API', () => {
252 var data = Immutable.fromJS({a: {v: 1}, b: {v: 2}, c: {v: 3}});
253 var onChange = jest.genMockFunction();
254 var cursor = Cursor.from(data, onChange);
255
256 var found = cursor.find(map => map.get('v') === 2);
257 expect(typeof found.deref).toBe('function'); // is a cursor!
258 found = found.set('v', 20);
259
260 var call = onChange.mock.calls[0];
261 expect(call[0]).toValueEqual(Immutable.fromJS({a: {v: 1}, b: {v: 20}, c: {v: 3}}));
262 expect(call[1]).toBe(data);
263 expect(call[2]).toEqual(['b', 'v']);
264 });
265
266 it('returns wrapped values for iteration API', () => {
267 var jsData = [{val: 0}, {val: 1}, {val: 2}];
268 var data = Immutable.fromJS(jsData);
269 var cursor = Cursor.from(data);
270 cursor.forEach(function (c, i) {
271 expect(typeof c.deref).toBe('function'); // is a cursor!
272 expect(c.get('val')).toBe(i);
273 });
274 });
275
276 it('can map over values to get subcursors', () => {
277 var data = Immutable.fromJS({a: {v: 1}, b: {v: 2}, c: {v: 3}});
278 var cursor = Cursor.from(data);
279
280 var mapped = cursor.map(val => {
281 expect(typeof val.deref).toBe('function'); // mapped values are cursors.
282 return val;
283 }).toMap();
284 // Mapped is not a cursor, but it is a sequence of cursors.
285 expect(typeof (<any>mapped).deref).not.toBe('function');
286 expect(typeof (<any>mapped.get('a')).deref).toBe('function');
287
288 // Same for indexed cursors
289 var data2 = Immutable.fromJS({x: [{v: 1}, {v: 2}, {v: 3}]});
290 var cursor2 = Cursor.from(data2);
291
292 var mapped2 = cursor2.get('x').map(val => {
293 expect(typeof val.deref).toBe('function'); // mapped values are cursors.
294 return val;
295 }).toList();
296 // Mapped is not a cursor, but it is a sequence of cursors.
297 expect(typeof mapped2.deref).not.toBe('function');
298 expect(typeof mapped2.get(0).deref).toBe('function');
299 });
300
301 it('can have mutations apply with a single callback', () => {
302 var onChange = jest.genMockFunction();
303 var data = Immutable.fromJS({'a': 1});
304
305 var c1 = Cursor.from(data, onChange);
306 var c2 = c1.withMutations(m => m.set('b', 2).set('c', 3).set('d', 4));
307
308 expect(c1.deref().toObject()).toEqual({'a': 1});
309 expect(c2.deref().toObject()).toEqual({'a': 1, 'b': 2, 'c': 3, 'd': 4});
310 expect(onChange.mock.calls.length).toBe(1);
311 });
312
313 it('can use withMutations on an unfulfilled cursor', () => {
314 var onChange = jest.genMockFunction();
315 var data = Immutable.fromJS({});
316
317 var c1 = Cursor.from(data, ['a', 'b', 'c'], onChange);
318 var c2 = c1.withMutations(m => m.set('x', 1).set('y', 2).set('z', 3));
319
320 expect(c1.deref()).toEqual(undefined);
321 expect(c2.deref()).toValueEqual(Immutable.fromJS(
322 { x: 1, y: 2, z: 3 }
323 ));
324 expect(onChange.mock.calls.length).toBe(1);
325 });
326
327 it('maintains indexed sequences', () => {
328 var data = Immutable.fromJS([]);
329 var c = Cursor.from(data);
330 expect(c.toJS()).toEqual([]);
331 });
332
333 it('properly acts as an iterable', () => {
334 var data = Immutable.fromJS({key: {val: 1}});
335 var c = Cursor.from(data).values();
336 var c1 = c.next().value.get('val');
337 expect(c1).toBe(1);
338 });
339
340 it('can update deeply', () => {
341 var onChange = jest.genMockFunction();
342 var data = Immutable.fromJS({a:{b:{c:1}}});
343 var c = Cursor.from(data, ['a'], onChange);
344 var c1 = c.updateIn(['b', 'c'], x => x * 10);
345 expect(c1.getIn(['b', 'c'])).toBe(10);
346
347 var call = onChange.mock.calls[0];
348 expect(call[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
349 expect(call[1]).toBe(data);
350 expect(call[2]).toEqual(['a', 'b', 'c']);
351 });
352
353 it('can set deeply', () => {
354 var onChange = jest.genMockFunction();
355 var data = Immutable.fromJS({a:{b:{c:1}}});
356 var c = Cursor.from(data, ['a'], onChange);
357 var c1 = c.setIn(['b', 'c'], 10);
358 expect(c1.getIn(['b', 'c'])).toBe(10);
359
360 var call = onChange.mock.calls[0];
361 expect(call[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
362 expect(call[1]).toBe(data);
363 expect(call[2]).toEqual(['a', 'b', 'c']);
364 });
365
366 it('can get Record value as a property', () => {
367 var User = Immutable.Record({ name: 'John' });
368 var users = Immutable.List.of(new User());
369 var data = Immutable.Map({'users': users});
370 var cursor = Cursor.from(data, ['users']);
371 expect(cursor.first().name).toBe('John');
372 });
373
374 it('can set value of a cursor directly', () => {
375 var onChange = jest.genMockFunction();
376 var data = Immutable.fromJS({a:1});
377 var c = Cursor.from(data, ['a'], onChange);
378 var c1 = c.set(2);
379 expect(c1.deref()).toBe(2);
380
381 var call = onChange.mock.calls[0];
382 expect(call[0]).toValueEqual(Immutable.fromJS({a:2}));
383 expect(call[1]).toBe(data);
384 expect(call[2]).toEqual(['a']);
385 });
386
387 it('can set value of a cursor to undefined directly', () => {
388 var onChange = jest.genMockFunction();
389 var data = Immutable.fromJS({a:1});
390 var c = Cursor.from(data, ['a'], onChange);
391 var c1 = c.set(undefined);
392 expect(c1.deref()).toBe(undefined);
393
394 var call = onChange.mock.calls[0];
395 expect(call[0]).toValueEqual(Immutable.fromJS({a:undefined}));
396 expect(call[1]).toBe(data);
397 expect(call[2]).toEqual(['a']);
398 });
399
400});
Note: See TracBrowser for help on using the repository browser.