mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 15:27:50 +00:00
896 lines
25 KiB
JavaScript
896 lines
25 KiB
JavaScript
;(function() {
|
|
|
|
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
|
|
var undefined;
|
|
|
|
/** Used as the size to cover large array optimizations. */
|
|
var LARGE_ARRAY_SIZE = 200;
|
|
|
|
/** Used as a reference to the global object. */
|
|
var root = (typeof global == 'object' && global) || this;
|
|
|
|
/** Used for native method references. */
|
|
var arrayProto = Array.prototype;
|
|
|
|
/** Method and object shortcuts. */
|
|
var phantom = root.phantom,
|
|
amd = root.define && define.amd,
|
|
document = !phantom && root.document,
|
|
noop = function() {},
|
|
slice = arrayProto.slice,
|
|
WeakMap = root.WeakMap;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/** Use a single "load" function. */
|
|
var load = (!amd && typeof require == 'function')
|
|
? require
|
|
: noop;
|
|
|
|
/** The unit testing framework. */
|
|
var QUnit = root.QUnit || (root.QUnit = (
|
|
QUnit = load('../node_modules/qunitjs/qunit/qunit.js') || root.QUnit,
|
|
QUnit = QUnit.QUnit || QUnit
|
|
));
|
|
|
|
/** Load stable Lodash and QUnit Extras. */
|
|
var _ = root._ || load('../lodash.js');
|
|
if (_) {
|
|
_ = _.runInContext(root);
|
|
}
|
|
var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
|
|
if (QUnitExtras) {
|
|
QUnitExtras.runInContext(root);
|
|
}
|
|
|
|
var convert = root.fp || load('../lib/fp/fp.js'),
|
|
mapping = root.mapping || load('../lib/fp/mapping.js'),
|
|
fp = convert(_.runInContext());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Skips a given number of tests with a passing result.
|
|
*
|
|
* @private
|
|
* @param {Object} assert The QUnit assert object.
|
|
* @param {number} [count=1] The number of tests to skip.
|
|
*/
|
|
function skipTest(assert, count) {
|
|
count || (count = 1);
|
|
while (count--) {
|
|
assert.ok(true, 'test skipped');
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('method aliases');
|
|
|
|
(function() {
|
|
QUnit.test('should have correct aliases', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var actual = _.transform(mapping.aliasMap, function(result, aliases, methodName) {
|
|
var func = fp[methodName];
|
|
_.each(aliases, function(alias) {
|
|
result.push([alias, fp[alias] === func]);
|
|
});
|
|
}, []);
|
|
|
|
assert.deepEqual(_.reject(actual, 1), []);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('method ary caps');
|
|
|
|
(function() {
|
|
QUnit.test('should have a cap of 1', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var funcMethods = [
|
|
'curry', 'iteratee', 'memoize', 'over', 'overEvery', 'overSome',
|
|
'method', 'methodOf', 'restParam', 'runInContext'
|
|
];
|
|
|
|
var exceptions = funcMethods.concat('mixin', 'template'),
|
|
expected = _.map(mapping.aryMethodMap[1], _.constant(true));
|
|
|
|
var actual = _.map(mapping.aryMethodMap[1], function(methodName) {
|
|
var arg = _.includes(funcMethods, methodName) ? _.noop : 1,
|
|
result = _.attempt(function() { return fp[methodName](arg); });
|
|
|
|
if (_.includes(exceptions, methodName)
|
|
? typeof result == 'function'
|
|
: typeof result != 'function'
|
|
) {
|
|
return true;
|
|
}
|
|
console.log(methodName, result);
|
|
return false;
|
|
});
|
|
|
|
assert.deepEqual(actual, expected);
|
|
});
|
|
|
|
QUnit.test('should have a cap of 2', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var funcMethods = [
|
|
'after', 'ary', 'before', 'bind', 'bindKey', 'cloneDeepWith', 'cloneWith',
|
|
'curryN', 'debounce', 'delay', 'overArgs', 'rearg', 'throttle', 'wrap'
|
|
];
|
|
|
|
var exceptions = _.difference(funcMethods.concat('matchesProperty'), ['cloneDeepWith', 'cloneWith', 'delay']),
|
|
expected = _.map(mapping.aryMethodMap[2], _.constant(true));
|
|
|
|
var actual = _.map(mapping.aryMethodMap[2], function(methodName) {
|
|
var args = _.includes(funcMethods, methodName) ? [methodName == 'curryN' ? 1 : _.noop, _.noop] : [1, []],
|
|
result = _.attempt(function() { return fp[methodName](args[0])(args[1]); });
|
|
|
|
if (_.includes(exceptions, methodName)
|
|
? typeof result == 'function'
|
|
: typeof result != 'function'
|
|
) {
|
|
return true;
|
|
}
|
|
console.log(methodName, result);
|
|
return false;
|
|
});
|
|
|
|
assert.deepEqual(actual, expected);
|
|
});
|
|
|
|
QUnit.test('should have a cap of 3', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var funcMethods = [
|
|
'assignWith', 'extendWith', 'isEqualWith', 'isMatchWith', 'omitBy',
|
|
'pickBy', 'reduce', 'reduceRight', 'transform', 'zipWith'
|
|
];
|
|
|
|
var expected = _.map(mapping.aryMethodMap[3], _.constant(true));
|
|
|
|
var actual = _.map(mapping.aryMethodMap[3], function(methodName) {
|
|
var args = _.includes(funcMethods, methodName) ? [_.noop, 0, 1] : [0, 1, []],
|
|
result = _.attempt(function() { return fp[methodName](args[0])(args[1])(args[2]); });
|
|
|
|
if (typeof result != 'function') {
|
|
return true;
|
|
}
|
|
console.log(methodName, result);
|
|
return false;
|
|
});
|
|
|
|
assert.deepEqual(actual, expected);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('methods that use `indexOf`');
|
|
|
|
(function() {
|
|
QUnit.test('should work with `fp.indexOf`', function(assert) {
|
|
assert.expect(10);
|
|
|
|
var array = ['a', 'b', 'c'],
|
|
other = ['b', 'b', 'd'],
|
|
object = { 'a': 1, 'b': 2, 'c': 2 },
|
|
actual = fp.difference(array, other);
|
|
|
|
assert.deepEqual(actual, ['a', 'c'], 'fp.difference');
|
|
|
|
actual = fp.includes('b', array);
|
|
assert.strictEqual(actual, true, 'fp.includes');
|
|
|
|
actual = fp.intersection(other, array);
|
|
assert.deepEqual(actual, ['b'], 'fp.intersection');
|
|
|
|
actual = fp.omit(other, object);
|
|
assert.deepEqual(actual, { 'a': 1, 'c': 2 }, 'fp.omit');
|
|
|
|
actual = fp.union(other, array);
|
|
assert.deepEqual(actual, ['a', 'b', 'c', 'd'], 'fp.union');
|
|
|
|
actual = fp.uniq(other);
|
|
assert.deepEqual(actual, ['b', 'd'], 'fp.uniq');
|
|
|
|
actual = fp.uniqBy(_.identity, other);
|
|
assert.deepEqual(actual, ['b', 'd'], 'fp.uniqBy');
|
|
|
|
actual = fp.without('b', array);
|
|
assert.deepEqual(actual, ['a', 'c'], 'fp.without');
|
|
|
|
actual = fp.xor(other, array);
|
|
assert.deepEqual(actual, ['a', 'c', 'd'], 'fp.xor');
|
|
|
|
actual = fp.pull('b', array);
|
|
assert.deepEqual(actual, ['a', 'c'], 'fp.pull');
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('cherry-picked methods');
|
|
|
|
(function() {
|
|
QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
|
|
assert.expect(4);
|
|
|
|
if (!document) {
|
|
var args,
|
|
array = [1, 2, 3],
|
|
object = { 'a': 1, 'b': 2 },
|
|
isFIFO = _.keys(object)[0] == 'a',
|
|
map = convert('map', _.map),
|
|
reduce = convert('reduce', _.reduce);
|
|
|
|
map(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(array);
|
|
|
|
assert.deepEqual(args, [1]);
|
|
|
|
args = undefined;
|
|
map(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(object);
|
|
|
|
assert.deepEqual(args, isFIFO ? [1] : [2]);
|
|
|
|
args = undefined;
|
|
reduce(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(0, array);
|
|
|
|
assert.deepEqual(args, [0, 1]);
|
|
|
|
args = undefined;
|
|
reduce(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(0, object);
|
|
|
|
assert.deepEqual(args, isFIFO ? [0, 1] : [0, 2]);
|
|
}
|
|
else {
|
|
skipTest(assert, 4);
|
|
}
|
|
});
|
|
|
|
QUnit.test('should not support shortcut fusion', function(assert) {
|
|
assert.expect(3);
|
|
|
|
if (!document) {
|
|
var array = fp.range(0, LARGE_ARRAY_SIZE),
|
|
filterCount = 0,
|
|
mapCount = 0;
|
|
|
|
var iteratee = function(value) {
|
|
mapCount++;
|
|
return value * value;
|
|
};
|
|
|
|
var predicate = function(value) {
|
|
filterCount++;
|
|
return value % 2 == 0;
|
|
};
|
|
|
|
var map1 = convert('map', _.map),
|
|
filter1 = convert('filter', _.filter),
|
|
take1 = convert('take', _.take);
|
|
|
|
var filter2 = filter1(predicate),
|
|
map2 = map1(iteratee),
|
|
take2 = take1(2);
|
|
|
|
var combined = fp.flow(map2, filter2, fp.compact, take2);
|
|
|
|
assert.deepEqual(combined(array), [4, 16]);
|
|
assert.strictEqual(filterCount, 200, 'filterCount');
|
|
assert.strictEqual(mapCount, 200, 'mapCount');
|
|
}
|
|
else {
|
|
skipTest(assert, 3);
|
|
}
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('curry methods');
|
|
|
|
_.each(['curry', 'curryRight'], function(methodName) {
|
|
var func = fp[methodName];
|
|
|
|
QUnit.test('`_.' + methodName + '` should only accept a `func` param', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.raises(function() { func(1, _.noop); }, TypeError);
|
|
});
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('curryN methods');
|
|
|
|
_.each(['curryN', 'curryRightN'], function(methodName) {
|
|
var func = fp[methodName];
|
|
|
|
QUnit.test('`_.' + methodName + '` accept an `arity` param', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var actual = func(1, function(a, b) { return [a, b]; })('a');
|
|
assert.deepEqual(actual, ['a', undefined]);
|
|
});
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.difference');
|
|
|
|
(function() {
|
|
QUnit.test('should return the elements of the first array not included in the second array', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.deepEqual(fp.difference([1, 2])([2, 3]), [1]);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.fill');
|
|
|
|
(function() {
|
|
QUnit.test('should have an argument order of `start`, `end`, then `value`', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var array = [1, 2, 3];
|
|
assert.deepEqual(fp.fill(1)(2)('*')(array), [1, '*', 3]);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.flow and fp.flowRight');
|
|
|
|
_.each(['flow', 'flowRight'], function(methodName, index) {
|
|
var func = fp[methodName],
|
|
isFlow = methodName == 'flow';
|
|
|
|
QUnit.test('`fp.' + methodName + '` should support shortcut fusion', function(assert) {
|
|
assert.expect(6);
|
|
|
|
var filterCount,
|
|
mapCount,
|
|
array = fp.range(0, LARGE_ARRAY_SIZE);
|
|
|
|
var iteratee = function(value) {
|
|
mapCount++;
|
|
return value * value;
|
|
};
|
|
|
|
var predicate = function(value) {
|
|
filterCount++;
|
|
return value % 2 == 0;
|
|
};
|
|
|
|
var filter = fp.filter(predicate),
|
|
map = fp.map(iteratee),
|
|
take = fp.take(2);
|
|
|
|
_.times(2, function(index) {
|
|
var combined = isFlow
|
|
? func(map, filter, fp.compact, take)
|
|
: func(take, fp.compact, filter, map);
|
|
|
|
filterCount = mapCount = 0;
|
|
|
|
if (WeakMap && WeakMap.name) {
|
|
assert.deepEqual(combined(array), [4, 16]);
|
|
assert.strictEqual(filterCount, 5, 'filterCount');
|
|
assert.strictEqual(mapCount, 5, 'mapCount');
|
|
}
|
|
else {
|
|
skipTest(assert, 3);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.inRange');
|
|
|
|
(function() {
|
|
QUnit.test('should have an argument order of `start`, `end`, then `value`', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.strictEqual(fp.inRange(2)(4)(3), true);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.iteratee');
|
|
|
|
(function() {
|
|
QUnit.test('should return a iteratee with capped params', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var func = fp.iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3);
|
|
assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]);
|
|
});
|
|
|
|
QUnit.test('should convert by name', function(assert) {
|
|
assert.expect(1);
|
|
|
|
if (!document) {
|
|
var iteratee = convert('iteratee', _.iteratee),
|
|
func = iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3);
|
|
|
|
assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]);
|
|
}
|
|
else {
|
|
skipTest(assert);
|
|
}
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.maxBy and fp.minBy');
|
|
|
|
_.each(['maxBy', 'minBy'], function(methodName, index) {
|
|
var array = [1, 2, 3],
|
|
func = fp[methodName],
|
|
isMax = !index;
|
|
|
|
QUnit.test('`fp.' + methodName + '` should work with an `iteratee` argument', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var actual = func(function(num) {
|
|
return -num;
|
|
})(array);
|
|
|
|
assert.strictEqual(actual, isMax ? 1 : 3);
|
|
});
|
|
|
|
QUnit.test('`fp.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var args;
|
|
|
|
func(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(array);
|
|
|
|
assert.deepEqual(args, [1]);
|
|
});
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.mixin');
|
|
|
|
(function() {
|
|
var source = { 'a': _.noop };
|
|
|
|
QUnit.test('should mixin static methods but not prototype methods', function(assert) {
|
|
assert.expect(2);
|
|
|
|
fp.mixin(source);
|
|
|
|
assert.strictEqual(typeof fp.a, 'function');
|
|
assert.notOk('a' in fp.prototype);
|
|
|
|
delete fp.a;
|
|
delete fp.prototype.a;
|
|
});
|
|
|
|
QUnit.test('should not assign inherited `source` methods', function(assert) {
|
|
assert.expect(2);
|
|
|
|
function Foo() {}
|
|
Foo.prototype.a = _.noop;
|
|
fp.mixin(new Foo);
|
|
|
|
assert.notOk('a' in fp);
|
|
assert.notOk('a' in fp.prototype);
|
|
|
|
delete fp.a;
|
|
delete fp.prototype.a;
|
|
});
|
|
|
|
QUnit.test('should not remove existing prototype methods', function(assert) {
|
|
assert.expect(2);
|
|
|
|
var each1 = fp.each,
|
|
each2 = fp.prototype.each;
|
|
|
|
fp.mixin({ 'each': source.a });
|
|
|
|
assert.strictEqual(fp.each, source.a);
|
|
assert.strictEqual(fp.prototype.each, each2);
|
|
|
|
fp.each = each1;
|
|
fp.prototype.each = each2;
|
|
});
|
|
|
|
QUnit.test('should not export to the global when `source` is not an object', function(assert) {
|
|
assert.expect(2);
|
|
|
|
var props = _.without(_.keys(_), '_');
|
|
|
|
_.times(2, function(index) {
|
|
fp.mixin.apply(fp, index ? [1] : []);
|
|
|
|
assert.ok(_.every(props, function(key) {
|
|
return root[key] !== fp[key];
|
|
}));
|
|
|
|
_.each(props, function(key) {
|
|
if (root[key] === fp[key]) {
|
|
delete root[key];
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
QUnit.test('should convert by name', function(assert) {
|
|
assert.expect(3);
|
|
|
|
if (!document) {
|
|
var object = { 'mixin': convert('mixin', _.mixin) };
|
|
|
|
function Foo() {}
|
|
Foo.mixin = object.mixin;
|
|
Foo.mixin(source);
|
|
|
|
assert.strictEqual(typeof Foo.a, 'function');
|
|
assert.notOk('a' in Foo.prototype);
|
|
|
|
object.mixin(source);
|
|
assert.strictEqual(typeof object.a, 'function');
|
|
}
|
|
else {
|
|
skipTest(assert, 3);
|
|
}
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.random');
|
|
|
|
(function() {
|
|
var array = Array(1000);
|
|
|
|
QUnit.test('should support a `min` and `max` argument', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var min = 5,
|
|
max = 10;
|
|
|
|
assert.ok(_.some(array, function() {
|
|
var result = fp.random(min)(max);
|
|
return result >= min && result <= max;
|
|
}));
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.range');
|
|
|
|
(function() {
|
|
QUnit.test('should have an argument order of `start` then `end`', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.deepEqual(fp.range(1)(4), [1, 2, 3]);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('reduce methods');
|
|
|
|
_.each(['reduce', 'reduceRight'], function(methodName) {
|
|
var func = fp[methodName],
|
|
isReduce = methodName == 'reduce';
|
|
|
|
QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments when iterating an array', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var args,
|
|
array = [1, 2, 3];
|
|
|
|
func(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(0, array);
|
|
|
|
assert.deepEqual(args, isReduce ? [0, 1] : [0, 3]);
|
|
});
|
|
|
|
QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments when iterating an object', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var args,
|
|
object = { 'a': 1, 'b': 2 },
|
|
isFIFO = _.keys(object)[0] == 'a';
|
|
|
|
var expected = isFIFO
|
|
? (isReduce ? [0, 1] : [0, 2])
|
|
: (isReduce ? [0, 2] : [0, 1]);
|
|
|
|
func(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(0, object);
|
|
|
|
assert.deepEqual(args, expected);
|
|
});
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.runInContext');
|
|
|
|
(function() {
|
|
QUnit.test('should return a converted lodash instance', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.strictEqual(typeof fp.runInContext({}).curryN, 'function');
|
|
});
|
|
|
|
QUnit.test('should convert by name', function(assert) {
|
|
assert.expect(1);
|
|
|
|
if (!document) {
|
|
var runInContext = convert('runInContext', _.runInContext);
|
|
assert.strictEqual(typeof runInContext({}).curryN, 'function');
|
|
}
|
|
else {
|
|
skipTest(assert);
|
|
}
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.uniqBy');
|
|
|
|
(function() {
|
|
var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
|
|
|
|
QUnit.test('should work with an `iteratee` argument', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var expected = objects.slice(0, 3);
|
|
|
|
var actual = fp.uniqBy(function(object) {
|
|
return object.a;
|
|
})(objects);
|
|
|
|
assert.deepEqual(actual, expected);
|
|
});
|
|
|
|
QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var args;
|
|
|
|
fp.uniqBy(function() {
|
|
args || (args = slice.call(arguments));
|
|
})(objects);
|
|
|
|
assert.deepEqual(args, [objects[0]]);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.zip');
|
|
|
|
(function() {
|
|
QUnit.test('should zip together two arrays', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.deepEqual(fp.zip([1, 2], [3, 4]), [[1, 3], [2, 4]]);
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('fp.zipObject');
|
|
|
|
(function() {
|
|
QUnit.test('should zip together key/value arrays into an object', function(assert) {
|
|
assert.expect(1);
|
|
|
|
assert.deepEqual(fp.zipObject(['a', 'b'], [1, 2]), { 'a': 1, 'b': 2 });
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('mutation methods');
|
|
|
|
(function() {
|
|
var array = [1, 2, 3],
|
|
object = { 'a': 1 },
|
|
deepObject = { 'a': { 'b': 2, 'c': 3 } };
|
|
|
|
QUnit.test('should not mutate values', function(assert) {
|
|
assert.expect(32);
|
|
|
|
function Foo() {}
|
|
Foo.prototype = { 'b': 2 };
|
|
|
|
var value = _.clone(object),
|
|
actual = fp.assign({ 'b': 2 }, value);
|
|
|
|
assert.deepEqual(value, object, 'fp.assign');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assign');
|
|
|
|
value = _.clone(object);
|
|
actual = fp.assignWith(function(objValue, srcValue) {
|
|
return srcValue;
|
|
}, { 'b': 2 }, value);
|
|
|
|
assert.deepEqual(value, object, 'fp.assignWith');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignWith');
|
|
|
|
value = _.clone(object);
|
|
actual = fp.defaults({ 'a': 2, 'b': 2 }, value);
|
|
|
|
assert.deepEqual(value, object, 'fp.defaults');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.defaults');
|
|
|
|
value = _.clone(object);
|
|
value.b = { 'c': 1 };
|
|
actual = fp.defaultsDeep({ 'b': { 'c': 2, 'd': 2 } }, value);
|
|
|
|
assert.deepEqual(value, { 'a': 1, 'b': { 'c': 1 } } , 'fp.defaultsDeep');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 1, 'd': 2 } }, 'fp.defaultsDeep');
|
|
|
|
value = _.clone(object);
|
|
actual = fp.extend(new Foo, value);
|
|
|
|
assert.deepEqual(value, object, 'fp.extend');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extend');
|
|
|
|
value = _.clone(object);
|
|
actual = fp.extendWith(function(objValue, srcValue) {
|
|
return srcValue;
|
|
}, new Foo, value);
|
|
|
|
assert.deepEqual(value, object, 'fp.extendWith');
|
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extendWith');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.fill(1, 2, '*', value);
|
|
|
|
assert.deepEqual(value, array, 'fp.fill');
|
|
assert.deepEqual(actual, [1, '*', 3], 'fp.fill');
|
|
|
|
value = { 'a': { 'b': 2 } };
|
|
actual = fp.merge({ 'a': { 'c': 3 } }, value);
|
|
|
|
assert.deepEqual(value, { 'a': { 'b': 2 } }, 'fp.merge');
|
|
assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3 } }, 'fp.merge');
|
|
|
|
value = { 'a': [1] };
|
|
actual = fp.mergeWith(function(objValue, srcValue) {
|
|
if (_.isArray(objValue)) {
|
|
return objValue.concat(srcValue);
|
|
}
|
|
}, { 'a': [2, 3] }, value);
|
|
|
|
assert.deepEqual(value, { 'a': [1] }, 'fp.mergeWith');
|
|
assert.deepEqual(actual, { 'a': [1, 2, 3] }, 'fp.mergeWith');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.pull(2, value);
|
|
|
|
assert.deepEqual(value, array, 'fp.pull');
|
|
assert.deepEqual(actual, [1, 3], 'fp.pull');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.pullAll([1, 3], value);
|
|
|
|
assert.deepEqual(value, array, 'fp.pullAll');
|
|
assert.deepEqual(actual, [2], 'fp.pullAll');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.pullAt([0, 2], value);
|
|
|
|
assert.deepEqual(value, array, 'fp.pullAt');
|
|
assert.deepEqual(actual, [2], 'fp.pullAt');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.remove(function(value) {
|
|
return value === 2;
|
|
}, value);
|
|
|
|
assert.deepEqual(value, array, 'fp.remove');
|
|
assert.deepEqual(actual, [1, 3], 'fp.remove');
|
|
|
|
value = _.clone(array);
|
|
actual = fp.reverse(value);
|
|
|
|
assert.deepEqual(value, array, 'fp.reverse');
|
|
assert.deepEqual(actual, [3, 2, 1], 'fp.reverse');
|
|
|
|
value = _.cloneDeep(deepObject);
|
|
actual = fp.set(3, 'a.b', value);
|
|
|
|
assert.deepEqual(value, deepObject, 'fp.set');
|
|
assert.deepEqual(actual, { 'a': { 'b': 3, 'c': 3 } }, 'fp.set');
|
|
|
|
value = _.cloneDeep(deepObject);
|
|
actual = fp.setWith(Object, 4, 'd.e', value);
|
|
|
|
assert.deepEqual(value, deepObject, 'fp.setWith');
|
|
assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3 }, 'd': { 'e': 4 } }, 'fp.setWith');
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.module('with methods');
|
|
|
|
(function() {
|
|
var array = [1, 2, 3],
|
|
object = { 'a': 1 };
|
|
|
|
QUnit.test('should provide the correct `customizer` arguments', function(assert) {
|
|
assert.expect(3);
|
|
|
|
var args,
|
|
value = _.clone(object);
|
|
|
|
var actual = fp.assignWith(function(objValue, srcValue) {
|
|
args || (args = _.map(arguments, _.cloneDeep));
|
|
return srcValue;
|
|
}, { 'b': 2 }, value);
|
|
|
|
assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.assignWith');
|
|
|
|
args = undefined;
|
|
value = _.clone(object);
|
|
actual = fp.extendWith(function(objValue, srcValue) {
|
|
args || (args = _.map(arguments, _.cloneDeep));
|
|
return srcValue;
|
|
}, { 'b': 2 }, value);
|
|
|
|
assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.extendWith');
|
|
|
|
var stack = { '__data__': { 'array': [], 'map': null } },
|
|
expected = [[1], [2, 3], 'a', { 'a': [ 1 ] }, { 'a': [2, 3] }, stack];
|
|
|
|
args = undefined;
|
|
value = { 'a': [1] };
|
|
actual = fp.mergeWith(function(objValue, srcValue) {
|
|
args || (args = _.map(arguments, _.cloneDeep));
|
|
if (_.isArray(objValue)) {
|
|
return objValue.concat(srcValue);
|
|
}
|
|
}, { 'a': [2, 3] }, value);
|
|
|
|
assert.deepEqual(args, expected, 'fp.mergeWith');
|
|
});
|
|
}());
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
QUnit.config.asyncRetries = 10;
|
|
QUnit.config.hidepassed = true;
|
|
|
|
if (!document) {
|
|
QUnit.config.noglobals = true;
|
|
QUnit.load();
|
|
}
|
|
}.call(this));
|