Remove OrderedMap and ReactPropTransferer
These are not exposed publicly and have been deprecated.
Dan Abramov committed
Mar 31, 2016 at 14:38 UTC
27233230064316a8820cd1eb825adf3ea68b8160
3 files changed
-1553
src/isomorphic/deprecated/OrderedMap.js
deleted
-505
@@ -1,505 +0,0 @@
1
-/**
2
- * Copyright 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @providesModule OrderedMap
10
- */
11
-
12
-'use strict';
13
-
14
-var invariant = require('invariant');
15
-
16
-var PREFIX = 'key:';
17
-
18
-/**
19
- * Utility to extract a backing object from an initialization `Array`, allowing
20
- * the caller to assist in resolving the unique ID for each entry via the
21
- * `keyExtractor` callback. The `keyExtractor` must extract non-empty strings or
22
- * numbers.
23
- * @param {Array<Object!>} arr Array of items.
24
- * @param {function} keyExtractor Extracts a unique key from each item.
25
- * @return {Object} Map from unique key to originating value that the key was
26
- * extracted from.
27
- * @throws Exception if the initialization array has duplicate extracted keys.
28
- */
29
-function extractObjectFromArray(arr, keyExtractor) {
30
- var normalizedObj = {};
31
- for (var i = 0; i < arr.length; i++) {
32
- var item = arr[i];
33
- var key = keyExtractor(item);
34
- assertValidPublicKey(key);
35
- var normalizedKey = PREFIX + key;
36
- invariant(
37
- !(normalizedKey in normalizedObj),
38
- 'OrderedMap: IDs returned by the key extraction function must be unique.'
39
- );
40
- normalizedObj[normalizedKey] = item;
41
- }
42
- return normalizedObj;
43
-}
44
-
45
-/**
46
- * Utility class for mappings with ordering. This class is to be used in an
47
- * immutable manner. A `OrderedMap` is very much like the native JavaScript
48
- * object, where keys map to values via the `get()` function. Also, like the
49
- * native JavaScript object, there is an ordering associated with the mapping.
50
- * This class is helpful because it eliminates many of the pitfalls that come
51
- * with the native JavaScript ordered mappings. Specifically, there are
52
- * inconsistencies with numeric keys in some JavaScript implementations
53
- * (enumeration ordering). This class protects against those pitfalls and
54
- * provides functional utilities for dealing with these `OrderedMap`s.
55
- *
56
- * - TODO:
57
- * - orderedMergeExclusive: Merges mutually exclusive `OrderedMap`s.
58
- * - mapReverse().
59
- *
60
- * @class {OrderedMap}
61
- * @constructor {OrderedMap}
62
- * @param {Object} normalizedObj Object that is known to be a defensive copy of
63
- * caller supplied data. We require a defensive copy to guard against callers
64
- * mutating. It is also assumed that the keys of `normalizedObj` have been
65
- * normalized and do not contain any numeric-appearing strings.
66
- * @param {number} computedLength The precomputed length of `_normalizedObj`
67
- * keys.
68
- * @private
69
- */
70
-function OrderedMapImpl(normalizedObj, computedLength) {
71
- this._normalizedObj = normalizedObj;
72
- this._computedPositions = null;
73
- this.length = computedLength;
74
-}
75
-
76
-/**
77
- * Validates a "public" key - that is, one that the public facing API supplies.
78
- * The key is then normalized for internal storage. In order to be considered
79
- * valid, all keys must be non-empty, defined, non-null strings or numbers.
80
- *
81
- * @param {string?} key Validates that the key is suitable for use in a
82
- * `OrderedMap`.
83
- * @throws Error if key is not appropriate for use in `OrderedMap`.
84
- */
85
-function assertValidPublicKey(key) {
86
- invariant(
87
- key !== '' && (typeof key === 'string' || typeof key === 'number'),
88
- 'OrderedMap: Key must be non-empty, non-null string or number.'
89
- );
90
-}
91
-
92
-/**
93
- * Validates that arguments to range operations are within the correct limits.
94
- *
95
- * @param {number} start Start of range.
96
- * @param {number} length Length of range.
97
- * @param {number} actualLen Actual length of range that should not be
98
- * exceeded.
99
- * @throws Error if range arguments are out of bounds.
100
- */
101
-function assertValidRangeIndices(start, length, actualLen) {
102
- invariant(
103
- typeof start === 'number' &&
104
- typeof length === 'number' &&
105
- length >= 0 &&
106
- start >= 0 &&
107
- start + length <= actualLen,
108
- 'OrderedMap: `mapRange` and `forEachRange` expect non-negative start and ' +
109
- 'length arguments within the bounds of the instance.'
110
- );
111
-}
112
-
113
-/**
114
- * Merges two "normalized" objects (objects who's key have been normalized) into
115
- * a `OrderedMap`.
116
- *
117
- * @param {Object} a Object of key value pairs.
118
- * @param {Object} b Object of key value pairs.
119
- * @return {OrderedMap} new `OrderedMap` that results in merging `a` and `b`.
120
- */
121
-function _fromNormalizedObjects(a, b) {
122
- // Second optional, both must be plain JavaScript objects.
123
- invariant(
124
- a && a.constructor === Object && (!b || b.constructor === Object),
125
- 'OrderedMap: Corrupted instance of OrderedMap detected.'
126
- );
127
-
128
- var newSet = {};
129
- var length = 0;
130
- var key;
131
- for (key in a) {
132
- if (a.hasOwnProperty(key)) {
133
- newSet[key] = a[key];
134
- length++;
135
- }
136
- }
137
-
138
- for (key in b) {
139
- if (b.hasOwnProperty(key)) {
140
- // Increment length if not already added via first object (a)
141
- if (!(key in newSet)) {
142
- length++;
143
- }
144
- newSet[key] = b[key];
145
- }
146
- }
147
- return new OrderedMapImpl(newSet, length);
148
-}
149
-
150
-/**
151
- * Methods for `OrderedMap` instances.
152
- *
153
- * @lends OrderedMap.prototype
154
- * TODO: Make this data structure lazy, unify with LazyArray.
155
- * TODO: Unify this with ImmutableObject - it is to be used immutably.
156
- * TODO: If so, consider providing `fromObject` API.
157
- * TODO: Create faster implementation of merging/mapping from original Array,
158
- * without having to first create an object - simply for the sake of merging.
159
- */
160
-var OrderedMapMethods = {
161
-
162
- /**
163
- * Returns whether or not a given key is present in the map.
164
- *
165
- * @param {string} key Valid string key to lookup membership for.
166
- * @return {boolean} Whether or not `key` is a member of the map.
167
- * @throws Error if provided known invalid key.
168
- */
169
- has: function(key) {
170
- assertValidPublicKey(key);
171
- var normalizedKey = PREFIX + key;
172
- return normalizedKey in this._normalizedObj;
173
- },
174
-
175
- /**
176
- * Returns the object for a given key, or `undefined` if not present. To
177
- * distinguish an undefined entry vs not being in the set, use `has()`.
178
- *
179
- * @param {string} key String key to lookup the value for.
180
- * @return {Object?} Object at key `key`, or undefined if not in map.
181
- * @throws Error if provided known invalid key.
182
- */
183
- get: function(key) {
184
- assertValidPublicKey(key);
185
- var normalizedKey = PREFIX + key;
186
- return this.has(key) ? this._normalizedObj[normalizedKey] : undefined;
187
- },
188
-
189
- /**
190
- * Merges, appending new keys to the end of the ordering. Keys in `orderedMap`
191
- * that are redundant with `this`, maintain the same ordering index that they
192
- * had in `this`. This is how standard JavaScript object merging would work.
193
- * If you wish to prepend a `OrderedMap` to the beginning of another
194
- * `OrderedMap` then simply reverse the order of operation. This is the analog
195
- * to `merge(x, y)`.
196
- *
197
- * @param {OrderedMap} orderedMap OrderedMap to merge onto the end.
198
- * @return {OrderedMap} New OrderedMap that represents the result of the
199
- * merge.
200
- */
201
- merge: function(orderedMap) {
202
- invariant(
203
- orderedMap instanceof OrderedMapImpl,
204
- 'OrderedMap.merge(...): Expected an OrderedMap instance.'
205
- );
206
- return _fromNormalizedObjects(
207
- this._normalizedObj,
208
- orderedMap._normalizedObj
209
- );
210
- },
211
-
212
- /**
213
- * Functional map API. Returns a new `OrderedMap`.
214
- *
215
- * @param {Function} cb Callback to invoke for each item.
216
- * @param {Object?=} context Context to invoke callback from.
217
- * @return {OrderedMap} OrderedMap that results from mapping.
218
- */
219
- map: function(cb, context) {
220
- return this.mapRange(cb, 0, this.length, context);
221
- },
222
-
223
- /**
224
- * The callback `cb` is invoked with the arguments (item, key,
225
- * indexInOriginal).
226
- *
227
- * @param {Function} cb Determines result for each item.
228
- * @param {number} start Start index of map range.
229
- * @param {end} length End index of map range.
230
- * @param {*!?} context Context of callback invocation.
231
- * @return {OrderedMap} OrderedMap resulting from mapping the range.
232
- */
233
- mapRange: function(cb, start, length, context) {
234
- var thisSet = this._normalizedObj;
235
- var newSet = {};
236
- var i = 0;
237
- assertValidRangeIndices(start, length, this.length);
238
- var end = start + length - 1;
239
- for (var key in thisSet) {
240
- if (thisSet.hasOwnProperty(key)) {
241
- if (i >= start) {
242
- if (i > end) {
243
- break;
244
- }
245
- var item = thisSet[key];
246
- newSet[key] = cb.call(context, item, key.substr(PREFIX.length), i);
247
- }
248
- i++;
249
- }
250
- }
251
- return new OrderedMapImpl(newSet, length);
252
- },
253
-
254
- /**
255
- * Function filter API. Returns new `OrderedMap`.
256
- *
257
- * @param {Function} cb Callback to invoke for each item.
258
- * @param {Object?=} context Context to invoke callback from.
259
- * @return {OrderedMap} OrderedMap that results from filtering.
260
- */
261
- filter: function(cb, context) {
262
- return this.filterRange(cb, 0, this.length, context);
263
- },
264
-
265
- /**
266
- * The callback `cb` is invoked with the arguments (item, key,
267
- * indexInOriginal).
268
- *
269
- * @param {Function} cb Returns true if item should be in result.
270
- * @param {number} start Start index of filter range.
271
- * @param {number} length End index of map range.
272
- * @param {*!?} context Context of callback invocation.
273
- * @return {OrderedMap} OrderedMap resulting from filtering the range.
274
- */
275
- filterRange: function(cb, start, length, context) {
276
- var newSet = {};
277
- var newSetLength = 0;
278
- this.forEachRange(function(item, key, originalIndex) {
279
- if (cb.call(context, item, key, originalIndex)) {
280
- var normalizedKey = PREFIX + key;
281
- newSet[normalizedKey] = item;
282
- newSetLength++;
283
- }
284
- }, start, length);
285
- return new OrderedMapImpl(newSet, newSetLength);
286
- },
287
-
288
- forEach: function(cb, context) {
289
- this.forEachRange(cb, 0, this.length, context);
290
- },
291
-
292
- forEachRange: function(cb, start, length, context) {
293
- assertValidRangeIndices(start, length, this.length);
294
- var thisSet = this._normalizedObj;
295
- var i = 0;
296
- var end = start + length - 1;
297
- for (var key in thisSet) {
298
- if (thisSet.hasOwnProperty(key)) {
299
- if (i >= start) {
300
- if (i > end) {
301
- break;
302
- }
303
- var item = thisSet[key];
304
- cb.call(context, item, key.substr(PREFIX.length), i);
305
- }
306
- i++;
307
- }
308
- }
309
- },
310
-
311
- /**
312
- * Even though `mapRange`/`forEachKeyRange` allow zero length mappings, we'll
313
- * impose an additional restriction here that the length of mapping be greater
314
- * than zero - the only reason is that there are many ways to express length
315
- * zero in terms of two keys and that is confusing.
316
- */
317
- mapKeyRange: function(cb, startKey, endKey, context) {
318
- var startIndex = this.indexOfKey(startKey);
319
- var endIndex = this.indexOfKey(endKey);
320
- invariant(
321
- startIndex !== undefined && endIndex !== undefined,
322
- 'mapKeyRange must be given keys that are present.'
323
- );
324
- invariant(
325
- endIndex >= startIndex,
326
- 'OrderedMap.mapKeyRange(...): `endKey` must not come before `startIndex`.'
327
- );
328
- return this.mapRange(cb, startIndex, (endIndex - startIndex) + 1, context);
329
- },
330
-
331
- forEachKeyRange: function(cb, startKey, endKey, context) {
332
- var startIndex = this.indexOfKey(startKey);
333
- var endIndex = this.indexOfKey(endKey);
334
- invariant(
335
- startIndex !== undefined && endIndex !== undefined,
336
- 'forEachKeyRange must be given keys that are present.'
337
- );
338
- invariant(
339
- endIndex >= startIndex,
340
- 'OrderedMap.forEachKeyRange(...): `endKey` must not come before ' +
341
- '`startIndex`.'
342
- );
343
- this.forEachRange(cb, startIndex, (endIndex - startIndex) + 1, context);
344
- },
345
-
346
- /**
347
- * @param {number} pos Index to search for key at.
348
- * @return {string|undefined} Either the key at index `pos` or undefined if
349
- * not in map.
350
- */
351
- keyAtIndex: function(pos) {
352
- var computedPositions = this._getOrComputePositions();
353
- var keyAtPos = computedPositions.keyByIndex[pos];
354
- return keyAtPos ? keyAtPos.substr(PREFIX.length) : undefined;
355
- },
356
-
357
- /**
358
- * @param {string} key String key from which to find the next key.
359
- * @return {string|undefined} Either the next key, or undefined if there is no
360
- * next key.
361
- * @throws Error if `key` is not in this `OrderedMap`.
362
- */
363
- keyAfter: function(key) {
364
- return this.nthKeyAfter(key, 1);
365
- },
366
-
367
- /**
368
- * @param {string} key String key from which to find the preceding key.
369
- * @return {string|undefined} Either the preceding key, or undefined if there
370
- * is no preceding.key.
371
- * @throws Error if `key` is not in this `OrderedMap`.
372
- */
373
- keyBefore: function(key) {
374
- return this.nthKeyBefore(key, 1);
375
- },
376
-
377
- /**
378
- * @param {string} key String key from which to find a following key.
379
- * @param {number} n Distance to scan forward after `key`.
380
- * @return {string|undefined} Either the nth key after `key`, or undefined if
381
- * there is no next key.
382
- * @throws Error if `key` is not in this `OrderedMap`.
383
- */
384
- nthKeyAfter: function(key, n) {
385
- var curIndex = this.indexOfKey(key);
386
- invariant(
387
- curIndex !== undefined,
388
- 'OrderedMap.nthKeyAfter: The key `%s` does not exist in this instance.',
389
- key
390
- );
391
- return this.keyAtIndex(curIndex + n);
392
- },
393
-
394
- /**
395
- * @param {string} key String key from which to find a preceding key.
396
- * @param {number} n Distance to scan backwards before `key`.
397
- * @return {string|undefined} Either the nth key before `key`, or undefined if
398
- * there is no previous key.
399
- * @throws Error if `key` is not in this `OrderedMap`.
400
- */
401
- nthKeyBefore: function(key, n) {
402
- return this.nthKeyAfter(key, -n);
403
- },
404
-
405
- /**
406
- * @param {string} key Key to find the index of.
407
- * @return {number|undefined} Index of the provided key, or `undefined` if the
408
- * key is not found.
409
- */
410
- indexOfKey: function(key) {
411
- assertValidPublicKey(key);
412
- var normalizedKey = PREFIX + key;
413
- var computedPositions = this._getOrComputePositions();
414
- var computedPosition = computedPositions.indexByKey[normalizedKey];
415
- // Just writing it this way to make it clear this is intentional.
416
- return computedPosition === undefined ? undefined : computedPosition;
417
- },
418
-
419
- /**
420
- * @return {Array} An ordered array of this object's values.
421
- */
422
- toArray: function() {
423
- var result = [];
424
- var thisSet = this._normalizedObj;
425
- for (var key in thisSet) {
426
- if (thisSet.hasOwnProperty(key)) {
427
- result.push(thisSet[key]);
428
- }
429
- }
430
- return result;
431
- },
432
-
433
- /**
434
- * Finds the key at a given position, or indicates via `undefined` that that
435
- * position does not exist in the `OrderedMap`. It is appropriate to return
436
- * undefined, indicating that the key doesn't exist in the `OrderedMap`
437
- * because `undefined` is not ever a valid `OrderedMap` key.
438
- *
439
- * @private
440
- * @return {string?} Name of the item at position `pos`, or `undefined` if
441
- * there is no item at that position.
442
- */
443
- _getOrComputePositions: function() {
444
- // TODO: Entertain computing this at construction time in some less
445
- // performance critical paths.
446
- var computedPositions = this._computedPositions;
447
- if (!computedPositions) {
448
- this._computePositions();
449
- }
450
- return this._computedPositions;
451
- },
452
-
453
- /**
454
- * Precomputes the index/key mapping for future lookup. Since `OrderedMap`s
455
- * are immutable, there is only ever a need to perform this once.
456
- * @private
457
- */
458
- _computePositions: function() {
459
- this._computedPositions = {
460
- keyByIndex: {},
461
- indexByKey: {},
462
- };
463
- var keyByIndex = this._computedPositions.keyByIndex;
464
- var indexByKey = this._computedPositions.indexByKey;
465
- var index = 0;
466
- var thisSet = this._normalizedObj;
467
- for (var key in thisSet) {
468
- if (thisSet.hasOwnProperty(key)) {
469
- keyByIndex[index] = key;
470
- indexByKey[key] = index;
471
- index++;
472
- }
473
- }
474
- },
475
-};
476
-
477
-Object.assign(OrderedMapImpl.prototype, OrderedMapMethods);
478
-
479
-var OrderedMap = {
480
- from: function(orderedMap) {
481
- invariant(
482
- orderedMap instanceof OrderedMapImpl,
483
- 'OrderedMap.from(...): Expected an OrderedMap instance.'
484
- );
485
- return _fromNormalizedObjects(orderedMap._normalizedObj, null);
486
- },
487
-
488
- fromArray: function(arr, keyExtractor) {
489
- invariant(
490
- Array.isArray(arr),
491
- 'OrderedMap.fromArray(...): First argument must be an array.'
492
- );
493
- invariant(
494
- typeof keyExtractor === 'function',
495
- 'OrderedMap.fromArray(...): Second argument must be a function used ' +
496
- 'to determine the unique key for each entry.'
497
- );
498
- return new OrderedMapImpl(
499
- extractObjectFromArray(arr, keyExtractor),
500
- arr.length
501
- );
502
- },
503
-};
504
-
505
-module.exports = OrderedMap;
src/isomorphic/deprecated/ReactPropTransferer.js
deleted
-107
@@ -1,107 +0,0 @@
1
-/**
2
- * Copyright 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @providesModule ReactPropTransferer
10
- */
11
-
12
-'use strict';
13
-
14
-var emptyFunction = require('emptyFunction');
15
-var joinClasses = require('joinClasses');
16
-
17
-/**
18
- * Creates a transfer strategy that will merge prop values using the supplied
19
- * `mergeStrategy`. If a prop was previously unset, this just sets it.
20
- *
21
- * @param {function} mergeStrategy
22
- * @return {function}
23
- */
24
-function createTransferStrategy(mergeStrategy) {
25
- return function(props, key, value) {
26
- if (!props.hasOwnProperty(key)) {
27
- props[key] = value;
28
- } else {
29
- props[key] = mergeStrategy(props[key], value);
30
- }
31
- };
32
-}
33
-
34
-var transferStrategyMerge = createTransferStrategy(function(a, b) {
35
- // `merge` overrides the first object's (`props[key]` above) keys using the
36
- // second object's (`value`) keys. An object's style's existing `propA` would
37
- // get overridden. Flip the order here.
38
- return Object.assign({}, b, a);
39
-});
40
-
41
-/**
42
- * Transfer strategies dictate how props are transferred by `transferPropsTo`.
43
- * NOTE: if you add any more exceptions to this list you should be sure to
44
- * update `cloneWithProps()` accordingly.
45
- */
46
-var TransferStrategies = {
47
- /**
48
- * Never transfer `children`.
49
- */
50
- children: emptyFunction,
51
- /**
52
- * Transfer the `className` prop by merging them.
53
- */
54
- className: createTransferStrategy(joinClasses),
55
- /**
56
- * Transfer the `style` prop (which is an object) by merging them.
57
- */
58
- style: transferStrategyMerge,
59
-};
60
-
61
-/**
62
- * Mutates the first argument by transferring the properties from the second
63
- * argument.
64
- *
65
- * @param {object} props
66
- * @param {object} newProps
67
- * @return {object}
68
- */
69
-function transferInto(props, newProps) {
70
- for (var thisKey in newProps) {
71
- if (!newProps.hasOwnProperty(thisKey)) {
72
- continue;
73
- }
74
-
75
- var transferStrategy = TransferStrategies[thisKey];
76
-
77
- if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) {
78
- transferStrategy(props, thisKey, newProps[thisKey]);
79
- } else if (!props.hasOwnProperty(thisKey)) {
80
- props[thisKey] = newProps[thisKey];
81
- }
82
- }
83
- return props;
84
-}
85
-
86
-/**
87
- * ReactPropTransferer are capable of transferring props to another component
88
- * using a `transferPropsTo` method.
89
- *
90
- * @class ReactPropTransferer
91
- */
92
-var ReactPropTransferer = {
93
-
94
- /**
95
- * Merge two props objects using TransferStrategies.
96
- *
97
- * @param {object} oldProps original props (they take precedence)
98
- * @param {object} newProps new props to merge in
99
- * @return {object} a new object containing both sets of props merged.
100
- */
101
- mergeProps: function(oldProps, newProps) {
102
- return transferInto(Object.assign({}, oldProps), newProps);
103
- },
104
-
105
-};
106
-
107
-module.exports = ReactPropTransferer;
src/shared/utils/__tests__/OrderedMap-test.js
deleted
-941
@@ -1,941 +0,0 @@
1
-/**
2
- * Copyright 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @emails react-core
10
- */
11
-
12
-'use strict';
13
-
14
-var OrderedMap;
15
-
16
-/**
17
- * Shared, reusable objects.
18
- */
19
-var hasEmptyStringKey = {
20
- 'thisKeyIsFine': {data: []},
21
- '': {thisShouldCauseAFailure: []},
22
- 'thisKeyIsAlsoFine': {data: []},
23
-};
24
-
25
-/**
26
- * Used as map/forEach callback.
27
- */
28
-var duplicate = function(itm, key, count) {
29
- return {
30
- uniqueID: itm.uniqueID,
31
- val: itm.val + key + count + this.justToTestScope,
32
- };
33
-};
34
-
35
-// Should not be allowed - because then null/'null' become impossible to
36
-// distinguish. Every key MUST be a string period!
37
-var hasNullAndUndefStringKey = [
38
- {uniqueID: 'undefined', val: 'thisIsUndefined'},
39
- {uniqueID: 'null', val: 'thisIsNull'},
40
-];
41
-var hasNullKey = [
42
- {uniqueID: 'thisKeyIsFine', data: []},
43
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
44
- {uniqueID: null, data: []},
45
-];
46
-
47
-var hasObjectKey = [
48
- {uniqueID: 'thisKeyIsFine', data: []},
49
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
50
- {uniqueID: {}, data: []},
51
-];
52
-
53
-var hasArrayKey = [
54
- {uniqueID: 'thisKeyIsFine', data: []},
55
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
56
- {uniqueID: [], data: []},
57
-];
58
-
59
-// This should be allowed
60
-var hasNullStringKey = [
61
- {uniqueID: 'thisKeyIsFine', data: []},
62
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
63
- {uniqueID: 'null', data: []},
64
-];
65
-
66
-var hasUndefinedKey = [
67
- {uniqueID: 'thisKeyIsFine', data: []},
68
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
69
- {uniqueID: undefined, data: []},
70
-];
71
-
72
-var hasUndefinedStringKey = [
73
- {uniqueID: 'thisKeyIsFine', data: []},
74
- {uniqueID: 'thisKeyIsAlsoFine', data: []},
75
- {uniqueID: 'undefined', data: []},
76
-];
77
-
78
-var hasPositiveNumericKey = [
79
- {uniqueID: 'notANumber', data: []},
80
- {uniqueID: '5', data: []},
81
- {uniqueID: 'notAnotherNumber', data: []},
82
-];
83
-
84
-var hasZeroStringKey = [
85
- {uniqueID: 'greg', data: 'grego'},
86
- {uniqueID: '0', data: '0o'},
87
- {uniqueID: 'tom', data: 'tomo'},
88
-];
89
-
90
-var hasZeroNumberKey = [
91
- {uniqueID: 'greg', data: 'grego'},
92
- {uniqueID: 0, data: '0o'},
93
- {uniqueID: 'tom', data: 'tomo'},
94
-];
95
-
96
-var hasAllNumericStringKeys = [
97
- {uniqueID: '0', name: 'Gregory'},
98
- {uniqueID: '2', name: 'James'},
99
- {uniqueID: '1', name: 'Tom'},
100
-];
101
-
102
-var hasAllNumericKeys = [
103
- {uniqueID: 0, name: 'Gregory'},
104
- {uniqueID: 2, name: 'James'},
105
- {uniqueID: 1, name: 'Tom'},
106
-];
107
-
108
-var hasAllValidKeys = [
109
- {uniqueID: 'keyOne', value: 'valueOne'},
110
- {uniqueID: 'keyTwo', value: 'valueTwo'},
111
-];
112
-
113
-var hasDuplicateKeys = [
114
- {uniqueID: 'keyOne', value: 'valueOne'},
115
- {uniqueID: 'keyTwo', value: 'valueTwo'},
116
- {uniqueID: 'keyOne', value: 'valueThree'},
117
-];
118
-
119
-var idEntities = [
120
- {uniqueID: 'greg', name: 'Gregory'},
121
- {uniqueID: 'james', name: 'James'},
122
- {uniqueID: 'tom', name: 'Tom'},
123
-];
124
-
125
-var hasEmptyKey = [
126
- {uniqueID: 'greg', name: 'Gregory'},
127
- {uniqueID: '', name: 'James'},
128
- {uniqueID: 'tom', name: 'Tom'},
129
-];
130
-
131
-var extractUniqueID = function(entity) {
132
- return entity.uniqueID;
133
-};
134
-
135
-describe('OrderedMap', function() {
136
- beforeEach(function() {
137
- jest.resetModuleRegistry();
138
- OrderedMap = require('OrderedMap');
139
- });
140
-
141
- it('should create according to simple object with keys', function() {
142
- OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
143
- // Iterate over and ensure key order.
144
- });
145
-
146
- it('should create from array when providing an identity CB', function() {
147
- expect(function() {
148
- OrderedMap.fromArray(idEntities, extractUniqueID);
149
- }).not.toThrow();
150
- });
151
-
152
- it('should throw if constructing from Array without identity CB', function() {
153
- OrderedMap.fromArray(idEntities, extractUniqueID);
154
- // Iterate and ensure key order
155
- });
156
-
157
- it('should not throw when fromArray extracts a numeric key', function() {
158
- expect(function() {
159
- OrderedMap.fromArray(hasPositiveNumericKey, extractUniqueID);
160
- }).not.toThrow();
161
-
162
- });
163
-
164
- it('should throw when any key is the empty string', function() {
165
- expect(function() {
166
- OrderedMap.fromArray(hasEmptyKey, extractUniqueID);
167
- }).toThrow();
168
- });
169
-
170
- it('should not throw when a key is the string "undefined" or "null"',
171
- function() {
172
- var om = OrderedMap.fromArray(hasNullAndUndefStringKey, extractUniqueID);
173
- expect(om.length).toBe(2);
174
- expect(om.indexOfKey('undefined')).toBe(0);
175
- expect(om.indexOfKey('null')).toBe(1);
176
- expect(om.keyAfter('undefined')).toBe('null');
177
- expect(om.keyAfter('null')).toBe(undefined);
178
- expect(om.keyBefore('undefined')).toBe(undefined);
179
- expect(om.has('undefined')).toBe(true);
180
- expect(om.has('null')).toBe(true);
181
- expect(om.get('undefined').val).toBe('thisIsUndefined');
182
- expect(om.get('null').val).toBe('thisIsNull');
183
- });
184
-
185
-
186
- /**
187
- * Numeric keys are cast to strings.
188
- */
189
- it('should not throw when a key is the number zero', function() {
190
- var om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);
191
- expect(om.length).toBe(3);
192
- expect(om.indexOfKey('0')).toBe(1);
193
- expect(om.indexOfKey(0)).toBe(1);
194
- });
195
-
196
- it('should throw when any key is falsey', function() {
197
- expect(function() {
198
- OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);
199
- }).toThrow();
200
-
201
- expect(function() {
202
- OrderedMap.fromArray(hasNullKey, extractUniqueID);
203
- }).toThrow();
204
-
205
- expect(function() {
206
- OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);
207
- }).toThrow();
208
- });
209
-
210
- it('should not throw on string keys "undefined/null"', function() {
211
- expect(function() {
212
- OrderedMap.fromArray(hasNullStringKey, extractUniqueID);
213
- }).not.toThrow();
214
-
215
- expect(function() {
216
- OrderedMap.fromArray(hasUndefinedStringKey, extractUniqueID);
217
- }).not.toThrow();
218
- });
219
-
220
- it('should throw on extracting keys that are not strings/nums', function() {
221
- expect(function() {
222
- OrderedMap.fromArray(hasObjectKey, extractUniqueID);
223
- }).toThrow();
224
-
225
- expect(function() {
226
- OrderedMap.fromArray(hasArrayKey, extractUniqueID);
227
- }).toThrow();
228
- });
229
-
230
- it('should throw if instantiating with duplicate key', function() {
231
- expect(function() {
232
- OrderedMap.fromArray(hasDuplicateKeys, extractUniqueID);
233
- }).toThrow();
234
- });
235
-
236
- it('should not throw when a key is the string "0"', function() {
237
- var verifyOM = function(om) {
238
- expect(om.length).toBe(3);
239
- expect(om.indexOfKey('greg')).toBe(0);
240
- expect(om.indexOfKey('0')).toBe(1);
241
- expect(om.indexOfKey(0)).toBe(1); // Casts on writes and reads.
242
- expect(om.indexOfKey('tom')).toBe(2);
243
- expect(om.keyAfter('greg')).toBe('0');
244
- expect(om.keyAfter('0')).toBe('tom');
245
- expect(om.keyAfter(0)).toBe('tom');
246
- expect(om.keyAfter('tom')).toBe(undefined);
247
- expect(om.keyBefore('greg')).toBe(undefined);
248
- expect(om.keyBefore(0)).toBe('greg');
249
- expect(om.keyBefore('0')).toBe('greg');
250
- expect(om.keyBefore('tom')).toBe('0');
251
- expect(om.has('undefined')).toBe(false);
252
- expect(om.has(0)).toBe(true);
253
- expect(om.has('0')).toBe(true);
254
- };
255
- verifyOM(OrderedMap.fromArray(hasZeroStringKey, extractUniqueID));
256
- verifyOM(OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID));
257
- });
258
-
259
- it('should throw when getting invalid public key', function() {
260
- var om = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
261
- expect(function() {
262
- om.has(undefined);
263
- }).toThrow();
264
- expect(function() {
265
- om.get(undefined);
266
- }).toThrow();
267
- expect(function() {
268
- om.has(null);
269
- }).toThrow();
270
- expect(function() {
271
- om.get(null);
272
- }).toThrow();
273
- expect(function() {
274
- om.has('');
275
- }).toThrow();
276
- expect(function() {
277
- om.get('');
278
- }).toThrow();
279
- });
280
-
281
- it('should throw when any key is falsey', function() {
282
- expect(function() {
283
- OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);
284
- }).toThrow();
285
-
286
- expect(function() {
287
- OrderedMap.fromArray(hasNullKey, extractUniqueID);
288
- }).toThrow();
289
-
290
- expect(function() {
291
- OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);
292
- }).toThrow();
293
- });
294
-
295
-
296
- it('should throw when fromArray is passed crazy args', function() {
297
- // Test passing another OrderedMap (when it expects a plain object.)
298
- // This is probably not what you meant to do! We should error.
299
- var validOM = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
300
- expect(function() {
301
- OrderedMap.fromArray({uniqueID: 'asdf'}, extractUniqueID);
302
- }).toThrow();
303
- expect(function() {
304
- OrderedMap.fromArray(validOM, extractUniqueID);
305
- }).toThrow();
306
- });
307
-
308
- it('should throw when fromArray is passed crazy things', function() {
309
- expect(function() {
310
- OrderedMap.fromArray(null, extractUniqueID);
311
- }).toThrow();
312
- expect(function() {
313
- OrderedMap.fromArray('stringgg', extractUniqueID);
314
- }).toThrow();
315
- expect(function() {
316
- OrderedMap.fromArray(undefined, extractUniqueID);
317
- }).toThrow();
318
- expect(function() {
319
- OrderedMap.fromArray(new Date(), extractUniqueID);
320
- }).toThrow();
321
- expect(function() {
322
- OrderedMap.fromArray({}, extractUniqueID);
323
- }).toThrow();
324
-
325
- // Test failure without extractor
326
- expect(function() {
327
- OrderedMap.fromArray(idEntities);
328
- }).toThrow();
329
- expect(function() {
330
- OrderedMap.fromArray(idEntities, extractUniqueID);
331
- }).not.toThrow();
332
- });
333
-
334
- // Testing methods that accept other `OrderedMap`s.
335
- it('should throw when from/merge is passed an non-OrderedMap.', function() {
336
- // Test passing an array to construction.
337
- expect(function() {
338
- OrderedMap.from(idEntities, extractUniqueID);
339
- }).toThrow();
340
-
341
- // Test passing an array to merge.
342
- expect(function() {
343
- OrderedMap.fromArray(idEntities, extractUniqueID)
344
- .merge(idEntities, extractUniqueID);
345
- }).toThrow();
346
-
347
-
348
- // Test passing a plain object to merge.
349
- expect(function() {
350
- OrderedMap.fromArray(
351
- idEntities,
352
- extractUniqueID
353
- ).merge({blah: 'willFail'});
354
- }).toThrow();
355
- });
356
-
357
- it('should throw when accessing key before/after of non-key', function() {
358
- var om = OrderedMap.fromArray(
359
- [
360
- {uniqueID: 'first'},
361
- {uniqueID: 'two'},
362
- ], extractUniqueID
363
- );
364
- expect(function() {
365
- om.keyBefore('dog');
366
- }).toThrow();
367
- expect(function() {
368
- om.keyAfter('cat');
369
- }).toThrow();
370
- expect(function() {
371
- om.keyAfter(null);
372
- }).toThrow();
373
- expect(function() {
374
- om.keyAfter(undefined);
375
- }).toThrow();
376
- });
377
-
378
- it('should throw passing invalid/not-present-keys to before/after',
379
- function() {
380
- var om = OrderedMap.fromArray([
381
- {uniqueID: 'one', val: 'first'},
382
- {uniqueID: 'two', val: 'second'},
383
- {uniqueID: 'three', val: 'third'},
384
- {uniqueID: 'four', val: 'fourth'},
385
- ], extractUniqueID);
386
-
387
- expect(function() {
388
- om.keyBefore('');
389
- }).toThrow();
390
- expect(function() {
391
- om.keyBefore(null);
392
- }).toThrow();
393
- expect(function() {
394
- om.keyBefore(undefined);
395
- }).toThrow();
396
- expect(function() {
397
- om.keyBefore('notInTheOrderedMap!');
398
- }).toThrow();
399
-
400
- expect(function() {
401
- om.keyAfter('');
402
- }).toThrow();
403
- expect(function() {
404
- om.keyAfter(null);
405
- }).toThrow();
406
- expect(function() {
407
- om.keyAfter(undefined);
408
- }).toThrow();
409
- expect(function() {
410
- om.keyAfter('notInTheOrderedMap!');
411
- }).toThrow();
412
-
413
- expect(function() {
414
- om.nthKeyAfter('', 1);
415
- }).toThrow();
416
- expect(function() {
417
- om.nthKeyAfter(null, 1);
418
- }).toThrow();
419
- expect(function() {
420
- om.nthKeyAfter(undefined, 1);
421
- }).toThrow();
422
- expect(function() {
423
- om.nthKeyAfter('notInTheOrderedMap!', 1);
424
- }).toThrow();
425
-
426
- expect(function() {
427
- om.nthKeyBefore('', 1);
428
- }).toThrow();
429
- expect(function() {
430
- om.nthKeyBefore(null, 1);
431
- }).toThrow();
432
- expect(function() {
433
- om.nthKeyBefore(undefined, 1);
434
- }).toThrow();
435
- expect(function() {
436
- om.nthKeyBefore('notInTheOrderedMap!', 1);
437
- }).toThrow();
438
- });
439
-
440
- it('should correctly determine the nth key after before', function() {
441
- var om = OrderedMap.fromArray([
442
- {uniqueID: 'one', val: 'first'},
443
- {uniqueID: 'two', val: 'second'},
444
- {uniqueID: 'three', val: 'third'},
445
- {uniqueID: 'four', val: 'fourth'},
446
- ], extractUniqueID);
447
- expect(om.keyBefore('one')).toBe(undefined); // first key
448
- expect(om.keyBefore('two')).toBe('one');
449
- expect(om.keyBefore('three')).toBe('two');
450
- expect(om.keyBefore('four')).toBe('three');
451
-
452
- expect(om.keyAfter('one')).toBe('two'); // first key
453
- expect(om.keyAfter('two')).toBe('three');
454
- expect(om.keyAfter('three')).toBe('four');
455
- expect(om.keyAfter('four')).toBe(undefined);
456
-
457
- expect(om.nthKeyBefore('one', 0)).toBe('one'); // first key
458
- expect(om.nthKeyBefore('one', 1)).toBe(undefined);
459
- expect(om.nthKeyBefore('one', 2)).toBe(undefined);
460
- expect(om.nthKeyBefore('two', 0)).toBe('two');
461
- expect(om.nthKeyBefore('two', 1)).toBe('one');
462
- expect(om.nthKeyBefore('four', 0)).toBe('four');
463
- expect(om.nthKeyBefore('four', 1)).toBe('three');
464
-
465
- expect(om.nthKeyAfter('one', 0)).toBe('one');
466
- expect(om.nthKeyAfter('one', 1)).toBe('two');
467
- expect(om.nthKeyAfter('one', 2)).toBe('three');
468
- expect(om.nthKeyAfter('two', 0)).toBe('two');
469
- expect(om.nthKeyAfter('two', 1)).toBe('three');
470
- expect(om.nthKeyAfter('four', 0)).toBe('four');
471
- expect(om.nthKeyAfter('four', 1)).toBe(undefined);
472
- });
473
-
474
- it('should compute key indices correctly', function() {
475
- var om = OrderedMap.fromArray([
476
- {uniqueID: 'one', val: 'first'},
477
- {uniqueID: 'two', val: 'second'},
478
- ], extractUniqueID);
479
- expect(om.keyAtIndex(0)).toBe('one');
480
- expect(om.keyAtIndex(1)).toBe('two');
481
- expect(om.keyAtIndex(2)).toBe(undefined);
482
- expect(om.indexOfKey('one')).toBe(0);
483
- expect(om.indexOfKey('two')).toBe(1);
484
- expect(om.indexOfKey('nope')).toBe(undefined);
485
- expect(function() {
486
- om.indexOfKey(null);
487
- }).toThrow();
488
- expect(function() {
489
- om.indexOfKey(undefined);
490
- }).toThrow();
491
- expect(function() {
492
- om.indexOfKey(''); // Empty key is not allowed
493
- }).toThrow();
494
- });
495
-
496
- it('should compute indices on array that extracted numeric ids', function() {
497
- var som = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);
498
- expect(som.keyAtIndex(0)).toBe('greg');
499
- expect(som.keyAtIndex(1)).toBe('0');
500
- expect(som.keyAtIndex(2)).toBe('tom');
501
- expect(som.indexOfKey('greg')).toBe(0);
502
- expect(som.indexOfKey('0')).toBe(1);
503
- expect(som.indexOfKey('tom')).toBe(2);
504
-
505
-
506
- var verifyNumericKeys = function(nom) {
507
- expect(nom.keyAtIndex(0)).toBe('0');
508
- expect(nom.keyAtIndex(1)).toBe('2');
509
- expect(nom.keyAtIndex(2)).toBe('1');
510
- expect(nom.indexOfKey('0')).toBe(0);
511
- expect(nom.indexOfKey('2')).toBe(1); // Prove these are not ordered by
512
- expect(nom.indexOfKey('1')).toBe(2); // their keys
513
- };
514
- var omStringNumberKeys =
515
- OrderedMap.fromArray(hasAllNumericStringKeys, extractUniqueID);
516
- verifyNumericKeys(omStringNumberKeys);
517
- var omNumericKeys =
518
- OrderedMap.fromArray(hasAllNumericKeys, extractUniqueID);
519
- verifyNumericKeys(omNumericKeys);
520
- });
521
-
522
- it('should compute indices on mutually exclusive merge', function() {
523
- var om = OrderedMap.fromArray([
524
- {uniqueID: 'one', val: 'first'},
525
- {uniqueID: 'two', val: 'second'},
526
- ], extractUniqueID);
527
- var om2 = OrderedMap.fromArray([
528
- {uniqueID: 'three', val: 'third'},
529
- ], extractUniqueID);
530
- var res = om.merge(om2);
531
-
532
- expect(res.length).toBe(3);
533
-
534
- expect(res.keyAtIndex(0)).toBe('one');
535
- expect(res.keyAtIndex(1)).toBe('two');
536
- expect(res.keyAtIndex(2)).toBe('three');
537
- expect(res.keyAtIndex(3)).toBe(undefined);
538
-
539
- expect(res.indexOfKey('one')).toBe(0);
540
- expect(res.indexOfKey('two')).toBe(1);
541
- expect(res.indexOfKey('three')).toBe(2);
542
- expect(res.indexOfKey('dog')).toBe(undefined);
543
-
544
- expect(res.has('one')).toBe(true);
545
- expect(res.has('two')).toBe(true);
546
- expect(res.has('three')).toBe(true);
547
- expect(res.has('dog')).toBe(false);
548
-
549
- expect(res.get('one').val).toBe('first');
550
- expect(res.get('two').val).toBe('second');
551
- expect(res.get('three').val).toBe('third');
552
- expect(res.get('dog')).toBe(undefined);
553
- });
554
-
555
- it('should compute indices on intersected merge', function() {
556
- var oneTwo = OrderedMap.fromArray([
557
- {uniqueID: 'one', val: 'first'},
558
- {uniqueID: 'two', val: 'secondOM1'},
559
- ], extractUniqueID);
560
-
561
- var testOneTwoMergedWithTwoThree = function(res) {
562
- expect(res.length).toBe(3);
563
- expect(res.keyAtIndex(0)).toBe('one');
564
- expect(res.keyAtIndex(1)).toBe('two');
565
- expect(res.keyAtIndex(2)).toBe('three');
566
- expect(res.keyAtIndex(3)).toBe(undefined);
567
- expect(res.indexOfKey('one')).toBe(0);
568
- expect(res.indexOfKey('two')).toBe(1);
569
- expect(res.indexOfKey('three')).toBe(2);
570
- expect(res.indexOfKey('dog')).toBe(undefined);
571
- expect(res.has('one')).toBe(true);
572
- expect(res.has('two')).toBe(true);
573
- expect(res.has('three')).toBe(true);
574
- expect(res.has('dog')).toBe(false);
575
- expect(res.get('one').val).toBe('first');
576
- expect(res.get('two').val).toBe('secondOM2');
577
- expect(res.get('three').val).toBe('third');
578
- expect(res.get('dog')).toBe(undefined);
579
- };
580
-
581
- var result =
582
- oneTwo.merge(OrderedMap.fromArray([
583
- {uniqueID: 'two', val: 'secondOM2'},
584
- {uniqueID: 'three', val: 'third'},
585
- ], extractUniqueID));
586
- testOneTwoMergedWithTwoThree(result);
587
-
588
- // Everything should be exactly as before, since the ordering of `two` was
589
- // already determined by `om`.
590
- result = oneTwo.merge(
591
- OrderedMap.fromArray([
592
- {uniqueID: 'three', val: 'third'},
593
- {uniqueID: 'two', val:'secondOM2'},
594
- ], extractUniqueID)
595
- );
596
- testOneTwoMergedWithTwoThree(result);
597
-
598
-
599
- var testTwoThreeMergedWithOneTwo = function(res) {
600
- expect(res.length).toBe(3);
601
- expect(res.keyAtIndex(0)).toBe('two');
602
- expect(res.keyAtIndex(1)).toBe('three');
603
- expect(res.keyAtIndex(2)).toBe('one');
604
- expect(res.keyAtIndex(3)).toBe(undefined);
605
- expect(res.indexOfKey('two')).toBe(0);
606
- expect(res.indexOfKey('three')).toBe(1);
607
- expect(res.indexOfKey('one')).toBe(2);
608
- expect(res.indexOfKey('cat')).toBe(undefined);
609
- expect(res.has('two')).toBe(true);
610
- expect(res.has('three')).toBe(true);
611
- expect(res.has('one')).toBe(true);
612
- expect(res.has('dog')).toBe(false);
613
- expect(res.get('one').val).toBe('first');
614
- expect(res.get('two').val).toBe('secondOM1');
615
- expect(res.get('three').val).toBe('third');
616
- expect(res.get('dog')).toBe(undefined);
617
- };
618
- result = OrderedMap.fromArray([
619
- {uniqueID: 'two', val: 'secondOM2'},
620
- {uniqueID: 'three', val: 'third'},
621
- ], extractUniqueID).merge(oneTwo);
622
- testTwoThreeMergedWithOneTwo(result);
623
-
624
- });
625
-
626
- it('should merge mutually exclusive keys to the end.', function() {
627
- var om = OrderedMap.fromArray([
628
- {uniqueID: 'one', val: 'first'},
629
- {uniqueID: 'two', val: 'second'},
630
- ], extractUniqueID);
631
- var om2 = OrderedMap.fromArray([
632
- {uniqueID: 'three', val: 'first'},
633
- {uniqueID: 'four', val: 'second'},
634
- ], extractUniqueID);
635
- var res = om.merge(om2);
636
- expect(res.length).toBe(4);
637
-
638
- });
639
-
640
- it('should map correctly', function() {
641
- var om = OrderedMap.fromArray([
642
- {uniqueID: 'x', val: 'xx'},
643
- {uniqueID: 'y', val: 'yy'},
644
- {uniqueID: 'z', val: 'zz'},
645
- ], extractUniqueID);
646
- var scope = {justToTestScope: 'justTestingScope'};
647
- var verifyResult = function(omResult) {
648
- expect(omResult.length).toBe(3);
649
- expect(omResult.keyAtIndex(0)).toBe('x');
650
- expect(omResult.keyAtIndex(1)).toBe('y');
651
- expect(omResult.keyAtIndex(2)).toBe('z');
652
- expect(omResult.get('x').val).toBe('xxx0justTestingScope');
653
- expect(omResult.get('y').val).toBe('yyy1justTestingScope');
654
- expect(omResult.get('z').val).toBe('zzz2justTestingScope');
655
- };
656
- var resultOM = om.map(function(itm, key, count) {
657
- return {
658
- uniqueID: itm.uniqueID,
659
- val: itm.val + key + count + this.justToTestScope,
660
- };
661
- }, scope);
662
- verifyResult(resultOM);
663
-
664
- var resArray = [];
665
- om.forEach(function(itm, key, count) {
666
- resArray.push({
667
- uniqueID: itm.uniqueID,
668
- val: itm.val + key + count + this.justToTestScope,
669
- });
670
- }, scope);
671
- resultOM = OrderedMap.fromArray(resArray, extractUniqueID);
672
- verifyResult(resultOM);
673
- });
674
-
675
- it('should filter correctly', function() {
676
- var om = OrderedMap.fromArray([
677
- {uniqueID: 'x', val: 'xx'},
678
- {uniqueID: 'y', val: 'yy'},
679
- {uniqueID: 'z', val: 'zz'},
680
- ], extractUniqueID);
681
- var scope = {justToTestScope: 'justTestingScope'};
682
-
683
- var filteringCallback = function(item, key, indexInOriginal) {
684
- expect(this).toBe(scope);
685
- expect(key === 'x' || key === 'y' || key === 'z').toBe(true);
686
- if (key === 'x') {
687
- expect(item.val).toBe('xx');
688
- expect(indexInOriginal).toBe(0);
689
- return false;
690
- } else if (key === 'y') {
691
- expect(item.val).toBe('yy');
692
- expect(indexInOriginal).toBe(1);
693
- return true;
694
- } else {
695
- expect(item.val).toBe('zz');
696
- expect(indexInOriginal).toBe(2);
697
- return true;
698
- }
699
- };
700
-
701
- var verifyResult = function(omResult) {
702
- expect(omResult.length).toBe(2);
703
- expect(omResult.keyAtIndex(0)).toBe('y');
704
- expect(omResult.keyAtIndex(1)).toBe('z');
705
- expect(omResult.has('x')).toBe(false);
706
- expect(omResult.has('z')).toBe(true);
707
- expect(omResult.get('z').val).toBe('zz');
708
- expect(omResult.has('y')).toBe(true);
709
- expect(omResult.get('y').val).toBe('yy');
710
- };
711
-
712
- var resultOM = om.filter(filteringCallback, scope);
713
- verifyResult(resultOM);
714
- });
715
-
716
- it('should throw when providing invalid ranges to ranging', function() {
717
- var om = OrderedMap.fromArray([
718
- {uniqueID: 'x', val: 'xx'},
719
- {uniqueID: 'y', val: 'yy'},
720
- {uniqueID: 'z', val: 'zz'},
721
- ], extractUniqueID);
722
- var scope = {justToTestScope: 'justTestingScope'};
723
-
724
- expect(function() {
725
- om.mapRange(duplicate, 0, 3, scope);
726
- }).not.toThrow();
727
- expect(function() {
728
- om.filterRange(duplicate, 0, 3, scope);
729
- }).not.toThrow();
730
- expect(function() {
731
- om.forEachRange(duplicate, 0, 3, scope);
732
- }).not.toThrow();
733
- expect(function() {
734
- om.mapKeyRange(duplicate, 'x', 3, scope);
735
- }).toThrow(
736
- 'mapKeyRange must be given keys that are present.'
737
- );
738
- expect(function() {
739
- om.forEachKeyRange(duplicate, 'x', 3, scope);
740
- }).toThrow(
741
- 'forEachKeyRange must be given keys that are present.'
742
- );
743
-
744
- expect(function() {
745
- om.mapRange(duplicate, 0, 4, scope);
746
- }).toThrow();
747
- expect(function() {
748
- om.filterRange(duplicate, 0, 4, scope);
749
- }).toThrow();
750
- expect(function() {
751
- om.forEachRange(duplicate, 0, 4, scope);
752
- }).toThrow();
753
- expect(function() {
754
- om.mapKeyRange(duplicate, 'x', null, scope);
755
- }).toThrow();
756
- expect(function() {
757
- om.forEachKeyRange(duplicate, 'x', null, scope);
758
- }).toThrow();
759
-
760
- expect(function() {
761
- om.mapRange(duplicate, -1, 1, scope);
762
- }).toThrow();
763
- expect(function() {
764
- om.filterRange(duplicate, -1, 1, scope);
765
- }).toThrow();
766
- expect(function() {
767
- om.forEachRange(duplicate, -1, 1, scope);
768
- }).toThrow();
769
- expect(function() {
770
- om.mapKeyRange(duplicate, null, 'y', scope);
771
- }).toThrow();
772
- expect(function() {
773
- om.forEachKeyRange(duplicate, null, 'y', scope);
774
- }).toThrow();
775
-
776
- expect(function() {
777
- om.mapRange(duplicate, 0, 0, scope);
778
- }).not.toThrow();
779
- expect(function() {
780
- om.filterRange(duplicate, 0, 0, scope);
781
- }).not.toThrow();
782
- expect(function() {
783
- om.forEachRange(duplicate, 0, 0, scope);
784
- }).not.toThrow();
785
- expect(function() {
786
- om.mapKeyRange(duplicate, 'x', 'x', scope);
787
- }).not.toThrow();
788
- expect(function() {
789
- om.forEachKeyRange(duplicate, 'x', 'x', scope);
790
- }).not.toThrow();
791
-
792
- expect(function() {
793
- om.mapRange(duplicate, 0, -1, scope);
794
- }).toThrow();
795
- expect(function() {
796
- om.filterRange(duplicate, 0, -1, scope);
797
- }).toThrow();
798
- expect(function() {
799
- om.forEachRange(duplicate, 0, -1, scope);
800
- }).toThrow();
801
- expect(function() {
802
- om.mapKeyRange(duplicate, 'x', null, scope);
803
- }).toThrow();
804
- expect(function() {
805
- om.forEachKeyRange(duplicate, 'x', null, scope);
806
- }).toThrow();
807
-
808
- expect(function() {
809
- om.mapRange(duplicate, 2, 1, scope);
810
- }).not.toThrow();
811
- expect(function() {
812
- om.filterRange(duplicate, 2, 1, scope);
813
- }).not.toThrow();
814
- expect(function() {
815
- om.forEachRange(duplicate, 2, 1, scope);
816
- }).not.toThrow();
817
- expect(function() {
818
- om.mapKeyRange(duplicate, 'z', 'z', scope);
819
- }).not.toThrow();
820
- expect(function() {
821
- om.forEachKeyRange(duplicate, 'z', 'z', scope);
822
- }).not.toThrow();
823
-
824
- expect(function() {
825
- om.mapRange(duplicate, 2, 2, scope);
826
- }).toThrow();
827
- expect(function() {
828
- om.filterRange(duplicate, 2, 2, scope);
829
- }).toThrow();
830
- expect(function() {
831
- om.forEachRange(duplicate, 2, 2, scope);
832
- }).toThrow();
833
- expect(function() {
834
- om.mapKeyRange(duplicate, 'z', null, scope);
835
- }).toThrow();
836
- expect(function() {
837
- om.forEachKeyRange(duplicate, 'z', null, scope);
838
- }).toThrow();
839
-
840
- // Provide keys in reverse order - should throw.
841
- expect(function() {
842
- om.mapKeyRange(duplicate, 'y', 'x', scope);
843
- }).toThrow();
844
- expect(function() {
845
- om.forEachKeyRange(duplicate, 'y', 'x', scope);
846
- }).toThrow();
847
- });
848
-
849
- // TEST length zero map, or keyrange start===end
850
-
851
- it('should map range correctly', function() {
852
- var om = OrderedMap.fromArray([
853
- {uniqueID: 'x', val: 'xx'},
854
- {uniqueID: 'y', val: 'yy'},
855
- {uniqueID: 'z', val: 'zz'},
856
- ], extractUniqueID);
857
- var scope = {justToTestScope: 'justTestingScope'};
858
- var verifyThreeItems = function(omResult) {
859
- expect(omResult.length).toBe(3);
860
- expect(omResult.keyAtIndex(0)).toBe('x');
861
- expect(omResult.keyAtIndex(1)).toBe('y');
862
- expect(omResult.keyAtIndex(2)).toBe('z');
863
- expect(omResult.get('x').val).toBe('xxx0justTestingScope');
864
- expect(omResult.get('y').val).toBe('yyy1justTestingScope');
865
- expect(omResult.get('z').val).toBe('zzz2justTestingScope');
866
- };
867
- var verifyFirstTwoItems = function(omResult) {
868
- expect(omResult.length).toBe(2);
869
- expect(omResult.keyAtIndex(0)).toBe('x');
870
- expect(omResult.keyAtIndex(1)).toBe('y');
871
- expect(omResult.get('x').val).toBe('xxx0justTestingScope');
872
- expect(omResult.get('y').val).toBe('yyy1justTestingScope');
873
- };
874
-
875
- var verifyLastTwoItems = function(omResult) {
876
- expect(omResult.length).toBe(2);
877
- expect(omResult.keyAtIndex(0)).toBe('y');
878
- expect(omResult.keyAtIndex(1)).toBe('z');
879
- expect(omResult.get('y').val).toBe('yyy1justTestingScope');
880
- expect(omResult.get('z').val).toBe('zzz2justTestingScope');
881
- };
882
-
883
- var verifyMiddleItem = function(omResult) {
884
- expect(omResult.length).toBe(1);
885
- expect(omResult.keyAtIndex(0)).toBe('y');
886
- expect(omResult.get('y').val).toBe('yyy1justTestingScope');
887
- };
888
-
889
- var verifyEmpty = function(omResult) {
890
- expect(omResult.length).toBe(0);
891
- };
892
-
893
- var omResultThree = om.mapRange(duplicate, 0, 3, scope);
894
- verifyThreeItems(omResultThree);
895
- var resArray = [];
896
- var pushToResArray = function(itm, key, count) {
897
- resArray.push({
898
- uniqueID: itm.uniqueID,
899
- val: itm.val + key + count + this.justToTestScope,
900
- });
901
- };
902
-
903
- om.forEachRange(pushToResArray, 0, 3, scope);
904
- omResultThree = OrderedMap.fromArray(resArray, extractUniqueID);
905
- verifyThreeItems(omResultThree);
906
-
907
- var omResultFirstTwo = om.mapRange(duplicate, 0, 2, scope);
908
- verifyFirstTwoItems(omResultFirstTwo);
909
- resArray = [];
910
- om.forEachRange(pushToResArray, 0, 2, scope);
911
- omResultFirstTwo = OrderedMap.fromArray(resArray, extractUniqueID);
912
- verifyFirstTwoItems(omResultFirstTwo);
913
-
914
- var omResultLastTwo = om.mapRange(duplicate, 1, 2, scope);
915
- verifyLastTwoItems(omResultLastTwo);
916
- resArray = [];
917
- om.forEachRange(pushToResArray, 1, 2, scope);
918
- omResultLastTwo = OrderedMap.fromArray(resArray, extractUniqueID);
919
- verifyLastTwoItems(omResultLastTwo);
920
-
921
- var omResultMiddle = om.mapRange(duplicate, 1, 1, scope);
922
- verifyMiddleItem(omResultMiddle);
923
- resArray = [];
924
- om.forEachRange(pushToResArray, 1, 1, scope);
925
- omResultMiddle = OrderedMap.fromArray(resArray, extractUniqueID);
926
- verifyMiddleItem(omResultMiddle);
927
-
928
- var omResultNone = om.mapRange(duplicate, 1, 0, scope);
929
- verifyEmpty(omResultNone);
930
- });
931
-
932
- it('should extract the original array correctly', function() {
933
- var sourceArray = [
934
- {uniqueID: 'x', val: 'xx'},
935
- {uniqueID: 'y', val: 'yy'},
936
- {uniqueID: 'z', val: 'zz'},
937
- ];
938
- var om = OrderedMap.fromArray(sourceArray, extractUniqueID);
939
- expect(om.toArray()).toEqual(sourceArray);
940
- });
941
-});