From 27233230064316a8820cd1eb825adf3ea68b8160 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 31 Mar 2016 14:38:25 +0100 Subject: [PATCH] Remove OrderedMap and ReactPropTransferer These are not exposed publicly and have been deprecated. --- src/isomorphic/deprecated/OrderedMap.js | 505 ---------- .../deprecated/ReactPropTransferer.js | 107 -- src/shared/utils/__tests__/OrderedMap-test.js | 941 ------------------ 3 files changed, 1553 deletions(-) delete mode 100644 src/isomorphic/deprecated/OrderedMap.js delete mode 100644 src/isomorphic/deprecated/ReactPropTransferer.js delete mode 100644 src/shared/utils/__tests__/OrderedMap-test.js diff --git a/src/isomorphic/deprecated/OrderedMap.js b/src/isomorphic/deprecated/OrderedMap.js deleted file mode 100644 index 4336cdc384495..0000000000000 --- a/src/isomorphic/deprecated/OrderedMap.js +++ /dev/null @@ -1,505 +0,0 @@ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule OrderedMap - */ - -'use strict'; - -var invariant = require('invariant'); - -var PREFIX = 'key:'; - -/** - * Utility to extract a backing object from an initialization `Array`, allowing - * the caller to assist in resolving the unique ID for each entry via the - * `keyExtractor` callback. The `keyExtractor` must extract non-empty strings or - * numbers. - * @param {Array} arr Array of items. - * @param {function} keyExtractor Extracts a unique key from each item. - * @return {Object} Map from unique key to originating value that the key was - * extracted from. - * @throws Exception if the initialization array has duplicate extracted keys. - */ -function extractObjectFromArray(arr, keyExtractor) { - var normalizedObj = {}; - for (var i = 0; i < arr.length; i++) { - var item = arr[i]; - var key = keyExtractor(item); - assertValidPublicKey(key); - var normalizedKey = PREFIX + key; - invariant( - !(normalizedKey in normalizedObj), - 'OrderedMap: IDs returned by the key extraction function must be unique.' - ); - normalizedObj[normalizedKey] = item; - } - return normalizedObj; -} - -/** - * Utility class for mappings with ordering. This class is to be used in an - * immutable manner. A `OrderedMap` is very much like the native JavaScript - * object, where keys map to values via the `get()` function. Also, like the - * native JavaScript object, there is an ordering associated with the mapping. - * This class is helpful because it eliminates many of the pitfalls that come - * with the native JavaScript ordered mappings. Specifically, there are - * inconsistencies with numeric keys in some JavaScript implementations - * (enumeration ordering). This class protects against those pitfalls and - * provides functional utilities for dealing with these `OrderedMap`s. - * - * - TODO: - * - orderedMergeExclusive: Merges mutually exclusive `OrderedMap`s. - * - mapReverse(). - * - * @class {OrderedMap} - * @constructor {OrderedMap} - * @param {Object} normalizedObj Object that is known to be a defensive copy of - * caller supplied data. We require a defensive copy to guard against callers - * mutating. It is also assumed that the keys of `normalizedObj` have been - * normalized and do not contain any numeric-appearing strings. - * @param {number} computedLength The precomputed length of `_normalizedObj` - * keys. - * @private - */ -function OrderedMapImpl(normalizedObj, computedLength) { - this._normalizedObj = normalizedObj; - this._computedPositions = null; - this.length = computedLength; -} - -/** - * Validates a "public" key - that is, one that the public facing API supplies. - * The key is then normalized for internal storage. In order to be considered - * valid, all keys must be non-empty, defined, non-null strings or numbers. - * - * @param {string?} key Validates that the key is suitable for use in a - * `OrderedMap`. - * @throws Error if key is not appropriate for use in `OrderedMap`. - */ -function assertValidPublicKey(key) { - invariant( - key !== '' && (typeof key === 'string' || typeof key === 'number'), - 'OrderedMap: Key must be non-empty, non-null string or number.' - ); -} - -/** - * Validates that arguments to range operations are within the correct limits. - * - * @param {number} start Start of range. - * @param {number} length Length of range. - * @param {number} actualLen Actual length of range that should not be - * exceeded. - * @throws Error if range arguments are out of bounds. - */ -function assertValidRangeIndices(start, length, actualLen) { - invariant( - typeof start === 'number' && - typeof length === 'number' && - length >= 0 && - start >= 0 && - start + length <= actualLen, - 'OrderedMap: `mapRange` and `forEachRange` expect non-negative start and ' + - 'length arguments within the bounds of the instance.' - ); -} - -/** - * Merges two "normalized" objects (objects who's key have been normalized) into - * a `OrderedMap`. - * - * @param {Object} a Object of key value pairs. - * @param {Object} b Object of key value pairs. - * @return {OrderedMap} new `OrderedMap` that results in merging `a` and `b`. - */ -function _fromNormalizedObjects(a, b) { - // Second optional, both must be plain JavaScript objects. - invariant( - a && a.constructor === Object && (!b || b.constructor === Object), - 'OrderedMap: Corrupted instance of OrderedMap detected.' - ); - - var newSet = {}; - var length = 0; - var key; - for (key in a) { - if (a.hasOwnProperty(key)) { - newSet[key] = a[key]; - length++; - } - } - - for (key in b) { - if (b.hasOwnProperty(key)) { - // Increment length if not already added via first object (a) - if (!(key in newSet)) { - length++; - } - newSet[key] = b[key]; - } - } - return new OrderedMapImpl(newSet, length); -} - -/** - * Methods for `OrderedMap` instances. - * - * @lends OrderedMap.prototype - * TODO: Make this data structure lazy, unify with LazyArray. - * TODO: Unify this with ImmutableObject - it is to be used immutably. - * TODO: If so, consider providing `fromObject` API. - * TODO: Create faster implementation of merging/mapping from original Array, - * without having to first create an object - simply for the sake of merging. - */ -var OrderedMapMethods = { - - /** - * Returns whether or not a given key is present in the map. - * - * @param {string} key Valid string key to lookup membership for. - * @return {boolean} Whether or not `key` is a member of the map. - * @throws Error if provided known invalid key. - */ - has: function(key) { - assertValidPublicKey(key); - var normalizedKey = PREFIX + key; - return normalizedKey in this._normalizedObj; - }, - - /** - * Returns the object for a given key, or `undefined` if not present. To - * distinguish an undefined entry vs not being in the set, use `has()`. - * - * @param {string} key String key to lookup the value for. - * @return {Object?} Object at key `key`, or undefined if not in map. - * @throws Error if provided known invalid key. - */ - get: function(key) { - assertValidPublicKey(key); - var normalizedKey = PREFIX + key; - return this.has(key) ? this._normalizedObj[normalizedKey] : undefined; - }, - - /** - * Merges, appending new keys to the end of the ordering. Keys in `orderedMap` - * that are redundant with `this`, maintain the same ordering index that they - * had in `this`. This is how standard JavaScript object merging would work. - * If you wish to prepend a `OrderedMap` to the beginning of another - * `OrderedMap` then simply reverse the order of operation. This is the analog - * to `merge(x, y)`. - * - * @param {OrderedMap} orderedMap OrderedMap to merge onto the end. - * @return {OrderedMap} New OrderedMap that represents the result of the - * merge. - */ - merge: function(orderedMap) { - invariant( - orderedMap instanceof OrderedMapImpl, - 'OrderedMap.merge(...): Expected an OrderedMap instance.' - ); - return _fromNormalizedObjects( - this._normalizedObj, - orderedMap._normalizedObj - ); - }, - - /** - * Functional map API. Returns a new `OrderedMap`. - * - * @param {Function} cb Callback to invoke for each item. - * @param {Object?=} context Context to invoke callback from. - * @return {OrderedMap} OrderedMap that results from mapping. - */ - map: function(cb, context) { - return this.mapRange(cb, 0, this.length, context); - }, - - /** - * The callback `cb` is invoked with the arguments (item, key, - * indexInOriginal). - * - * @param {Function} cb Determines result for each item. - * @param {number} start Start index of map range. - * @param {end} length End index of map range. - * @param {*!?} context Context of callback invocation. - * @return {OrderedMap} OrderedMap resulting from mapping the range. - */ - mapRange: function(cb, start, length, context) { - var thisSet = this._normalizedObj; - var newSet = {}; - var i = 0; - assertValidRangeIndices(start, length, this.length); - var end = start + length - 1; - for (var key in thisSet) { - if (thisSet.hasOwnProperty(key)) { - if (i >= start) { - if (i > end) { - break; - } - var item = thisSet[key]; - newSet[key] = cb.call(context, item, key.substr(PREFIX.length), i); - } - i++; - } - } - return new OrderedMapImpl(newSet, length); - }, - - /** - * Function filter API. Returns new `OrderedMap`. - * - * @param {Function} cb Callback to invoke for each item. - * @param {Object?=} context Context to invoke callback from. - * @return {OrderedMap} OrderedMap that results from filtering. - */ - filter: function(cb, context) { - return this.filterRange(cb, 0, this.length, context); - }, - - /** - * The callback `cb` is invoked with the arguments (item, key, - * indexInOriginal). - * - * @param {Function} cb Returns true if item should be in result. - * @param {number} start Start index of filter range. - * @param {number} length End index of map range. - * @param {*!?} context Context of callback invocation. - * @return {OrderedMap} OrderedMap resulting from filtering the range. - */ - filterRange: function(cb, start, length, context) { - var newSet = {}; - var newSetLength = 0; - this.forEachRange(function(item, key, originalIndex) { - if (cb.call(context, item, key, originalIndex)) { - var normalizedKey = PREFIX + key; - newSet[normalizedKey] = item; - newSetLength++; - } - }, start, length); - return new OrderedMapImpl(newSet, newSetLength); - }, - - forEach: function(cb, context) { - this.forEachRange(cb, 0, this.length, context); - }, - - forEachRange: function(cb, start, length, context) { - assertValidRangeIndices(start, length, this.length); - var thisSet = this._normalizedObj; - var i = 0; - var end = start + length - 1; - for (var key in thisSet) { - if (thisSet.hasOwnProperty(key)) { - if (i >= start) { - if (i > end) { - break; - } - var item = thisSet[key]; - cb.call(context, item, key.substr(PREFIX.length), i); - } - i++; - } - } - }, - - /** - * Even though `mapRange`/`forEachKeyRange` allow zero length mappings, we'll - * impose an additional restriction here that the length of mapping be greater - * than zero - the only reason is that there are many ways to express length - * zero in terms of two keys and that is confusing. - */ - mapKeyRange: function(cb, startKey, endKey, context) { - var startIndex = this.indexOfKey(startKey); - var endIndex = this.indexOfKey(endKey); - invariant( - startIndex !== undefined && endIndex !== undefined, - 'mapKeyRange must be given keys that are present.' - ); - invariant( - endIndex >= startIndex, - 'OrderedMap.mapKeyRange(...): `endKey` must not come before `startIndex`.' - ); - return this.mapRange(cb, startIndex, (endIndex - startIndex) + 1, context); - }, - - forEachKeyRange: function(cb, startKey, endKey, context) { - var startIndex = this.indexOfKey(startKey); - var endIndex = this.indexOfKey(endKey); - invariant( - startIndex !== undefined && endIndex !== undefined, - 'forEachKeyRange must be given keys that are present.' - ); - invariant( - endIndex >= startIndex, - 'OrderedMap.forEachKeyRange(...): `endKey` must not come before ' + - '`startIndex`.' - ); - this.forEachRange(cb, startIndex, (endIndex - startIndex) + 1, context); - }, - - /** - * @param {number} pos Index to search for key at. - * @return {string|undefined} Either the key at index `pos` or undefined if - * not in map. - */ - keyAtIndex: function(pos) { - var computedPositions = this._getOrComputePositions(); - var keyAtPos = computedPositions.keyByIndex[pos]; - return keyAtPos ? keyAtPos.substr(PREFIX.length) : undefined; - }, - - /** - * @param {string} key String key from which to find the next key. - * @return {string|undefined} Either the next key, or undefined if there is no - * next key. - * @throws Error if `key` is not in this `OrderedMap`. - */ - keyAfter: function(key) { - return this.nthKeyAfter(key, 1); - }, - - /** - * @param {string} key String key from which to find the preceding key. - * @return {string|undefined} Either the preceding key, or undefined if there - * is no preceding.key. - * @throws Error if `key` is not in this `OrderedMap`. - */ - keyBefore: function(key) { - return this.nthKeyBefore(key, 1); - }, - - /** - * @param {string} key String key from which to find a following key. - * @param {number} n Distance to scan forward after `key`. - * @return {string|undefined} Either the nth key after `key`, or undefined if - * there is no next key. - * @throws Error if `key` is not in this `OrderedMap`. - */ - nthKeyAfter: function(key, n) { - var curIndex = this.indexOfKey(key); - invariant( - curIndex !== undefined, - 'OrderedMap.nthKeyAfter: The key `%s` does not exist in this instance.', - key - ); - return this.keyAtIndex(curIndex + n); - }, - - /** - * @param {string} key String key from which to find a preceding key. - * @param {number} n Distance to scan backwards before `key`. - * @return {string|undefined} Either the nth key before `key`, or undefined if - * there is no previous key. - * @throws Error if `key` is not in this `OrderedMap`. - */ - nthKeyBefore: function(key, n) { - return this.nthKeyAfter(key, -n); - }, - - /** - * @param {string} key Key to find the index of. - * @return {number|undefined} Index of the provided key, or `undefined` if the - * key is not found. - */ - indexOfKey: function(key) { - assertValidPublicKey(key); - var normalizedKey = PREFIX + key; - var computedPositions = this._getOrComputePositions(); - var computedPosition = computedPositions.indexByKey[normalizedKey]; - // Just writing it this way to make it clear this is intentional. - return computedPosition === undefined ? undefined : computedPosition; - }, - - /** - * @return {Array} An ordered array of this object's values. - */ - toArray: function() { - var result = []; - var thisSet = this._normalizedObj; - for (var key in thisSet) { - if (thisSet.hasOwnProperty(key)) { - result.push(thisSet[key]); - } - } - return result; - }, - - /** - * Finds the key at a given position, or indicates via `undefined` that that - * position does not exist in the `OrderedMap`. It is appropriate to return - * undefined, indicating that the key doesn't exist in the `OrderedMap` - * because `undefined` is not ever a valid `OrderedMap` key. - * - * @private - * @return {string?} Name of the item at position `pos`, or `undefined` if - * there is no item at that position. - */ - _getOrComputePositions: function() { - // TODO: Entertain computing this at construction time in some less - // performance critical paths. - var computedPositions = this._computedPositions; - if (!computedPositions) { - this._computePositions(); - } - return this._computedPositions; - }, - - /** - * Precomputes the index/key mapping for future lookup. Since `OrderedMap`s - * are immutable, there is only ever a need to perform this once. - * @private - */ - _computePositions: function() { - this._computedPositions = { - keyByIndex: {}, - indexByKey: {}, - }; - var keyByIndex = this._computedPositions.keyByIndex; - var indexByKey = this._computedPositions.indexByKey; - var index = 0; - var thisSet = this._normalizedObj; - for (var key in thisSet) { - if (thisSet.hasOwnProperty(key)) { - keyByIndex[index] = key; - indexByKey[key] = index; - index++; - } - } - }, -}; - -Object.assign(OrderedMapImpl.prototype, OrderedMapMethods); - -var OrderedMap = { - from: function(orderedMap) { - invariant( - orderedMap instanceof OrderedMapImpl, - 'OrderedMap.from(...): Expected an OrderedMap instance.' - ); - return _fromNormalizedObjects(orderedMap._normalizedObj, null); - }, - - fromArray: function(arr, keyExtractor) { - invariant( - Array.isArray(arr), - 'OrderedMap.fromArray(...): First argument must be an array.' - ); - invariant( - typeof keyExtractor === 'function', - 'OrderedMap.fromArray(...): Second argument must be a function used ' + - 'to determine the unique key for each entry.' - ); - return new OrderedMapImpl( - extractObjectFromArray(arr, keyExtractor), - arr.length - ); - }, -}; - -module.exports = OrderedMap; diff --git a/src/isomorphic/deprecated/ReactPropTransferer.js b/src/isomorphic/deprecated/ReactPropTransferer.js deleted file mode 100644 index da009cafe0acd..0000000000000 --- a/src/isomorphic/deprecated/ReactPropTransferer.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTransferer - */ - -'use strict'; - -var emptyFunction = require('emptyFunction'); -var joinClasses = require('joinClasses'); - -/** - * Creates a transfer strategy that will merge prop values using the supplied - * `mergeStrategy`. If a prop was previously unset, this just sets it. - * - * @param {function} mergeStrategy - * @return {function} - */ -function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { - if (!props.hasOwnProperty(key)) { - props[key] = value; - } else { - props[key] = mergeStrategy(props[key], value); - } - }; -} - -var transferStrategyMerge = createTransferStrategy(function(a, b) { - // `merge` overrides the first object's (`props[key]` above) keys using the - // second object's (`value`) keys. An object's style's existing `propA` would - // get overridden. Flip the order here. - return Object.assign({}, b, a); -}); - -/** - * Transfer strategies dictate how props are transferred by `transferPropsTo`. - * NOTE: if you add any more exceptions to this list you should be sure to - * update `cloneWithProps()` accordingly. - */ -var TransferStrategies = { - /** - * Never transfer `children`. - */ - children: emptyFunction, - /** - * Transfer the `className` prop by merging them. - */ - className: createTransferStrategy(joinClasses), - /** - * Transfer the `style` prop (which is an object) by merging them. - */ - style: transferStrategyMerge, -}; - -/** - * Mutates the first argument by transferring the properties from the second - * argument. - * - * @param {object} props - * @param {object} newProps - * @return {object} - */ -function transferInto(props, newProps) { - for (var thisKey in newProps) { - if (!newProps.hasOwnProperty(thisKey)) { - continue; - } - - var transferStrategy = TransferStrategies[thisKey]; - - if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { - transferStrategy(props, thisKey, newProps[thisKey]); - } else if (!props.hasOwnProperty(thisKey)) { - props[thisKey] = newProps[thisKey]; - } - } - return props; -} - -/** - * ReactPropTransferer are capable of transferring props to another component - * using a `transferPropsTo` method. - * - * @class ReactPropTransferer - */ -var ReactPropTransferer = { - - /** - * Merge two props objects using TransferStrategies. - * - * @param {object} oldProps original props (they take precedence) - * @param {object} newProps new props to merge in - * @return {object} a new object containing both sets of props merged. - */ - mergeProps: function(oldProps, newProps) { - return transferInto(Object.assign({}, oldProps), newProps); - }, - -}; - -module.exports = ReactPropTransferer; diff --git a/src/shared/utils/__tests__/OrderedMap-test.js b/src/shared/utils/__tests__/OrderedMap-test.js deleted file mode 100644 index cdcff5aa4aaf4..0000000000000 --- a/src/shared/utils/__tests__/OrderedMap-test.js +++ /dev/null @@ -1,941 +0,0 @@ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @emails react-core - */ - -'use strict'; - -var OrderedMap; - -/** - * Shared, reusable objects. - */ -var hasEmptyStringKey = { - 'thisKeyIsFine': {data: []}, - '': {thisShouldCauseAFailure: []}, - 'thisKeyIsAlsoFine': {data: []}, -}; - -/** - * Used as map/forEach callback. - */ -var duplicate = function(itm, key, count) { - return { - uniqueID: itm.uniqueID, - val: itm.val + key + count + this.justToTestScope, - }; -}; - -// Should not be allowed - because then null/'null' become impossible to -// distinguish. Every key MUST be a string period! -var hasNullAndUndefStringKey = [ - {uniqueID: 'undefined', val: 'thisIsUndefined'}, - {uniqueID: 'null', val: 'thisIsNull'}, -]; -var hasNullKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: null, data: []}, -]; - -var hasObjectKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: {}, data: []}, -]; - -var hasArrayKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: [], data: []}, -]; - -// This should be allowed -var hasNullStringKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: 'null', data: []}, -]; - -var hasUndefinedKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: undefined, data: []}, -]; - -var hasUndefinedStringKey = [ - {uniqueID: 'thisKeyIsFine', data: []}, - {uniqueID: 'thisKeyIsAlsoFine', data: []}, - {uniqueID: 'undefined', data: []}, -]; - -var hasPositiveNumericKey = [ - {uniqueID: 'notANumber', data: []}, - {uniqueID: '5', data: []}, - {uniqueID: 'notAnotherNumber', data: []}, -]; - -var hasZeroStringKey = [ - {uniqueID: 'greg', data: 'grego'}, - {uniqueID: '0', data: '0o'}, - {uniqueID: 'tom', data: 'tomo'}, -]; - -var hasZeroNumberKey = [ - {uniqueID: 'greg', data: 'grego'}, - {uniqueID: 0, data: '0o'}, - {uniqueID: 'tom', data: 'tomo'}, -]; - -var hasAllNumericStringKeys = [ - {uniqueID: '0', name: 'Gregory'}, - {uniqueID: '2', name: 'James'}, - {uniqueID: '1', name: 'Tom'}, -]; - -var hasAllNumericKeys = [ - {uniqueID: 0, name: 'Gregory'}, - {uniqueID: 2, name: 'James'}, - {uniqueID: 1, name: 'Tom'}, -]; - -var hasAllValidKeys = [ - {uniqueID: 'keyOne', value: 'valueOne'}, - {uniqueID: 'keyTwo', value: 'valueTwo'}, -]; - -var hasDuplicateKeys = [ - {uniqueID: 'keyOne', value: 'valueOne'}, - {uniqueID: 'keyTwo', value: 'valueTwo'}, - {uniqueID: 'keyOne', value: 'valueThree'}, -]; - -var idEntities = [ - {uniqueID: 'greg', name: 'Gregory'}, - {uniqueID: 'james', name: 'James'}, - {uniqueID: 'tom', name: 'Tom'}, -]; - -var hasEmptyKey = [ - {uniqueID: 'greg', name: 'Gregory'}, - {uniqueID: '', name: 'James'}, - {uniqueID: 'tom', name: 'Tom'}, -]; - -var extractUniqueID = function(entity) { - return entity.uniqueID; -}; - -describe('OrderedMap', function() { - beforeEach(function() { - jest.resetModuleRegistry(); - OrderedMap = require('OrderedMap'); - }); - - it('should create according to simple object with keys', function() { - OrderedMap.fromArray(hasAllValidKeys, extractUniqueID); - // Iterate over and ensure key order. - }); - - it('should create from array when providing an identity CB', function() { - expect(function() { - OrderedMap.fromArray(idEntities, extractUniqueID); - }).not.toThrow(); - }); - - it('should throw if constructing from Array without identity CB', function() { - OrderedMap.fromArray(idEntities, extractUniqueID); - // Iterate and ensure key order - }); - - it('should not throw when fromArray extracts a numeric key', function() { - expect(function() { - OrderedMap.fromArray(hasPositiveNumericKey, extractUniqueID); - }).not.toThrow(); - - }); - - it('should throw when any key is the empty string', function() { - expect(function() { - OrderedMap.fromArray(hasEmptyKey, extractUniqueID); - }).toThrow(); - }); - - it('should not throw when a key is the string "undefined" or "null"', - function() { - var om = OrderedMap.fromArray(hasNullAndUndefStringKey, extractUniqueID); - expect(om.length).toBe(2); - expect(om.indexOfKey('undefined')).toBe(0); - expect(om.indexOfKey('null')).toBe(1); - expect(om.keyAfter('undefined')).toBe('null'); - expect(om.keyAfter('null')).toBe(undefined); - expect(om.keyBefore('undefined')).toBe(undefined); - expect(om.has('undefined')).toBe(true); - expect(om.has('null')).toBe(true); - expect(om.get('undefined').val).toBe('thisIsUndefined'); - expect(om.get('null').val).toBe('thisIsNull'); - }); - - - /** - * Numeric keys are cast to strings. - */ - it('should not throw when a key is the number zero', function() { - var om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID); - expect(om.length).toBe(3); - expect(om.indexOfKey('0')).toBe(1); - expect(om.indexOfKey(0)).toBe(1); - }); - - it('should throw when any key is falsey', function() { - expect(function() { - OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID); - }).toThrow(); - - expect(function() { - OrderedMap.fromArray(hasNullKey, extractUniqueID); - }).toThrow(); - - expect(function() { - OrderedMap.fromArray(hasUndefinedKey, extractUniqueID); - }).toThrow(); - }); - - it('should not throw on string keys "undefined/null"', function() { - expect(function() { - OrderedMap.fromArray(hasNullStringKey, extractUniqueID); - }).not.toThrow(); - - expect(function() { - OrderedMap.fromArray(hasUndefinedStringKey, extractUniqueID); - }).not.toThrow(); - }); - - it('should throw on extracting keys that are not strings/nums', function() { - expect(function() { - OrderedMap.fromArray(hasObjectKey, extractUniqueID); - }).toThrow(); - - expect(function() { - OrderedMap.fromArray(hasArrayKey, extractUniqueID); - }).toThrow(); - }); - - it('should throw if instantiating with duplicate key', function() { - expect(function() { - OrderedMap.fromArray(hasDuplicateKeys, extractUniqueID); - }).toThrow(); - }); - - it('should not throw when a key is the string "0"', function() { - var verifyOM = function(om) { - expect(om.length).toBe(3); - expect(om.indexOfKey('greg')).toBe(0); - expect(om.indexOfKey('0')).toBe(1); - expect(om.indexOfKey(0)).toBe(1); // Casts on writes and reads. - expect(om.indexOfKey('tom')).toBe(2); - expect(om.keyAfter('greg')).toBe('0'); - expect(om.keyAfter('0')).toBe('tom'); - expect(om.keyAfter(0)).toBe('tom'); - expect(om.keyAfter('tom')).toBe(undefined); - expect(om.keyBefore('greg')).toBe(undefined); - expect(om.keyBefore(0)).toBe('greg'); - expect(om.keyBefore('0')).toBe('greg'); - expect(om.keyBefore('tom')).toBe('0'); - expect(om.has('undefined')).toBe(false); - expect(om.has(0)).toBe(true); - expect(om.has('0')).toBe(true); - }; - verifyOM(OrderedMap.fromArray(hasZeroStringKey, extractUniqueID)); - verifyOM(OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID)); - }); - - it('should throw when getting invalid public key', function() { - var om = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID); - expect(function() { - om.has(undefined); - }).toThrow(); - expect(function() { - om.get(undefined); - }).toThrow(); - expect(function() { - om.has(null); - }).toThrow(); - expect(function() { - om.get(null); - }).toThrow(); - expect(function() { - om.has(''); - }).toThrow(); - expect(function() { - om.get(''); - }).toThrow(); - }); - - it('should throw when any key is falsey', function() { - expect(function() { - OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID); - }).toThrow(); - - expect(function() { - OrderedMap.fromArray(hasNullKey, extractUniqueID); - }).toThrow(); - - expect(function() { - OrderedMap.fromArray(hasUndefinedKey, extractUniqueID); - }).toThrow(); - }); - - - it('should throw when fromArray is passed crazy args', function() { - // Test passing another OrderedMap (when it expects a plain object.) - // This is probably not what you meant to do! We should error. - var validOM = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID); - expect(function() { - OrderedMap.fromArray({uniqueID: 'asdf'}, extractUniqueID); - }).toThrow(); - expect(function() { - OrderedMap.fromArray(validOM, extractUniqueID); - }).toThrow(); - }); - - it('should throw when fromArray is passed crazy things', function() { - expect(function() { - OrderedMap.fromArray(null, extractUniqueID); - }).toThrow(); - expect(function() { - OrderedMap.fromArray('stringgg', extractUniqueID); - }).toThrow(); - expect(function() { - OrderedMap.fromArray(undefined, extractUniqueID); - }).toThrow(); - expect(function() { - OrderedMap.fromArray(new Date(), extractUniqueID); - }).toThrow(); - expect(function() { - OrderedMap.fromArray({}, extractUniqueID); - }).toThrow(); - - // Test failure without extractor - expect(function() { - OrderedMap.fromArray(idEntities); - }).toThrow(); - expect(function() { - OrderedMap.fromArray(idEntities, extractUniqueID); - }).not.toThrow(); - }); - - // Testing methods that accept other `OrderedMap`s. - it('should throw when from/merge is passed an non-OrderedMap.', function() { - // Test passing an array to construction. - expect(function() { - OrderedMap.from(idEntities, extractUniqueID); - }).toThrow(); - - // Test passing an array to merge. - expect(function() { - OrderedMap.fromArray(idEntities, extractUniqueID) - .merge(idEntities, extractUniqueID); - }).toThrow(); - - - // Test passing a plain object to merge. - expect(function() { - OrderedMap.fromArray( - idEntities, - extractUniqueID - ).merge({blah: 'willFail'}); - }).toThrow(); - }); - - it('should throw when accessing key before/after of non-key', function() { - var om = OrderedMap.fromArray( - [ - {uniqueID: 'first'}, - {uniqueID: 'two'}, - ], extractUniqueID - ); - expect(function() { - om.keyBefore('dog'); - }).toThrow(); - expect(function() { - om.keyAfter('cat'); - }).toThrow(); - expect(function() { - om.keyAfter(null); - }).toThrow(); - expect(function() { - om.keyAfter(undefined); - }).toThrow(); - }); - - it('should throw passing invalid/not-present-keys to before/after', - function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'second'}, - {uniqueID: 'three', val: 'third'}, - {uniqueID: 'four', val: 'fourth'}, - ], extractUniqueID); - - expect(function() { - om.keyBefore(''); - }).toThrow(); - expect(function() { - om.keyBefore(null); - }).toThrow(); - expect(function() { - om.keyBefore(undefined); - }).toThrow(); - expect(function() { - om.keyBefore('notInTheOrderedMap!'); - }).toThrow(); - - expect(function() { - om.keyAfter(''); - }).toThrow(); - expect(function() { - om.keyAfter(null); - }).toThrow(); - expect(function() { - om.keyAfter(undefined); - }).toThrow(); - expect(function() { - om.keyAfter('notInTheOrderedMap!'); - }).toThrow(); - - expect(function() { - om.nthKeyAfter('', 1); - }).toThrow(); - expect(function() { - om.nthKeyAfter(null, 1); - }).toThrow(); - expect(function() { - om.nthKeyAfter(undefined, 1); - }).toThrow(); - expect(function() { - om.nthKeyAfter('notInTheOrderedMap!', 1); - }).toThrow(); - - expect(function() { - om.nthKeyBefore('', 1); - }).toThrow(); - expect(function() { - om.nthKeyBefore(null, 1); - }).toThrow(); - expect(function() { - om.nthKeyBefore(undefined, 1); - }).toThrow(); - expect(function() { - om.nthKeyBefore('notInTheOrderedMap!', 1); - }).toThrow(); - }); - - it('should correctly determine the nth key after before', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'second'}, - {uniqueID: 'three', val: 'third'}, - {uniqueID: 'four', val: 'fourth'}, - ], extractUniqueID); - expect(om.keyBefore('one')).toBe(undefined); // first key - expect(om.keyBefore('two')).toBe('one'); - expect(om.keyBefore('three')).toBe('two'); - expect(om.keyBefore('four')).toBe('three'); - - expect(om.keyAfter('one')).toBe('two'); // first key - expect(om.keyAfter('two')).toBe('three'); - expect(om.keyAfter('three')).toBe('four'); - expect(om.keyAfter('four')).toBe(undefined); - - expect(om.nthKeyBefore('one', 0)).toBe('one'); // first key - expect(om.nthKeyBefore('one', 1)).toBe(undefined); - expect(om.nthKeyBefore('one', 2)).toBe(undefined); - expect(om.nthKeyBefore('two', 0)).toBe('two'); - expect(om.nthKeyBefore('two', 1)).toBe('one'); - expect(om.nthKeyBefore('four', 0)).toBe('four'); - expect(om.nthKeyBefore('four', 1)).toBe('three'); - - expect(om.nthKeyAfter('one', 0)).toBe('one'); - expect(om.nthKeyAfter('one', 1)).toBe('two'); - expect(om.nthKeyAfter('one', 2)).toBe('three'); - expect(om.nthKeyAfter('two', 0)).toBe('two'); - expect(om.nthKeyAfter('two', 1)).toBe('three'); - expect(om.nthKeyAfter('four', 0)).toBe('four'); - expect(om.nthKeyAfter('four', 1)).toBe(undefined); - }); - - it('should compute key indices correctly', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'second'}, - ], extractUniqueID); - expect(om.keyAtIndex(0)).toBe('one'); - expect(om.keyAtIndex(1)).toBe('two'); - expect(om.keyAtIndex(2)).toBe(undefined); - expect(om.indexOfKey('one')).toBe(0); - expect(om.indexOfKey('two')).toBe(1); - expect(om.indexOfKey('nope')).toBe(undefined); - expect(function() { - om.indexOfKey(null); - }).toThrow(); - expect(function() { - om.indexOfKey(undefined); - }).toThrow(); - expect(function() { - om.indexOfKey(''); // Empty key is not allowed - }).toThrow(); - }); - - it('should compute indices on array that extracted numeric ids', function() { - var som = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID); - expect(som.keyAtIndex(0)).toBe('greg'); - expect(som.keyAtIndex(1)).toBe('0'); - expect(som.keyAtIndex(2)).toBe('tom'); - expect(som.indexOfKey('greg')).toBe(0); - expect(som.indexOfKey('0')).toBe(1); - expect(som.indexOfKey('tom')).toBe(2); - - - var verifyNumericKeys = function(nom) { - expect(nom.keyAtIndex(0)).toBe('0'); - expect(nom.keyAtIndex(1)).toBe('2'); - expect(nom.keyAtIndex(2)).toBe('1'); - expect(nom.indexOfKey('0')).toBe(0); - expect(nom.indexOfKey('2')).toBe(1); // Prove these are not ordered by - expect(nom.indexOfKey('1')).toBe(2); // their keys - }; - var omStringNumberKeys = - OrderedMap.fromArray(hasAllNumericStringKeys, extractUniqueID); - verifyNumericKeys(omStringNumberKeys); - var omNumericKeys = - OrderedMap.fromArray(hasAllNumericKeys, extractUniqueID); - verifyNumericKeys(omNumericKeys); - }); - - it('should compute indices on mutually exclusive merge', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'second'}, - ], extractUniqueID); - var om2 = OrderedMap.fromArray([ - {uniqueID: 'three', val: 'third'}, - ], extractUniqueID); - var res = om.merge(om2); - - expect(res.length).toBe(3); - - expect(res.keyAtIndex(0)).toBe('one'); - expect(res.keyAtIndex(1)).toBe('two'); - expect(res.keyAtIndex(2)).toBe('three'); - expect(res.keyAtIndex(3)).toBe(undefined); - - expect(res.indexOfKey('one')).toBe(0); - expect(res.indexOfKey('two')).toBe(1); - expect(res.indexOfKey('three')).toBe(2); - expect(res.indexOfKey('dog')).toBe(undefined); - - expect(res.has('one')).toBe(true); - expect(res.has('two')).toBe(true); - expect(res.has('three')).toBe(true); - expect(res.has('dog')).toBe(false); - - expect(res.get('one').val).toBe('first'); - expect(res.get('two').val).toBe('second'); - expect(res.get('three').val).toBe('third'); - expect(res.get('dog')).toBe(undefined); - }); - - it('should compute indices on intersected merge', function() { - var oneTwo = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'secondOM1'}, - ], extractUniqueID); - - var testOneTwoMergedWithTwoThree = function(res) { - expect(res.length).toBe(3); - expect(res.keyAtIndex(0)).toBe('one'); - expect(res.keyAtIndex(1)).toBe('two'); - expect(res.keyAtIndex(2)).toBe('three'); - expect(res.keyAtIndex(3)).toBe(undefined); - expect(res.indexOfKey('one')).toBe(0); - expect(res.indexOfKey('two')).toBe(1); - expect(res.indexOfKey('three')).toBe(2); - expect(res.indexOfKey('dog')).toBe(undefined); - expect(res.has('one')).toBe(true); - expect(res.has('two')).toBe(true); - expect(res.has('three')).toBe(true); - expect(res.has('dog')).toBe(false); - expect(res.get('one').val).toBe('first'); - expect(res.get('two').val).toBe('secondOM2'); - expect(res.get('three').val).toBe('third'); - expect(res.get('dog')).toBe(undefined); - }; - - var result = - oneTwo.merge(OrderedMap.fromArray([ - {uniqueID: 'two', val: 'secondOM2'}, - {uniqueID: 'three', val: 'third'}, - ], extractUniqueID)); - testOneTwoMergedWithTwoThree(result); - - // Everything should be exactly as before, since the ordering of `two` was - // already determined by `om`. - result = oneTwo.merge( - OrderedMap.fromArray([ - {uniqueID: 'three', val: 'third'}, - {uniqueID: 'two', val:'secondOM2'}, - ], extractUniqueID) - ); - testOneTwoMergedWithTwoThree(result); - - - var testTwoThreeMergedWithOneTwo = function(res) { - expect(res.length).toBe(3); - expect(res.keyAtIndex(0)).toBe('two'); - expect(res.keyAtIndex(1)).toBe('three'); - expect(res.keyAtIndex(2)).toBe('one'); - expect(res.keyAtIndex(3)).toBe(undefined); - expect(res.indexOfKey('two')).toBe(0); - expect(res.indexOfKey('three')).toBe(1); - expect(res.indexOfKey('one')).toBe(2); - expect(res.indexOfKey('cat')).toBe(undefined); - expect(res.has('two')).toBe(true); - expect(res.has('three')).toBe(true); - expect(res.has('one')).toBe(true); - expect(res.has('dog')).toBe(false); - expect(res.get('one').val).toBe('first'); - expect(res.get('two').val).toBe('secondOM1'); - expect(res.get('three').val).toBe('third'); - expect(res.get('dog')).toBe(undefined); - }; - result = OrderedMap.fromArray([ - {uniqueID: 'two', val: 'secondOM2'}, - {uniqueID: 'three', val: 'third'}, - ], extractUniqueID).merge(oneTwo); - testTwoThreeMergedWithOneTwo(result); - - }); - - it('should merge mutually exclusive keys to the end.', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'one', val: 'first'}, - {uniqueID: 'two', val: 'second'}, - ], extractUniqueID); - var om2 = OrderedMap.fromArray([ - {uniqueID: 'three', val: 'first'}, - {uniqueID: 'four', val: 'second'}, - ], extractUniqueID); - var res = om.merge(om2); - expect(res.length).toBe(4); - - }); - - it('should map correctly', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'x', val: 'xx'}, - {uniqueID: 'y', val: 'yy'}, - {uniqueID: 'z', val: 'zz'}, - ], extractUniqueID); - var scope = {justToTestScope: 'justTestingScope'}; - var verifyResult = function(omResult) { - expect(omResult.length).toBe(3); - expect(omResult.keyAtIndex(0)).toBe('x'); - expect(omResult.keyAtIndex(1)).toBe('y'); - expect(omResult.keyAtIndex(2)).toBe('z'); - expect(omResult.get('x').val).toBe('xxx0justTestingScope'); - expect(omResult.get('y').val).toBe('yyy1justTestingScope'); - expect(omResult.get('z').val).toBe('zzz2justTestingScope'); - }; - var resultOM = om.map(function(itm, key, count) { - return { - uniqueID: itm.uniqueID, - val: itm.val + key + count + this.justToTestScope, - }; - }, scope); - verifyResult(resultOM); - - var resArray = []; - om.forEach(function(itm, key, count) { - resArray.push({ - uniqueID: itm.uniqueID, - val: itm.val + key + count + this.justToTestScope, - }); - }, scope); - resultOM = OrderedMap.fromArray(resArray, extractUniqueID); - verifyResult(resultOM); - }); - - it('should filter correctly', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'x', val: 'xx'}, - {uniqueID: 'y', val: 'yy'}, - {uniqueID: 'z', val: 'zz'}, - ], extractUniqueID); - var scope = {justToTestScope: 'justTestingScope'}; - - var filteringCallback = function(item, key, indexInOriginal) { - expect(this).toBe(scope); - expect(key === 'x' || key === 'y' || key === 'z').toBe(true); - if (key === 'x') { - expect(item.val).toBe('xx'); - expect(indexInOriginal).toBe(0); - return false; - } else if (key === 'y') { - expect(item.val).toBe('yy'); - expect(indexInOriginal).toBe(1); - return true; - } else { - expect(item.val).toBe('zz'); - expect(indexInOriginal).toBe(2); - return true; - } - }; - - var verifyResult = function(omResult) { - expect(omResult.length).toBe(2); - expect(omResult.keyAtIndex(0)).toBe('y'); - expect(omResult.keyAtIndex(1)).toBe('z'); - expect(omResult.has('x')).toBe(false); - expect(omResult.has('z')).toBe(true); - expect(omResult.get('z').val).toBe('zz'); - expect(omResult.has('y')).toBe(true); - expect(omResult.get('y').val).toBe('yy'); - }; - - var resultOM = om.filter(filteringCallback, scope); - verifyResult(resultOM); - }); - - it('should throw when providing invalid ranges to ranging', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'x', val: 'xx'}, - {uniqueID: 'y', val: 'yy'}, - {uniqueID: 'z', val: 'zz'}, - ], extractUniqueID); - var scope = {justToTestScope: 'justTestingScope'}; - - expect(function() { - om.mapRange(duplicate, 0, 3, scope); - }).not.toThrow(); - expect(function() { - om.filterRange(duplicate, 0, 3, scope); - }).not.toThrow(); - expect(function() { - om.forEachRange(duplicate, 0, 3, scope); - }).not.toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'x', 3, scope); - }).toThrow( - 'mapKeyRange must be given keys that are present.' - ); - expect(function() { - om.forEachKeyRange(duplicate, 'x', 3, scope); - }).toThrow( - 'forEachKeyRange must be given keys that are present.' - ); - - expect(function() { - om.mapRange(duplicate, 0, 4, scope); - }).toThrow(); - expect(function() { - om.filterRange(duplicate, 0, 4, scope); - }).toThrow(); - expect(function() { - om.forEachRange(duplicate, 0, 4, scope); - }).toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'x', null, scope); - }).toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'x', null, scope); - }).toThrow(); - - expect(function() { - om.mapRange(duplicate, -1, 1, scope); - }).toThrow(); - expect(function() { - om.filterRange(duplicate, -1, 1, scope); - }).toThrow(); - expect(function() { - om.forEachRange(duplicate, -1, 1, scope); - }).toThrow(); - expect(function() { - om.mapKeyRange(duplicate, null, 'y', scope); - }).toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, null, 'y', scope); - }).toThrow(); - - expect(function() { - om.mapRange(duplicate, 0, 0, scope); - }).not.toThrow(); - expect(function() { - om.filterRange(duplicate, 0, 0, scope); - }).not.toThrow(); - expect(function() { - om.forEachRange(duplicate, 0, 0, scope); - }).not.toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'x', 'x', scope); - }).not.toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'x', 'x', scope); - }).not.toThrow(); - - expect(function() { - om.mapRange(duplicate, 0, -1, scope); - }).toThrow(); - expect(function() { - om.filterRange(duplicate, 0, -1, scope); - }).toThrow(); - expect(function() { - om.forEachRange(duplicate, 0, -1, scope); - }).toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'x', null, scope); - }).toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'x', null, scope); - }).toThrow(); - - expect(function() { - om.mapRange(duplicate, 2, 1, scope); - }).not.toThrow(); - expect(function() { - om.filterRange(duplicate, 2, 1, scope); - }).not.toThrow(); - expect(function() { - om.forEachRange(duplicate, 2, 1, scope); - }).not.toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'z', 'z', scope); - }).not.toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'z', 'z', scope); - }).not.toThrow(); - - expect(function() { - om.mapRange(duplicate, 2, 2, scope); - }).toThrow(); - expect(function() { - om.filterRange(duplicate, 2, 2, scope); - }).toThrow(); - expect(function() { - om.forEachRange(duplicate, 2, 2, scope); - }).toThrow(); - expect(function() { - om.mapKeyRange(duplicate, 'z', null, scope); - }).toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'z', null, scope); - }).toThrow(); - - // Provide keys in reverse order - should throw. - expect(function() { - om.mapKeyRange(duplicate, 'y', 'x', scope); - }).toThrow(); - expect(function() { - om.forEachKeyRange(duplicate, 'y', 'x', scope); - }).toThrow(); - }); - - // TEST length zero map, or keyrange start===end - - it('should map range correctly', function() { - var om = OrderedMap.fromArray([ - {uniqueID: 'x', val: 'xx'}, - {uniqueID: 'y', val: 'yy'}, - {uniqueID: 'z', val: 'zz'}, - ], extractUniqueID); - var scope = {justToTestScope: 'justTestingScope'}; - var verifyThreeItems = function(omResult) { - expect(omResult.length).toBe(3); - expect(omResult.keyAtIndex(0)).toBe('x'); - expect(omResult.keyAtIndex(1)).toBe('y'); - expect(omResult.keyAtIndex(2)).toBe('z'); - expect(omResult.get('x').val).toBe('xxx0justTestingScope'); - expect(omResult.get('y').val).toBe('yyy1justTestingScope'); - expect(omResult.get('z').val).toBe('zzz2justTestingScope'); - }; - var verifyFirstTwoItems = function(omResult) { - expect(omResult.length).toBe(2); - expect(omResult.keyAtIndex(0)).toBe('x'); - expect(omResult.keyAtIndex(1)).toBe('y'); - expect(omResult.get('x').val).toBe('xxx0justTestingScope'); - expect(omResult.get('y').val).toBe('yyy1justTestingScope'); - }; - - var verifyLastTwoItems = function(omResult) { - expect(omResult.length).toBe(2); - expect(omResult.keyAtIndex(0)).toBe('y'); - expect(omResult.keyAtIndex(1)).toBe('z'); - expect(omResult.get('y').val).toBe('yyy1justTestingScope'); - expect(omResult.get('z').val).toBe('zzz2justTestingScope'); - }; - - var verifyMiddleItem = function(omResult) { - expect(omResult.length).toBe(1); - expect(omResult.keyAtIndex(0)).toBe('y'); - expect(omResult.get('y').val).toBe('yyy1justTestingScope'); - }; - - var verifyEmpty = function(omResult) { - expect(omResult.length).toBe(0); - }; - - var omResultThree = om.mapRange(duplicate, 0, 3, scope); - verifyThreeItems(omResultThree); - var resArray = []; - var pushToResArray = function(itm, key, count) { - resArray.push({ - uniqueID: itm.uniqueID, - val: itm.val + key + count + this.justToTestScope, - }); - }; - - om.forEachRange(pushToResArray, 0, 3, scope); - omResultThree = OrderedMap.fromArray(resArray, extractUniqueID); - verifyThreeItems(omResultThree); - - var omResultFirstTwo = om.mapRange(duplicate, 0, 2, scope); - verifyFirstTwoItems(omResultFirstTwo); - resArray = []; - om.forEachRange(pushToResArray, 0, 2, scope); - omResultFirstTwo = OrderedMap.fromArray(resArray, extractUniqueID); - verifyFirstTwoItems(omResultFirstTwo); - - var omResultLastTwo = om.mapRange(duplicate, 1, 2, scope); - verifyLastTwoItems(omResultLastTwo); - resArray = []; - om.forEachRange(pushToResArray, 1, 2, scope); - omResultLastTwo = OrderedMap.fromArray(resArray, extractUniqueID); - verifyLastTwoItems(omResultLastTwo); - - var omResultMiddle = om.mapRange(duplicate, 1, 1, scope); - verifyMiddleItem(omResultMiddle); - resArray = []; - om.forEachRange(pushToResArray, 1, 1, scope); - omResultMiddle = OrderedMap.fromArray(resArray, extractUniqueID); - verifyMiddleItem(omResultMiddle); - - var omResultNone = om.mapRange(duplicate, 1, 0, scope); - verifyEmpty(omResultNone); - }); - - it('should extract the original array correctly', function() { - var sourceArray = [ - {uniqueID: 'x', val: 'xx'}, - {uniqueID: 'y', val: 'yy'}, - {uniqueID: 'z', val: 'zz'}, - ]; - var om = OrderedMap.fromArray(sourceArray, extractUniqueID); - expect(om.toArray()).toEqual(sourceArray); - }); -});