test.js (lodash-3.0.0) | : | test.js (lodash-4.0.0) |
---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |
/** Used to detect when a function becomes hot. */ | /** Used to detect when a function becomes hot. */ | |
var HOT_COUNT = 150; | var HOT_COUNT = 150; | |
/** Used as the size to cover large array optimizations. */ | /** Used as the size to cover large array optimizations. */ | |
var LARGE_ARRAY_SIZE = 200; | var LARGE_ARRAY_SIZE = 200; | |
/** Used as the `TypeError` message for "Functions" methods. */ | /** Used as the `TypeError` message for "Functions" methods. */ | |
var FUNC_ERROR_TEXT = 'Expected a function'; | var FUNC_ERROR_TEXT = 'Expected a function'; | |
/** Used as references for the max length and index of an array. */ | /** Used as references for various `Number` constants. */ | |
var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, | var MAX_SAFE_INTEGER = 9007199254740991, | |
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; | MAX_INTEGER = 1.7976931348623157e+308; | |
/** Used as the maximum length an array-like object. */ | /** Used as references for the maximum length and index of an array. */ | |
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; | var MAX_ARRAY_LENGTH = 4294967295, | |
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; | ||
/** `Object#toString` result references. */ | /** `Object#toString` result references. */ | |
var funcTag = '[object Function]', | var funcTag = '[object Function]', | |
numberTag = '[object Number]', | numberTag = '[object Number]', | |
objectTag = '[object Object]'; | objectTag = '[object Object]'; | |
/** Used as a reference to the global object. */ | /** Used as a reference to the global object. */ | |
var root = (typeof global == 'object' && global) || this; | var root = (typeof global == 'object' && global) || this; | |
/** Used to store lodash to test for bad extensions/shims. */ | /** Used to store lodash to test for bad extensions/shims. */ | |
var lodashBizarro = root.lodashBizarro; | var lodashBizarro = root.lodashBizarro; | |
/** Used for native method references. */ | /** Used for native method references. */ | |
var arrayProto = Array.prototype, | var arrayProto = Array.prototype, | |
errorProto = Error.prototype, | errorProto = Error.prototype, | |
funcProto = Function.prototype, | funcProto = Function.prototype, | |
objectProto = Object.prototype, | objectProto = Object.prototype, | |
numberProto = Number.prototype, | ||
stringProto = String.prototype; | stringProto = String.prototype; | |
/** Method and object shortcuts. */ | /** Method and object shortcuts. */ | |
var phantom = root.phantom, | var phantom = root.phantom, | |
amd = root.define && define.amd, | amd = root.define && define.amd, | |
argv = root.process && process.argv, | argv = root.process && process.argv, | |
ArrayBuffer = root.ArrayBuffer, | ArrayBuffer = root.ArrayBuffer, | |
defineProperty = Object.defineProperty, | ||
document = !phantom && root.document, | document = !phantom && root.document, | |
body = root.document && root.document.body, | body = root.document && root.document.body, | |
create = Object.create, | create = Object.create, | |
fnToString = funcProto.toString, | fnToString = funcProto.toString, | |
freeze = Object.freeze, | freeze = Object.freeze, | |
hasOwnProperty = objectProto.hasOwnProperty, | identity = function(value) { return value; }, | |
JSON = root.JSON, | JSON = root.JSON, | |
Map = root.Map, | ||
noop = function() {}, | noop = function() {}, | |
objToString = objectProto.toString, | objToString = objectProto.toString, | |
params = root.arguments, | params = argv, | |
push = arrayProto.push, | push = arrayProto.push, | |
realm = {}, | ||
Set = root.Set, | ||
slice = arrayProto.slice, | slice = arrayProto.slice, | |
system = root.system, | Symbol = root.Symbol, | |
Uint8Array = root.Uint8Array; | symbol = Symbol ? Symbol('a') : undefined, | |
Uint8Array = root.Uint8Array, | ||
/** Used to set property descriptors. */ | WeakMap = root.WeakMap; | |
var defineProperty = (function() { | ||
try { | /** Math helpers. */ | |
var o = {}, | var add = function(x, y) { return x + y; }, | |
func = Object.defineProperty, | doubled = function(n) { return n * 2; }, | |
result = func(o, o, o) && func; | isEven = function(n) { return n % 2 == 0; }, | |
} catch(e) {} | square = function(n) { return n * n; }; | |
return result; | ||
}()); | /** Constant functions. */ | |
var alwaysA = function() { return 'a'; }, | ||
alwaysB = function() { return 'b'; }, | ||
alwaysC = function() { return 'c'; }; | ||
var alwaysTrue = function() { return true; }, | ||
alwaysFalse = function() { return false; }; | ||
var alwaysNaN = function() { return NaN; }, | ||
alwaysNull = function() { return null; }, | ||
alwaysUndefined = function() { return undefined; }; | ||
var alwaysZero = function() { return 0; }, | ||
alwaysOne = function() { return 1; }, | ||
alwaysTwo = function() { return 2; }, | ||
alwaysThree = function() { return 3; }, | ||
alwaysFour = function() { return 4; }; | ||
var alwaysEmptyArray = function() { return []; }, | ||
alwaysEmptyObject = function() { return {}; }, | ||
alwaysEmptyString = function() { return ''; }; | ||
/** The file path of the lodash file to test. */ | /** The file path of the lodash file to test. */ | |
var filePath = (function() { | var filePath = (function() { | |
var min = 0, | var min = 2, | |
result = []; | result = params || []; | |
if (phantom) { | if (phantom) { | |
result = params = phantom.args; | min = 0; | |
} else if (system) { | result = params = phantom.args || require('system').args; | |
min = 1; | ||
result = params = system.args; | ||
} else if (argv) { | ||
min = 2; | ||
result = params = argv; | ||
} else if (params) { | ||
result = params; | ||
} | } | |
var last = result[result.length - 1]; | var last = result[result.length - 1]; | |
result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../ lodash.src.js'; | result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../ lodash.js'; | |
if (!amd) { | if (!amd) { | |
try { | try { | |
result = require('fs').realpathSync(result); | result = require('fs').realpathSync(result); | |
} catch(e) {} | } catch (e) {} | |
try { | try { | |
result = require.resolve(result); | result = require.resolve(result); | |
} catch(e) {} | } catch (e) {} | |
} | } | |
return result; | return result; | |
}()); | }()); | |
/** The `ui` object. */ | /** The `ui` object. */ | |
var ui = root.ui || (root.ui = { | var ui = root.ui || (root.ui = { | |
'buildPath': filePath, | 'buildPath': filePath, | |
'loaderPath': '', | 'loaderPath': '', | |
'isModularize': /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test(f ilePath), | 'isModularize': /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test(f ilePath), | |
'isStrict': /\bes6?\b/.test(filePath), | 'isStrict': /\bes6?\b/.test(filePath), | |
'urlParams': {} | 'urlParams': {} | |
}); | }); | |
/** The basename of the lodash file to test. */ | /** The basename of the lodash file to test. */ | |
var basename = /[\w.-]+$/.exec(filePath)[0]; | var basename = /[\w.-]+$/.exec(filePath)[0]; | |
/** Detect if in a Java environment. */ | ||
var isJava = !document && !!root.java; | ||
/** Used to indicate testing a modularized build. */ | /** Used to indicate testing a modularized build. */ | |
var isModularize = ui.isModularize; | var isModularize = ui.isModularize; | |
/** Detect if testing `npm` modules. */ | /** Detect if testing `npm` modules. */ | |
var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]) ; | var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]) ; | |
/** Detect if running in PhantomJS. */ | /** Detect if running in PhantomJS. */ | |
var isPhantom = phantom || typeof callPhantom == 'function'; | var isPhantom = phantom || (typeof callPhantom == 'function'); | |
/** Detect if running in Rhino. */ | ||
var isRhino = isJava && typeof global == 'function' && global().Array === root | ||
.Array; | ||
/** Detect if lodash is in strict mode. */ | /** Detect if lodash is in strict mode. */ | |
var isStrict = ui.isStrict; | var isStrict = ui.isStrict; | |
/** Used to test Web Workers. */ | ||
var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) && document && | ||
root.Worker; | ||
/** Used to test host objects in IE. */ | ||
try { | ||
var xml = new ActiveXObject('Microsoft.XMLDOM'); | ||
} catch(e) {} | ||
/** Use a single "load" function. */ | ||
var load = (typeof require == 'function' && !amd) | ||
? require | ||
: (isJava ? root.load : 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 and install QUnit Extras and ES6 Set/WeakMap shims. */ | ||
(function() { | ||
var paths = [ | ||
'./asset/set.js', | ||
'./asset/weakmap.js', | ||
'../node_modules/qunit-extras/qunit-extras.js' | ||
]; | ||
var index = -1, | ||
length = paths.length; | ||
while (++index < length) { | ||
var object = load(paths[index]); | ||
if (object) { | ||
object.runInContext(root); | ||
} | ||
} | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
// Log params provided to `test.js`. | // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs. | |
if (params) { | root.msWDfn = undefined; | |
console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(p | ||
arams))); | ||
} | ||
// Exit early if going to run tests in a PhantomJS web page. | // Exit early if going to run tests in a PhantomJS web page. | |
if (phantom && isModularize) { | if (phantom && isModularize) { | |
var page = require('webpage').create(); | var page = require('webpage').create(); | |
page.open(filePath, function(status) { | ||
if (status != 'success') { | ||
console.log('PhantomJS failed to load page: ' + filePath); | ||
phantom.exit(1); | ||
} | ||
}); | ||
page.onCallback = function(details) { | page.onCallback = function(details) { | |
var coverage = details.coverage; | var coverage = details.coverage; | |
if (coverage) { | if (coverage) { | |
var fs = require('fs'), | var fs = require('fs'), | |
cwd = fs.workingDirectory, | cwd = fs.workingDirectory, | |
sep = fs.separator; | sep = fs.separator; | |
fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(co verage)); | fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(co verage)); | |
} | } | |
skipping to change at line 212 | skipping to change at line 180 | |
page.evaluate(function() { | page.evaluate(function() { | |
document.addEventListener('DOMContentLoaded', function() { | document.addEventListener('DOMContentLoaded', function() { | |
QUnit.done(function(details) { | QUnit.done(function(details) { | |
details.coverage = window.__coverage__; | details.coverage = window.__coverage__; | |
callPhantom(details); | callPhantom(details); | |
}); | }); | |
}); | }); | |
}); | }); | |
}; | }; | |
page.open(filePath, function(status) { | ||
if (status != 'success') { | ||
console.log('PhantomJS failed to load page: ' + filePath); | ||
phantom.exit(1); | ||
} | ||
}); | ||
console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(p | ||
arams))); | ||
return; | return; | |
} | } | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
/** Used to test Web Workers. */ | ||
var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) && | ||
(document && document.origin != 'null') && root.Worker; | ||
/** Used to test host objects in IE. */ | ||
try { | ||
var xml = new ActiveXObject('Microsoft.XMLDOM'); | ||
} catch (e) {} | ||
/** Poison the free variable `root` in Node.js */ | ||
try { | ||
defineProperty(global.root, 'root', { | ||
'configurable': false, | ||
'enumerable': false, | ||
'get': function() { throw new ReferenceError; } | ||
}); | ||
} catch (e) {} | ||
/** Use a single "load" function. */ | ||
var load = (!amd && typeof require == 'function') | ||
? require | ||
: noop; | ||
/** The unit testing framework. */ | ||
var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qu | ||
nit.js')); | ||
/** Load stable Lodash and QUnit Extras. */ | ||
var lodashStable = root.lodashStable || load('../node_modules/lodash/index.js' | ||
); | ||
if (lodashStable) { | ||
lodashStable = lodashStable.runInContext(root); | ||
} | ||
var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js'); | ||
if (QUnitExtras) { | ||
QUnitExtras.runInContext(root); | ||
} | ||
/** The `lodash` function to test. */ | /** The `lodash` function to test. */ | |
var _ = root._ || (root._ = ( | var _ = root._ || (root._ = ( | |
_ = load(filePath) || root._, | _ = load(filePath), | |
_ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default' ]) || _, | _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default' ]) || _, | |
(_.runInContext ? _.runInContext(root) : _) | (_.runInContext ? _.runInContext(root) : _) | |
)); | )); | |
/** Used to detect instrumented istanbul code coverage runs. */ | ||
var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(v | ||
alue, key) { | ||
return /^(?:\$\$cov_\d+\$\$)$/.test(key); | ||
})]; | ||
/** Used to restore the `_` reference. */ | ||
var oldDash = root._; | ||
/** Used to test generator functions. */ | ||
var generator = lodashStable.attempt(function() { | ||
return Function('return function*(){}'); | ||
}); | ||
/** List of latin-1 supplementary letters to basic latin letters. */ | /** List of latin-1 supplementary letters to basic latin letters. */ | |
var burredLetters = [ | var burredLetters = [ | |
'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc 9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', | '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc 9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', | |
'\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd 9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', | '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd 9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', | |
'\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe 8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', | '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe 8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', | |
'\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf 9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' | '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf 9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' | |
]; | ]; | |
/** List of combining diacritical marks. */ | ||
var comboMarks = [ | ||
'\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u030 | ||
7', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030 | ||
f', | ||
'\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u031 | ||
7', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031 | ||
f', | ||
'\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u032 | ||
7', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032 | ||
f', | ||
'\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u033 | ||
7', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033 | ||
f', | ||
'\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u034 | ||
7', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034 | ||
f', | ||
'\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u035 | ||
7', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035 | ||
f', | ||
'\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u036 | ||
7', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036 | ||
f', | ||
'\ufe20', '\ufe21', '\ufe22', '\ufe23' | ||
]; | ||
/** List of `burredLetters` translated to basic latin letters. */ | /** List of `burredLetters` translated to basic latin letters. */ | |
var deburredLetters = [ | var deburredLetters = [ | |
'A', 'A', 'A', 'A', 'A', 'A', 'Ae', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I' , | 'A', 'A', 'A', 'A', 'A', 'A', 'Ae', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I' , | |
'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th ', | 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th ', | |
'ss', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i' , 'i', | 'ss', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i' , 'i', | |
'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'th ', 'y' | 'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'th ', 'y' | |
]; | ]; | |
/** List of emoji modifiers. */ | ||
var emojiModifiers = [ | ||
'\ud83c\udffb', | ||
'\ud83c\udffc', | ||
'\ud83c\udffd', | ||
'\ud83c\udffe', | ||
'\ud83c\udfff' | ||
]; | ||
/** Used to specify the emoji style glyph variant of characters. */ | ||
var emojiVar = '\ufe0f'; | ||
/** Used to provide falsey values to methods. */ | /** Used to provide falsey values to methods. */ | |
var falsey = [, '', 0, false, NaN, null, undefined]; | var falsey = [, '', 0, false, NaN, null, undefined]; | |
/** Used to provide empty values to methods. */ | /** Used to provide empty values to methods. */ | |
var empties = [[], {}].concat(falsey.slice(1)); | var empties = [[], {}].concat(falsey.slice(1)); | |
/** Used to test error objects. */ | /** Used to test error objects. */ | |
var errors = [ | var errors = [ | |
new Error, | new Error, | |
new EvalError, | new EvalError, | |
new RangeError, | new RangeError, | |
new ReferenceError, | new ReferenceError, | |
new SyntaxError, | new SyntaxError, | |
new TypeError, | new TypeError, | |
new URIError | new URIError | |
]; | ]; | |
/** Used to check problem JScript properties (a.k.a. the `[[DontEnum]]` bug). | ||
*/ | ||
var shadowProps = [ | ||
'constructor', | ||
'hasOwnProperty', | ||
'isPrototypeOf', | ||
'propertyIsEnumerable', | ||
'toLocaleString', | ||
'toString', | ||
'valueOf' | ||
]; | ||
/** Used to check problem JScript properties too. */ | ||
var shadowObject = _.invert(shadowProps); | ||
/** Used to check whether methods support typed arrays. */ | /** Used to check whether methods support typed arrays. */ | |
var typedArrays = [ | var typedArrays = [ | |
'Float32Array', | 'Float32Array', | |
'Float64Array', | 'Float64Array', | |
'Int8Array', | 'Int8Array', | |
'Int16Array', | 'Int16Array', | |
'Int32Array', | 'Int32Array', | |
'Uint8Array', | 'Uint8Array', | |
'Uint8ClampedArray', | 'Uint8ClampedArray', | |
'Uint16Array', | 'Uint16Array', | |
'Uint32Array' | 'Uint32Array' | |
]; | ]; | |
/** | /** | |
* Used to check for problems removing whitespace. For a whitespace reference | * Used to check for problems removing whitespace. For a whitespace reference, | |
* see V8's unit test https://code.google.com/p/v8/source/browse/branches/blee | * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bl | |
ding_edge/test/mjsunit/whitespaces.js. | eeding_edge/test/mjsunit/whitespaces.js). | |
*/ | */ | |
var whitespace = ' \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\ | var whitespace = lodashStable.filter([ | |
u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'; | // Basic whitespace characters. | |
' ', '\t', '\x0b', '\f', '\xa0', '\ufeff', | ||
// Line terminators. | ||
'\n', '\r', '\u2028', '\u2029', | ||
// Unicode category "Zs" space separators. | ||
'\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u200 | ||
5', | ||
'\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u300 | ||
0' | ||
], | ||
function(chr) { return /\s/.exec(chr); }) | ||
.join(''); | ||
/** | /** | |
* Extracts the unwrapped value from its wrapper. | * Extracts the unwrapped value from its wrapper. | |
* | * | |
* @private | * @private | |
* @param {Object} wrapper The wrapper to unwrap. | * @param {Object} wrapper The wrapper to unwrap. | |
* @returns {*} Returns the unwrapped value. | * @returns {*} Returns the unwrapped value. | |
*/ | */ | |
function getUnwrappedValue(wrapper) { | function getUnwrappedValue(wrapper) { | |
var index = -1, | var index = -1, | |
skipping to change at line 320 | skipping to change at line 367 | |
return result; | return result; | |
} | } | |
/** | /** | |
* Removes all own enumerable properties from a given object. | * Removes all own enumerable properties from a given object. | |
* | * | |
* @private | * @private | |
* @param {Object} object The object to empty. | * @param {Object} object The object to empty. | |
*/ | */ | |
function emptyObject(object) { | function emptyObject(object) { | |
_.forOwn(object, function(value, key, object) { | lodashStable.forOwn(object, function(value, key, object) { | |
delete object[key]; | delete object[key]; | |
}); | }); | |
} | } | |
/** | /** | |
* Sets a non-enumerable property value on `object`. | * Sets a non-enumerable property value on `object`. | |
* | * | |
* Note: This function is used to avoid a bug in older versions of V8 where | * Note: This function is used to avoid a bug in older versions of V8 where | |
* overwriting non-enumerable built-ins makes them enumerable. | * overwriting non-enumerable built-ins makes them enumerable. | |
* See https://code.google.com/p/v8/issues/detail?id=1623 | * See https://code.google.com/p/v8/issues/detail?id=1623 | |
* | * | |
* @private | * @private | |
* @param {Object} object The object augment. | * @param {Object} object The object modify. | |
* @param {string} key The name of the property to set. | * @param {string} key The name of the property to set. | |
* @param {*} value The property value. | * @param {*} value The property value. | |
*/ | */ | |
function setProperty(object, key, value) { | function setProperty(object, key, value) { | |
try { | try { | |
defineProperty(object, key, { | defineProperty(object, key, { | |
'configurable': true, | 'configurable': true, | |
'enumerable': false, | 'enumerable': false, | |
'writable': true, | 'writable': true, | |
'value': value | 'value': value | |
}); | }); | |
} catch(e) { | } catch (e) { | |
object[key] = value; | object[key] = value; | |
} | } | |
return object; | ||
} | } | |
/** | /** | |
* Skips a given number of tests with a passing result. | * Skips a given number of tests with a passing result. | |
* | * | |
* @private | * @private | |
* @param {Object} assert The QUnit assert object. | ||
* @param {number} [count=1] The number of tests to skip. | * @param {number} [count=1] The number of tests to skip. | |
*/ | */ | |
function skipTest(count) { | function skipTest(assert, count) { | |
count || (count = 1); | count || (count = 1); | |
while (count--) { | while (count--) { | |
ok(true, 'test skipped'); | assert.ok(true, 'test skipped'); | |
} | } | |
} | } | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
// Setup values for Node.js. | // Add bizarro values. | |
(function() { | (function() { | |
if (amd) { | if (document || (typeof require != 'function')) { | |
return; | return; | |
} | } | |
try { | ||
// Add values from a different realm. | ||
_.extend(_, require('vm').runInNewContext([ | ||
'(function() {', | ||
' var object = {', | ||
" '_arguments': (function() { return arguments; }(1, 2, 3)),", | ||
" '_array': [1, 2, 3],", | ||
" '_boolean': Object(false),", | ||
" '_date': new Date,", | ||
" '_errors': [new Error, new EvalError, new RangeError, new ReferenceEr | ||
ror, new SyntaxError, new TypeError, new URIError],", | ||
" '_function': function() {},", | ||
" '_nan': NaN,", | ||
" '_null': null,", | ||
" '_number': Object(0),", | ||
" '_object': { 'a': 1, 'b': 2, 'c': 3 },", | ||
" '_regexp': /x/,", | ||
" '_string': Object('a'),", | ||
" '_undefined': undefined", | ||
' };', | ||
'', | ||
" ['" + typedArrays.join("', '") + "'].forEach(function(type) {", | ||
" var Ctor = Function('return typeof ' + type + \" != 'undefined' && | ||
\" + type)()", | ||
' if (Ctor) {', | ||
" object['_' + type.toLowerCase()] = new Ctor(new ArrayBuffer(24)); | ||
", | ||
' }', | ||
" });", | ||
'', | ||
' return object;', | ||
'}())' | ||
].join('\n'))); | ||
} | ||
catch(e) { | ||
if (!phantom) { | ||
return; | ||
} | ||
} | ||
var nativeString = fnToString.call(toString), | var nativeString = fnToString.call(toString), | |
reToString = /toString/g; | reToString = /toString/g; | |
function createToString(funcName) { | function createToString(funcName) { | |
return _.constant(nativeString.replace(reToString, funcName)); | return lodashStable.constant(nativeString.replace(reToString, funcName)); | |
} | } | |
// Expose internal modules for better code coverage. | ||
if (isModularize && !isNpm) { | ||
_.each(['baseEach', 'isIndex', 'isIterateeCall', 'isLength'], function(fun | ||
cName) { | ||
var path = require('path'), | ||
func = require(path.join(path.dirname(filePath), 'internal', 'baseEa | ||
ch.js')); | ||
_['_' + funcName] = func[funcName] || func['default'] || func; | ||
}); | ||
} | ||
// Allow bypassing native checks. | // Allow bypassing native checks. | |
setProperty(funcProto, 'toString', function wrapper() { | setProperty(funcProto, 'toString', function wrapper() { | |
setProperty(funcProto, 'toString', fnToString); | setProperty(funcProto, 'toString', fnToString); | |
var result = _.has(this, 'toString') ? this.toString() : fnToString.call(t his); | var result = _.has(this, 'toString') ? this.toString() : fnToString.call(t his); | |
setProperty(funcProto, 'toString', wrapper); | setProperty(funcProto, 'toString', wrapper); | |
return result; | return result; | |
}); | }); | |
// Add built-in prototype extensions. | // Add prototype extensions. | |
funcProto._method = _.noop; | funcProto._method = noop; | |
// Set bad shims. | // Set bad shims. | |
var _isArray = Array.isArray; | ||
setProperty(Array, 'isArray', _.noop); | ||
var _now = Date.now; | ||
setProperty(Date, 'now', _.noop); | ||
var _getPrototypeOf = Object.getPrototypeOf; | ||
setProperty(Object, 'getPrototypeOf', _.noop); | ||
var _keys = Object.keys; | ||
setProperty(Object, 'keys', _.noop); | ||
var _propertyIsEnumerable = objectProto.propertyIsEnumerable; | var _propertyIsEnumerable = objectProto.propertyIsEnumerable; | |
setProperty(objectProto, 'propertyIsEnumerable', function(key) { | setProperty(objectProto, 'propertyIsEnumerable', function(key) { | |
if (key == '1' && _.isArguments(this) && _.isEqual(_.values(this), [0, 0]) | return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnu | |
) { | merable.call(this, key); | |
throw new Error; | ||
} | ||
return _.has(this, key); | ||
}); | }); | |
var _isFinite = Number.isFinite; | if (Map) { | |
setProperty(Number, 'isFinite', _.noop); | setProperty(root, 'Map', (function() { | |
var count = 0; | ||
var _ArrayBuffer = ArrayBuffer; | return function() { | |
setProperty(root, 'ArrayBuffer', (function() { | if (count++) { | |
function ArrayBuffer(byteLength) { | return new Map; | |
var buffer = new _ArrayBuffer(byteLength); | } | |
if (!byteLength) { | var result = {}; | |
setProperty(buffer, 'slice', buffer.slice ? null : bufferSlice); | setProperty(root, 'Map', Map); | |
} | return result; | |
return buffer; | }; | |
} | ||
function bufferSlice() { | ||
var newBuffer = new _ArrayBuffer(this.byteLength), | ||
view = new Uint8Array(newBuffer); | ||
view.set(new Uint8Array(this)); | ||
return newBuffer; | ||
} | ||
setProperty(ArrayBuffer, 'toString', createToString('ArrayBuffer')); | ||
setProperty(bufferSlice, 'toString', createToString('slice')); | ||
return ArrayBuffer; | ||
}())); | ||
if (!root.Float64Array) { | ||
setProperty(root, 'Float64Array', (function() { | ||
function Float64Array(buffer, byteOffset, length) { | ||
return arguments.length == 1 | ||
? new Uint8Array(buffer) | ||
: new Uint8Array(buffer, byteOffset || 0, length || buffer.byteLengt | ||
h); | ||
} | ||
setProperty(Float64Array, 'BYTES_PER_ELEMENT', 8); | ||
setProperty(Float64Array, 'toString', createToString('Float64Array')); | ||
return Float64Array; | ||
}())); | }())); | |
setProperty(root.Map, 'toString', createToString('Map')); | ||
} | } | |
var _parseInt = parseInt; | setProperty(Object, 'create', noop); | |
setProperty(root, 'parseInt', (function() { | ||
var checkStr = whitespace + '08', | var _getOwnPropertySymbols = Object.getOwnPropertySymbols; | |
isFaked = _parseInt(checkStr) != 8, | setProperty(Object, 'getOwnPropertySymbols', undefined); | |
reHexPrefix = /^0[xX]/, | ||
reTrim = RegExp('^[' + whitespace + ']+|[' + whitespace + ']+$'); | setProperty(root, 'Set', noop); | |
setProperty(root, 'Symbol', undefined); | ||
return function(value, radix) { | setProperty(root, 'WeakMap', noop); | |
if (value == checkStr && !isFaked) { | ||
isFaked = true; | ||
return 0; | ||
} | ||
value = String(value == null ? '' : value).replace(reTrim, ''); | ||
return _parseInt(value, +radix || (reHexPrefix.test(value) ? 16 : 10)); | ||
}; | ||
}())); | ||
var _Set = root.Set; | ||
setProperty(root, 'Set', _.noop); | ||
var _WeakMap = root.WeakMap; | ||
setProperty(root, 'WeakMap', _.noop); | ||
// Fake the DOM. | ||
setProperty(root, 'window', {}); | ||
setProperty(root.window, 'document', {}); | ||
setProperty(root.window.document, 'createDocumentFragment', function() { | ||
return { 'nodeType': 11 }; | ||
}); | ||
// Fake `WinRTError`. | // Fake `WinRTError`. | |
setProperty(root, 'WinRTError', Error); | setProperty(root, 'WinRTError', Error); | |
// Clear cache so lodash can be reloaded. | // Clear cache so lodash can be reloaded. | |
emptyObject(require.cache); | emptyObject(require.cache); | |
// Load lodash and expose it to the bad extensions/shims. | // Load lodash and expose it to the bad extensions/shims. | |
lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['defa ult'] || lodashBizarro; | lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['defa ult'] || lodashBizarro; | |
root._ = oldDash; | ||
// Restore built-in methods. | // Restore built-in methods. | |
setProperty(Array, 'isArray', _isArray); | if (_getOwnPropertySymbols) { | |
setProperty(Date, 'now', _now); | Object.getOwnPropertySymbols = _getOwnPropertySymbols; | |
setProperty(Object, 'getPrototypeOf', _getPrototypeOf); | ||
setProperty(Object, 'keys', _keys); | ||
setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); | ||
setProperty(root, 'parseInt', _parseInt); | ||
if (_isFinite) { | ||
setProperty(Number, 'isFinite', _isFinite); | ||
} else { | } else { | |
delete Number.isFinite; | delete Object.getOwnPropertySymbols; | |
} | } | |
if (_ArrayBuffer) { | if (Map) { | |
setProperty(root, 'ArrayBuffer', _ArrayBuffer); | setProperty(root, 'Map', Map); | |
} else { | } else { | |
delete root.ArrayBuffer; | delete root.Map; | |
} | } | |
if (_Set) { | if (Set) { | |
setProperty(root, 'Set', Set); | setProperty(root, 'Set', Set); | |
} else { | } else { | |
delete root.Set; | delete root.Set; | |
} | } | |
if (_WeakMap) { | if (Symbol) { | |
setProperty(root, 'Symbol', Symbol); | ||
} else { | ||
delete root.Symbol; | ||
} | ||
if (WeakMap) { | ||
setProperty(root, 'WeakMap', WeakMap); | setProperty(root, 'WeakMap', WeakMap); | |
} else { | } else { | |
delete root.WeakMap; | delete root.WeakMap; | |
} | } | |
setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); | ||
setProperty(Object, 'create', create); | ||
delete root.WinRTError; | delete root.WinRTError; | |
delete root.window; | ||
delete funcProto._method; | delete funcProto._method; | |
}()); | }()); | |
// Add values from an iframe. | // Add other realm values from the `vm` module. | |
(function() { | lodashStable.attempt(function() { | |
if (_._object || !document) { | lodashStable.assign(realm, require('vm').runInNewContext([ | |
return; | '(function() {', | |
} | ' var noop = function() {},', | |
' root = this;', | ||
'', | ||
' var object = {', | ||
" 'arguments': (function() { return arguments; }(1, 2, 3)),", | ||
" 'array': [1, 2, 3],", | ||
" 'arrayBuffer': new (root.ArrayBuffer || noop),", | ||
" 'boolean': Object(false),", | ||
" 'date': new Date,", | ||
" 'errors': [new Error, new EvalError, new RangeError, new ReferenceErr | ||
or, new SyntaxError, new TypeError, new URIError],", | ||
" 'function': noop,", | ||
" 'map': new (root.Map || noop),", | ||
" 'nan': NaN,", | ||
" 'null': null,", | ||
" 'number': Object(0),", | ||
" 'object': { 'a': 1, 'b': 2, 'c': 3 },", | ||
" 'regexp': /x/,", | ||
" 'set': new (root.Set || noop),", | ||
" 'string': Object('a'),", | ||
" 'symbol': Object((root.Symbol || noop)()),", | ||
" 'undefined': undefined", | ||
' };', | ||
'', | ||
" ['" + typedArrays.join("', '") + "'].forEach(function(type) {", | ||
" var Ctor = root[type]", | ||
' if (Ctor) {', | ||
" object[type.toLowerCase()] = new Ctor(new ArrayBuffer(24));", | ||
' }', | ||
" });", | ||
'', | ||
' return object;', | ||
'}())' | ||
].join('\n'))); | ||
}); | ||
// Add other realm values from an iframe. | ||
lodashStable.attempt(function() { | ||
_._realm = realm; | ||
var iframe = document.createElement('iframe'); | var iframe = document.createElement('iframe'); | |
iframe.frameBorder = iframe.height = iframe.width = 0; | iframe.frameBorder = iframe.height = iframe.width = 0; | |
body.appendChild(iframe); | body.appendChild(iframe); | |
var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc; | var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc; | |
idoc.write([ | idoc.write([ | |
'<script>', | '<script>', | |
'parent._._arguments = (function() { return arguments; }(1, 2, 3));', | 'var _ = parent._;', | |
'parent._._array = [1, 2, 3];', | '', | |
'parent._._boolean = Object(false);', | ' var noop = function() {},', | |
'parent._._date = new Date;', | ' root = this;', | |
"parent._._element = document.createElement('div');", | ||
'parent._._errors = [new Error, new EvalError, new RangeError, new Referen | ||
ceError, new SyntaxError, new TypeError, new URIError];', | ||
'parent._._function = function() {};', | ||
'parent._._nan = NaN;', | ||
'parent._._null = null;', | ||
'parent._._number = Object(0);', | ||
"parent._._object = { 'a': 1, 'b': 2, 'c': 3 };", | ||
'parent._._regexp = /x/;', | ||
"parent._._string = Object('a');", | ||
'parent._._undefined = undefined;', | ||
'', | '', | |
'var root = this;', | 'var object = {', | |
"parent._.each(['" + typedArrays.join("', '") + "'], function(type) {", | " 'arguments': (function() { return arguments; }(1, 2, 3)),", | |
" 'array': [1, 2, 3],", | ||
" 'arrayBuffer': new (root.ArrayBuffer || noop),", | ||
" 'boolean': Object(false),", | ||
" 'date': new Date,", | ||
" 'errors': [new Error, new EvalError, new RangeError, new ReferenceError | ||
, new SyntaxError, new TypeError, new URIError],", | ||
" 'function': noop,", | ||
" 'map': new (root.Map || noop),", | ||
" 'nan': NaN,", | ||
" 'null': null,", | ||
" 'number': Object(0),", | ||
" 'object': { 'a': 1, 'b': 2, 'c': 3 },", | ||
" 'regexp': /x/,", | ||
" 'set': new (root.Set || noop),", | ||
" 'string': Object('a'),", | ||
" 'symbol': Object((root.Symbol || noop)()),", | ||
" 'undefined': undefined", | ||
'};', | ||
'', | ||
"_.each(['" + typedArrays.join("', '") + "'], function(type) {", | ||
' var Ctor = root[type];', | ' var Ctor = root[type];', | |
' if (Ctor) {', | ' if (Ctor) {', | |
" parent._['_' + type.toLowerCase()] = new Ctor(new ArrayBuffer(24));", | " object[type.toLowerCase()] = new Ctor(new ArrayBuffer(24));", | |
' }', | ' }', | |
'});', | '});', | |
'', | ||
'_.assign(_._realm, object);', | ||
'<\/script>' | '<\/script>' | |
].join('\n')); | ].join('\n')); | |
idoc.close(); | idoc.close(); | |
}()); | delete _._realm; | |
}); | ||
// Add a web worker. | // Add a web worker. | |
(function() { | lodashStable.attempt(function() { | |
if (!Worker) { | ||
return; | ||
} | ||
var worker = new Worker('./asset/worker.js?t=' + (+new Date)); | var worker = new Worker('./asset/worker.js?t=' + (+new Date)); | |
worker.addEventListener('message', function(e) { | worker.addEventListener('message', function(e) { | |
_._VERSION = e.data || ''; | _._VERSION = e.data || ''; | |
}, false); | }, false); | |
worker.postMessage(ui.buildPath); | worker.postMessage(ui.buildPath); | |
}()); | }); | |
// Expose internal modules for better code coverage. | ||
lodashStable.attempt(function() { | ||
var path = require('path'), | ||
basePath = path.dirname(filePath); | ||
if (isModularize && !(amd || isNpm)) { | ||
lodashStable.each([ | ||
'internal/baseEach', | ||
'internal/isIndex', | ||
'internal/isIterateeCall' | ||
], function(relPath) { | ||
var func = require(path.join(basePath, relPath)), | ||
funcName = path.basename(relPath); | ||
_['_' + funcName] = func[funcName] || func['default'] || func; | ||
}); | ||
} | ||
}); | ||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
if (params) { | ||
console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(p | ||
arams))); | ||
} | ||
QUnit.module(basename); | QUnit.module(basename); | |
(function() { | (function() { | |
test('should support loading ' + basename + ' as the "lodash" module', 1, fu | QUnit.test('should support loading ' + basename + ' as the "lodash" module', | |
nction() { | function(assert) { | |
assert.expect(1); | ||
if (amd) { | if (amd) { | |
strictEqual((lodashModule || {}).moduleName, 'lodash'); | assert.strictEqual((lodashModule || {}).moduleName, 'lodash'); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should support loading ' + basename + ' with the Require.js "shim" con | QUnit.test('should support loading ' + basename + ' with the Require.js "shi | |
figuration option', 1, function() { | m" configuration option', function(assert) { | |
if (amd && _.includes(ui.loaderPath, 'requirejs')) { | assert.expect(1); | |
strictEqual((shimmedModule || {}).moduleName, 'shimmed'); | ||
if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) { | ||
assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed'); | ||
} else { | } else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should support loading ' + basename + ' as the "underscore" module', 1 | QUnit.test('should support loading ' + basename + ' as the "underscore" modu | |
, function() { | le', function(assert) { | |
assert.expect(1); | ||
if (amd) { | if (amd) { | |
strictEqual((underscoreModule || {}).moduleName, 'underscore'); | assert.strictEqual((underscoreModule || {}).moduleName, 'underscore'); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
asyncTest('should support loading ' + basename + ' in a web worker', 1, func | QUnit.test('should support loading ' + basename + ' in a web worker', functi | |
tion() { | on(assert) { | |
assert.expect(1); | ||
var done = assert.async(); | ||
if (Worker) { | if (Worker) { | |
var limit = 30000 / QUnit.config.asyncRetries, | var limit = 30000 / QUnit.config.asyncRetries, | |
start = +new Date; | start = +new Date; | |
var attempt = function() { | var attempt = function() { | |
var actual = _._VERSION; | var actual = _._VERSION; | |
if ((new Date - start) < limit && typeof actual != 'string') { | if ((new Date - start) < limit && typeof actual != 'string') { | |
setTimeout(attempt, 16); | setTimeout(attempt, 16); | |
return; | return; | |
} | } | |
strictEqual(actual, _.VERSION); | assert.strictEqual(actual, _.VERSION); | |
QUnit.start(); | done(); | |
}; | }; | |
attempt(); | attempt(); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
QUnit.start(); | done(); | |
} | } | |
}); | }); | |
test('should not add `Function.prototype` extensions to lodash', 1, function | QUnit.test('should not add `Function.prototype` extensions to lodash', funct | |
() { | ion(assert) { | |
assert.expect(1); | ||
if (lodashBizarro) { | if (lodashBizarro) { | |
ok(!('_method' in lodashBizarro)); | assert.notOk('_method' in lodashBizarro); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should avoid overwritten native methods', 12, function() { | QUnit.test('should avoid overwritten native methods', function(assert) { | |
function Foo() {} | assert.expect(6); | |
function message(lodashMethod, nativeMethod) { | function message(lodashMethod, nativeMethod) { | |
return '`' + lodashMethod + '` should avoid overwritten native `' + nati veMethod + '`'; | return '`' + lodashMethod + '` should avoid overwritten native `' + nati veMethod + '`'; | |
} | } | |
function Foo() { this.a = 1; } | ||
Foo.prototype.b = 2; | ||
var object = { 'a': 1 }, | var object = { 'a': 1 }, | |
otherObject = { 'b': 2 }, | otherObject = { 'b': 2 }, | |
largeArray = _.times(LARGE_ARRAY_SIZE, _.constant(object)); | largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constan t(object)); | |
if (lodashBizarro) { | if (lodashBizarro) { | |
try { | try { | |
var actual = [lodashBizarro.isArray([]), lodashBizarro.isArray({ 'leng | var actual = lodashBizarro.keysIn(new Foo).sort(); | |
th': 0 })]; | } catch (e) { | |
} catch(e) { | ||
actual = null; | actual = null; | |
} | } | |
deepEqual(actual, [true, false], message('_.isArray', 'Array.isArray')); | var label = message('_.keysIn', 'Object#propertyIsEnumerable'); | |
assert.deepEqual(actual, ['a', 'b'], label); | ||
try { | try { | |
actual = lodashBizarro.now(); | actual = [ | |
} catch(e) { | lodashBizarro.difference([object, otherObject], largeArray), | |
lodashBizarro.intersection(largeArray, [object]), | ||
lodashBizarro.uniq(largeArray) | ||
]; | ||
} catch (e) { | ||
actual = null; | actual = null; | |
} | } | |
ok(typeof actual == 'number', message('_.now', 'Date.now')); | label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object. | |
create` and `Map'); | ||
assert.deepEqual(actual, [[otherObject], [object], [object]], label); | ||
try { | try { | |
actual = [lodashBizarro.isPlainObject({}), lodashBizarro.isPlainObject | if (Symbol) { | |
([])]; | object[symbol] = {}; | |
} catch(e) { | } | |
actual = [ | ||
lodashBizarro.clone(object), | ||
lodashBizarro.cloneDeep(object) | ||
]; | ||
} catch (e) { | ||
actual = null; | actual = null; | |
} | } | |
deepEqual(actual, [true, false], message('_.isPlainObject', 'Object.getP | label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbo | |
rototypeOf')); | ls'); | |
assert.deepEqual(actual, [object, object], label); | ||
try { | try { | |
actual = [lodashBizarro.keys(object), lodashBizarro.keys()]; | var symObject = Object(symbol); | |
} catch(e) { | symObject.constructor = Object; | |
actual = [ | ||
Symbol ? lodashBizarro.clone(symObject) : {}, | ||
Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false, | ||
Symbol ? lodashBizarro.toString(symObject) : '' | ||
]; | ||
} catch (e) { | ||
actual = null; | actual = null; | |
} | } | |
deepEqual(actual, [['a'], []], message('_.keys', 'Object.keys')); | label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol'); | |
assert.deepEqual(actual, [{}, false, ''], label); | ||
try { | try { | |
actual = [lodashBizarro.isFinite(1), lodashBizarro.isFinite(NaN)]; | var map = new lodashBizarro.memoize.Cache; | |
} catch(e) { | actual = map.set('a', 1).get('a'); | |
} catch (e) { | ||
actual = null; | actual = null; | |
} | } | |
deepEqual(actual, [true, false], message('_.isFinite', 'Number.isFinite' | label = message('_.memoize.Cache', 'Map'); | |
)); | assert.deepEqual(actual, 1, label); | |
try { | try { | |
actual = [ | map = new (Map || Object); | |
lodashBizarro.difference([object, otherObject], largeArray), | if (Symbol && Symbol.iterator) { | |
lodashBizarro.intersection(largeArray, [object]), | map[Symbol.iterator] = null; | |
lodashBizarro.uniq(largeArray) | } | |
]; | actual = lodashBizarro.toArray(map); | |
} catch(e) { | } catch (e) { | |
actual = null; | actual = null; | |
} | } | |
deepEqual(actual, [[otherObject], [object], [object]], message('_.differ | label = message('_.toArray', 'Map'); | |
ence`, `_.intersection`, and `_.uniq', 'Set')); | assert.deepEqual(actual, [], label); | |
} | ||
else { | ||
skipTest(assert, 6); | ||
} | ||
}); | ||
}()); | ||
try { | /*--------------------------------------------------------------------------*/ | |
actual = _.map(['6', '08', '10'], lodashBizarro.parseInt); | ||
} catch(e) { | ||
actual = null; | ||
} | ||
deepEqual(actual, [6, 8, 10], '`_.parseInt` should work in its bizarro f | ||
orm'); | ||
if (ArrayBuffer) { | QUnit.module('isIndex'); | |
try { | ||
var buffer = new ArrayBuffer(10); | (function() { | |
actual = lodashBizarro.clone(buffer); | var func = _._isIndex; | |
} catch(e) { | ||
actual = null; | QUnit.test('should return `true` for indexes', function(assert) { | |
} | assert.expect(1); | |
deepEqual(actual, buffer, message('_.clone', 'ArrayBuffer#slice')); | ||
notStrictEqual(actual, buffer, message('_.clone', 'ArrayBuffer#slice') | if (func) { | |
); | var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]], | |
} | expected = lodashStable.map(values, alwaysTrue); | |
else { | ||
skipTest(2); | var actual = lodashStable.map(values, function(args) { | |
} | return func.apply(undefined, args); | |
if (ArrayBuffer && Uint8Array) { | }); | |
try { | ||
var array = new Uint8Array(new ArrayBuffer(10)); | assert.deepEqual(actual, expected); | |
actual = lodashBizarro.cloneDeep(array); | } | |
} catch(e) { | else { | |
actual = null; | skipTest(assert); | |
} | } | |
deepEqual(actual, array, message('_.cloneDeep', 'Float64Array')); | }); | |
notStrictEqual(actual && actual.buffer, array.buffer, message('_.clone | ||
Deep', 'Float64Array')); | QUnit.test('should return `false` for non-indexes', function(assert) { | |
notStrictEqual(actual, array, message('_.cloneDeep', 'Float64Array')); | assert.expect(1); | |
} | ||
else { | if (func) { | |
skipTest(3); | var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE | |
_INTEGER]], | ||
expected = lodashStable.map(values, alwaysFalse); | ||
var actual = lodashStable.map(values, function(args) { | ||
return func.apply(undefined, args); | ||
}); | ||
assert.deepEqual(actual, expected); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('isIterateeCall'); | ||
(function() { | ||
var array = [1], | ||
func = _._isIterateeCall, | ||
object = { 'a': 1 }; | ||
QUnit.test('should return `true` for iteratee calls', function(assert) { | ||
assert.expect(3); | ||
function Foo() {} | ||
Foo.prototype.a = 1; | ||
if (func) { | ||
assert.strictEqual(func(1, 0, array), true); | ||
assert.strictEqual(func(1, 'a', object), true); | ||
assert.strictEqual(func(1, 'a', new Foo), true); | ||
} | ||
else { | ||
skipTest(assert, 3); | ||
} | ||
}); | ||
QUnit.test('should return `false` for non-iteratee calls', function(assert) | ||
{ | ||
assert.expect(4); | ||
if (func) { | ||
assert.strictEqual(func(2, 0, array), false); | ||
assert.strictEqual(func(1, 1.1, array), false); | ||
assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false | ||
); | ||
assert.strictEqual(func(1, 'b', object), false); | ||
} | ||
else { | ||
skipTest(assert, 4); | ||
} | ||
}); | ||
QUnit.test('should work with `NaN` values', function(assert) { | ||
assert.expect(2); | ||
if (func) { | ||
assert.strictEqual(func(NaN, 0, [NaN]), true); | ||
assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true); | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | ||
}); | ||
QUnit.test('should not error when `index` is an object without a `toString` | ||
method', function(assert) { | ||
assert.expect(1); | ||
if (func) { | ||
try { | ||
var actual = func(1, { 'toString': null }, [1]); | ||
} catch (e) { | ||
var message = e.message; | ||
} | } | |
assert.strictEqual(actual, false, message || ''); | ||
} | } | |
else { | else { | |
skipTest(12); | skipTest(assert); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash constructor'); | QUnit.module('lodash constructor'); | |
(function() { | (function() { | |
var values = empties.concat(true, 1, 'a'), | var values = empties.concat(true, 1, 'a'), | |
expected = _.map(values, _.constant(true)); | expected = lodashStable.map(values, alwaysTrue); | |
QUnit.test('should create a new instance when called without the `new` opera | ||
tor', function(assert) { | ||
assert.expect(1); | ||
test('creates a new instance when called without the `new` operator', 1, fun ction() { | ||
if (!isNpm) { | if (!isNpm) { | |
var actual = _.map(values, function(value) { | var actual = lodashStable.map(values, function(value) { | |
return _(value) instanceof _; | return _(value) instanceof _; | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should return provided `lodash` instances', 1, function() { | QUnit.test('should return provided `lodash` instances', function(assert) { | |
assert.expect(1); | ||
if (!isNpm) { | if (!isNpm) { | |
var actual = _.map(values, function(value) { | var actual = lodashStable.map(values, function(value) { | |
var wrapped = _(value); | var wrapped = _(value); | |
return _(wrapped) === wrapped; | return _(wrapped) === wrapped; | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should convert foreign wrapped values to `lodash` instances', 1, funct | QUnit.test('should convert foreign wrapped values to `lodash` instances', fu | |
ion() { | nction(assert) { | |
assert.expect(1); | ||
if (!isNpm && lodashBizarro) { | if (!isNpm && lodashBizarro) { | |
var actual = _.map(values, function(value) { | var actual = lodashStable.map(values, function(value) { | |
var wrapped = _(lodashBizarro(value)), | var wrapped = _(lodashBizarro(value)), | |
unwrapped = wrapped.value(); | unwrapped = wrapped.value(); | |
return wrapped instanceof _ && | return wrapped instanceof _ && | |
(unwrapped === value || (_.isNaN(unwrapped) && _.isNaN(value))); | ((unwrapped === value) || (unwrapped !== unwrapped && value !== valu e)); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.add'); | ||
(function() { | ||
QUnit.test('should add two numbers', function(assert) { | ||
assert.expect(3); | ||
assert.strictEqual(_.add(6, 4), 10); | ||
assert.strictEqual(_.add(-6, 4), -2); | ||
assert.strictEqual(_.add(-6, -4), -10); | ||
}); | ||
QUnit.test('should not coerce arguments to numbers', function(assert) { | ||
assert.expect(2); | ||
assert.strictEqual(_.add('6', '4'), '64'); | ||
assert.strictEqual(_.add('x', 'y'), 'xy'); | ||
}); | ||
QUnit.test('should work with only an `augend` or `addend`', function(assert) | ||
{ | ||
assert.expect(3); | ||
assert.strictEqual(_.add(6), 6); | ||
assert.strictEqual(_.add(6, undefined), 6); | ||
assert.strictEqual(_.add(undefined, 4), 4); | ||
}); | ||
QUnit.test('should return an unwrapped value when implicitly chaining', func | ||
tion(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
assert.strictEqual(_(1).add(2), 3); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
QUnit.test('should return a wrapped value when explicitly chaining', functio | ||
n(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
assert.ok(_(1).chain().add(2) instanceof _); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.after'); | QUnit.module('lodash.after'); | |
(function() { | (function() { | |
function after(n, times) { | function after(n, times) { | |
var count = 0; | var count = 0; | |
_.times(times, _.after(n, function() { count++; })); | lodashStable.times(times, _.after(n, function() { count++; })); | |
return count; | return count; | |
} | } | |
test('should create a function that invokes `func` after `n` calls', 4, func | ||
tion() { | ||
strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being cal | ||
led `n` times'); | ||
strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before bein | ||
g called `n` times'); | ||
strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately | ||
'); | ||
strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called onc | ||
e'); | ||
}); | ||
test('should coerce non-finite `n` values to `0`', 1, function() { | ||
var values = [-Infinity, NaN, Infinity], | ||
expected = _.map(values, _.constant(1)); | ||
var actual = _.map(values, function(n) { | QUnit.test('should create a function that invokes `func` after `n` calls', f | |
return after(n, 1); | unction(assert) { | |
}); | assert.expect(4); | |
deepEqual(actual, expected); | assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after be | |
ing called `n` times'); | ||
assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` befo | ||
re being called `n` times'); | ||
assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` imme | ||
diately'); | ||
assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when cal | ||
led once'); | ||
}); | }); | |
test('should allow `func` as the first argument', 1, function() { | QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) { | |
var count = 0; | assert.expect(1); | |
try { | ||
var after = _.after(function() { count++; }, 1); | ||
after(); | ||
after(); | ||
} catch(e) {} | ||
strictEqual(count, 2); | assert.strictEqual(after(NaN, 1), 1); | |
}); | }); | |
test('should not set a `this` binding', 2, function() { | QUnit.test('should not set a `this` binding', function(assert) { | |
var after = _.after(1, function() { return ++this.count; }), | assert.expect(2); | |
object = { 'count': 0, 'after': after }; | ||
var after = _.after(1, function(assert) { return ++this.count; }), | ||
object = { 'after': after, 'count': 0 }; | ||
object.after(); | object.after(); | |
strictEqual(object.after(), 2); | assert.strictEqual(object.after(), 2); | |
strictEqual(object.count, 2); | assert.strictEqual(object.count, 2); | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.ary'); | QUnit.module('lodash.ary'); | |
(function() { | (function() { | |
function fn(a, b, c) { | function fn(a, b, c) { | |
return slice.call(arguments); | return slice.call(arguments); | |
} | } | |
test('should cap the numer of params provided to `func`', 2, function() { | QUnit.test('should cap the number of arguments provided to `func`', function | |
var actual = _.map(['6', '8', '10'], _.ary(parseInt, 1)); | (assert) { | |
deepEqual(actual, [6, 8, 10]); | assert.expect(2); | |
var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1)); | ||
assert.deepEqual(actual, [6, 8, 10]); | ||
var capped = _.ary(fn, 2); | var capped = _.ary(fn, 2); | |
deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']); | assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']); | |
}); | }); | |
test('should use `func.length` if `n` is not provided', 1, function() { | QUnit.test('should use `func.length` if `n` is not provided', function(asser | |
t) { | ||
assert.expect(1); | ||
var capped = _.ary(fn); | var capped = _.ary(fn); | |
deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']); | assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']); | |
}); | }); | |
test('should treat a negative `n` as `0`', 1, function() { | QUnit.test('should treat a negative `n` as `0`', function(assert) { | |
assert.expect(1); | ||
var capped = _.ary(fn, -1); | var capped = _.ary(fn, -1); | |
try { | try { | |
var actual = capped('a'); | var actual = capped('a'); | |
} catch(e) {} | } catch (e) {} | |
deepEqual(actual, []); | assert.deepEqual(actual, []); | |
}); | }); | |
test('should work when provided less than the capped numer of arguments', 1, | QUnit.test('should coerce `n` to an integer', function(assert) { | |
function() { | assert.expect(1); | |
var values = ['1', 1.6, 'xyz'], | ||
expected = [['a'], ['a'], []]; | ||
var actual = lodashStable.map(values, function(n) { | ||
var capped = _.ary(fn, n); | ||
return capped('a', 'b'); | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | ||
QUnit.test('should work when provided less than the capped number of argumen | ||
ts', function(assert) { | ||
assert.expect(1); | ||
var capped = _.ary(fn, 3); | var capped = _.ary(fn, 3); | |
deepEqual(capped('a'), ['a']); | assert.deepEqual(capped('a'), ['a']); | |
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should use the existing `ary` if smaller', function(assert) { | |
var funcs = _.map([fn], _.ary), | assert.expect(1); | |
var capped = _.ary(_.ary(fn, 1), 2); | ||
assert.deepEqual(capped('a', 'b', 'c'), ['a']); | ||
}); | ||
QUnit.test('should work as an iteratee for methods like `_.map`', function(a | ||
ssert) { | ||
assert.expect(1); | ||
var funcs = lodashStable.map([fn], _.ary), | ||
actual = funcs[0]('a', 'b', 'c'); | actual = funcs[0]('a', 'b', 'c'); | |
deepEqual(actual, ['a', 'b', 'c']); | assert.deepEqual(actual, ['a', 'b', 'c']); | |
}); | }); | |
test('should work when combined with other methods that use metadata', 2, fu | QUnit.test('should work when combined with other methods that use metadata', | |
nction() { | function(assert) { | |
assert.expect(2); | ||
var array = ['a', 'b', 'c'], | var array = ['a', 'b', 'c'], | |
includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2); | includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2); | |
strictEqual(includes('b')(array, 2), true); | assert.strictEqual(includes('b')(array, 2), true); | |
if (!isNpm) { | if (!isNpm) { | |
includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value(); | includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value(); | |
strictEqual(includes('b')(array, 2), true); | assert.strictEqual(includes('b')(array, 2), true); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.assign'); | QUnit.module('lodash.assignIn'); | |
(function() { | (function() { | |
test('should assign properties of a source object to the destination object' | QUnit.test('should be aliased', function(assert) { | |
, 1, function() { | assert.expect(1); | |
deepEqual(_.assign({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 }); | ||
assert.strictEqual(_.extend, _.assignIn); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.assign and lodash.assignIn'); | ||
lodashStable.each(['assign', 'assignIn'], function(methodName) { | ||
var func = _[methodName]; | ||
QUnit.test('`_.' + methodName + '` should assign source properties to `objec | ||
t`', function(assert) { | ||
assert.expect(1); | ||
assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 }); | ||
}); | }); | |
test('should accept multiple source objects', 2, function() { | QUnit.test('`_.' + methodName + '` should accept multiple sources', function | |
(assert) { | ||
assert.expect(2); | ||
var expected = { 'a': 1, 'b': 2, 'c': 3 }; | var expected = { 'a': 1, 'b': 2, 'c': 3 }; | |
deepEqual(_.assign({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected); | assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected); | |
deepEqual(_.assign({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected); | assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expecte | |
d); | ||
}); | }); | |
test('should overwrite destination properties', 1, function() { | QUnit.test('`_.' + methodName + '` should overwrite destination properties', | |
function(assert) { | ||
assert.expect(1); | ||
var expected = { 'a': 3, 'b': 2, 'c': 1 }; | var expected = { 'a': 3, 'b': 2, 'c': 1 }; | |
deepEqual(_.assign({ 'a': 1, 'b': 2 }, expected), expected); | assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); | |
}); | }); | |
test('should assign source properties with `null` and `undefined` values', 1 | QUnit.test('`_.' + methodName + '` should assign source properties with null | |
, function() { | ish values', function(assert) { | |
assert.expect(1); | ||
var expected = { 'a': null, 'b': undefined, 'c': null }; | var expected = { 'a': null, 'b': undefined, 'c': null }; | |
deepEqual(_.assign({ 'a': 1, 'b': 2 }, expected), expected); | assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); | |
}); | }); | |
test('should work with a `customizer` callback', 1, function() { | QUnit.test('`_.' + methodName + '` should skip assignments if values are the | |
var actual = _.assign({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, | same', function(assert) { | |
b) { | assert.expect(1); | |
return typeof a == 'undefined' ? b : a; | ||
}); | ||
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); | var object = {}; | |
}); | ||
test('should work with a `customizer` that returns `undefined`', 1, function | var descriptor = { | |
() { | 'configurable': true, | |
var expected = { 'a': undefined }; | 'enumerable': true, | |
deepEqual(_.assign({}, expected, _.identity), expected); | 'set': function() { throw new Error; } | |
}; | ||
var source = { | ||
'a': 1, | ||
'b': undefined, | ||
'c': NaN, | ||
'd': undefined, | ||
'constructor': Object, | ||
'toString': lodashStable.constant('source') | ||
}; | ||
defineProperty(object, 'a', lodashStable.assign({}, descriptor, { | ||
'get': alwaysOne | ||
})); | ||
defineProperty(object, 'b', lodashStable.assign({}, descriptor, { | ||
'get': alwaysUndefined | ||
})); | ||
defineProperty(object, 'c', lodashStable.assign({}, descriptor, { | ||
'get': alwaysNaN | ||
})); | ||
defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, | ||
{ | ||
'get': lodashStable.constant(Object) | ||
})); | ||
try { | ||
var actual = func(object, source); | ||
} catch (e) {} | ||
assert.deepEqual(actual, source); | ||
}); | }); | |
}); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.assignInWith'); | ||
(function() { | ||
QUnit.test('should be aliased', function(assert) { | ||
assert.expect(1); | ||
test('should be aliased', 1, function() { | assert.strictEqual(_.extendWith, _.assignInWith); | |
strictEqual(_.extend, _.assign); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.assignWith and lodash.assignInWith'); | ||
lodashStable.each(['assignWith', 'assignInWith'], function(methodName) { | ||
var func = _[methodName]; | ||
QUnit.test('`_.' + methodName + '` should work with a `customizer` callback' | ||
, function(assert) { | ||
assert.expect(1); | ||
var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) { | ||
return a === undefined ? b : a; | ||
}); | ||
assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should work with a `customizer` that retu | ||
rns `undefined`', function(assert) { | ||
assert.expect(1); | ||
var expected = { 'a': undefined }; | ||
assert.deepEqual(func({}, expected, alwaysUndefined), expected); | ||
}); | ||
}); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.at'); | QUnit.module('lodash.at'); | |
(function() { | (function() { | |
var args = arguments, | var args = arguments, | |
array = ['a', 'b', 'c']; | array = ['a', 'b', 'c'], | |
object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; | ||
array['1.1'] = array['-1'] = 1; | QUnit.test('should return the elements corresponding to the specified keys', | |
function(assert) { | ||
assert.expect(1); | ||
test('should return the elements corresponding to the specified keys', 1, fu nction() { | ||
var actual = _.at(array, [0, 2]); | var actual = _.at(array, [0, 2]); | |
deepEqual(actual, ['a', 'c']); | assert.deepEqual(actual, ['a', 'c']); | |
}); | }); | |
test('should return `undefined` for nonexistent keys', 1, function() { | QUnit.test('should return `undefined` for nonexistent keys', function(assert | |
) { | ||
assert.expect(1); | ||
var actual = _.at(array, [2, 4, 0]); | var actual = _.at(array, [2, 4, 0]); | |
deepEqual(actual, ['c', undefined, 'a']); | assert.deepEqual(actual, ['c', undefined, 'a']); | |
}); | }); | |
test('should use `undefined` for non-index keys on array-like values', 1, fu | QUnit.test('should work with non-index keys on array values', function(asser | |
nction() { | t) { | |
var values = _.reject(empties, function(value) { | assert.expect(1); | |
return value === 0 || _.isArray(value); | ||
var values = lodashStable.reject(empties, function(value) { | ||
return (value === 0) || lodashStable.isArray(value); | ||
}).concat(-1, 1.1); | }).concat(-1, 1.1); | |
var expected = _.map(values, _.constant(undefined)), | var array = lodashStable.transform(values, function(result, value) { | |
result[value] = 1; | ||
}, []); | ||
var expected = lodashStable.map(values, alwaysOne), | ||
actual = _.at(array, values); | actual = _.at(array, values); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should return an empty array when no keys are provided', 2, function() | QUnit.test('should return an empty array when no keys are provided', functio | |
{ | n(assert) { | |
deepEqual(_.at(array), []); | assert.expect(2); | |
deepEqual(_.at(array, [], []), []); | ||
assert.deepEqual(_.at(array), []); | ||
assert.deepEqual(_.at(array, [], []), []); | ||
}); | }); | |
test('should accept multiple key arguments', 1, function() { | QUnit.test('should accept multiple key arguments', function(assert) { | |
assert.expect(1); | ||
var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2); | var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2); | |
deepEqual(actual, ['d', 'a', 'c']); | assert.deepEqual(actual, ['d', 'a', 'c']); | |
}); | }); | |
test('should work with a falsey `collection` argument when keys are provided | QUnit.test('should work with a falsey `object` argument when keys are provid | |
', 1, function() { | ed', function(assert) { | |
var expected = _.map(falsey, _.constant([undefined, undefined])); | assert.expect(1); | |
var actual = _.map(falsey, function(value) { | var expected = lodashStable.map(falsey, lodashStable.constant(Array(4))); | |
var actual = lodashStable.map(falsey, function(object) { | ||
try { | try { | |
return _.at(value, 0, 1); | return _.at(object, 0, 1, 'pop', 'push'); | |
} catch(e) {} | } catch (e) {} | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should work with an `arguments` object for `collection`', 1, function( | QUnit.test('should work with an `arguments` object for `object`', function(a | |
) { | ssert) { | |
assert.expect(1); | ||
var actual = _.at(args, [2, 0]); | var actual = _.at(args, [2, 0]); | |
deepEqual(actual, [3, 1]); | assert.deepEqual(actual, [3, 1]); | |
}); | }); | |
test('should work with `arguments` object as secondary arguments', 1, functi | QUnit.test('should work with `arguments` object as secondary arguments', fun | |
on() { | ction(assert) { | |
assert.expect(1); | ||
var actual = _.at([1, 2, 3, 4, 5], args); | var actual = _.at([1, 2, 3, 4, 5], args); | |
deepEqual(actual, [2, 3, 4]); | assert.deepEqual(actual, [2, 3, 4]); | |
}); | }); | |
test('should work with an object for `collection`', 1, function() { | QUnit.test('should work with an object for `object`', function(assert) { | |
var actual = _.at({ 'a': 1, 'b': 2, 'c': 3 }, ['c', 'a']); | assert.expect(1); | |
deepEqual(actual, [3, 1]); | ||
var actual = _.at(object, ['a[0].b.c', 'a[1]']); | ||
assert.deepEqual(actual, [3, 4]); | ||
}); | }); | |
test('should pluck inherited property values', 1, function() { | QUnit.test('should pluck inherited property values', function(assert) { | |
assert.expect(1); | ||
function Foo() { this.a = 1; } | function Foo() { this.a = 1; } | |
Foo.prototype.b = 2; | Foo.prototype.b = 2; | |
var actual = _.at(new Foo, 'b'); | var actual = _.at(new Foo, 'b'); | |
deepEqual(actual, [2]); | assert.deepEqual(actual, [2]); | |
}); | }); | |
_.each({ | QUnit.test('should work in a lazy sequence', function(assert) { | |
'literal': 'abc', | assert.expect(6); | |
'object': Object('abc') | ||
}, | if (!isNpm) { | |
function(collection, key) { | var largeArray = lodashStable.range(LARGE_ARRAY_SIZE), | |
test('should work with a string ' + key + ' for `collection`', 1, function | smallArray = array; | |
() { | ||
deepEqual(_.at(collection, [2, 0]), ['c', 'a']); | lodashStable.each([[2], ['2'], [2, 1]], function(paths) { | |
}); | lodashStable.times(2, function(index) { | |
var array = index ? largeArray : smallArray, | ||
wrapped = _(array).map(identity).at(paths); | ||
assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths | ||
)); | ||
}); | ||
}); | ||
} | ||
else { | ||
skipTest(assert, 6); | ||
} | ||
}); | ||
QUnit.test('should support shortcut fusion', function(assert) { | ||
assert.expect(8); | ||
if (!isNpm) { | ||
var array = lodashStable.range(LARGE_ARRAY_SIZE), | ||
count = 0, | ||
iteratee = function(value) { count++; return square(value); }, | ||
lastIndex = LARGE_ARRAY_SIZE - 1; | ||
lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], fun | ||
ction(n, index) { | ||
count = 0; | ||
var actual = _(array).map(iteratee).at(n).value(), | ||
expected = index < 2 ? 1 : 0; | ||
assert.strictEqual(count, expected); | ||
expected = index == 3 ? [] : [index == 2 ? undefined : square(lastInde | ||
x)]; | ||
assert.deepEqual(actual, expected); | ||
}); | ||
} | ||
else { | ||
skipTest(assert, 8); | ||
} | ||
}); | ||
QUnit.test('work with an object for `object` when chaining', function(assert | ||
) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
var paths = ['a[0].b.c', 'a[1]'], | ||
wrapped = _(object).map(identity).at(paths); | ||
assert.deepEqual(wrapped.value(), _.at(_.map(object, identity), paths)); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | }); | |
}(1, 2, 3)); | }(1, 2, 3)); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.attempt'); | QUnit.module('lodash.attempt'); | |
(function() { | (function() { | |
test('should return the result of `func`', 1, function() { | QUnit.test('should return the result of `func`', function(assert) { | |
strictEqual(_.attempt(_.constant('x')), 'x'); | assert.expect(1); | |
assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x'); | ||
}); | }); | |
test('should return the caught error', 1, function() { | QUnit.test('should provide additional arguments to `func`', function(assert) | |
var expected = _.map(errors, _.constant(true)); | { | |
assert.expect(1); | ||
var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2) | ||
; | ||
assert.deepEqual(actual, [1, 2]); | ||
}); | ||
QUnit.test('should return the caught error', function(assert) { | ||
assert.expect(1); | ||
var expected = lodashStable.map(errors, alwaysTrue); | ||
var actual = _.map(errors, function(error) { | var actual = lodashStable.map(errors, function(error) { | |
return _.attempt(function() { throw error; }) === error; | return _.attempt(function() { throw error; }) === error; | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should coerce errors to error objects', 1, function() { | QUnit.test('should coerce errors to error objects', function(assert) { | |
assert.expect(1); | ||
var actual = _.attempt(function() { throw 'x'; }); | var actual = _.attempt(function() { throw 'x'; }); | |
ok(_.isEqual(actual, Error('x'))); | assert.ok(lodashStable.isEqual(actual, Error('x'))); | |
}); | }); | |
test('should work with an error object from another realm', 1, function() { | QUnit.test('should work with an error object from another realm', function(a | |
if (_._object) { | ssert) { | |
var expected = _.map(_._errors, _.constant(true)); | assert.expect(1); | |
if (realm.errors) { | ||
var expected = lodashStable.map(realm.errors, alwaysTrue); | ||
var actual = _.map(_._errors, function(error) { | var actual = lodashStable.map(realm.errors, function(error) { | |
return _.attempt(function() { throw error; }) === error; | return _.attempt(function() { throw error; }) === error; | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should return an unwrapped value when chaining', 1, function() { | QUnit.test('should return an unwrapped value when implicitly chaining', func | |
tion(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | if (!isNpm) { | |
strictEqual(_(_.constant('x')).attempt(), 'x'); | assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x'); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | ||
}); | ||
QUnit.test('should return a wrapped value when explicitly chaining', functio | ||
n(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.before'); | QUnit.module('lodash.before'); | |
(function() { | (function() { | |
function before(n, times) { | function before(n, times) { | |
var count = 0; | var count = 0; | |
_.times(times, _.before(n, function() { count++; })); | lodashStable.times(times, _.before(n, function() { count++; })); | |
return count; | return count; | |
} | } | |
test('should create a function that invokes `func` after `n` calls', 4, func | ||
tion() { | ||
strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being | ||
called `n` times'); | ||
strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after bei | ||
ng called `n - 1` times'); | ||
strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediate | ||
ly'); | ||
strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when call | ||
ed'); | ||
}); | ||
test('should coerce non-finite `n` values to `0`', 1, function() { | QUnit.test('should create a function that invokes `func` after `n` calls', f | |
var values = [-Infinity, NaN, Infinity], | unction(assert) { | |
expected = _.map(values, _.constant(0)); | assert.expect(4); | |
var actual = _.map(values, function(n) { | assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before | |
return before(n); | being called `n` times'); | |
}); | assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` af | |
ter being called `n - 1` times'); | ||
deepEqual(actual, expected); | assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` im | |
mediately'); | ||
assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` wh | ||
en called'); | ||
}); | }); | |
test('should allow `func` as the first argument', 1, function() { | QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) { | |
var count = 0; | assert.expect(1); | |
try { | ||
var before = _.before(function() { count++; }, 2); | ||
before(); | ||
before(); | ||
} catch(e) {} | ||
strictEqual(count, 1); | assert.strictEqual(before(NaN, 1), 0); | |
}); | }); | |
test('should not set a `this` binding', 2, function() { | QUnit.test('should not set a `this` binding', function(assert) { | |
var before = _.before(2, function() { return ++this.count; }), | assert.expect(2); | |
object = { 'count': 0, 'before': before }; | ||
var before = _.before(2, function(assert) { return ++this.count; }), | ||
object = { 'before': before, 'count': 0 }; | ||
object.before(); | object.before(); | |
strictEqual(object.before(), 1); | assert.strictEqual(object.before(), 1); | |
strictEqual(object.count, 1); | assert.strictEqual(object.count, 1); | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.bind'); | QUnit.module('lodash.bind'); | |
(function() { | (function() { | |
function fn() { | function fn() { | |
var result = [this]; | var result = [this]; | |
push.apply(result, arguments); | push.apply(result, arguments); | |
return result; | return result; | |
} | } | |
test('should bind a function to an object', 1, function() { | QUnit.test('should bind a function to an object', function(assert) { | |
assert.expect(1); | ||
var object = {}, | var object = {}, | |
bound = _.bind(fn, object); | bound = _.bind(fn, object); | |
deepEqual(bound('a'), [object, 'a']); | assert.deepEqual(bound('a'), [object, 'a']); | |
}); | }); | |
test('should accept a falsey `thisArg` argument', 1, function() { | QUnit.test('should accept a falsey `thisArg` argument', function(assert) { | |
var values = _.reject(falsey.slice(1), function(value) { return value == n | assert.expect(1); | |
ull; }), | ||
expected = _.map(values, function(value) { return [value]; }); | ||
var actual = _.map(values, function(value) { | var values = lodashStable.reject(falsey.slice(1), function(value) { return | |
value == null; }), | ||
expected = lodashStable.map(values, function(value) { return [value]; | ||
}); | ||
var actual = lodashStable.map(values, function(value) { | ||
try { | try { | |
var bound = _.bind(fn, value); | var bound = _.bind(fn, value); | |
return bound(); | return bound(); | |
} catch(e) {} | } catch (e) {} | |
}); | }); | |
ok(_.every(actual, function(value, index) { | assert.ok(lodashStable.every(actual, function(value, index) { | |
return _.isEqual(value, expected[index]); | return lodashStable.isEqual(value, expected[index]); | |
})); | })); | |
}); | }); | |
test('should bind a function to `null` or `undefined`', 6, function() { | QUnit.test('should bind a function to nullish values', function(assert) { | |
assert.expect(6); | ||
var bound = _.bind(fn, null), | var bound = _.bind(fn, null), | |
actual = bound('a'); | actual = bound('a'); | |
ok(actual[0] === null || actual[0] && actual[0].Array); | assert.ok((actual[0] === null) || (actual[0] && actual[0].Array)); | |
strictEqual(actual[1], 'a'); | assert.strictEqual(actual[1], 'a'); | |
_.times(2, function(index) { | lodashStable.times(2, function(index) { | |
bound = index ? _.bind(fn, undefined) : _.bind(fn); | bound = index ? _.bind(fn, undefined) : _.bind(fn); | |
actual = bound('b'); | actual = bound('b'); | |
ok(actual[0] === undefined || actual[0] && actual[0].Array); | assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array)); | |
strictEqual(actual[1], 'b'); | assert.strictEqual(actual[1], 'b'); | |
}); | }); | |
}); | }); | |
test('should partially apply arguments ', 4, function() { | QUnit.test('should partially apply arguments ', function(assert) { | |
assert.expect(4); | ||
var object = {}, | var object = {}, | |
bound = _.bind(fn, object, 'a'); | bound = _.bind(fn, object, 'a'); | |
deepEqual(bound(), [object, 'a']); | assert.deepEqual(bound(), [object, 'a']); | |
bound = _.bind(fn, object, 'a'); | bound = _.bind(fn, object, 'a'); | |
deepEqual(bound('b'), [object, 'a', 'b']); | assert.deepEqual(bound('b'), [object, 'a', 'b']); | |
bound = _.bind(fn, object, 'a', 'b'); | bound = _.bind(fn, object, 'a', 'b'); | |
deepEqual(bound(), [object, 'a', 'b']); | assert.deepEqual(bound(), [object, 'a', 'b']); | |
deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']); | assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']); | |
}); | }); | |
test('should support placeholders', 4, function() { | QUnit.test('should support placeholders', function(assert) { | |
assert.expect(4); | ||
var object = {}, | var object = {}, | |
ph = _.bind.placeholder, | ph = _.bind.placeholder, | |
bound = _.bind(fn, object, ph, 'b', ph); | bound = _.bind(fn, object, ph, 'b', ph); | |
deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']); | assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']); | |
deepEqual(bound('a'), [object, 'a', 'b', undefined]); | assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]); | |
deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']); | assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']); | |
deepEqual(bound(), [object, undefined, 'b', undefined]); | assert.deepEqual(bound(), [object, undefined, 'b', undefined]); | |
}); | }); | |
test('should create a function with a `length` of `0`', 2, function() { | QUnit.test('should create a function with a `length` of `0`', function(asser | |
t) { | ||
assert.expect(2); | ||
var fn = function(a, b, c) {}, | var fn = function(a, b, c) {}, | |
bound = _.bind(fn, {}); | bound = _.bind(fn, {}); | |
strictEqual(bound.length, 0); | assert.strictEqual(bound.length, 0); | |
bound = _.bind(fn, {}, 1); | bound = _.bind(fn, {}, 1); | |
strictEqual(bound.length, 0); | assert.strictEqual(bound.length, 0); | |
}); | }); | |
test('should ignore binding when called with the `new` operator', 3, functio | QUnit.test('should ignore binding when called with the `new` operator', func | |
n() { | tion(assert) { | |
assert.expect(3); | ||
function Foo() { | function Foo() { | |
return this; | return this; | |
} | } | |
var bound = _.bind(Foo, { 'a': 1 }), | var bound = _.bind(Foo, { 'a': 1 }), | |
newBound = new bound; | newBound = new bound; | |
strictEqual(newBound.a, undefined); | assert.strictEqual(bound().a, 1); | |
strictEqual(bound().a, 1); | assert.strictEqual(newBound.a, undefined); | |
ok(newBound instanceof Foo); | assert.ok(newBound instanceof Foo); | |
}); | }); | |
test('ensure `new bound` is an instance of `func`', 2, function() { | QUnit.test('should handle a number of arguments when called with the `new` o | |
perator', function(assert) { | ||
assert.expect(1); | ||
function Foo() { | ||
return this; | ||
} | ||
function Bar() {} | ||
var thisArg = { 'a': 1 }, | ||
boundFoo = _.bind(Foo, thisArg), | ||
boundBar = _.bind(Bar, thisArg), | ||
count = 9, | ||
expected = lodashStable.times(count, lodashStable.constant([undefined, | ||
undefined])); | ||
var actual = lodashStable.times(count, function(index) { | ||
try { | ||
switch (index) { | ||
case 0: return [new boundFoo().a, new boundBar().a]; | ||
case 1: return [new boundFoo(1).a, new boundBar(1).a]; | ||
case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a]; | ||
case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a]; | ||
case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4) | ||
.a]; | ||
case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, | ||
4, 5).a]; | ||
case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, | ||
3, 4, 5, 6).a]; | ||
case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, | ||
2, 3, 4, 5, 6, 7).a]; | ||
case 8: return [new boundFoo(1, 2, 3, 4, 5, 6, 7, 8).a, new boundBar | ||
(1, 2, 3, 4, 5, 6, 7, 8).a]; | ||
} | ||
} catch (e) {} | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | ||
QUnit.test('should ensure `new bound` is an instance of `func`', function(as | ||
sert) { | ||
assert.expect(2); | ||
function Foo(value) { | function Foo(value) { | |
return value && object; | return value && object; | |
} | } | |
var bound = _.bind(Foo), | var bound = _.bind(Foo), | |
object = {}; | object = {}; | |
ok(new bound instanceof Foo); | assert.ok(new bound instanceof Foo); | |
strictEqual(new bound(true), object); | assert.strictEqual(new bound(true), object); | |
}); | }); | |
test('should append array arguments to partially applied arguments (test in | QUnit.test('should append array arguments to partially applied arguments', f | |
IE < 9)', 1, function() { | unction(assert) { | |
assert.expect(1); | ||
var object = {}, | var object = {}, | |
bound = _.bind(fn, object, 'a'); | bound = _.bind(fn, object, 'a'); | |
deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']); | assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']); | |
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should not rebind functions', function(assert) { | |
if (!isNpm) { | assert.expect(3); | |
var object = {}, | ||
bound = _(fn).bind({}, 'a', 'b'); | ||
ok(bound instanceof _); | ||
var actual = bound.value()('c'); | ||
deepEqual(actual, [object, 'a', 'b', 'c']); | ||
} | ||
else { | ||
skipTest(2); | ||
} | ||
}); | ||
test('should rebind functions correctly', 3, function() { | ||
var object1 = {}, | var object1 = {}, | |
object2 = {}, | object2 = {}, | |
object3 = {}; | object3 = {}; | |
var bound1 = _.bind(fn, object1), | var bound1 = _.bind(fn, object1), | |
bound2 = _.bind(bound1, object2, 'a'), | bound2 = _.bind(bound1, object2, 'a'), | |
bound3 = _.bind(bound1, object3, 'b'); | bound3 = _.bind(bound1, object3, 'b'); | |
deepEqual(bound1(), [object1]); | assert.deepEqual(bound1(), [object1]); | |
deepEqual(bound2(), [object1, 'a']); | assert.deepEqual(bound2(), [object1, 'a']); | |
deepEqual(bound3(), [object1, 'b']); | assert.deepEqual(bound3(), [object1, 'b']); | |
}); | }); | |
}()); | ||
/*--------------------------------------------------------------------------*/ | QUnit.test('should not error when instantiating bound built-ins', function(a | |
ssert) { | ||
assert.expect(2); | ||
QUnit.module('lodash.bindAll'); | var Ctor = _.bind(Date, null), | |
expected = new Date(2012, 4, 23, 0, 0, 0, 0); | ||
(function() { | try { | |
var args = arguments; | var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0); | |
} catch (e) {} | ||
test('should bind all methods of `object`', 1, function() { | assert.deepEqual(actual, expected); | |
function Foo() { | ||
this._a = 1; | Ctor = _.bind(Date, null, 2012, 4, 23); | |
this._b = 2; | ||
this.a = function() { return this._a; }; | try { | |
actual = new Ctor(0, 0, 0, 0); | ||
} catch (e) {} | ||
assert.deepEqual(actual, expected); | ||
}); | ||
QUnit.test('should not error when calling bound class constructors with the | ||
`new` operator', function(assert) { | ||
assert.expect(1); | ||
var createCtor = lodashStable.attempt(Function, '"use strict";return class | ||
A{}'); | ||
if (typeof createCtor == 'function') { | ||
var bound = _.bind(createCtor()), | ||
count = 8, | ||
expected = lodashStable.times(count, alwaysTrue); | ||
var actual = lodashStable.times(count, function(index) { | ||
try { | ||
switch (index) { | ||
case 0: return !!(new bound); | ||
case 1: return !!(new bound(1)); | ||
case 2: return !!(new bound(1, 2)); | ||
case 3: return !!(new bound(1, 2, 3)); | ||
case 4: return !!(new bound(1, 2, 3, 4)); | ||
case 5: return !!(new bound(1, 2, 3, 4, 5)); | ||
case 6: return !!(new bound(1, 2, 3, 4, 5, 6)); | ||
case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7)); | ||
} | ||
} catch (e) {} | ||
}); | ||
assert.deepEqual(actual, expected); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | } | |
Foo.prototype.b = function() { return this._b; }; | }); | |
var object = new Foo; | QUnit.test('should return a wrapped value when chaining', function(assert) { | |
_.bindAll(object); | assert.expect(2); | |
var actual = _.map(_.functions(object).sort(), function(methodName) { | if (!isNpm) { | |
return object[methodName].call({}); | var object = {}, | |
}); | bound = _(fn).bind({}, 'a', 'b'); | |
assert.ok(bound instanceof _); | ||
deepEqual(actual, [1, 2]); | var actual = bound.value()('c'); | |
assert.deepEqual(actual, [object, 'a', 'b', 'c']); | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | ||
}); | }); | |
}()); | ||
test('should accept individual method names', 1, function() { | /*--------------------------------------------------------------------------*/ | |
var object = { | ||
'_a': 1, | QUnit.module('lodash.bindAll'); | |
'_b': 2, | ||
'_c': 3, | (function() { | |
'a': function() { return this._a; }, | var args = arguments; | |
'b': function() { return this._b; }, | ||
'c': function() { return this._c; } | var source = { | |
}; | '_a': 1, | |
'_b': 2, | ||
'_c': 3, | ||
'_d': 4, | ||
'a': function() { return this._a; }, | ||
'b': function() { return this._b; }, | ||
'c': function() { return this._c; }, | ||
'd': function() { return this._d; } | ||
}; | ||
QUnit.test('should accept individual method names', function(assert) { | ||
assert.expect(1); | ||
var object = lodashStable.cloneDeep(source); | ||
_.bindAll(object, 'a', 'b'); | _.bindAll(object, 'a', 'b'); | |
var actual = _.map(_.functions(object).sort(), function(methodName) { | var actual = lodashStable.map(['a', 'b', 'c'], function(methodName) { | |
return object[methodName].call({}); | return object[methodName].call({}); | |
}); | }); | |
deepEqual(actual, [1, 2, undefined]); | assert.deepEqual(actual, [1, 2, undefined]); | |
}); | }); | |
test('should accept arrays of method names', 1, function() { | QUnit.test('should accept arrays of method names', function(assert) { | |
var object = { | assert.expect(1); | |
'_a': 1, | ||
'_b': 2, | ||
'_c': 3, | ||
'_d': 4, | ||
'a': function() { return this._a; }, | ||
'b': function() { return this._b; }, | ||
'c': function() { return this._c; }, | ||
'd': function() { return this._d; } | ||
}; | ||
var object = lodashStable.cloneDeep(source); | ||
_.bindAll(object, ['a', 'b'], ['c']); | _.bindAll(object, ['a', 'b'], ['c']); | |
var actual = _.map(_.functions(object).sort(), function(methodName) { | var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(methodName) { | |
return object[methodName].call({}); | return object[methodName].call({}); | |
}); | }); | |
deepEqual(actual, [1, 2, 3, undefined]); | assert.deepEqual(actual, [1, 2, 3, undefined]); | |
}); | }); | |
test('should work with an array `object` argument', 1, function() { | QUnit.test('should work with an array `object` argument', function(assert) { | |
assert.expect(1); | ||
var array = ['push', 'pop']; | var array = ['push', 'pop']; | |
_.bindAll(array); | _.bindAll(array); | |
strictEqual(array.pop, arrayProto.pop); | assert.strictEqual(array.pop, arrayProto.pop); | |
}); | }); | |
test('should work with `arguments` objects as secondary arguments', 1, funct | QUnit.test('should work with `arguments` objects as secondary arguments', fu | |
ion() { | nction(assert) { | |
var object = { | assert.expect(1); | |
'_a': 1, | ||
'a': function() { return this._a; } | ||
}; | ||
var object = lodashStable.cloneDeep(source); | ||
_.bindAll(object, args); | _.bindAll(object, args); | |
var actual = _.map(_.functions(object).sort(), function(methodName) { | var actual = lodashStable.map(args, function(methodName) { | |
return object[methodName].call({}); | return object[methodName].call({}); | |
}); | }); | |
deepEqual(actual, [1]); | assert.deepEqual(actual, [1]); | |
}); | }); | |
}('a')); | }('a')); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.bindKey'); | QUnit.module('lodash.bindKey'); | |
(function() { | (function() { | |
test('should work when the target function is overwritten', 2, function() { | QUnit.test('should work when the target function is overwritten', function(a | |
ssert) { | ||
assert.expect(2); | ||
var object = { | var object = { | |
'user': 'fred', | 'user': 'fred', | |
'greet': function(greeting) { | 'greet': function(greeting) { | |
return this.user + ' says: ' + greeting; | return this.user + ' says: ' + greeting; | |
} | } | |
}; | }; | |
var bound = _.bindKey(object, 'greet', 'hi'); | var bound = _.bindKey(object, 'greet', 'hi'); | |
strictEqual(bound(), 'fred says: hi'); | assert.strictEqual(bound(), 'fred says: hi'); | |
object.greet = function(greeting) { | object.greet = function(greeting) { | |
return this.user + ' says: ' + greeting + '!'; | return this.user + ' says: ' + greeting + '!'; | |
}; | }; | |
strictEqual(bound(), 'fred says: hi!'); | assert.strictEqual(bound(), 'fred says: hi!'); | |
}); | }); | |
test('should support placeholders', 4, function() { | QUnit.test('should support placeholders', function(assert) { | |
assert.expect(4); | ||
var object = { | var object = { | |
'fn': function() { | 'fn': function() { | |
return slice.call(arguments); | return slice.call(arguments); | |
} | } | |
}; | }; | |
var ph = _.bindKey.placeholder, | var ph = _.bindKey.placeholder, | |
bound = _.bindKey(object, 'fn', ph, 'b', ph); | bound = _.bindKey(object, 'fn', ph, 'b', ph); | |
deepEqual(bound('a', 'c'), ['a', 'b', 'c']); | assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']); | |
deepEqual(bound('a'), ['a', 'b', undefined]); | assert.deepEqual(bound('a'), ['a', 'b', undefined]); | |
deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']); | assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']); | |
deepEqual(bound(), [undefined, 'b', undefined]); | assert.deepEqual(bound(), [undefined, 'b', undefined]); | |
}); | ||
QUnit.test('should ensure `new bound` is an instance of `object[key]`', func | ||
tion(assert) { | ||
assert.expect(2); | ||
function Foo(value) { | ||
return value && object; | ||
} | ||
var object = { 'Foo': Foo }, | ||
bound = _.bindKey(object, 'Foo'); | ||
assert.ok(new bound instanceof Foo); | ||
assert.strictEqual(new bound(true), object); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('case methods'); | QUnit.module('case methods'); | |
_.each(['camel', 'kebab', 'snake'], function(caseName) { | lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], func tion(caseName) { | |
var methodName = caseName + 'Case', | var methodName = caseName + 'Case', | |
func = _[methodName]; | func = _[methodName]; | |
var strings = [ | var strings = [ | |
'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar', | 'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar', | |
'FOO BAR', 'fooBar', '--foo-bar', '__foo_bar__' | 'FOO BAR', 'fooBar', '--foo-bar', '__foo_bar__' | |
]; | ]; | |
var expected = (function() { | var converted = (function() { | |
switch (caseName) { | switch (caseName) { | |
case 'camel': return 'fooBar'; | case 'camel': return 'fooBar'; | |
case 'kebab': return 'foo-bar'; | case 'kebab': return 'foo-bar'; | |
case 'lower': return 'foo bar'; | ||
case 'snake': return 'foo_bar'; | case 'snake': return 'foo_bar'; | |
case 'start': return 'Foo Bar'; | ||
case 'upper': return 'FOO BAR'; | ||
} | } | |
}()); | }()); | |
test('`_.' + methodName + '` should convert `string` to ' + caseName + ' cas | QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + | |
e', 1, function() { | ' case', function(assert) { | |
var actual = _.map(strings, function(string) { | assert.expect(1); | |
return func(string) === expected; | ||
var actual = lodashStable.map(strings, function(string) { | ||
return func(string) === converted; | ||
}); | }); | |
deepEqual(actual, _.map(strings, _.constant(true))); | assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue)); | |
}); | }); | |
test('`_.' + methodName + '` should handle double-converting strings', 1, fu | QUnit.test('`_.' + methodName + '` should handle double-converting strings', | |
nction() { | function(assert) { | |
var actual = _.map(strings, function(string) { | assert.expect(1); | |
return func(func(string)) === expected; | ||
var actual = lodashStable.map(strings, function(string) { | ||
return func(func(string)) === converted; | ||
}); | }); | |
deepEqual(actual, _.map(strings, _.constant(true))); | assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue)); | |
}); | }); | |
test('`_.' + methodName + '` should deburr letters', 1, function() { | QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) | |
var actual = _.map(burredLetters, function(burred, index) { | { | |
return func(burred) === deburredLetters[index].toLowerCase(); | assert.expect(1); | |
var actual = lodashStable.map(burredLetters, function(burred, index) { | ||
var letter = deburredLetters[index]; | ||
if (caseName == 'start') { | ||
letter = lodashStable.capitalize(letter); | ||
} else if (caseName == 'upper') { | ||
letter = letter.toUpperCase(); | ||
} else { | ||
letter = letter.toLowerCase(); | ||
} | ||
return func(burred) === letter; | ||
}); | }); | |
deepEqual(actual, _.map(burredLetters, _.constant(true))); | assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue)); | |
}); | }); | |
test('should trim latin-1 mathematical operators', 1, function() { | QUnit.test('`_.' + methodName + '` should trim latin-1 mathematical operator | |
var actual = _.map(['\xd7', '\xf7'], func); | s', function(assert) { | |
deepEqual(actual, ['', '']); | assert.expect(1); | |
var actual = lodashStable.map(['\xd7', '\xf7'], func); | ||
assert.deepEqual(actual, ['', '']); | ||
}); | }); | |
test('`_.' + methodName + '` should coerce `string` to a string', 2, functio | QUnit.test('`_.' + methodName + '` should coerce `string` to a string', func | |
n() { | tion(assert) { | |
var string = 'Foo Bar'; | assert.expect(2); | |
strictEqual(func(Object(string)), expected); | ||
strictEqual(func({ 'toString': _.constant(string) }), expected); | var string = 'foo bar'; | |
assert.strictEqual(func(Object(string)), converted); | ||
assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), co | ||
nverted); | ||
}); | }); | |
test('`_.' + methodName + '` should return an unwrapped value when chaining' | QUnit.test('`_.' + methodName + '` should return an unwrapped value implicit | |
, 1, function() { | ly when chaining', function(assert) { | |
assert.expect(1); | ||
if (!isNpm) { | if (!isNpm) { | |
strictEqual(_('foo bar')[methodName](), expected); | assert.strictEqual(_('foo bar')[methodName](), converted); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | ||
}); | ||
QUnit.test('`_.' + methodName + '` should return a wrapped value when explic | ||
itly chaining', function(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
assert.ok(_('foo bar').chain()[methodName]() instanceof _); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | } | |
}); | }); | |
}); | }); | |
(function() { | ||
QUnit.test('should get the original value after cycling through all case met | ||
hods', function(assert) { | ||
assert.expect(1); | ||
var funcs = [_.camelCase, _.kebabCase, _.snakeCase, _.startCase, _.camelCa | ||
se]; | ||
var actual = lodashStable.reduce(funcs, function(result, func) { | ||
return func(result); | ||
}, 'enable 24h format'); | ||
assert.strictEqual(actual, 'enable24hFormat'); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.camelCase'); | QUnit.module('lodash.camelCase'); | |
(function() { | (function() { | |
test('should work with numbers', 3, function() { | QUnit.test('should work with numbers', function(assert) { | |
strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit'); | assert.expect(5); | |
strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles'); | ||
strictEqual(_.camelCase('xhr2 request'), 'xhr2Request'); | assert.strictEqual(_.camelCase('12 feet'), '12Feet'); | |
assert.strictEqual(_.camelCase('enable 24h format'), 'enable24hFormat'); | ||
assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit'); | ||
assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles'); | ||
assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request'); | ||
}); | }); | |
test('should handle acronyms', 6, function() { | QUnit.test('should handle acronyms', function(assert) { | |
_.each(['safe HTML', 'safeHTML'], function(string) { | assert.expect(6); | |
strictEqual(_.camelCase(string), 'safeHtml'); | ||
lodashStable.each(['safe HTML', 'safeHTML'], function(string) { | ||
assert.strictEqual(_.camelCase(string), 'safeHtml'); | ||
}); | }); | |
_.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) { | lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function | |
strictEqual(_.camelCase(string), 'escapeHtmlEntities'); | (string) { | |
assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities'); | ||
}); | }); | |
_.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) { | lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) { | |
strictEqual(_.camelCase(string), 'xmlHttpRequest'); | assert.strictEqual(_.camelCase(string), 'xmlHttpRequest'); | |
}); | }); | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.capitalize'); | QUnit.module('lodash.capitalize'); | |
(function() { | (function() { | |
test('should capitalize the first character of a string', 3, function() { | QUnit.test('should capitalize the first character of a string', function(ass | |
strictEqual(_.capitalize('fred'), 'Fred'); | ert) { | |
strictEqual(_.capitalize('Fred'), 'Fred'); | assert.expect(3); | |
strictEqual(_.capitalize(' fred'), ' fred'); | ||
}); | ||
test('should return an unwrapped value when chaining', 1, function() { | assert.strictEqual(_.capitalize('fred'), 'Fred'); | |
if (!isNpm) { | assert.strictEqual(_.capitalize('Fred'), 'Fred'); | |
strictEqual(_('fred').capitalize(), 'Fred'); | assert.strictEqual(_.capitalize(' fred'), ' fred'); | |
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.chain'); | QUnit.module('lodash.chain'); | |
(function() { | (function() { | |
test('should return a wrapped value', 1, function() { | QUnit.test('should return a wrapped value', function(assert) { | |
assert.expect(1); | ||
if (!isNpm) { | if (!isNpm) { | |
var actual = _.chain({ 'a': 0 }); | var actual = _.chain({ 'a': 0 }); | |
ok(actual instanceof _); | assert.ok(actual instanceof _); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('should return existing wrapped values', 2, function() { | QUnit.test('should return existing wrapped values', function(assert) { | |
assert.expect(2); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _({ 'a': 0 }); | var wrapped = _({ 'a': 0 }); | |
strictEqual(_.chain(wrapped), wrapped); | assert.strictEqual(_.chain(wrapped), wrapped); | |
strictEqual(wrapped.chain(), wrapped); | assert.strictEqual(wrapped.chain(), wrapped); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
test('should enable chaining of methods that return unwrapped values by defa | QUnit.test('should enable chaining for methods that return unwrapped values' | |
ult', 6, function() { | , function(assert) { | |
assert.expect(6); | ||
if (!isNpm) { | if (!isNpm) { | |
var array = ['c', 'b', 'a']; | var array = ['c', 'b', 'a']; | |
ok(_.chain(array).first() instanceof _); | assert.ok(_.chain(array).head() instanceof _); | |
ok(_(array).chain().first() instanceof _); | assert.ok(_(array).chain().head() instanceof _); | |
ok(_.chain(array).isArray() instanceof _); | assert.ok(_.chain(array).isArray() instanceof _); | |
ok(_(array).chain().isArray() instanceof _); | assert.ok(_(array).chain().isArray() instanceof _); | |
ok(_.chain(array).sortBy().first() instanceof _); | assert.ok(_.chain(array).sortBy().head() instanceof _); | |
ok(_(array).chain().sortBy().first() instanceof _); | assert.ok(_(array).chain().sortBy().head() instanceof _); | |
} | } | |
else { | else { | |
skipTest(6); | skipTest(assert, 6); | |
} | } | |
}); | }); | |
test('should chain multiple methods', 6, function() { | QUnit.test('should chain multiple methods', function(assert) { | |
assert.expect(6); | ||
if (!isNpm) { | if (!isNpm) { | |
_.times(2, function(index) { | lodashStable.times(2, function(index) { | |
var array = ['one two three four', 'five six seven eight', 'nine ten e leven twelve'], | var array = ['one two three four', 'five six seven eight', 'nine ten e leven twelve'], | |
expected = { ' ': 9, 'e': 14, 'f': 2, 'g': 1, 'h': 2, 'i': 4, 'l': 2, 'n': 6, 'o': 3, 'r': 2, 's': 2, 't': 5, 'u': 1, 'v': 4, 'w': 2, 'x': 1 }, | expected = { ' ': 9, 'e': 14, 'f': 2, 'g': 1, 'h': 2, 'i': 4, 'l': 2, 'n': 6, 'o': 3, 'r': 2, 's': 2, 't': 5, 'u': 1, 'v': 4, 'w': 2, 'x': 1 }, | |
wrapped = index ? _(array).chain() : _.chain(array); | wrapped = index ? _(array).chain() : _.chain(array); | |
var actual = wrapped | var actual = wrapped | |
.chain() | .chain() | |
.map(function(value) { return value.split(''); }) | .map(function(value) { return value.split(''); }) | |
.flatten() | .flatten() | |
.reduce(function(object, chr) { | .reduce(function(object, chr) { | |
object[chr] || (object[chr] = 0); | object[chr] || (object[chr] = 0); | |
object[chr]++; | object[chr]++; | |
return object; | return object; | |
}, {}) | }, {}) | |
.value(); | .value(); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
array = [1, 2, 3, 4, 5, 6]; | array = [1, 2, 3, 4, 5, 6]; | |
wrapped = index ? _(array).chain() : _.chain(array); | wrapped = index ? _(array).chain() : _.chain(array); | |
actual = wrapped | actual = wrapped | |
.chain() | .chain() | |
.filter(function(n) { return n % 2; }) | .filter(function(n) { return n % 2 != 0; }) | |
.reject(function(n) { return n % 3 == 0; }) | .reject(function(n) { return n % 3 == 0; }) | |
.sortBy(function(n) { return -n; }) | .sortBy(function(n) { return -n; }) | |
.value(); | .value(); | |
deepEqual(actual, [5, 1]); | assert.deepEqual(actual, [5, 1]); | |
array = [3, 4]; | array = [3, 4]; | |
wrapped = index ? _(array).chain() : _.chain(array); | wrapped = index ? _(array).chain() : _.chain(array); | |
actual = wrapped | actual = wrapped | |
.reverse() | .reverse() | |
.concat([2, 1]) | .concat([2, 1]) | |
.unshift(5) | .unshift(5) | |
.tap(function(value) { value.pop(); }) | .tap(function(value) { value.pop(); }) | |
.map(function(n) { return n * n; }) | .map(square) | |
.value(); | .value(); | |
deepEqual(actual,[25, 16, 9, 4]); | assert.deepEqual(actual, [25, 16, 9, 4]); | |
}); | }); | |
} | } | |
else { | else { | |
skipTest(6); | skipTest(assert, 6); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.chunk'); | QUnit.module('lodash.chunk'); | |
(function() { | (function() { | |
var array = [0, 1, 2, 3, 4, 5]; | var array = [0, 1, 2, 3, 4, 5]; | |
test('should return chunked arrays', 1, function() { | QUnit.test('should return chunked arrays', function(assert) { | |
assert.expect(1); | ||
var actual = _.chunk(array, 3); | var actual = _.chunk(array, 3); | |
deepEqual(actual, [[0, 1, 2], [3, 4, 5]]); | assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]); | |
}); | }); | |
test('should return the last chunk as remaining elements', 1, function() { | QUnit.test('should return the last chunk as remaining elements', function(as | |
sert) { | ||
assert.expect(1); | ||
var actual = _.chunk(array, 4); | var actual = _.chunk(array, 4); | |
deepEqual(actual, [[0, 1, 2, 3], [4, 5]]); | assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]); | |
}); | }); | |
test('should ensure the minimum `chunkSize` is `1`', 1, function() { | QUnit.test('should ensure the minimum `size` is `0`', function(assert) { | |
assert.expect(1); | ||
var values = falsey.concat(-1, -Infinity), | var values = falsey.concat(-1, -Infinity), | |
expected = _.map(values, _.constant([[0], [1], [2], [3], [4], [5]])); | expected = lodashStable.map(values, alwaysEmptyArray); | |
var actual = _.map(values, function(value, index) { | var actual = lodashStable.map(values, function(value, index) { | |
return index ? _.chunk(array, value) : _.chunk(array); | return index ? _.chunk(array, value) : _.chunk(array); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | ||
QUnit.test('should coerce `size` to an integer', function(assert) { | ||
assert.expect(1); | ||
assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4 | ||
], [5]]); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.clamp'); | ||
(function() { | ||
QUnit.test('should work with a `max` argument', function(assert) { | ||
assert.expect(2); | ||
assert.strictEqual(_.clamp(5, 3), 3); | ||
assert.strictEqual(_.clamp(1, 3), 1); | ||
}); | ||
QUnit.test('should clamp negative numbers', function(assert) { | ||
assert.expect(3); | ||
assert.strictEqual(_.clamp(-10, -5, 5), -5); | ||
assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5); | ||
assert.strictEqual(_.clamp(-Infinity, -5, 5), -5); | ||
}); | ||
QUnit.test('should clamp positive numbers', function(assert) { | ||
assert.expect(3); | ||
assert.strictEqual(_.clamp(10, -5, 5), 5); | ||
assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4); | ||
assert.strictEqual(_.clamp(Infinity, -5, 5), 5); | ||
}); | ||
QUnit.test('should not alter negative numbers in range', function(assert) { | ||
assert.expect(3); | ||
assert.strictEqual(_.clamp(-4, -5, 5), -4); | ||
assert.strictEqual(_.clamp(-5, -5, 5), -5); | ||
assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5); | ||
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should not alter positive numbers in range', function(assert) { | |
var actual = _.map([[1, 2], [3, 4]], _.chunk); | assert.expect(3); | |
deepEqual(actual, [[[1], [2]], [[3], [4]]]); | ||
assert.strictEqual(_.clamp(4, -5, 5), 4); | ||
assert.strictEqual(_.clamp(5, -5, 5), 5); | ||
assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5); | ||
}); | ||
QUnit.test('should not alter `0` in range', function(assert) { | ||
assert.expect(1); | ||
assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity); | ||
}); | ||
QUnit.test('should clamp to `0`', function(assert) { | ||
assert.expect(1); | ||
assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity); | ||
}); | ||
QUnit.test('should not alter `-0` in range', function(assert) { | ||
assert.expect(1); | ||
assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity); | ||
}); | ||
QUnit.test('should clamp to `-0`', function(assert) { | ||
assert.expect(1); | ||
assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity); | ||
}); | ||
QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) { | ||
assert.expect(1); | ||
assert.deepEqual(_.clamp(NaN, -5, 5), NaN); | ||
}); | ||
QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) | ||
{ | ||
assert.expect(2); | ||
assert.deepEqual(_.clamp(1, -5, NaN), 0); | ||
assert.deepEqual(_.clamp(-1, NaN, 5), 0); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('clone methods'); | QUnit.module('clone methods'); | |
(function() { | (function() { | |
function Foo() { this.a = 1; } | function Foo() { this.a = 1; } | |
Foo.prototype = { 'b': 1 }; | Foo.prototype.b = 1; | |
Foo.c = function() {}; | Foo.c = function() {}; | |
if (Map) { | ||
var map = new Map; | ||
map.set('a', 1); | ||
map.set('b', 2); | ||
} | ||
if (Set) { | ||
var set = new Set; | ||
set.add(1); | ||
set.add(2); | ||
} | ||
var objects = { | var objects = { | |
'`arguments` objects': arguments, | '`arguments` objects': arguments, | |
'arrays': ['a', ''], | 'arrays': ['a', ''], | |
'array-like-objects': { '0': 'a', '1': '', 'length': 3 }, | 'array-like-objects': { '0': 'a', '1': '', 'length': 3 }, | |
'booleans': false, | 'booleans': false, | |
'boolean objects': Object(false), | 'boolean objects': Object(false), | |
'date objects': new Date, | ||
'Foo instances': new Foo, | 'Foo instances': new Foo, | |
'objects': { 'a': 0, 'b': 1, 'c': 3 }, | 'objects': { 'a': 0, 'b': 1, 'c': 2 }, | |
'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } }, | 'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } }, | |
'objects from another document': _._object || {}, | 'objects from another document': realm.object || {}, | |
'maps': map, | ||
'null values': null, | 'null values': null, | |
'numbers': 3, | 'numbers': 0, | |
'number objects': Object(3), | 'number objects': Object(0), | |
'regexes': /a/gim, | 'regexes': /a/gim, | |
'sets': set, | ||
'strings': 'a', | 'strings': 'a', | |
'string objects': Object('a'), | 'string objects': Object('a'), | |
'undefined values': undefined | 'undefined values': undefined | |
}; | }; | |
objects['arrays'].length = 3; | objects['arrays'].length = 3; | |
var uncloneable = { | var uncloneable = { | |
'DOM elements': body, | 'DOM elements': body, | |
'functions': Foo | 'functions': Foo, | |
'generators': generator | ||
}; | }; | |
_.each(errors, function(error) { | lodashStable.each(errors, function(error) { | |
uncloneable[error.name + 's'] = error; | uncloneable[error.name + 's'] = error; | |
}); | }); | |
test('`_.clone` should perform a shallow clone', 2, function() { | QUnit.test('`_.clone` should perform a shallow clone', function(assert) { | |
var expected = [{ 'a': 0 }, { 'b': 1 }], | assert.expect(2); | |
actual = _.clone(expected); | ||
deepEqual(actual, expected); | ||
ok(actual !== expected && actual[0] === expected[0]); | ||
}); | ||
test('`_.clone` should work with `isDeep`', 2, function() { | var array = [{ 'a': 0 }, { 'b': 1 }], | |
var expected = [{ 'a': 0 }, { 'b': 1 }], | actual = _.clone(array); | |
actual = _.clone(expected, true); | ||
deepEqual(actual, expected); | assert.deepEqual(actual, array); | |
ok(actual !== expected && actual[0] !== expected[0]); | assert.ok(actual !== array && actual[0] === array[0]); | |
}); | }); | |
test('`_.cloneDeep` should deep clone objects with circular references', 1, | QUnit.test('`_.cloneDeep` should deep clone objects with circular references | |
function() { | ', function(assert) { | |
assert.expect(1); | ||
var object = { | var object = { | |
'foo': { 'b': { 'c': { 'd': {} } } }, | 'foo': { 'b': { 'c': { 'd': {} } } }, | |
'bar': {} | 'bar': {} | |
}; | }; | |
object.foo.b.c.d = object; | object.foo.b.c.d = object; | |
object.bar.b = object.foo.b; | object.bar.b = object.foo.b; | |
var clone = _.cloneDeep(object); | var actual = _.cloneDeep(object); | |
ok(clone.bar.b === clone.foo.b && clone === clone.foo.b.c.d && clone !== o | assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && | |
bject); | actual !== object); | |
}); | }); | |
_.each(['clone', 'cloneDeep'], function(methodName, index) { | QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular re | |
var func = _[methodName], | ferences', function(assert) { | |
isDeep = !!index; | assert.expect(2); | |
_.forOwn(objects, function(object, key) { | var cyclical = {}; | |
test('`_.' + methodName + '` should clone ' + key, 2, function() { | lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) { | |
var actual = func(object); | cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical] | |
ok(_.isEqual(actual, object)); | ; | |
}); | ||
if (_.isObject(object)) { | var clone = _.cloneDeep(cyclical), | |
notStrictEqual(actual, object); | actual = clone['v' + LARGE_ARRAY_SIZE][0]; | |
} else { | ||
strictEqual(actual, object); | assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]); | |
} | assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]); | |
}); | }); | |
QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', funct | ||
ion(assert) { | ||
assert.expect(164); | ||
var Stack, | ||
keys = [true, false, 1, -Infinity, NaN, {}, null, 'a', symbol || {}, u | ||
ndefined]; | ||
var pairs = lodashStable.map(keys, function(key, index) { | ||
var lastIndex = keys.length - 1; | ||
return [key, keys[lastIndex - index]]; | ||
}); | }); | |
_.forOwn(uncloneable, function(value, key) { | _.cloneDeepWith({ 'a': 1 }, function() { | |
test('`_.' + methodName + '` should not clone ' + key, 3, function() { | if (arguments.length > 1) { | |
var object = { 'a': value, 'b': { 'c': value } }, | Stack || (Stack = _.last(arguments).constructor); | |
actual = func(object); | } | |
}); | ||
notStrictEqual(actual, object); | var stacks = [new Stack(pairs), new Stack(pairs)]; | |
deepEqual(actual, object); | ||
var expected = typeof value == 'function' ? { 'c': Foo.c } : (value && | lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() { | |
{}); | stacks[1].set({}, {}); | |
deepEqual(func(value), expected); | }); | |
lodashStable.each(stacks, function(stack) { | ||
lodashStable.each(keys, function(key, index) { | ||
var value = pairs[index][1]; | ||
assert.deepEqual(stack.get(key), value); | ||
assert.strictEqual(stack.has(key), true); | ||
assert.strictEqual(stack['delete'](key), true); | ||
assert.strictEqual(stack.has(key), false); | ||
assert.strictEqual(stack.get(key), undefined); | ||
assert.strictEqual(stack['delete'](key), false); | ||
assert.strictEqual(stack.set(key, value), stack); | ||
assert.strictEqual(stack.has(key), true); | ||
}); | }); | |
test('`_.' + methodName + '` should work with a `customizer` callback an | assert.strictEqual(stack.clear(), undefined); | |
d ' + key, 4, function() { | assert.ok(lodashStable.every(keys, function(key) { | |
var customizer = function(value) { | return !stack.has(key); | |
return _.isPlainObject(value) ? undefined : value; | })); | |
}; | }); | |
}); | ||
var actual = func(value, customizer); | lodashStable.each(['clone', 'cloneDeep'], function(methodName) { | |
var func = _[methodName], | ||
isDeep = methodName == 'cloneDeep'; | ||
deepEqual(actual, value); | lodashStable.forOwn(objects, function(object, key) { | |
strictEqual(actual, value); | QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert | |
) { | ||
assert.expect(2); | ||
var object = { 'a': value, 'b': { 'c': value } }; | var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashSta | |
actual = func(object, customizer); | ble.isEqual, | |
actual = func(object); | ||
assert.ok(isEqual(actual, object)); | ||
deepEqual(actual, object); | if (lodashStable.isObject(object)) { | |
notStrictEqual(actual, object); | assert.notStrictEqual(actual, object); | |
} else { | ||
assert.strictEqual(actual, object); | ||
} | ||
}); | }); | |
}); | }); | |
test('`_.' + methodName + '` should clone array buffers', 2, function() { | QUnit.test('`_.' + methodName + '` should clone array buffers', function(a | |
ssert) { | ||
assert.expect(2); | ||
if (ArrayBuffer) { | if (ArrayBuffer) { | |
var buffer = new ArrayBuffer(10), | var buffer = new ArrayBuffer(10), | |
actual = func(buffer); | actual = func(buffer); | |
strictEqual(actual.byteLength, buffer.byteLength); | assert.strictEqual(actual.byteLength, buffer.byteLength); | |
notStrictEqual(actual, buffer); | assert.notStrictEqual(actual, buffer); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
_.each(typedArrays, function(type) { | QUnit.test('`_.' + methodName + '` should clone `index` and `input` array | |
test('`_.' + methodName + '` should clone ' + type + ' arrays', 10, func | properties', function(assert) { | |
tion() { | assert.expect(2); | |
var Ctor = root[type]; | ||
_.times(2, function(index) { | var array = /x/.exec('vwxyz'), | |
if (Ctor) { | actual = func(array); | |
var buffer = new ArrayBuffer(24), | ||
array = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer), | ||
actual = func(array); | ||
deepEqual(actual, array); | assert.strictEqual(actual.index, 2); | |
notStrictEqual(actual, array); | assert.strictEqual(actual.input, 'vwxyz'); | |
strictEqual(actual.buffer === array.buffer, !isDeep); | ||
strictEqual(actual.byteOffset, array.byteOffset); | ||
strictEqual(actual.length, array.length); | ||
} | ||
else { | ||
skipTest(5); | ||
} | ||
}); | ||
}); | ||
}); | }); | |
test('`_.' + methodName + '` should clone problem JScript properties (test | QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp propert | |
in IE < 9)', 2, function() { | y', function(assert) { | |
var actual = func(shadowObject); | assert.expect(1); | |
deepEqual(actual, shadowObject); | ||
notStrictEqual(actual, shadowObject); | // Avoid a regexp literal for older Opera and use `exec` for older Safar | |
i. | ||
var regexp = RegExp('x', 'g'); | ||
regexp.exec('vwxyz'); | ||
var actual = func(regexp); | ||
assert.strictEqual(actual.lastIndex, 3); | ||
}); | }); | |
test('`_.' + methodName + '` should provide the correct `customizer` argum | QUnit.test('`_.' + methodName + '` should create clone with the same `[[Pr | |
ents', 1, function() { | ototype]]` as `value`', function(assert) { | |
var argsList = [], | assert.expect(1); | |
foo = new Foo; | ||
func(foo, function() { | assert.ok(func(new Foo) instanceof Foo); | |
argsList.push(slice.call(arguments)); | }); | |
}); | ||
deepEqual(argsList, isDeep ? [[foo], [1, 'a', foo]] : [[foo]]); | QUnit.test('should ensure `value` constructor is a function before using i | |
ts `[[Prototype]]`', function(assert) { | ||
assert.expect(1); | ||
Foo.prototype.constructor = null; | ||
assert.notOk(func(new Foo) instanceof Foo); | ||
Foo.prototype.constructor = Foo; | ||
}); | }); | |
test('`_.' + methodName + '` should support the `thisArg` argument', 1, fu | QUnit.test('`_.' + methodName + '` should clone properties that shadow tho | |
nction() { | se on `Object.prototype`', function(assert) { | |
var actual = func('a', function(value) { | assert.expect(2); | |
return this[value]; | ||
}, { 'a': 'A' }); | var object = { | |
'constructor': objectProto.constructor, | ||
'hasOwnProperty': objectProto.hasOwnProperty, | ||
'isPrototypeOf': objectProto.isPrototypeOf, | ||
'propertyIsEnumerable': objectProto.propertyIsEnumerable, | ||
'toLocaleString': objectProto.toLocaleString, | ||
'toString': objectProto.toString, | ||
'valueOf': objectProto.valueOf | ||
}; | ||
var actual = func(object); | ||
strictEqual(actual, 'A'); | assert.deepEqual(actual, object); | |
assert.notStrictEqual(actual, object); | ||
}); | }); | |
test('`_.' + methodName + '` should handle cloning if `customizer` returns | QUnit.test('`_.' + methodName + '` should clone symbol properties', functi | |
`undefined`', 1, function() { | on(assert) { | |
var actual = func({ 'a': { 'b': 'c' } }, _.noop); | assert.expect(2); | |
deepEqual(actual, { 'a': { 'b': 'c' } }); | ||
if (Symbol) { | ||
var object = {}; | ||
object[symbol] = {}; | ||
assert.strictEqual(func(object)[symbol], object[symbol]); | ||
if (isDeep) { | ||
object = { 'a': { 'b': {} } }; | ||
object.a.b[symbol] = {}; | ||
assert.strictEqual(func(object).a.b[symbol], object.a.b[symbol]); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | ||
}); | }); | |
test('`_.' + methodName + '` should clone `index` and `input` array proper | QUnit.test('`_.' + methodName + '` should clone symbol objects', function( | |
ties', 2, function() { | assert) { | |
var array = /x/.exec('vwxyz'), | assert.expect(4); | |
actual = func(array); | ||
if (Symbol) { | ||
assert.strictEqual(func(symbol), symbol); | ||
var object = Object(symbol), | ||
actual = func(object); | ||
strictEqual(actual.index, 2); | assert.strictEqual(typeof actual, 'object'); | |
strictEqual(actual.input, 'vwxyz'); | assert.strictEqual(typeof actual.valueOf(), 'symbol'); | |
assert.notStrictEqual(actual, object); | ||
} | ||
else { | ||
skipTest(assert, 4); | ||
} | ||
}); | }); | |
test('`_.' + methodName + '` should clone `lastIndex` regexp property', 1, | QUnit.test('`_.' + methodName + '` should not clone symbol primitives', fu | |
function() { | nction(assert) { | |
// Avoid a regexp literal for older Opera and use `exec` for older Safar | assert.expect(1); | |
i. | ||
var regexp = RegExp('x', 'g'); | ||
regexp.exec('vwxyz'); | ||
var actual = func(regexp); | if (Symbol) { | |
strictEqual(actual.lastIndex, 3); | assert.strictEqual(func(symbol), symbol); | |
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | }); | |
test('`_.' + methodName + '` should not error on DOM elements', 1, functio | QUnit.test('`_.' + methodName + '` should not error on DOM elements', func | |
n() { | tion(assert) { | |
assert.expect(1); | ||
if (document) { | if (document) { | |
var element = document.createElement('div'); | var element = document.createElement('div'); | |
try { | try { | |
deepEqual(func(element), {}); | assert.deepEqual(func(element), {}); | |
} catch(e) { | } catch (e) { | |
ok(false, e.message); | assert.ok(false, e.message); | |
} | } | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shal | QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : | |
low') + ' clone when used as an iteratee for `_.map`', 3, function() { | 'shallow') + ' clone when used as an iteratee for methods like `_.map`', functi | |
on(assert) { | ||
assert.expect(2); | ||
var expected = [{ 'a': [0] }, { 'b': [1] }], | var expected = [{ 'a': [0] }, { 'b': [1] }], | |
actual = _.map(expected, func); | actual = lodashStable.map(expected, func); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
if (isDeep) { | if (isDeep) { | |
ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actua l[1].b !== expected[1].b); | assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a & & actual[1].b !== expected[1].b); | |
} else { | } else { | |
ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actua l[1].b === expected[1].b); | assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a & & actual[1].b === expected[1].b); | |
} | } | |
actual = _.map(isDeep ? Object('abc') : 'abc', func); | ||
deepEqual(actual, ['a', 'b', 'c']); | ||
}); | }); | |
test('`_.' + methodName + '` should create an object from the same realm a | QUnit.test('`_.' + methodName + '` should create an object from the same r | |
s `value`', 1, function() { | ealm as `value`', function(assert) { | |
var objects = _.transform(_, function(result, value, key) { | assert.expect(1); | |
if (_.startsWith(key, '_') && _.isObject(value) && !_.isArguments(valu | ||
e) && !_.isElement(value) && !_.isFunction(value)) { | var props = []; | |
var objects = lodashStable.transform(_, function(result, value, key) { | ||
if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) | ||
&& !lodashStable.isArguments(value) && !lodashStable.isElement(value) && !lodash | ||
Stable.isFunction(value)) { | ||
props.push(lodashStable.capitalize(lodashStable.camelCase(key))); | ||
result.push(value); | result.push(value); | |
} | } | |
}, []); | }, []); | |
var expected = _.times(objects.length, _.constant(true)); | var expected = lodashStable.map(objects, alwaysTrue); | |
var actual = _.map(objects, function(object) { | var actual = lodashStable.map(objects, function(object) { | |
var Ctor = object.constructor, | var Ctor = object.constructor, | |
result = func(object); | result = func(object); | |
return result !== object && (result instanceof Ctor || !(new Ctor inst anceof Ctor)); | return result !== object && ((result instanceof Ctor) || !(new Ctor in stanceof Ctor)); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected, props.join(', ')); | |
}); | }); | |
test('`_.' + methodName + '` should return a unwrapped value when chaining | QUnit.test('`_.' + methodName + '` should return a unwrapped value when ch | |
', 2, function() { | aining', function(assert) { | |
assert.expect(2); | ||
if (!isNpm) { | if (!isNpm) { | |
var object = objects['objects'], | var object = objects['objects'], | |
actual = _(object)[methodName](); | actual = _(object)[methodName](); | |
deepEqual(actual, object); | assert.deepEqual(actual, object); | |
notStrictEqual(actual, object); | assert.notStrictEqual(actual, object); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
}); | ||
}(1, 2, 3)); | ||
/*--------------------------------------------------------------------------*/ | lodashStable.each(typedArrays, function(type) { | |
QUnit.test('`_.' + methodName + '` should clone ' + type + ' arrays', fu | ||
nction(assert) { | ||
assert.expect(10); | ||
QUnit.module('lodash.compact'); | var Ctor = root[type]; | |
(function() { | lodashStable.times(2, function(index) { | |
test('should filter falsey values', 1, function() { | if (Ctor) { | |
var array = ['0', '1', '2']; | var buffer = new ArrayBuffer(24), | |
deepEqual(_.compact(falsey.concat(array)), array); | array = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer), | |
}); | actual = func(array); | |
test('should return a wrapped value when chaining', 2, function() { | assert.deepEqual(actual, array); | |
if (!isNpm) { | assert.notStrictEqual(actual, array); | |
var wrapped = _(falsey).compact(); | assert.strictEqual(actual.buffer === array.buffer, !isDeep); | |
ok(wrapped instanceof _); | assert.strictEqual(actual.byteOffset, array.byteOffset); | |
deepEqual(wrapped.value(), []); | assert.strictEqual(actual.length, array.length); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 5); | |
} | } | |
}); | ||
}); | ||
}); | ||
lodashStable.forOwn(uncloneable, function(value, key) { | ||
QUnit.test('`_.' + methodName + '` should not clone ' + key, function(as | ||
sert) { | ||
assert.expect(3); | ||
if (value) { | ||
var object = { 'a': value, 'b': { 'c': value } }, | ||
actual = func(object), | ||
expected = (typeof value == 'function' && !!value.c) ? { 'c': Fo | ||
o.c } : {}; | ||
assert.deepEqual(actual, object); | ||
assert.notStrictEqual(actual, object); | ||
assert.deepEqual(func(value), expected); | ||
} | ||
else { | ||
skipTest(assert, 3); | ||
} | ||
}); | ||
}); | ||
}); | }); | |
test('should work when in between lazy operators', 2, function() { | lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) { | |
if (!isNpm) { | var func = _[methodName], | |
var actual = _(falsey).slice().compact().slice().value(); | isDeep = methodName == 'cloneDeepWith'; | |
deepEqual(actual, []); | ||
actual = _(falsey).slice().push(true, 1).compact().push('a').slice().val | QUnit.test('`_.' + methodName + '` should provide the correct `customizer` | |
ue(); | arguments', function(assert) { | |
deepEqual(actual, [true, 1, 'a']); | assert.expect(1); | |
} | ||
else { | ||
skipTest(2); | ||
} | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | var argsList = [], | |
foo = new Foo; | ||
QUnit.module('lodash.flowRight'); | func(foo, function() { | |
var length = arguments.length, | ||
args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0)); | ||
(function() { | argsList.push(args); | |
test('should be aliased', 2, function() { | }); | |
strictEqual(_.backflow, _.flowRight); | ||
strictEqual(_.compose, _.flowRight); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | assert.deepEqual(argsList, isDeep ? [[foo], [1, 'a', foo]] : [[foo]]); | |
}); | ||
QUnit.module('flow methods'); | QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` r | |
eturns `undefined`', function(assert) { | ||
assert.expect(1); | ||
_.each(['flow', 'flowRight'], function(methodName, index) { | var actual = func({ 'a': { 'b': 'c' } }, noop); | |
var func = _[methodName], | assert.deepEqual(actual, { 'a': { 'b': 'c' } }); | |
isFlow = !index; | }); | |
test('`_.' + methodName + '` should supply each function with the return val | lodashStable.forOwn(uncloneable, function(value, key) { | |
ue of the previous', 1, function() { | QUnit.test('`_.' + methodName + '` should work with a `customizer` callb | |
function add(x, y) { | ack and ' + key, function(assert) { | |
return x + y; | assert.expect(4); | |
} | ||
function square(n) { | var customizer = function(value) { | |
return n * n; | return lodashStable.isPlainObject(value) ? undefined : value; | |
} | }; | |
function fixed(n) { | var actual = func(value, customizer); | |
return n.toFixed(1); | ||
} | assert.deepEqual(actual, value); | |
assert.strictEqual(actual, value); | ||
var object = { 'a': value, 'b': { 'c': value } }; | ||
actual = func(object, customizer); | ||
var combined = isFlow ? func(add, square, fixed) : func(fixed, square, add | assert.deepEqual(actual, object); | |
); | assert.notStrictEqual(actual, object); | |
strictEqual(combined(1, 2), '9.0'); | }); | |
}); | ||
}); | }); | |
}(1, 2, 3)); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.compact'); | ||
(function() { | ||
QUnit.test('should filter falsey values', function(assert) { | ||
assert.expect(1); | ||
test('`_.' + methodName + '` should return a new function', 1, function() { | var array = ['0', '1', '2']; | |
notStrictEqual(func(_.noop), _.noop); | assert.deepEqual(_.compact(falsey.concat(array)), array); | |
}); | }); | |
test('`_.' + methodName + '` should return a noop function when no arguments | QUnit.test('should work when in-between lazy operators', function(assert) { | |
are provided', 2, function() { | assert.expect(2); | |
var combined = func(); | ||
try { | if (!isNpm) { | |
strictEqual(combined(), undefined); | var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value(); | |
} catch(e) { | assert.deepEqual(actual, []); | |
ok(false, e.message); | ||
actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value | ||
(); | ||
assert.deepEqual(actual, [true, 1, 'a']); | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | } | |
notStrictEqual(combined, _.noop); | ||
}); | }); | |
test('`_.' + methodName + '` should return a wrapped value when chaining', 1 | QUnit.test('should work in a lazy sequence', function(assert) { | |
, function() { | assert.expect(1); | |
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(_.noop)[methodName](); | var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(null), | |
ok(wrapped instanceof _); | actual = _(array).slice(1).compact().reverse().take().value(); | |
assert.deepEqual(actual, _.take(_.compact(_.slice(array, 1)).reverse())) | ||
; | ||
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
}); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.constant'); | QUnit.module('lodash.concat'); | |
(function() { | (function() { | |
test('should create a function that returns `value`', 1, function() { | QUnit.test('should concat arrays and values', function(assert) { | |
var object = { 'a': 1 }, | assert.expect(2); | |
values = Array(2).concat(empties, true, 1, 'a'), | ||
constant = _.constant(object), | ||
expected = _.map(values, function() { return true; }); | ||
var actual = _.map(values, function(value, index) { | var array = [1], | |
if (index == 0) { | actual = _.concat(array, 2, [3], [[4]]); | |
var result = constant(); | ||
} else if (index == 1) { | ||
result = constant.call({}); | ||
} else { | ||
result = constant(value); | ||
} | ||
return result === object; | ||
}); | ||
deepEqual(actual, expected); | assert.deepEqual(actual, [1, 2, 3, [4]]); | |
assert.deepEqual(array, [1]); | ||
}); | }); | |
test('should work with falsey values', 1, function() { | QUnit.test('should treat sparse arrays as dense', function(assert) { | |
var expected = _.map(falsey, function() { return true; }); | assert.expect(3); | |
var actual = _.map(falsey, function(value, index) { | var expected = [], | |
var constant = index ? _.constant(value) : _.constant(), | actual = _.concat(Array(1), Array(1)); | |
result = constant(); | ||
return result === value || (_.isNaN(result) && _.isNaN(value)); | expected.push(undefined, undefined); | |
}); | ||
deepEqual(actual, expected); | assert.ok('0'in actual); | |
assert.ok('1' in actual); | ||
assert.deepEqual(actual, expected); | ||
}); | }); | |
test('should return a wrapped value when chaining', 1, function() { | QUnit.test('should return a new wrapped array', function(assert) { | |
assert.expect(2); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(true).constant(); | var array = [1], | |
ok(wrapped instanceof _); | wrapped = _(array).concat([2, 3]), | |
actual = wrapped.value(); | ||
assert.deepEqual(array, [1]); | ||
assert.deepEqual(actual, [1, 2, 3]); | ||
} | } | |
else { | else { | |
skipTest(); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.countBy'); | QUnit.module('lodash.cond'); | |
(function() { | (function() { | |
var array = [4.2, 6.1, 6.4]; | QUnit.test('should create a conditional function', function(assert) { | |
assert.expect(3); | ||
test('should work with an iteratee', 1, function() { | var cond = _.cond([ | |
var actual = _.countBy(array, function(num) { | [lodashStable.matches({ 'a': 1 }), alwaysA], | |
return Math.floor(num); | [lodashStable.matchesProperty('b', 1), alwaysB], | |
}, Math); | [lodashStable.property('c'), alwaysC] | |
]); | ||
deepEqual(actual, { '4': 1, '6': 2 }); | assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a'); | |
assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b'); | ||
assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c'); | ||
}); | }); | |
test('should use `_.identity` when `iteratee` is nullish', 1, function() { | QUnit.test('should provide arguments to functions', function(assert) { | |
var array = [4, 6, 6], | assert.expect(2); | |
values = [, null, undefined], | ||
expected = _.map(values, _.constant({ '4': 1, '6': 2 })); | ||
var actual = _.map(values, function(value, index) { | var args1, | |
return index ? _.countBy(array, value) : _.countBy(array); | args2, | |
}); | expected = ['a', 'b', 'c']; | |
deepEqual(actual, expected); | ||
}); | ||
test('should provide the correct `iteratee` arguments', 1, function() { | ||
var args; | ||
_.countBy(array, function() { | ||
args || (args = slice.call(arguments)); | ||
}); | ||
deepEqual(args, [4.2, 0, array]); | var cond = _.cond([[ | |
}); | function() { args1 || (args1 = slice.call(arguments)); return true; }, | |
function() { args2 || (args2 = slice.call(arguments)); } | ||
]]); | ||
test('should support the `thisArg` argument', 1, function() { | cond('a', 'b', 'c'); | |
var actual = _.countBy(array, function(num) { | ||
return this.floor(num); | ||
}, Math); | ||
deepEqual(actual, { '4': 1, '6': 2 }); | assert.deepEqual(args1, expected); | |
assert.deepEqual(args2, expected); | ||
}); | }); | |
test('should only add values to own, not inherited, properties', 2, function | QUnit.test('should work with predicate shorthands', function(assert) { | |
() { | assert.expect(3); | |
var actual = _.countBy([4.2, 6.1, 6.4], function(num) { | ||
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; | ||
}); | ||
deepEqual(actual.constructor, 1); | var cond = _.cond([ | |
deepEqual(actual.hasOwnProperty, 2); | [{ 'a': 1 }, alwaysA], | |
}); | [['b', 1], alwaysB], | |
['c', alwaysC] | ||
]); | ||
test('should work with a "_.pluck" style `iteratee`', 1, function() { | assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a'); | |
var actual = _.countBy(['one', 'two', 'three'], 'length'); | assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b'); | |
deepEqual(actual, { '3': 2, '5': 1 }); | assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c'); | |
}); | }); | |
test('should work with a number for `iteratee`', 2, function() { | QUnit.test('should return `undefined` when no condition is met', function(as | |
var array = [ | sert) { | |
[1, 'a'], | assert.expect(1); | |
[2, 'a'], | ||
[2, 'b'] | ||
]; | ||
deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 }); | var cond = _.cond([[alwaysFalse, alwaysA]]); | |
deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 }); | assert.strictEqual(cond({ 'a': 1 }), undefined); | |
}); | }); | |
test('should work with an object for `collection`', 1, function() { | QUnit.test('should throw a TypeError if `pairs` is not composed of functions | |
var actual = _.countBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) { | ', function(assert) { | |
return Math.floor(num); | assert.expect(2); | |
}); | ||
deepEqual(actual, { '4': 1, '6': 2 }); | lodashStable.each([true, false], function(value) { | |
assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError | ||
); | ||
}); | ||
}); | }); | |
test('should work in a lazy chain sequence', 1, function() { | QUnit.test('should use `this` binding of function for `pairs`', function(ass | |
if (!isNpm) { | ert) { | |
var array = [1, 2, 1, 3], | assert.expect(1); | |
predicate = function(value) { return value > 1; }, | ||
actual = _(array).countBy(_.identity).map(String).filter(predicate). | ||
take().value(); | ||
deepEqual(actual, ['2']); | var cond = _.cond([ | |
} | [function(a) { return this[a]; }, function(a, b) { return this[b]; }] | |
else { | ]); | |
skipTest(); | ||
} | var object = { 'cond': cond, 'a': 1, 'b': 2 }; | |
assert.strictEqual(object.cond('a', 'b'), 2); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.create'); | QUnit.module('lodash.conforms'); | |
(function() { | (function() { | |
function Shape() { | var objects = [ | |
this.x = 0; | { 'a': 1, 'b': 8 }, | |
this.y = 0; | { 'a': 2, 'b': 4 }, | |
} | { 'a': 3, 'b': 16 } | |
]; | ||
function Circle() { | ||
Shape.call(this); | ||
} | ||
test('should create an object that inherits from the given `prototype` objec | ||
t', 3, function() { | ||
Circle.prototype = _.create(Shape.prototype); | ||
Circle.prototype.constructor = Circle; | ||
var actual = new Circle; | QUnit.test('should create a function that checks if a given object conforms | |
to `source`', function(assert) { | ||
assert.expect(2); | ||
ok(actual instanceof Circle); | var conforms = _.conforms({ | |
ok(actual instanceof Shape); | 'b': function(value) { return value > 4; } | |
notStrictEqual(Circle.prototype, Shape.prototype); | }); | |
}); | ||
test('should assign `properties` to the created object', 3, function() { | var actual = lodashStable.filter(objects, conforms); | |
var expected = { 'constructor': Circle, 'radius': 0 }; | assert.deepEqual(actual, [objects[0], objects[2]]); | |
Circle.prototype = _.create(Shape.prototype, expected); | ||
var actual = new Circle; | conforms = _.conforms({ | |
'b': function(value) { return value > 8; }, | ||
'a': function(value) { return value > 1; } | ||
}); | ||
ok(actual instanceof Circle); | actual = lodashStable.filter(objects, conforms); | |
ok(actual instanceof Shape); | assert.deepEqual(actual, [objects[2]]); | |
deepEqual(Circle.prototype, expected); | ||
}); | }); | |
test('should assign own properties', 1, function() { | QUnit.test('should not match by inherited `source` properties', function(ass | |
ert) { | ||
assert.expect(1); | ||
function Foo() { | function Foo() { | |
this.a = 1; | this.a = function(value) { | |
this.c = 3; | return value > 1; | |
}; | ||
} | } | |
Foo.prototype.b = 2; | ||
deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 }); | Foo.prototype.b = function(value) { | |
return value > 8; | ||
}; | ||
var conforms = _.conforms(new Foo), | ||
actual = lodashStable.filter(objects, conforms); | ||
assert.deepEqual(actual, [objects[1], objects[2]]); | ||
}); | }); | |
test('should accept a falsey `prototype` argument', 1, function() { | QUnit.test('should not invoke `source` predicates for missing `object` prope | |
var expected = _.map(falsey, _.constant({})); | rties', function(assert) { | |
assert.expect(2); | ||
var count = 0; | ||
var actual = _.map(falsey, function(value, index) { | var conforms = _.conforms({ | |
return index ? _.create(value) : _.create(); | 'a': function() { count++; return true; } | |
}); | }); | |
deepEqual(actual, expected); | assert.strictEqual(conforms({}), false); | |
assert.strictEqual(count, 0); | ||
}); | }); | |
test('should ignore primitive `prototype` arguments and use an empty object | QUnit.test('should work with a function for `object`', function(assert) { | |
instead', 1, function() { | assert.expect(2); | |
var primitives = [true, null, 1, 'a', undefined], | ||
expected = _.map(primitives, _.constant(true)); | function Foo() {} | |
Foo.a = 1; | ||
var actual = _.map(primitives, function(value, index) { | function Bar() {} | |
return _.isPlainObject(index ? _.create(value) : _.create()); | Bar.a = 2; | |
var conforms = _.conforms({ | ||
'a': function(value) { return value > 1; } | ||
}); | }); | |
deepEqual(actual, expected); | assert.strictEqual(conforms(Foo), false); | |
assert.strictEqual(conforms(Bar), true); | ||
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should work with a function for `source`', function(assert) { | |
var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }], | assert.expect(1); | |
expected = _.map(array, _.constant(true)), | ||
objects = _.map(array, _.create); | ||
var actual = _.map(objects, function(object) { | function Foo() {} | |
return object.a === 1 && !_.keys(object).length; | Foo.a = function(value) { return value > 1; }; | |
}); | ||
deepEqual(actual, expected); | var objects = [{ 'a': 1 }, { 'a': 2 }], | |
}); | actual = lodashStable.filter(objects, _.conforms(Foo)); | |
}()); | ||
/*--------------------------------------------------------------------------*/ | assert.deepEqual(actual, [objects[1]]); | |
}); | ||
QUnit.module('lodash.callback'); | QUnit.test('should work with a non-plain `object`', function(assert) { | |
assert.expect(1); | ||
(function() { | function Foo() { | |
test('should provide arguments to `func`', 3, function() { | this.a = 1; | |
function fn() { | ||
var result = [this]; | ||
push.apply(result, arguments); | ||
return result; | ||
} | } | |
Foo.prototype.b = 2; | ||
var callback = _.callback(fn), | var conforms = _.conforms({ | |
actual = callback('a', 'b', 'c', 'd', 'e', 'f'); | 'b': function(value) { return value > 1; } | |
}); | ||
ok(actual[0] === null || actual[0] && actual[0].Array); | assert.strictEqual(conforms(new Foo), true); | |
deepEqual(actual.slice(1), ['a', 'b', 'c', 'd', 'e', 'f']); | }); | |
var object = {}; | QUnit.test('should return `false` when `object` is nullish', function(assert | |
callback = _.callback(fn, object); | ) { | |
actual = callback('a', 'b'); | assert.expect(1); | |
deepEqual(actual, [object, 'a', 'b']); | var values = [, null, undefined], | |
}); | expected = lodashStable.map(values, alwaysFalse); | |
test('should return `_.identity` when `func` is nullish', 1, function() { | var conforms = _.conforms({ | |
var object = {}, | 'a': function(value) { return value > 1; } | |
values = [, null, undefined], | }); | |
expected = _.map(values, _.constant(object)); | ||
var actual = _.map(values, function(value, index) { | var actual = lodashStable.map(values, function(value, index) { | |
var callback = index ? _.callback(value) : _.callback(); | try { | |
return callback(object); | return index ? conforms(value) : conforms(); | |
} catch (e) {} | ||
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should not error when `func` is nullish and a `thisArg` is provided', | QUnit.test('should return `true` when comparing an empty `source` to a nulli | |
2, function() { | sh `object`', function(assert) { | |
var object = {}; | assert.expect(1); | |
_.each([null, undefined], function(value) { | var values = [, null, undefined], | |
expected = lodashStable.map(values, alwaysTrue), | ||
conforms = _.conforms({}); | ||
var actual = lodashStable.map(values, function(value, index) { | ||
try { | try { | |
var callback = _.callback(value, {}); | return index ? conforms(value) : conforms(); | |
strictEqual(callback(object), object); | } catch (e) {} | |
} catch(e) { | ||
ok(false, e.message); | ||
} | ||
}); | }); | |
}); | ||
test('should create a callback with a falsey `thisArg`', 1, function() { | assert.deepEqual(actual, expected); | |
var fn = function() { return this; }, | }); | |
object = {}; | ||
var expected = _.map(falsey, function(value) { | QUnit.test('should return `true` when comparing an empty `source`', function | |
var result = fn.call(value); | (assert) { | |
return (result && result.Array) ? object : result; | assert.expect(1); | |
}); | ||
var actual = _.map(falsey, function(value) { | var object = { 'a': 1 }, | |
var callback = _.callback(fn, value), | expected = lodashStable.map(empties, alwaysTrue); | |
result = callback(); | ||
return (result && result.Array) ? object : result; | var actual = lodashStable.map(empties, function(value) { | |
var conforms = _.conforms(value); | ||
return conforms(object); | ||
}); | }); | |
ok(_.isEqual(actual, expected)); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should return a callback created by `_.matches` when `func` is an obje | QUnit.test('should not change behavior if `source` is modified', function(as | |
ct', 2, function() { | sert) { | |
var callback = _.callback({ 'a': 1 }); | assert.expect(2); | |
strictEqual(callback({ 'a': 1, 'b': 2 }), true); | ||
strictEqual(callback({}), false); | ||
}); | ||
test('should return a callback created by `_.property` when `func` is a numb | var source = { | |
er or string', 2, function() { | 'a': function(value) { return value > 1; } | |
var array = ['a'], | }; | |
callback = _.callback(0); | ||
var object = { 'a': 2 }, | ||
conforms = _.conforms(source); | ||
strictEqual(callback(array), 'a'); | assert.strictEqual(conforms(object), true); | |
callback = _.callback('0'); | source.a = function(value) { return value < 2; }; | |
strictEqual(callback(array), 'a'); | assert.strictEqual(conforms(object), true); | |
}); | }); | |
}()); | ||
test('should work with functions created by `_.partial` and `_.partialRight` | /*--------------------------------------------------------------------------*/ | |
', 2, function() { | ||
function fn() { | ||
var result = [this.a]; | ||
push.apply(result, arguments); | ||
return result; | ||
} | ||
var expected = [1, 2, 3], | QUnit.module('lodash.constant'); | |
object = { 'a': 1 }, | ||
callback = _.callback(_.partial(fn, 2), object); | ||
deepEqual(callback(3), expected); | (function() { | |
QUnit.test('should create a function that returns `value`', function(assert) | ||
{ | ||
assert.expect(1); | ||
callback = _.callback(_.partialRight(fn, 3), object); | var object = { 'a': 1 }, | |
deepEqual(callback(2), expected); | values = Array(2).concat(empties, true, 1, 'a'), | |
constant = _.constant(object), | ||
expected = lodashStable.map(values, function() { return true; }); | ||
var actual = lodashStable.map(values, function(value, index) { | ||
if (index == 0) { | ||
var result = constant(); | ||
} else if (index == 1) { | ||
result = constant.call({}); | ||
} else { | ||
result = constant(value); | ||
} | ||
return result === object; | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | }); | |
test('should support binding built-in methods', 2, function() { | QUnit.test('should work with falsey values', function(assert) { | |
var object = { 'a': 1 }, | assert.expect(1); | |
callback = _.callback(hasOwnProperty, object); | ||
strictEqual(callback('a'), true); | var expected = lodashStable.map(falsey, function() { return true; }); | |
var fn = function() {}, | var actual = lodashStable.map(falsey, function(value, index) { | |
bound = fn.bind && fn.bind(object); | var constant = index ? _.constant(value) : _.constant(), | |
result = constant(); | ||
if (bound) { | return (result === value) || (result !== result && value !== value); | |
callback = _.callback(bound, object); | }); | |
notStrictEqual(callback, bound); | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('should return the function provided when there is no `this` reference' | assert.deepEqual(actual, expected); | |
, 2, function() { | }); | |
function a() {} | ||
function b() { return this.b; } | ||
var object = {}; | QUnit.test('should return a wrapped value when chaining', function(assert) { | |
assert.expect(1); | ||
if (_.support.funcDecomp) { | if (!isNpm) { | |
strictEqual(_.callback(a, object), a); | var wrapped = _(true).constant(); | |
notStrictEqual(_.callback(b, object), b); | assert.ok(wrapped instanceof _); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert); | |
} | } | |
}); | }); | |
}()); | ||
test('should work with bizarro `_.support.funcNames`', 6, function() { | /*--------------------------------------------------------------------------*/ | |
function a() {} | ||
var b = function() {}; | QUnit.module('lodash.countBy'); | |
function c() { | (function() { | |
return this; | var array = [4.2, 6.1, 6.4]; | |
} | ||
var object = {}, | QUnit.test('should work with an iteratee', function(assert) { | |
supportBizarro = lodashBizarro ? lodashBizarro.support : {}, | assert.expect(1); | |
funcDecomp = supportBizarro.funcDecomp, | ||
funcNames = supportBizarro.funcNames; | ||
supportBizarro.funcNames = !supportBizarro.funcNames; | ||
supportBizarro.funcDecomp = true; | ||
_.each([a, b, c], function(fn) { | ||
if (lodashBizarro && _.support.funcDecomp) { | ||
var callback = lodashBizarro.callback(fn, object); | ||
strictEqual(callback(), fn === c ? object : undefined); | ||
strictEqual(callback === fn, _.support.funcNames && fn === a); | ||
} | ||
else { | ||
skipTest(2); | ||
} | ||
}); | ||
supportBizarro.funcDecomp = funcDecomp; | var actual = _.countBy(array, function(num) { | |
supportBizarro.funcNames = funcNames; | return Math.floor(num); | |
}, Math); | ||
assert.deepEqual(actual, { '4': 1, '6': 2 }); | ||
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should use `_.identity` when `iteratee` is nullish', function(as | |
var fn = function() { return this instanceof Number; }, | sert) { | |
array = [fn, fn, fn], | assert.expect(1); | |
expected = _.map(array, _.constant(false)), | ||
callbacks = _.map(array, _.callback); | var array = [4, 6, 6], | |
values = [, null, undefined], | ||
expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6 | ||
': 2 })); | ||
var actual = _.map(callbacks, function(callback) { | var actual = lodashStable.map(values, function(value, index) { | |
return callback(); | return index ? _.countBy(array, value) : _.countBy(array); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should be aliased', 1, function() { | QUnit.test('should work with a "_.property" style `iteratee`', function(asse | |
strictEqual(_.iteratee, _.callback); | rt) { | |
assert.expect(1); | ||
var actual = _.countBy(['one', 'two', 'three'], 'length'); | ||
assert.deepEqual(actual, { '3': 2, '5': 1 }); | ||
}); | }); | |
}()); | ||
/*--------------------------------------------------------------------------*/ | QUnit.test('should only add values to own, not inherited, properties', funct | |
ion(assert) { | ||
assert.expect(2); | ||
QUnit.module('custom `_.callback` methods'); | var actual = _.countBy([4.2, 6.1, 6.4], function(num) { | |
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; | ||
}); | ||
(function() { | assert.deepEqual(actual.constructor, 1); | |
var array = ['one', 'two', 'three'], | assert.deepEqual(actual.hasOwnProperty, 2); | |
callback = _.callback, | }); | |
getPropA = _.partial(_.property, 'a'), | ||
getPropB = _.partial(_.property, 'b'), | ||
getLength = _.partial(_.property, 'length'); | ||
var getSum = function() { | QUnit.test('should work with a number for `iteratee`', function(assert) { | |
return function(result, object) { | assert.expect(2); | |
return result + object.a; | ||
}; | ||
}; | ||
var objects = [ | var array = [ | |
{ 'a': 0, 'b': 0 }, | [1, 'a'], | |
{ 'a': 1, 'b': 0 }, | [2, 'a'], | |
{ 'a': 1, 'b': 1 } | [2, 'b'] | |
]; | ]; | |
test('`_.countBy` should use `_.callback` internally', 1, function() { | assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 }); | |
if (!isModularize) { | assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 }); | |
_.callback = getLength; | ||
deepEqual(_.countBy(array), { '3': 2, '5': 1 }); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.dropRightWhile` should use `_.callback` internally', 1, function() | QUnit.test('should work with an object for `collection`', function(assert) { | |
{ | assert.expect(1); | |
if (!isModularize) { | ||
_.callback = getPropB; | ||
deepEqual(_.dropRightWhile(objects), objects.slice(0, 2)); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.dropWhile` should use `_.callback` internally', 1, function() { | var actual = _.countBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) { | |
if (!isModularize) { | return Math.floor(num); | |
_.callback = getPropB; | }); | |
deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().sl | ||
ice(0, 2)); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.every` should use `_.callback` internally', 1, function() { | assert.deepEqual(actual, { '4': 1, '6': 2 }); | |
if (!isModularize) { | ||
_.callback = getPropA; | ||
strictEqual(_.every(objects.slice(1)), true); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.filter` should use `_.callback` internally', 1, function() { | QUnit.test('should work in a lazy sequence', function(assert) { | |
if (!isModularize) { | assert.expect(1); | |
var objects = [{ 'a': 0 }, { 'a': 1 }]; | ||
_.callback = getPropA; | if (!isNpm) { | |
deepEqual(_.filter(objects), [objects[1]]); | var array = lodashStable.range(LARGE_ARRAY_SIZE).concat( | |
_.callback = callback; | lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE) | |
} | , | |
else { | lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZ | |
skipTest(); | E) | |
} | ); | |
}); | ||
test('`_.find` should use `_.callback` internally', 1, function() { | var actual = _(array).countBy().map(square).filter(isEven).take().value( | |
if (!isModularize) { | ); | |
_.callback = getPropA; | ||
strictEqual(_.find(objects), objects[1]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.findIndex` should use `_.callback` internally', 1, function() { | assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square) | |
if (!isModularize) { | , isEven))); | |
_.callback = getPropA; | ||
strictEqual(_.findIndex(objects), 1); | ||
_.callback = callback; | ||
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
}()); | ||
test('`_.findLast` should use `_.callback` internally', 1, function() { | /*--------------------------------------------------------------------------*/ | |
if (!isModularize) { | ||
_.callback = getPropA; | ||
strictEqual(_.findLast(objects), objects[2]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.findLastIndex` should use `_.callback` internally', 1, function() { | QUnit.module('lodash.create'); | |
if (!isModularize) { | ||
_.callback = getPropA; | ||
strictEqual(_.findLastIndex(objects), 2); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.findLastKey` should use `_.callback` internally', 1, function() { | (function() { | |
if (!isModularize) { | function Shape() { | |
_.callback = getPropB; | this.x = 0; | |
strictEqual(_.findKey(objects), '2'); | this.y = 0; | |
_.callback = callback; | } | |
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.findKey` should use `_.callback` internally', 1, function() { | function Circle() { | |
if (!isModularize) { | Shape.call(this); | |
_.callback = getPropB; | } | |
strictEqual(_.findLastKey(objects), '2'); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.groupBy` should use `_.callback` internally', 1, function() { | QUnit.test('should create an object that inherits from the given `prototype` | |
if (!isModularize) { | object', function(assert) { | |
_.callback = getLength; | assert.expect(3); | |
deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] }); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.indexBy` should use `_.callback` internally', 1, function() { | Circle.prototype = _.create(Shape.prototype); | |
if (!isModularize) { | Circle.prototype.constructor = Circle; | |
_.callback = getLength; | ||
deepEqual(_.indexBy(array), { '3': 'two', '5': 'three' }); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.map` should use `_.callback` internally', 1, function() { | var actual = new Circle; | |
if (!isModularize) { | ||
_.callback = getPropA; | ||
deepEqual(_.map(objects), [0, 1, 1]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.mapValues` should use `_.callback` internally', 1, function() { | assert.ok(actual instanceof Circle); | |
if (!isModularize) { | assert.ok(actual instanceof Shape); | |
_.callback = getPropB; | assert.notStrictEqual(Circle.prototype, Shape.prototype); | |
deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 }); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.max` should use `_.callback` internally', 1, function() { | QUnit.test('should assign `properties` to the created object', function(asse | |
if (!isModularize) { | rt) { | |
_.callback = getPropB; | assert.expect(3); | |
deepEqual(_.max(objects), objects[2]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.min` should use `_.callback` internally', 1, function() { | var expected = { 'constructor': Circle, 'radius': 0 }; | |
if (!isModularize) { | Circle.prototype = _.create(Shape.prototype, expected); | |
_.callback = getPropB; | ||
deepEqual(_.min(objects), objects[0]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.partition` should use `_.callback` internally', 1, function() { | var actual = new Circle; | |
if (!isModularize) { | ||
var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }]; | ||
_.callback = getPropA; | assert.ok(actual instanceof Circle); | |
deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]) | assert.ok(actual instanceof Shape); | |
; | assert.deepEqual(Circle.prototype, expected); | |
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.reduce` should use `_.callback` internally', 1, function() { | QUnit.test('should assign own properties', function(assert) { | |
if (!isModularize) { | assert.expect(1); | |
_.callback = getSum; | ||
strictEqual(_.reduce(objects, undefined, 0), 2); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.reduceRight` should use `_.callback` internally', 1, function() { | function Foo() { | |
if (!isModularize) { | this.a = 1; | |
_.callback = getSum; | this.c = 3; | |
strictEqual(_.reduceRight(objects, undefined, 0), 2); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | } | |
}); | Foo.prototype.b = 2; | |
test('`_.reject` should use `_.callback` internally', 1, function() { | ||
if (!isModularize) { | ||
var objects = [{ 'a': 0 }, { 'a': 1 }]; | ||
_.callback = getPropA; | assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 }); | |
deepEqual(_.reject(objects), [objects[0]]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.remove` should use `_.callback` internally', 1, function() { | QUnit.test('should accept a falsey `prototype` argument', function(assert) { | |
if (!isModularize) { | assert.expect(1); | |
var objects = [{ 'a': 0 }, { 'a': 1 }]; | ||
_.callback = getPropA; | var expected = lodashStable.map(falsey, alwaysEmptyObject); | |
_.remove(objects); | ||
deepEqual(objects, [{ 'a': 0 }]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.some` should use `_.callback` internally', 1, function() { | var actual = lodashStable.map(falsey, function(prototype, index) { | |
if (!isModularize) { | return index ? _.create(prototype) : _.create(); | |
_.callback = getPropB; | }); | |
strictEqual(_.some(objects), true); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.sortBy` should use `_.callback` internally', 1, function() { | assert.deepEqual(actual, expected); | |
if (!isModularize) { | ||
_.callback = getPropA; | ||
deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], | ||
objects[1]]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.sortedIndex` should use `_.callback` internally', 1, function() { | QUnit.test('should ignore primitive `prototype` arguments and use an empty o | |
if (!isModularize) { | bject instead', function(assert) { | |
var objects = [{ 'a': 30 }, { 'a': 50 }]; | assert.expect(1); | |
_.callback = getPropA; | ||
strictEqual(_.sortedIndex(objects, { 'a': 40 }), 1); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.sortedLastIndex` should use `_.callback` internally', 1, function() | var primitives = [true, null, 1, 'a', undefined], | |
{ | expected = lodashStable.map(primitives, alwaysTrue); | |
if (!isModularize) { | ||
var objects = [{ 'a': 30 }, { 'a': 50 }]; | ||
_.callback = getPropA; | var actual = lodashStable.map(primitives, function(value, index) { | |
strictEqual(_.sortedLastIndex(objects, { 'a': 40 }), 1); | return lodashStable.isPlainObject(index ? _.create(value) : _.create()); | |
_.callback = callback; | }); | |
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.takeRightWhile` should use `_.callback` internally', 1, function() | assert.deepEqual(actual, expected); | |
{ | ||
if (!isModularize) { | ||
_.callback = getPropB; | ||
deepEqual(_.takeRightWhile(objects), objects.slice(2)); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
test('`_.takeWhile` should use `_.callback` internally', 1, function() { | QUnit.test('should work as an iteratee for methods like `_.map`', function(a | |
if (!isModularize) { | ssert) { | |
_.callback = getPropB; | assert.expect(1); | |
deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2)); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.transform` should use `_.callback` internally', 1, function() { | var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }], | |
if (!isModularize) { | expected = lodashStable.map(array, alwaysTrue), | |
_.callback = function() { | objects = lodashStable.map(array, _.create); | |
return function(result, object) { | ||
result.sum += object.a; | ||
}; | ||
}; | ||
deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 }); | var actual = lodashStable.map(objects, function(object) { | |
_.callback = callback; | return object.a === 1 && !_.keys(object).length; | |
} | }); | |
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('`_.uniq` should use `_.callback` internally', 1, function() { | assert.deepEqual(actual, expected); | |
if (!isModularize) { | ||
_.callback = getPropB; | ||
deepEqual(_.uniq(objects), [objects[0], objects[2]]); | ||
_.callback = callback; | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.curry'); | QUnit.module('lodash.curry'); | |
(function() { | (function() { | |
function fn(a, b, c, d) { | function fn(a, b, c, d) { | |
return slice.call(arguments); | return slice.call(arguments); | |
} | } | |
test('should curry based on the number of arguments provided', 3, function() | QUnit.test('should curry based on the number of arguments provided', functio | |
{ | n(assert) { | |
assert.expect(3); | ||
var curried = _.curry(fn), | var curried = _.curry(fn), | |
expected = [1, 2, 3, 4]; | expected = [1, 2, 3, 4]; | |
deepEqual(curried(1)(2)(3)(4), expected); | assert.deepEqual(curried(1)(2)(3)(4), expected); | |
deepEqual(curried(1, 2)(3, 4), expected); | assert.deepEqual(curried(1, 2)(3, 4), expected); | |
deepEqual(curried(1, 2, 3, 4), expected); | assert.deepEqual(curried(1, 2, 3, 4), expected); | |
}); | }); | |
test('should allow specifying `arity`', 3, function() { | QUnit.test('should allow specifying `arity`', function(assert) { | |
assert.expect(3); | ||
var curried = _.curry(fn, 3), | var curried = _.curry(fn, 3), | |
expected = [1, 2, 3]; | expected = [1, 2, 3]; | |
deepEqual(curried(1)(2, 3), expected); | assert.deepEqual(curried(1)(2, 3), expected); | |
deepEqual(curried(1, 2)(3), expected); | assert.deepEqual(curried(1, 2)(3), expected); | |
deepEqual(curried(1, 2, 3), expected); | assert.deepEqual(curried(1, 2, 3), expected); | |
}); | }); | |
test('should coerce `arity` to a number', 2, function() { | QUnit.test('should coerce `arity` to an integer', function(assert) { | |
var values = ['0', 'xyz'], | assert.expect(2); | |
expected = _.map(values, _.constant([])); | ||
var values = ['0', 0.6, 'xyz'], | ||
expected = lodashStable.map(values, alwaysEmptyArray); | ||
var actual = _.map(values, function(arity) { | var actual = lodashStable.map(values, function(arity) { | |
return _.curry(fn, arity)(); | return _.curry(fn, arity)(); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
deepEqual(_.curry(fn, '2')(1)(2), [1, 2]); | assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]); | |
}); | }); | |
test('should support placeholders', 4, function() { | QUnit.test('should support placeholders', function(assert) { | |
assert.expect(4); | ||
var curried = _.curry(fn), | var curried = _.curry(fn), | |
ph = curried.placeholder; | ph = curried.placeholder; | |
deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]); | assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]); | |
deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]); | assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]); | |
deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]); | assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]); | |
deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]); | assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4] | |
); | ||
}); | }); | |
test('should work with partialed methods', 2, function() { | QUnit.test('should provide additional arguments after reaching the target ar | |
var curried = _.curry(fn), | ity', function(assert) { | |
expected = [1, 2, 3, 4]; | assert.expect(3); | |
var a = _.partial(curried, 1), | ||
b = _.bind(a, null, 2), | ||
c = _.partialRight(b, 4), | ||
d = _.partialRight(b(3), 4); | ||
deepEqual(c(3), expected); | ||
deepEqual(d(), expected); | ||
}); | ||
test('should provide additional arguments after reaching the target arity', | ||
3, function() { | ||
var curried = _.curry(fn, 3); | var curried = _.curry(fn, 3); | |
deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]); | assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]); | |
deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]); | assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]); | |
deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); | assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); | |
}); | }); | |
test('should return a function with a `length` of `0`', 6, function() { | QUnit.test('should return a function with a `length` of `0`', function(asser | |
_.times(2, function(index) { | t) { | |
assert.expect(6); | ||
lodashStable.times(2, function(index) { | ||
var curried = index ? _.curry(fn, 4) : _.curry(fn); | var curried = index ? _.curry(fn, 4) : _.curry(fn); | |
strictEqual(curried.length, 0); | assert.strictEqual(curried.length, 0); | |
strictEqual(curried(1).length, 0); | assert.strictEqual(curried(1).length, 0); | |
strictEqual(curried(1, 2).length, 0); | assert.strictEqual(curried(1, 2).length, 0); | |
}); | }); | |
}); | }); | |
test('ensure `new curried` is an instance of `func`', 2, function() { | QUnit.test('should ensure `new curried` is an instance of `func`', function( | |
assert) { | ||
assert.expect(2); | ||
var Foo = function(value) { | var Foo = function(value) { | |
return value && object; | return value && object; | |
}; | }; | |
var curried = _.curry(Foo), | var curried = _.curry(Foo), | |
object = {}; | object = {}; | |
ok(new curried(false) instanceof Foo); | assert.ok(new curried(false) instanceof Foo); | |
strictEqual(new curried(true), object); | assert.strictEqual(new curried(true), object); | |
}); | }); | |
test('should not set a `this` binding', 9, function() { | QUnit.test('should not set a `this` binding', function(assert) { | |
assert.expect(9); | ||
var fn = function(a, b, c) { | var fn = function(a, b, c) { | |
var value = this || {}; | var value = this || {}; | |
return [value[a], value[b], value[c]]; | return [value[a], value[b], value[c]]; | |
}; | }; | |
var object = { 'a': 1, 'b': 2, 'c': 3 }, | var object = { 'a': 1, 'b': 2, 'c': 3 }, | |
expected = [1, 2, 3]; | expected = [1, 2, 3]; | |
deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected); | assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected); | |
deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected); | assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected); | |
deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected); | assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected); | |
deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3)); | assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3)); | |
deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3)); | assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3)); | |
deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected); | assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected); | |
object.curried = _.curry(fn); | object.curried = _.curry(fn); | |
deepEqual(object.curried('a')('b')('c'), Array(3)); | assert.deepEqual(object.curried('a')('b')('c'), Array(3)); | |
deepEqual(object.curried('a', 'b')('c'), Array(3)); | assert.deepEqual(object.curried('a', 'b')('c'), Array(3)); | |
deepEqual(object.curried('a', 'b', 'c'), expected); | assert.deepEqual(object.curried('a', 'b', 'c'), expected); | |
}); | ||
QUnit.test('should work with partialed methods', function(assert) { | ||
assert.expect(2); | ||
var curried = _.curry(fn), | ||
expected = [1, 2, 3, 4]; | ||
var a = _.partial(curried, 1), | ||
b = _.bind(a, null, 2), | ||
c = _.partialRight(b, 4), | ||
d = _.partialRight(b(3), 4); | ||
assert.deepEqual(c(3), expected); | ||
assert.deepEqual(d(), expected); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.curryRight'); | QUnit.module('lodash.curryRight'); | |
(function() { | (function() { | |
function fn(a, b, c, d) { | function fn(a, b, c, d) { | |
return slice.call(arguments); | return slice.call(arguments); | |
} | } | |
test('should curry based on the number of arguments provided', 3, function() | QUnit.test('should curry based on the number of arguments provided', functio | |
{ | n(assert) { | |
assert.expect(3); | ||
var curried = _.curryRight(fn), | var curried = _.curryRight(fn), | |
expected = [1, 2, 3, 4]; | expected = [1, 2, 3, 4]; | |
deepEqual(curried(4)(3)(2)(1), expected); | assert.deepEqual(curried(4)(3)(2)(1), expected); | |
deepEqual(curried(3, 4)(1, 2), expected); | assert.deepEqual(curried(3, 4)(1, 2), expected); | |
deepEqual(curried(1, 2, 3, 4), expected); | assert.deepEqual(curried(1, 2, 3, 4), expected); | |
}); | }); | |
test('should allow specifying `arity`', 3, function() { | QUnit.test('should allow specifying `arity`', function(assert) { | |
assert.expect(3); | ||
var curried = _.curryRight(fn, 3), | var curried = _.curryRight(fn, 3), | |
expected = [1, 2, 3]; | expected = [1, 2, 3]; | |
deepEqual(curried(3)(1, 2), expected); | assert.deepEqual(curried(3)(1, 2), expected); | |
deepEqual(curried(2, 3)(1), expected); | assert.deepEqual(curried(2, 3)(1), expected); | |
deepEqual(curried(1, 2, 3), expected); | assert.deepEqual(curried(1, 2, 3), expected); | |
}); | }); | |
test('should work with partialed methods', 2, function() { | QUnit.test('should coerce `arity` to an integer', function(assert) { | |
var curried = _.curryRight(fn), | assert.expect(2); | |
expected = [1, 2, 3, 4]; | ||
var a = _.partialRight(curried, 4), | var values = ['0', 0.6, 'xyz'], | |
b = _.partialRight(a, 3), | expected = lodashStable.map(values, alwaysEmptyArray); | |
c = _.bind(b, null, 1), | ||
d = _.partial(b(2), 1); | ||
deepEqual(c(2), expected); | var actual = lodashStable.map(values, function(arity) { | |
deepEqual(d(), expected); | return _.curryRight(fn, arity)(); | |
}); | ||
assert.deepEqual(actual, expected); | ||
assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]); | ||
}); | }); | |
test('should support placeholders', 4, function() { | QUnit.test('should support placeholders', function(assert) { | |
assert.expect(4); | ||
var curried = _.curryRight(fn), | var curried = _.curryRight(fn), | |
expected = [1, 2, 3, 4], | expected = [1, 2, 3, 4], | |
ph = curried.placeholder; | ph = curried.placeholder; | |
deepEqual(curried(4)(2, ph)(1, ph)(3), expected); | assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected); | |
deepEqual(curried(3, ph)(4)(1, ph)(2), expected); | assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected); | |
deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected); | assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected); | |
deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected); | assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected); | |
}); | }); | |
test('should provide additional arguments after reaching the target arity', | QUnit.test('should provide additional arguments after reaching the target ar | |
3, function() { | ity', function(assert) { | |
assert.expect(3); | ||
var curried = _.curryRight(fn, 3); | var curried = _.curryRight(fn, 3); | |
deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]); | assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]); | |
deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]); | assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]); | |
deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); | assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); | |
}); | }); | |
test('should return a function with a `length` of `0`', 6, function() { | QUnit.test('should return a function with a `length` of `0`', function(asser | |
_.times(2, function(index) { | t) { | |
assert.expect(6); | ||
lodashStable.times(2, function(index) { | ||
var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn); | var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn); | |
strictEqual(curried.length, 0); | assert.strictEqual(curried.length, 0); | |
strictEqual(curried(4).length, 0); | assert.strictEqual(curried(4).length, 0); | |
strictEqual(curried(3, 4).length, 0); | assert.strictEqual(curried(3, 4).length, 0); | |
}); | }); | |
}); | }); | |
test('ensure `new curried` is an instance of `func`', 2, function() { | QUnit.test('should ensure `new curried` is an instance of `func`', function( | |
assert) { | ||
assert.expect(2); | ||
var Foo = function(value) { | var Foo = function(value) { | |
return value && object; | return value && object; | |
}; | }; | |
var curried = _.curryRight(Foo), | var curried = _.curryRight(Foo), | |
object = {}; | object = {}; | |
ok(new curried(false) instanceof Foo); | assert.ok(new curried(false) instanceof Foo); | |
strictEqual(new curried(true), object); | assert.strictEqual(new curried(true), object); | |
}); | }); | |
test('should not set a `this` binding', 9, function() { | QUnit.test('should not set a `this` binding', function(assert) { | |
assert.expect(9); | ||
var fn = function(a, b, c) { | var fn = function(a, b, c) { | |
var value = this || {}; | var value = this || {}; | |
return [value[a], value[b], value[c]]; | return [value[a], value[b], value[c]]; | |
}; | }; | |
var object = { 'a': 1, 'b': 2, 'c': 3 }, | var object = { 'a': 1, 'b': 2, 'c': 3 }, | |
expected = [1, 2, 3]; | expected = [1, 2, 3]; | |
deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected); | assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expec | |
deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected); | ted); | |
deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected); | assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expec | |
ted); | ||
deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3)); | assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expec | |
deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3)); | ted); | |
deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected); | ||
assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3) | ||
); | ||
assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3) | ||
); | ||
assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected | ||
); | ||
object.curried = _.curryRight(fn); | object.curried = _.curryRight(fn); | |
deepEqual(object.curried('c')('b')('a'), Array(3)); | assert.deepEqual(object.curried('c')('b')('a'), Array(3)); | |
deepEqual(object.curried('b', 'c')('a'), Array(3)); | assert.deepEqual(object.curried('b', 'c')('a'), Array(3)); | |
deepEqual(object.curried('a', 'b', 'c'), expected); | assert.deepEqual(object.curried('a', 'b', 'c'), expected); | |
}); | ||
QUnit.test('should work with partialed methods', function(assert) { | ||
assert.expect(2); | ||
var curried = _.curryRight(fn), | ||
expected = [1, 2, 3, 4]; | ||
var a = _.partialRight(curried, 4), | ||
b = _.partialRight(a, 3), | ||
c = _.bind(b, null, 1), | ||
d = _.partial(b(2), 1); | ||
assert.deepEqual(c(2), expected); | ||
assert.deepEqual(d(), expected); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('curry methods'); | QUnit.module('curry methods'); | |
_.each(['curry', 'curryRight'], function(methodName) { | lodashStable.each(['curry', 'curryRight'], function(methodName) { | |
var func = _[methodName]; | var func = _[methodName], | |
fn = function(a, b) { return slice.call(arguments); }, | ||
isCurry = methodName == 'curry'; | ||
test('`_.' + methodName + '` should work as an iteratee for `_.map`', 1, fun | QUnit.test('`_.' + methodName + '` should not error on functions with the sa | |
ction() { | me name as lodash methods', function(assert) { | |
var array = [_.identity, _.identity, _.identity], | assert.expect(1); | |
curries = _.map(array, func); | ||
var actual = _.map(curries, function(curried, index) { | function run(a, b) { | |
return curried(index); | return a + b; | |
}); | } | |
deepEqual(actual, [0, 1, 2]); | var curried = func(run); | |
try { | ||
var actual = curried(1)(2); | ||
} catch (e) {} | ||
assert.strictEqual(actual, 3); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should work as an iteratee for methods li | ||
ke `_.map`', function(assert) { | ||
assert.expect(2); | ||
var array = [fn, fn, fn], | ||
object = { 'a': fn, 'b': fn, 'c': fn }; | ||
lodashStable.each([array, object], function(collection) { | ||
var curries = lodashStable.map(collection, func), | ||
expected = lodashStable.map(collection, lodashStable.constant(isCurr | ||
y ? ['a', 'b'] : ['b', 'a'])); | ||
var actual = lodashStable.map(curries, function(curried) { | ||
return curried('a')('b'); | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | ||
}); | }); | |
}); | }); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.debounce'); | QUnit.module('lodash.debounce'); | |
(function() { | (function() { | |
asyncTest('should debounce a function', 2, function() { | QUnit.test('should debounce a function', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var count = 0, | ||
debounced = _.debounce(function() { count++; }, 32); | ||
debounced(); | var done = assert.async(); | |
debounced(); | ||
debounced(); | ||
strictEqual(count, 0); | var callCount = 0, | |
debounced = _.debounce(function() { callCount++; }, 32); | ||
setTimeout(function() { | debounced(); | |
strictEqual(count, 1); | debounced(); | |
QUnit.start(); | debounced(); | |
}, 96); | ||
} | assert.strictEqual(callCount, 0); | |
else { | ||
skipTest(2); | setTimeout(function() { | |
QUnit.start(); | assert.strictEqual(callCount, 1); | |
} | done(); | |
}, 96); | ||
}); | }); | |
asyncTest('subsequent debounced calls return the last `func` result', 2, fun | QUnit.test('subsequent debounced calls return the last `func` result', funct | |
ction() { | ion(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var debounced = _.debounce(_.identity, 32); | ||
debounced('x'); | ||
setTimeout(function() { | var done = assert.async(); | |
notEqual(debounced('y'), 'y'); | ||
}, 64); | ||
setTimeout(function() { | var debounced = _.debounce(identity, 32); | |
notEqual(debounced('z'), 'z'); | debounced('x'); | |
QUnit.start(); | ||
}, 128); | setTimeout(function() { | |
} | assert.notEqual(debounced('y'), 'y'); | |
else { | }, 64); | |
skipTest(2); | ||
QUnit.start(); | setTimeout(function() { | |
} | assert.notEqual(debounced('z'), 'z'); | |
done(); | ||
}, 128); | ||
}); | }); | |
asyncTest('subsequent "immediate" debounced calls return the last `func` res | QUnit.test('subsequent "immediate" debounced calls return the last `func` re | |
ult', 2, function() { | sult', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var debounced = _.debounce(_.identity, 32, true), | ||
result = [debounced('x'), debounced('y')]; | ||
deepEqual(result, ['x', 'x']); | var done = assert.async(); | |
setTimeout(function() { | var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': fa | |
var result = [debounced('a'), debounced('b')]; | lse }), | |
deepEqual(result, ['a', 'a']); | result = [debounced('x'), debounced('y')]; | |
QUnit.start(); | ||
}, 64); | assert.deepEqual(result, ['x', 'x']); | |
} | ||
else { | setTimeout(function() { | |
skipTest(2); | var result = [debounced('a'), debounced('b')]; | |
QUnit.start(); | assert.deepEqual(result, ['a', 'a']); | |
} | done(); | |
}, 64); | ||
}); | }); | |
asyncTest('should apply default options correctly', 2, function() { | QUnit.test('should apply default options', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var count = 0; | ||
var debounced = _.debounce(function(value) { | var done = assert.async(); | |
count++; | ||
return value; | ||
}, 32, {}); | ||
strictEqual(debounced('x'), undefined); | var callCount = 0; | |
setTimeout(function() { | var debounced = _.debounce(function(value) { | |
strictEqual(count, 1); | callCount++; | |
QUnit.start(); | return value; | |
}, 64); | }, 32, {}); | |
} | ||
else { | assert.strictEqual(debounced('a'), undefined); | |
skipTest(2); | ||
QUnit.start(); | setTimeout(function() { | |
} | assert.strictEqual(callCount, 1); | |
done(); | ||
}, 64); | ||
}); | }); | |
asyncTest('should support a `leading` option', 7, function() { | QUnit.test('should support a `leading` option', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(5); | |
var withLeading, | ||
counts = [0, 0, 0]; | ||
_.each([true, { 'leading': true }], function(options, index) { | var done = assert.async(); | |
var debounced = _.debounce(function(value) { | ||
counts[index]++; | ||
return value; | ||
}, 32, options); | ||
if (index == 1) { | var callCounts = [0, 0]; | |
withLeading = debounced; | ||
} | ||
strictEqual(debounced('x'), 'x'); | ||
}); | ||
_.each([false, { 'leading': false }], function(options) { | var withLeading = _.debounce(function(value) { | |
var withoutLeading = _.debounce(_.identity, 32, options); | callCounts[0]++; | |
strictEqual(withoutLeading('x'), undefined); | return value; | |
}); | }, 32, { 'leading': true }); | |
var withLeadingAndTrailing = _.debounce(function() { | assert.strictEqual(withLeading('a'), 'a'); | |
counts[2]++; | ||
}, 32, { 'leading': true }); | ||
withLeadingAndTrailing(); | var withoutLeading = _.debounce(identity, 32, { 'leading': false }); | |
withLeadingAndTrailing(); | assert.strictEqual(withoutLeading('a'), undefined); | |
strictEqual(counts[2], 1); | var withLeadingAndTrailing = _.debounce(function() { | |
callCounts[1]++; | ||
}, 32, { 'leading': true }); | ||
setTimeout(function() { | withLeadingAndTrailing(); | |
deepEqual(counts, [1, 1, 2]); | withLeadingAndTrailing(); | |
withLeading('x'); | assert.strictEqual(callCounts[1], 1); | |
strictEqual(counts[1], 2); | ||
QUnit.start(); | setTimeout(function() { | |
}, 64); | assert.deepEqual(callCounts, [1, 2]); | |
} | ||
else { | withLeading('a'); | |
skipTest(7); | assert.strictEqual(callCounts[0], 2); | |
QUnit.start(); | ||
} | done(); | |
}, 64); | ||
}); | }); | |
asyncTest('should support a `trailing` option', 4, function() { | QUnit.test('should support a `trailing` option', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(4); | |
var withCount = 0, | ||
withoutCount = 0; | ||
var withTrailing = _.debounce(function(value) { | var done = assert.async(); | |
withCount++; | ||
return value; | ||
}, 32, { 'trailing': true }); | ||
var withoutTrailing = _.debounce(function(value) { | var withCount = 0, | |
withoutCount++; | withoutCount = 0; | |
return value; | ||
}, 32, { 'trailing': false }); | ||
strictEqual(withTrailing('x'), undefined); | var withTrailing = _.debounce(function(value) { | |
strictEqual(withoutTrailing('x'), undefined); | withCount++; | |
return value; | ||
}, 32, { 'trailing': true }); | ||
setTimeout(function() { | var withoutTrailing = _.debounce(function(value) { | |
strictEqual(withCount, 1); | withoutCount++; | |
strictEqual(withoutCount, 0); | return value; | |
QUnit.start(); | }, 32, { 'trailing': false }); | |
}, 64); | ||
} | assert.strictEqual(withTrailing('a'), undefined); | |
else { | assert.strictEqual(withoutTrailing('a'), undefined); | |
skipTest(4); | ||
QUnit.start(); | setTimeout(function() { | |
} | assert.strictEqual(withCount, 1); | |
assert.strictEqual(withoutCount, 0); | ||
done(); | ||
}, 64); | ||
}); | }); | |
asyncTest('should support a `maxWait` option', 1, function() { | QUnit.test('should support a `maxWait` option', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(1); | |
var limit = (argv || isPhantom) ? 1000 : 320, | ||
withCount = 0, | ||
withoutCount = 0; | ||
var withMaxWait = _.debounce(function() { | var done = assert.async(); | |
withCount++; | ||
}, 64, { 'maxWait': 128 }); | ||
var withoutMaxWait = _.debounce(function() { | var limit = (argv || isPhantom) ? 1000 : 320, | |
withoutCount++; | withCount = 0, | |
}, 96); | withoutCount = 0; | |
var start = +new Date; | var withMaxWait = _.debounce(function() { | |
while ((new Date - start) < limit) { | withCount++; | |
withMaxWait(); | }, 64, { 'maxWait': 128 }); | |
withoutMaxWait(); | ||
} | ||
var actual = [Boolean(withCount), Boolean(withoutCount)]; | ||
setTimeout(function() { | var withoutMaxWait = _.debounce(function() { | |
deepEqual(actual, [true, false]); | withoutCount++; | |
QUnit.start(); | }, 96); | |
}, 1); | ||
} | var start = +new Date; | |
else { | while ((new Date - start) < limit) { | |
skipTest(); | withMaxWait(); | |
QUnit.start(); | withoutMaxWait(); | |
} | } | |
var actual = [Boolean(withCount), Boolean(withoutCount)]; | ||
setTimeout(function() { | ||
assert.deepEqual(actual, [true, false]); | ||
done(); | ||
}, 1); | ||
}); | }); | |
asyncTest('should cancel `maxDelayed` when `delayed` is invoked', 1, functio | QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function( | |
n() { | assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(1); | |
var count = 0; | ||
var debounced = _.debounce(function() { | var done = assert.async(); | |
count++; | ||
}, 32, { 'maxWait': 64 }); | ||
debounced(); | var callCount = 0; | |
setTimeout(function() { | var debounced = _.debounce(function() { | |
strictEqual(count, 1); | callCount++; | |
QUnit.start(); | }, 32, { 'maxWait': 64 }); | |
}, 128); | ||
} | debounced(); | |
else { | ||
skipTest(); | setTimeout(function() { | |
QUnit.start(); | assert.strictEqual(callCount, 1); | |
} | done(); | |
}, 128); | ||
}); | }); | |
asyncTest('should invoke the `trailing` call with the correct arguments and | QUnit.test('should invoke the `trailing` call with the correct arguments and | |
`this` binding', 2, function() { | `this` binding', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var actual, | ||
count = 0, | ||
object = {}; | ||
var debounced = _.debounce(function(value) { | var done = assert.async(); | |
actual = [this]; | ||
push.apply(actual, arguments); | ||
return ++count != 2; | ||
}, 32, { 'leading': true, 'maxWait': 64 }); | ||
while (true) { | var actual, | |
if (!debounced.call(object, 'a')) { | callCount = 0, | |
break; | object = {}; | |
} | ||
} | var debounced = _.debounce(function(value) { | |
setTimeout(function() { | actual = [this]; | |
strictEqual(count, 2); | push.apply(actual, arguments); | |
deepEqual(actual, [object, 'a']); | return ++callCount != 2; | |
QUnit.start(); | }, 32, { 'leading': true, 'maxWait': 64 }); | |
}, 64); | ||
} | while (true) { | |
else { | if (!debounced.call(object, 'a')) { | |
skipTest(2); | break; | |
QUnit.start(); | } | |
} | } | |
setTimeout(function() { | ||
assert.strictEqual(callCount, 2); | ||
assert.deepEqual(actual, [object, 'a']); | ||
done(); | ||
}, 64); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.deburr'); | QUnit.module('lodash.deburr'); | |
(function() { | (function() { | |
test('should convert latin-1 supplementary letters to basic latin', 1, funct | QUnit.test('should convert latin-1 supplementary letters to basic latin', fu | |
ion() { | nction(assert) { | |
var actual = _.map(burredLetters, _.deburr); | assert.expect(1); | |
deepEqual(actual, deburredLetters); | ||
var actual = lodashStable.map(burredLetters, _.deburr); | ||
assert.deepEqual(actual, deburredLetters); | ||
}); | }); | |
test('should not deburr latin-1 mathematical operators', 1, function() { | QUnit.test('should not deburr latin-1 mathematical operators', function(asse | |
rt) { | ||
assert.expect(1); | ||
var operators = ['\xd7', '\xf7'], | var operators = ['\xd7', '\xf7'], | |
actual = _.map(operators, _.deburr); | actual = lodashStable.map(operators, _.deburr); | |
deepEqual(actual, operators); | assert.deepEqual(actual, operators); | |
}); | ||
QUnit.test('should deburr combining diacritical marks', function(assert) { | ||
assert.expect(1); | ||
var expected = lodashStable.map(comboMarks, lodashStable.constant('ei')); | ||
var actual = lodashStable.map(comboMarks, function(chr) { | ||
return _.deburr('e' + chr + 'i'); | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.defaults'); | QUnit.module('lodash.defaults'); | |
(function() { | (function() { | |
test('should assign properties of a source object if missing on the destinat | QUnit.test('should assign source properties if missing on `object`', functio | |
ion object', 1, function() { | n(assert) { | |
deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 }); | assert.expect(1); | |
assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b' | ||
: 2 }); | ||
}); | }); | |
test('should accept multiple source objects', 2, function() { | QUnit.test('should accept multiple sources', function(assert) { | |
assert.expect(2); | ||
var expected = { 'a': 1, 'b': 2, 'c': 3 }; | var expected = { 'a': 1, 'b': 2, 'c': 3 }; | |
deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected | assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), e | |
); | xpected); | |
deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), | assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': | |
expected); | 2 }), expected); | |
}); | }); | |
test('should not overwrite `null` values', 1, function() { | QUnit.test('should not overwrite `null` values', function(assert) { | |
assert.expect(1); | ||
var actual = _.defaults({ 'a': null }, { 'a': 1 }); | var actual = _.defaults({ 'a': null }, { 'a': 1 }); | |
strictEqual(actual.a, null); | assert.strictEqual(actual.a, null); | |
}); | }); | |
test('should overwrite `undefined` values', 1, function() { | QUnit.test('should overwrite `undefined` values', function(assert) { | |
assert.expect(1); | ||
var actual = _.defaults({ 'a': undefined }, { 'a': 1 }); | var actual = _.defaults({ 'a': undefined }, { 'a': 1 }); | |
strictEqual(actual.a, 1); | assert.strictEqual(actual.a, 1); | |
}); | ||
QUnit.test('should assign properties that shadow those on `Object.prototype` | ||
', function(assert) { | ||
assert.expect(2); | ||
var object = { | ||
'constructor': objectProto.constructor, | ||
'hasOwnProperty': objectProto.hasOwnProperty, | ||
'isPrototypeOf': objectProto.isPrototypeOf, | ||
'propertyIsEnumerable': objectProto.propertyIsEnumerable, | ||
'toLocaleString': objectProto.toLocaleString, | ||
'toString': objectProto.toString, | ||
'valueOf': objectProto.valueOf | ||
}; | ||
var source = { | ||
'constructor': 1, | ||
'hasOwnProperty': 2, | ||
'isPrototypeOf': 3, | ||
'propertyIsEnumerable': 4, | ||
'toLocaleString': 5, | ||
'toString': 6, | ||
'valueOf': 7 | ||
}; | ||
assert.deepEqual(_.defaults({}, source), source); | ||
assert.deepEqual(_.defaults({}, object, source), object); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.defaultsDeep'); | ||
(function() { | ||
QUnit.test('should deep assign source properties if missing on `object`', fu | ||
nction(assert) { | ||
assert.expect(1); | ||
var object = { 'a': { 'b': 2 }, 'd': 4 }, | ||
source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 }, | ||
expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 }; | ||
assert.deepEqual(_.defaultsDeep(object, source), expected); | ||
}); | ||
QUnit.test('should accept multiple sources', function(assert) { | ||
assert.expect(2); | ||
var source1 = { 'a': { 'b': 3 } }, | ||
source2 = { 'a': { 'c': 3 } }, | ||
source3 = { 'a': { 'b': 3, 'c': 3 } }, | ||
source4 = { 'a': { 'c': 4 } }, | ||
expected = { 'a': { 'b': 2, 'c': 3 } }; | ||
assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), ex | ||
pected); | ||
assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), ex | ||
pected); | ||
}); | ||
QUnit.test('should not overwrite `null` values', function(assert) { | ||
assert.expect(1); | ||
var object = { 'a': { 'b': null } }, | ||
source = { 'a': { 'b': 2 } }, | ||
actual = _.defaultsDeep(object, source); | ||
assert.strictEqual(actual.a.b, null); | ||
}); | ||
QUnit.test('should overwrite `undefined` values', function(assert) { | ||
assert.expect(1); | ||
var object = { 'a': { 'b': undefined } }, | ||
source = { 'a': { 'b': 2 } }, | ||
actual = _.defaultsDeep(object, source); | ||
assert.strictEqual(actual.a.b, 2); | ||
}); | ||
QUnit.test('should merge sources containing circular references', function(a | ||
ssert) { | ||
assert.expect(1); | ||
var object = { | ||
'foo': { 'b': { 'c': { 'd': {} } } }, | ||
'bar': { 'a': 2 } | ||
}; | ||
var source = { | ||
'foo': { 'b': { 'c': { 'd': {} } } }, | ||
'bar': {} | ||
}; | ||
object.foo.b.c.d = object; | ||
source.foo.b.c.d = source; | ||
source.bar.b = source.foo.b; | ||
var actual = _.defaultsDeep(object, source); | ||
assert.ok(actual.bar.b === actual.foo.b && actual.foo.b.c.d === actual.foo | ||
.b.c.d.foo.b.c.d); | ||
}); | ||
QUnit.test('should not modify sources', function(assert) { | ||
assert.expect(3); | ||
var source1 = { 'a': 1, 'b': { 'c': 2 } }, | ||
source2 = { 'b': { 'c': 3, 'd': 3 } }, | ||
actual = _.defaultsDeep({}, source1, source2); | ||
assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } }); | ||
assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } }); | ||
assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } }); | ||
}); | ||
QUnit.test('should not attempt a merge of a string into an array', function( | ||
assert) { | ||
assert.expect(1); | ||
var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' }); | ||
assert.deepEqual(actual, { 'a': ['abc'] }); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.defer'); | QUnit.module('lodash.defer'); | |
(function() { | (function() { | |
asyncTest('should defer `func` execution', 1, function() { | QUnit.test('should defer `func` execution', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(1); | |
var pass = false; | ||
_.defer(function() { pass = true; }); | ||
setTimeout(function() { | var done = assert.async(); | |
ok(pass); | ||
QUnit.start(); | var pass = false; | |
}, 128); | _.defer(function() { pass = true; }); | |
} | ||
else { | setTimeout(function() { | |
skipTest(); | assert.ok(pass); | |
QUnit.start(); | done(); | |
} | }, 32); | |
}); | }); | |
asyncTest('should accept additional arguments', 1, function() { | QUnit.test('should provide additional arguments to `func`', function(assert) | |
if (!(isRhino && isModularize)) { | { | |
var args; | assert.expect(1); | |
_.defer(function() { | var done = assert.async(); | |
args = slice.call(arguments); | ||
}, 1, 2, 3); | ||
setTimeout(function() { | var args; | |
deepEqual(args, [1, 2, 3]); | ||
QUnit.start(); | _.defer(function() { | |
}, 128); | args = slice.call(arguments); | |
} | }, 1, 2); | |
else { | ||
skipTest(); | setTimeout(function() { | |
QUnit.start(); | assert.deepEqual(args, [1, 2]); | |
} | done(); | |
}, 32); | ||
}); | }); | |
asyncTest('should be cancelable', 1, function() { | QUnit.test('should be cancelable', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(1); | |
var pass = true; | ||
var timerId = _.defer(function() { | var done = assert.async(); | |
pass = false; | ||
}); | ||
clearTimeout(timerId); | var pass = true; | |
setTimeout(function() { | var timerId = _.defer(function() { | |
ok(pass); | pass = false; | |
QUnit.start(); | }); | |
}, 128); | ||
} | clearTimeout(timerId); | |
else { | ||
skipTest(); | setTimeout(function() { | |
QUnit.start(); | assert.ok(pass); | |
} | done(); | |
}, 32); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.delay'); | QUnit.module('lodash.delay'); | |
(function() { | (function() { | |
asyncTest('should delay `func` execution', 2, function() { | QUnit.test('should delay `func` execution', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var pass = false; | ||
_.delay(function() { pass = true; }, 96); | ||
setTimeout(function() { | var done = assert.async(); | |
ok(!pass); | ||
}, 32); | ||
setTimeout(function() { | var pass = false; | |
ok(pass); | _.delay(function() { pass = true; }, 32); | |
QUnit.start(); | ||
}, 160); | setTimeout(function() { | |
} | assert.notOk(pass); | |
else { | }, 1); | |
skipTest(2); | ||
QUnit.start(); | setTimeout(function() { | |
} | assert.ok(pass); | |
done(); | ||
}, 64); | ||
}); | }); | |
asyncTest('should accept additional arguments', 1, function() { | QUnit.test('should provide additional arguments to `func`', function(assert) | |
if (!(isRhino && isModularize)) { | { | |
var args; | assert.expect(1); | |
_.delay(function() { | var done = assert.async(); | |
args = slice.call(arguments); | ||
}, 32, 1, 2, 3); | ||
setTimeout(function() { | var args; | |
deepEqual(args, [1, 2, 3]); | ||
QUnit.start(); | _.delay(function() { | |
}, 128); | args = slice.call(arguments); | |
} | }, 32, 1, 2); | |
else { | ||
skipTest(); | setTimeout(function() { | |
QUnit.start(); | assert.deepEqual(args, [1, 2]); | |
} | done(); | |
}, 64); | ||
}); | }); | |
asyncTest('should be cancelable', 1, function() { | QUnit.test('should use a default `wait` of `0`', function(assert) { | |
if (!(isRhino && isModularize)) { | assert.expect(2); | |
var pass = true; | ||
var timerId = _.delay(function() { | var done = assert.async(); | |
pass = false; | ||
}, 32); | ||
clearTimeout(timerId); | var pass = false; | |
setTimeout(function() { | _.delay(function() { | |
ok(pass); | pass = true; | |
QUnit.start(); | }); | |
}, 128); | ||
} | assert.notOk(pass); | |
else { | ||
skipTest(); | setTimeout(function() { | |
QUnit.start(); | assert.ok(pass); | |
} | done(); | |
}, 0); | ||
}); | ||
QUnit.test('should be cancelable', function(assert) { | ||
assert.expect(1); | ||
var done = assert.async(); | ||
var pass = true; | ||
var timerId = _.delay(function() { | ||
pass = false; | ||
}, 32); | ||
clearTimeout(timerId); | ||
setTimeout(function() { | ||
assert.ok(pass); | ||
done(); | ||
}, 64); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.difference'); | QUnit.module('difference methods'); | |
(function() { | lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(m | |
var args = arguments; | ethodName) { | |
var args = (function() { return arguments; }(1, 2, 3)), | ||
func = _[methodName]; | ||
test('should return the difference of the given arrays', 2, function() { | QUnit.test('`_.' + methodName + '` should return the difference of the given | |
var actual = _.difference([1, 2, 3, 4, 5], [5, 2, 10]); | arrays', function(assert) { | |
deepEqual(actual, [1, 3, 4]); | assert.expect(2); | |
actual = _.difference([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]); | var actual = func([1, 2, 3, 4, 5], [5, 2, 10]); | |
deepEqual(actual, [1, 3]); | assert.deepEqual(actual, [1, 3, 4]); | |
actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]); | ||
assert.deepEqual(actual, [1, 3]); | ||
}); | }); | |
test('should match `NaN`', 1, function() { | QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { | |
deepEqual(_.difference([1, NaN, 3], [NaN, 5, NaN]), [1, 3]); | assert.expect(1); | |
assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]); | ||
}); | }); | |
test('should work with large arrays', 1, function() { | QUnit.test('`_.' + methodName + '` should work with large arrays', function( | |
var array1 = _.range(LARGE_ARRAY_SIZE + 1), | assert) { | |
array2 = _.range(LARGE_ARRAY_SIZE), | assert.expect(1); | |
var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1), | ||
array2 = lodashStable.range(LARGE_ARRAY_SIZE), | ||
a = {}, | a = {}, | |
b = {}, | b = {}, | |
c = {}; | c = {}; | |
array1.push(a, b, c); | array1.push(a, b, c); | |
array2.push(b, c, a); | array2.push(b, c, a); | |
deepEqual(_.difference(array1, array2), [LARGE_ARRAY_SIZE]); | assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]); | |
}); | }); | |
test('should work with large arrays of objects', 1, function() { | QUnit.test('`_.' + methodName + '` should work with large arrays of objects' | |
, function(assert) { | ||
assert.expect(1); | ||
var object1 = {}, | var object1 = {}, | |
object2 = {}, | object2 = {}, | |
largeArray = _.times(LARGE_ARRAY_SIZE, _.constant(object1)); | largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constan t(object1)); | |
deepEqual(_.difference([object1, object2], largeArray), [object2]); | assert.deepEqual(func([object1, object2], largeArray), [object2]); | |
}); | }); | |
test('should work with large arrays of `NaN`', 1, function() { | QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', | |
var largeArray = _.times(LARGE_ARRAY_SIZE, _.constant(NaN)); | function(assert) { | |
deepEqual(_.difference([1, NaN, 3], largeArray), [1, 3]); | assert.expect(1); | |
var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN); | ||
assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]); | ||
}); | }); | |
test('should ignore values that are not arrays or `arguments` objects', 3, f | QUnit.test('`_.' + methodName + '` should ignore values that are not array-l | |
unction() { | ike', function(assert) { | |
var array = [0, 1, null, 3]; | assert.expect(3); | |
deepEqual(_.difference(array, 3, null, { '0': 1 }), array); | ||
deepEqual(_.difference(null, array, null, [2, 1]), [0, null, 3]); | var array = [1, null, 3]; | |
deepEqual(_.difference(null, array, null, args), [0, null]); | assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]); | |
assert.deepEqual(func(null, array, 1), []); | ||
assert.deepEqual(func(array, args, null), [null]); | ||
}); | }); | |
}(1, 2, 3)); | }); | |
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.differenceBy'); | ||
(function() { | ||
QUnit.test('should accept an `iteratee` argument', function(assert) { | ||
assert.expect(2); | ||
var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); | ||
assert.deepEqual(actual, [3.1, 1.3]); | ||
actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); | ||
assert.deepEqual(actual, [{ 'x': 2 }]); | ||
}); | ||
QUnit.test('should provide the correct `iteratee` arguments', function(asser | ||
t) { | ||
assert.expect(1); | ||
var args; | ||
_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() { | ||
args || (args = slice.call(arguments)); | ||
}); | ||
assert.deepEqual(args, [4.4]); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.differenceWith'); | ||
(function() { | ||
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; | ||
QUnit.test('should work with a `comparator` argument', function(assert) { | ||
assert.expect(1); | ||
var actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable. | ||
isEqual); | ||
assert.deepEqual(actual, [{ 'x': 2, 'y': 1 }]); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.drop'); | QUnit.module('lodash.drop'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | var array = [1, 2, 3]; | |
test('should drop the first two elements', 1, function() { | QUnit.test('should drop the first two elements', function(assert) { | |
deepEqual(_.drop(array, 2), [3]); | assert.expect(1); | |
assert.deepEqual(_.drop(array, 2), [3]); | ||
}); | }); | |
test('should treat falsey `n` values, except nullish, as `0`', 1, function() | QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', fun | |
{ | ction(assert) { | |
var expected = _.map(falsey, function(value) { | assert.expect(1); | |
return value == null ? [2, 3] : array; | ||
var expected = lodashStable.map(falsey, function(value) { | ||
return value === undefined ? [2, 3] : array; | ||
}); | }); | |
var actual = _.map(falsey, function(n) { | var actual = lodashStable.map(falsey, function(n) { | |
return _.drop(array, n); | return _.drop(array, n); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should return all elements when `n` < `1`', 3, function() { | QUnit.test('should return all elements when `n` < `1`', function(assert) { | |
_.each([0, -1, -Infinity], function(n) { | assert.expect(3); | |
deepEqual(_.drop(array, n), array); | ||
lodashStable.each([0, -1, -Infinity], function(n) { | ||
assert.deepEqual(_.drop(array, n), array); | ||
}); | }); | |
}); | }); | |
test('should return an empty array when `n` >= `array.length`', 4, function( | QUnit.test('should return an empty array when `n` >= `array.length`', functi | |
) { | on(assert) { | |
_.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | assert.expect(4); | |
deepEqual(_.drop(array, n), []); | ||
lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | ||
assert.deepEqual(_.drop(array, n), []); | ||
}); | }); | |
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should coerce `n` to an integer', function(assert) { | |
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | assert.expect(1); | |
actual = _.map(array, _.drop); | ||
deepEqual(actual, [[2, 3], [5, 6], [8, 9]]); | assert.deepEqual(_.drop(array, 1.6), [2, 3]); | |
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should work as an iteratee for methods like `_.map`', function(a | |
if (!isNpm) { | ssert) { | |
var wrapped = _(array).drop(2); | assert.expect(1); | |
ok(wrapped instanceof _); | ||
deepEqual(wrapped.value(), [3]); | var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | |
} | actual = lodashStable.map(array, _.drop); | |
else { | ||
skipTest(2); | assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]); | |
} | ||
}); | }); | |
test('should work in a lazy chain sequence', 4, function() { | QUnit.test('should work in a lazy sequence', function(assert) { | |
assert.expect(6); | ||
if (!isNpm) { | if (!isNpm) { | |
var array = [1, 2, 3, 4, 5, 6, 7, 8], | var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), | |
predicate = function(value) { return value > 1; }, | predicate = function(value) { values.push(value); return isEven(valu | |
e); }, | ||
values = [], | ||
actual = _(array).drop(2).drop().value(); | actual = _(array).drop(2).drop().value(); | |
deepEqual(actual, [4, 5, 6, 7, 8]); | assert.deepEqual(actual, array.slice(3)); | |
actual = _(array).filter(predicate).drop(2).drop().value(); | actual = _(array).filter(predicate).drop(2).drop().value(); | |
deepEqual(actual, [5, 6, 7, 8]); | assert.deepEqual(values, array); | |
assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2))); | ||
actual = _(array).drop(2).dropRight().drop().dropRight(2).value(); | actual = _(array).drop(2).dropRight().drop().dropRight(2).value(); | |
deepEqual(actual, [4, 5]); | assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2) )), 2)); | |
actual = _(array).filter(predicate).drop(2).dropRight().drop().dropRight | values = []; | |
(2).value(); | ||
deepEqual(actual, [5]); | actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dr | |
opRight(2).value(); | ||
assert.deepEqual(values, array.slice(1)); | ||
assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter( | ||
_.drop(array), predicate), 2))), 2)); | ||
} | } | |
else { | else { | |
skipTest(4); | skipTest(assert, 6); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.dropRight'); | QUnit.module('lodash.dropRight'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | var array = [1, 2, 3]; | |
test('should drop the last two elements', 1, function() { | QUnit.test('should drop the last two elements', function(assert) { | |
deepEqual(_.dropRight(array, 2), [1]); | assert.expect(1); | |
assert.deepEqual(_.dropRight(array, 2), [1]); | ||
}); | }); | |
test('should treat falsey `n` values, except nullish, as `0`', 1, function() | QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', fun | |
{ | ction(assert) { | |
var expected = _.map(falsey, function(value) { | assert.expect(1); | |
return value == null ? [1, 2] : array; | ||
var expected = lodashStable.map(falsey, function(value) { | ||
return value === undefined ? [1, 2] : array; | ||
}); | }); | |
var actual = _.map(falsey, function(n) { | var actual = lodashStable.map(falsey, function(n) { | |
return _.dropRight(array, n); | return _.dropRight(array, n); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should return all elements when `n` < `1`', 3, function() { | QUnit.test('should return all elements when `n` < `1`', function(assert) { | |
_.each([0, -1, -Infinity], function(n) { | assert.expect(3); | |
deepEqual(_.dropRight(array, n), array); | ||
lodashStable.each([0, -1, -Infinity], function(n) { | ||
assert.deepEqual(_.dropRight(array, n), array); | ||
}); | }); | |
}); | }); | |
test('should return an empty array when `n` >= `array.length`', 4, function( | QUnit.test('should return an empty array when `n` >= `array.length`', functi | |
) { | on(assert) { | |
_.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | assert.expect(4); | |
deepEqual(_.dropRight(array, n), []); | ||
lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | ||
assert.deepEqual(_.dropRight(array, n), []); | ||
}); | }); | |
}); | }); | |
test('should work as an iteratee for `_.map`', 1, function() { | QUnit.test('should coerce `n` to an integer', function(assert) { | |
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | assert.expect(1); | |
actual = _.map(array, _.dropRight); | ||
deepEqual(actual, [[1, 2], [4, 5], [7, 8]]); | assert.deepEqual(_.dropRight(array, 1.6), [1, 2]); | |
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should work as an iteratee for methods like `_.map`', function(a | |
if (!isNpm) { | ssert) { | |
var wrapped = _(array).dropRight(2); | assert.expect(1); | |
ok(wrapped instanceof _); | ||
deepEqual(wrapped.value(), [1]); | var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | |
} | actual = lodashStable.map(array, _.dropRight); | |
else { | ||
skipTest(2); | assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]); | |
} | ||
}); | }); | |
test('should work in a lazy chain sequence', 4, function() { | QUnit.test('should work in a lazy sequence', function(assert) { | |
assert.expect(6); | ||
if (!isNpm) { | if (!isNpm) { | |
var array = [1, 2, 3, 4, 5, 6, 7, 8], | var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), | |
predicate = function(value) { return value < 8; }, | predicate = function(value) { values.push(value); return isEven(valu | |
e); }, | ||
values = [], | ||
actual = _(array).dropRight(2).dropRight().value(); | actual = _(array).dropRight(2).dropRight().value(); | |
deepEqual(actual, [1, 2, 3, 4, 5]); | assert.deepEqual(actual, array.slice(0, -3)); | |
actual = _(array).filter(predicate).dropRight(2).dropRight().value(); | actual = _(array).filter(predicate).dropRight(2).dropRight().value(); | |
deepEqual(actual, [1, 2, 3, 4]); | assert.deepEqual(values, array); | |
assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predica | ||
te), 2))); | ||
actual = _(array).dropRight(2).drop().dropRight().drop(2).value(); | actual = _(array).dropRight(2).drop().dropRight().drop(2).value(); | |
deepEqual(actual, [4, 5]); | assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2) )), 2)); | |
actual = _(array).filter(predicate).dropRight(2).drop().dropRight().drop | values = []; | |
(2).value(); | ||
deepEqual(actual, [4]); | actual = _(array).dropRight().filter(predicate).dropRight(2).drop().drop | |
Right().drop(2).value(); | ||
assert.deepEqual(values, array.slice(0, -1)); | ||
assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter( | ||
_.dropRight(array), predicate), 2))), 2)); | ||
} | } | |
else { | else { | |
skipTest(4); | skipTest(assert, 6); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.dropRightWhile'); | QUnit.module('lodash.dropRightWhile'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | var array = [1, 2, 3, 4]; | |
var objects = [ | var objects = [ | |
{ 'a': 0, 'b': 0 }, | { 'a': 0, 'b': 0 }, | |
{ 'a': 1, 'b': 1 }, | { 'a': 1, 'b': 1 }, | |
{ 'a': 2, 'b': 2 } | { 'a': 2, 'b': 2 } | |
]; | ]; | |
test('should drop elements while `predicate` returns truthy', 1, function() | QUnit.test('should drop elements while `predicate` returns truthy', function | |
{ | (assert) { | |
assert.expect(1); | ||
var actual = _.dropRightWhile(array, function(num) { | var actual = _.dropRightWhile(array, function(num) { | |
return num > 1; | return num > 2; | |
}); | }); | |
deepEqual(actual, [1]); | assert.deepEqual(actual, [1, 2]); | |
}); | }); | |
test('should provide the correct `predicate` arguments', 1, function() { | QUnit.test('should provide the correct `predicate` arguments', function(asse | |
rt) { | ||
assert.expect(1); | ||
var args; | var args; | |
_.dropRightWhile(array, function() { | _.dropRightWhile(array, function() { | |
args = slice.call(arguments); | args = slice.call(arguments); | |
}); | }); | |
deepEqual(args, [3, 2, array]); | assert.deepEqual(args, [4, 3, array]); | |
}); | }); | |
test('should support the `thisArg` argument', 1, function() { | QUnit.test('should work with a "_.matches" style `predicate`', function(asse | |
var actual = _.dropRightWhile(array, function(num, index) { | rt) { | |
return this[index] > 1; | assert.expect(1); | |
}, array); | ||
deepEqual(actual, [1]); | assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2 )); | |
}); | }); | |
test('should work with a "_.pluck" style `predicate`', 1, function() { | QUnit.test('should work with a "_.matchesProperty" style `predicate`', funct | |
deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1)); | ion(assert) { | |
assert.expect(1); | ||
assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2)) | ||
; | ||
}); | }); | |
test('should work with a "_.where" style `predicate`', 1, function() { | QUnit.test('should work with a "_.property" style `predicate`', function(ass | |
deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2)); | ert) { | |
assert.expect(1); | ||
assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1)); | ||
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should return a wrapped value when chaining', function(assert) { | |
assert.expect(2); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(array).dropRightWhile(function(num) { | var wrapped = _(array).dropRightWhile(function(num) { | |
return num > 1; | return num > 2; | |
}); | }); | |
ok(wrapped instanceof _); | assert.ok(wrapped instanceof _); | |
deepEqual(wrapped.value(), [1]); | assert.deepEqual(wrapped.value(), [1, 2]); | |
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.dropWhile'); | QUnit.module('lodash.dropWhile'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | var array = [1, 2, 3, 4]; | |
var objects = [ | var objects = [ | |
{ 'a': 2, 'b': 2 }, | { 'a': 2, 'b': 2 }, | |
{ 'a': 1, 'b': 1 }, | { 'a': 1, 'b': 1 }, | |
{ 'a': 0, 'b': 0 } | { 'a': 0, 'b': 0 } | |
]; | ]; | |
test('should drop elements while `predicate` returns truthy', 1, function() | QUnit.test('should drop elements while `predicate` returns truthy', function | |
{ | (assert) { | |
assert.expect(1); | ||
var actual = _.dropWhile(array, function(num) { | var actual = _.dropWhile(array, function(num) { | |
return num < 3; | return num < 3; | |
}); | }); | |
deepEqual(actual, [3]); | assert.deepEqual(actual, [3, 4]); | |
}); | }); | |
test('should provide the correct `predicate` arguments', 1, function() { | QUnit.test('should provide the correct `predicate` arguments', function(asse | |
rt) { | ||
assert.expect(1); | ||
var args; | var args; | |
_.dropWhile(array, function() { | _.dropWhile(array, function() { | |
args = slice.call(arguments); | args = slice.call(arguments); | |
}); | }); | |
deepEqual(args, [1, 0, array]); | assert.deepEqual(args, [1, 0, array]); | |
}); | }); | |
test('should support the `thisArg` argument', 1, function() { | QUnit.test('should work with a "_.matches" style `predicate`', function(asse | |
var actual = _.dropWhile(array, function(num, index) { | rt) { | |
return this[index] < 3; | assert.expect(1); | |
}, array); | ||
deepEqual(actual, [3]); | assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1)); | |
}); | }); | |
test('should work with a "_.pluck" style `predicate`', 1, function() { | QUnit.test('should work with a "_.matchesProperty" style `predicate`', funct | |
deepEqual(_.dropWhile(objects, 'b'), objects.slice(2)); | ion(assert) { | |
assert.expect(1); | ||
assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1)); | ||
}); | }); | |
test('should work with a "_.where" style `predicate`', 1, function() { | QUnit.test('should work with a "_.property" style `predicate`', function(ass | |
deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1)); | ert) { | |
assert.expect(1); | ||
assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2)); | ||
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should work in a lazy sequence', function(assert) { | |
assert.expect(3); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(array).dropWhile(function(num) { | var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3), | |
return num < 3; | predicate = function(num) { return num < 3; }, | |
}); | expected = _.dropWhile(array, predicate), | |
wrapped = _(array).dropWhile(predicate); | ||
assert.deepEqual(wrapped.value(), expected); | ||
assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse()); | ||
assert.strictEqual(wrapped.last(), _.last(expected)); | ||
} | ||
else { | ||
skipTest(assert, 3); | ||
} | ||
}); | ||
QUnit.test('should work in a lazy sequence with `drop`', function(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3); | ||
var actual = _(array) | ||
.dropWhile(function(num) { return num == 1; }) | ||
.drop() | ||
.dropWhile(function(num) { return num == 3; }) | ||
.value(); | ||
ok(wrapped instanceof _); | assert.deepEqual(actual, array.slice(3)); | |
deepEqual(wrapped.value(), [3]); | ||
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.endsWith'); | QUnit.module('lodash.endsWith'); | |
(function() { | (function() { | |
var string = 'abc'; | var string = 'abc'; | |
test('should return `true` if a string ends with `target`', 1, function() { | QUnit.test('should return `true` if a string ends with `target`', function(a | |
strictEqual(_.endsWith(string, 'c'), true); | ssert) { | |
assert.expect(1); | ||
assert.strictEqual(_.endsWith(string, 'c'), true); | ||
}); | }); | |
test('should return `false` if a string does not end with `target`', 1, func | QUnit.test('should return `false` if a string does not end with `target`', f | |
tion() { | unction(assert) { | |
strictEqual(_.endsWith(string, 'b'), false); | assert.expect(1); | |
assert.strictEqual(_.endsWith(string, 'b'), false); | ||
}); | }); | |
test('should work with a `position` argument', 1, function() { | QUnit.test('should work with a `position` argument', function(assert) { | |
strictEqual(_.endsWith(string, 'b', 2), true); | assert.expect(1); | |
assert.strictEqual(_.endsWith(string, 'b', 2), true); | ||
}); | }); | |
test('should work with `position` >= `string.length`', 4, function() { | QUnit.test('should work with `position` >= `string.length`', function(assert | |
_.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) { | ) { | |
strictEqual(_.endsWith(string, 'c', position), true); | assert.expect(4); | |
lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) { | ||
assert.strictEqual(_.endsWith(string, 'c', position), true); | ||
}); | }); | |
}); | }); | |
test('should treat falsey `position` values, except `undefined`, as `0`', 1, | QUnit.test('should treat falsey `position` values, except `undefined`, as `0 | |
function() { | `', function(assert) { | |
var expected = _.map(falsey, _.constant(true)); | assert.expect(1); | |
var actual = _.map(falsey, function(position) { | var expected = lodashStable.map(falsey, alwaysTrue); | |
var actual = lodashStable.map(falsey, function(position) { | ||
return _.endsWith(string, position === undefined ? 'c' : '', position); | return _.endsWith(string, position === undefined ? 'c' : '', position); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should treat a negative `position` as `0`', 6, function() { | QUnit.test('should treat a negative `position` as `0`', function(assert) { | |
_.each([-1, -3, -Infinity], function(position) { | assert.expect(6); | |
ok(_.every(string, function(chr) { | ||
lodashStable.each([-1, -3, -Infinity], function(position) { | ||
assert.ok(lodashStable.every(string, function(chr) { | ||
return _.endsWith(string, chr, position) === false; | return _.endsWith(string, chr, position) === false; | |
})); | })); | |
strictEqual(_.endsWith(string, '', position), true); | assert.strictEqual(_.endsWith(string, '', position), true); | |
}); | }); | |
}); | }); | |
test('should return `true` when `target` is an empty string regardless of `p | QUnit.test('should coerce `position` to an integer', function(assert) { | |
osition`', 1, function() { | assert.expect(1); | |
ok(_.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infin | ||
ity], function(position) { | assert.strictEqual(_.endsWith(string, 'ab', 2.2), true); | |
}); | ||
QUnit.test('should return `true` when `target` is an empty string regardless | ||
of `position`', function(assert) { | ||
assert.expect(1); | ||
assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_S | ||
AFE_INTEGER, Infinity], function(position) { | ||
return _.endsWith(string, '', position, true); | return _.endsWith(string, '', position, true); | |
})); | })); | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.eq'); | ||
(function() { | ||
QUnit.test('should perform a `SameValueZero` comparison of two values', func | ||
tion(assert) { | ||
assert.expect(11); | ||
assert.strictEqual(_.eq(), true); | ||
assert.strictEqual(_.eq(undefined), true); | ||
assert.strictEqual(_.eq(0, -0), true); | ||
assert.strictEqual(_.eq(NaN, NaN), true); | ||
assert.strictEqual(_.eq(1, 1), true); | ||
assert.strictEqual(_.eq(null, undefined), false); | ||
assert.strictEqual(_.eq(1, Object(1)), false); | ||
assert.strictEqual(_.eq(1, '1'), false); | ||
assert.strictEqual(_.eq(1, '1'), false); | ||
var object = { 'a': 1 }; | ||
assert.strictEqual(_.eq(object, object), true); | ||
assert.strictEqual(_.eq(object, { 'a': 1 }), false); | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.escape'); | QUnit.module('lodash.escape'); | |
(function() { | (function() { | |
var escaped = '&<>"'`\/', | var escaped = '&<>"'`\/', | |
unescaped = '&<>"\'`\/'; | unescaped = '&<>"\'`\/'; | |
escaped += escaped; | escaped += escaped; | |
unescaped += unescaped; | unescaped += unescaped; | |
test('should escape values', 1, function() { | QUnit.test('should escape values', function(assert) { | |
strictEqual(_.escape(unescaped), escaped); | assert.expect(1); | |
assert.strictEqual(_.escape(unescaped), escaped); | ||
}); | }); | |
test('should not escape the "/" character', 1, function() { | QUnit.test('should not escape the "/" character', function(assert) { | |
strictEqual(_.escape('/'), '/'); | assert.expect(1); | |
assert.strictEqual(_.escape('/'), '/'); | ||
}); | }); | |
test('should handle strings with nothing to escape', 1, function() { | QUnit.test('should handle strings with nothing to escape', function(assert) | |
strictEqual(_.escape('abc'), 'abc'); | { | |
assert.expect(1); | ||
assert.strictEqual(_.escape('abc'), 'abc'); | ||
}); | }); | |
test('should escape the same characters unescaped by `_.unescape`', 1, funct | QUnit.test('should escape the same characters unescaped by `_.unescape`', fu | |
ion() { | nction(assert) { | |
strictEqual(_.escape(_.unescape(escaped)), escaped); | assert.expect(1); | |
assert.strictEqual(_.escape(_.unescape(escaped)), escaped); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.escapeRegExp'); | QUnit.module('lodash.escapeRegExp'); | |
(function() { | (function() { | |
var escaped = '\\.\\*\\+\\?\\^\\$\\{\\}\\(\\)\\|\\[\\]\\/\\\\', | var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\', | |
unescaped = '.*+?^${}()|[\]\/\\'; | unescaped = '^$.*+?()[]{}|\\'; | |
escaped += escaped; | QUnit.test('should escape values', function(assert) { | |
unescaped += unescaped; | assert.expect(1); | |
assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escape | ||
d); | ||
}); | ||
QUnit.test('should handle strings with nothing to escape', function(assert) | ||
{ | ||
assert.expect(1); | ||
test('should escape values', 1, function() { | assert.strictEqual(_.escapeRegExp('ghi'), 'ghi'); | |
strictEqual(_.escapeRegExp(unescaped), escaped); | ||
}); | }); | |
test('should handle strings with nothing to escape', 1, function() { | QUnit.test('should return an empty string for empty values', function(assert | |
strictEqual(_.escapeRegExp('abc'), 'abc'); | ) { | |
assert.expect(1); | ||
var values = [, null, undefined, ''], | ||
expected = lodashStable.map(values, alwaysEmptyString); | ||
var actual = lodashStable.map(values, function(value, index) { | ||
return index ? _.escapeRegExp(value) : _.escapeRegExp(); | ||
}); | ||
assert.deepEqual(actual, expected); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.every'); | QUnit.module('lodash.every'); | |
(function() { | (function() { | |
test('should return `true` for empty collections', 1, function() { | QUnit.test('should return `true` if `predicate` returns truthy for all eleme | |
var expected = _.map(empties, _.constant(true)); | nts', function(assert) { | |
assert.expect(1); | ||
assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true); | ||
}); | ||
QUnit.test('should return `true` for empty collections', function(assert) { | ||
assert.expect(1); | ||
var expected = lodashStable.map(empties, alwaysTrue); | ||
var actual = _.map(empties, function(value) { | var actual = lodashStable.map(empties, function(value) { | |
try { | try { | |
return _.every(value, _.identity); | return _.every(value, identity); | |
} catch(e) {} | } catch (e) {} | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | }); | |
test('should return `true` if `predicate` returns truthy for all elements in | QUnit.test('should return `false` as soon as `predicate` returns falsey', fu | |
the collection', 1, function() { | nction(assert) { | |
strictEqual(_.every([true, 1, 'a'], _.identity), true); | assert.expect(2); | |
}); | ||
test('should return `false` as soon as `predicate` returns falsey', 1, funct | var count = 0; | |
ion() { | ||
strictEqual(_.every([true, null, true], _.identity), false); | ||
}); | ||
test('should work with collections of `undefined` values (test in IE < 9)', | assert.strictEqual(_.every([true, null, true], function(value) { | |
1, function() { | count++; | |
strictEqual(_.every([undefined, undefined, undefined], _.identity), false) | return value; | |
; | }), false); | |
}); | ||
test('should work with a "_.pluck" style `predicate`', 2, function() { | assert.strictEqual(count, 2); | |
var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }]; | ||
strictEqual(_.every(objects, 'a'), false); | ||
strictEqual(_.every(objects, 'b'), true); | ||
}); | }); | |
test('should work with a "_where" style `predicate`', 2, function() { | QUnit.test('should work with collections of `undefined` values (test in IE < | |
var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }]; | 9)', function(assert) { | |
strictEqual(_.every(objects, { 'a': 0 }), true); | assert.expect(1); | |
strictEqual(_.every(objects, { 'b': 1 }), false); | ||
assert.strictEqual(_.every([undefined, undefined, undefined], identity), f | ||
alse); | ||
}); | }); | |
test('should use `_.identity` when `predicate` is nullish', 2, function() { | QUnit.test('should use `_.identity` when `predicate` is nullish', function(a | |
ssert) { | ||
assert.expect(2); | ||
var values = [, null, undefined], | var values = [, null, undefined], | |
expected = _.map(values, _.constant(false)); | expected = lodashStable.map(values, alwaysFalse); | |
var actual = _.map(values, function(value, index) { | var actual = lodashStable.map(values, function(value, index) { | |
var array = [0]; | var array = [0]; | |
return index ? _.every(array, value) : _.every(array); | return index ? _.every(array, value) : _.every(array); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
expected = _.map(values, _.constant(true)); | expected = lodashStable.map(values, alwaysTrue); | |
actual = _.map(values, function(value, index) { | actual = lodashStable.map(values, function(value, index) { | |
var array = [1]; | var array = [1]; | |
return index ? _.every(array, value) : _.every(array); | return index ? _.every(array, value) : _.every(array); | |
}); | }); | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
}); | ||
QUnit.test('should work with a "_.property" style `predicate`', function(ass | ||
ert) { | ||
assert.expect(2); | ||
var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }]; | ||
assert.strictEqual(_.every(objects, 'a'), false); | ||
assert.strictEqual(_.every(objects, 'b'), true); | ||
}); | ||
QUnit.test('should work with a "_.matches" style `predicate`', function(asse | ||
rt) { | ||
assert.expect(2); | ||
var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }]; | ||
assert.strictEqual(_.every(objects, { 'a': 0 }), true); | ||
assert.strictEqual(_.every(objects, { 'b': 1 }), false); | ||
}); | }); | |
test('should be aliased', 1, function() { | QUnit.test('should work as an iteratee for methods like `_.map`', function(a | |
strictEqual(_.all, _.every); | ssert) { | |
assert.expect(1); | ||
var actual = lodashStable.map([[1]], _.every); | ||
assert.deepEqual(actual, [true]); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('strict mode checks'); | QUnit.module('strict mode checks'); | |
_.each(['assign', 'bindAll', 'defaults'], function(methodName) { | lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(meth | |
var func = _[methodName]; | odName) { | |
var func = _[methodName], | ||
isBindAll = methodName == 'bindAll'; | ||
QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'th | ||
row strict mode errors', function(assert) { | ||
assert.expect(1); | ||
test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw st rict mode errors', 1, function() { | ||
if (freeze) { | if (freeze) { | |
var object = { 'a': undefined, 'b': function() {} }, | var object = freeze({ 'a': undefined, 'b': function() {} }), | |
pass = !isStrict; | pass = !isStrict; | |
freeze(object); | ||
try { | try { | |
if (methodName == 'bindAll') { | func(object, isBindAll ? 'b' : { 'a': 1 }); | |
func(object); | } catch (e) { | |
} else { | ||
func(object, { 'a': 1 }); | ||
} | ||
} catch(e) { | ||
pass = !pass; | pass = !pass; | |
} | } | |
ok(pass); | assert.ok(pass); | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
}); | }); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.filter'); | QUnit.module('lodash.fill'); | |
(function() { | (function() { | |
test('should return elements `predicate` returns truthy for', 1, function() | QUnit.test('should use a default `start` of `0` and a default `end` of `arra | |
{ | y.length`', function(assert) { | |
var actual = _.filter([1, 2, 3], function(num) { | assert.expect(1); | |
return num % 2; | ||
}); | ||
deepEqual(actual, [1, 3]); | var array = [1, 2, 3]; | |
assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']); | ||
}); | }); | |
test('should iterate correctly over an object with numeric keys (test in Mob | QUnit.test('should use `undefined` for `value` if not provided', function(as | |
ile Safari 8)', 1, function() { | sert) { | |
// Trigger a Mobile Safari 8 JIT bug. | assert.expect(2); | |
// See https://github.com/lodash/lodash/issues/799. | ||
var counter = 0, | ||
object = { '1': 'foo', '8': 'bar', '50': 'baz' }; | ||
_.times(1000, function() { | var array = [1, 2, 3], | |
_.filter([], _.constant(true)); | actual = _.fill(array); | |
}); | ||
_.filter(object, function() { | ||
counter++; | ||
return true; | ||
}); | ||
strictEqual(counter, 3); | ||
}); | ||
test('should be aliased', 1, function() { | assert.deepEqual(actual, Array(3)); | |
strictEqual(_.select, _.filter); | assert.ok(lodashStable.every(actual, function(value, index) { | |
return index in actual; | ||
})); | ||
}); | }); | |
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
_.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLast | QUnit.test('should work with a positive `start`', function(assert) { | |
Key'], function(methodName) { | assert.expect(1); | |
QUnit.module('lodash.' + methodName); | ||
var func = _[methodName]; | ||
(function() { | var array = [1, 2, 3]; | |
var objects = [ | assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']); | |
{ 'a': 0, 'b': 0 }, | }); | |
{ 'a': 1, 'b': 1 }, | ||
{ 'a': 2, 'b': 2 } | ||
]; | ||
var expected = ({ | QUnit.test('should work with a `start` >= `array.length`', function(assert) | |
'find': [objects[1], undefined, objects[2], objects[1]], | { | |
'findLast': [objects[2], undefined, objects[2], objects[2]], | assert.expect(4); | |
'findIndex': [1, -1, 2, 1], | ||
'findLastIndex': [2, -1, 2, 2], | ||
'findKey': ['1', undefined, '2', '1'], | ||
'findLastKey': ['2', undefined, '2', '2'] | ||
})[methodName]; | ||
test('should return the correct value', 1, function() { | lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) { | |
strictEqual(func(objects, function(object) { return object.a; }), expect | var array = [1, 2, 3]; | |
ed[0]); | assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]); | |
}); | }); | |
}); | ||
test('should work with a `thisArg`', 1, function() { | QUnit.test('should treat falsey `start` values as `0`', function(assert) { | |
strictEqual(func(objects, function(object, index) { return this[index].a | assert.expect(1); | |
; }, objects), expected[0]); | ||
}); | ||
test('should return `' + expected[1] + '` if value is not found', 1, funct | var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', ' | |
ion() { | a'])); | |
strictEqual(func(objects, function(object) { return object.a === 3; }), | ||
expected[1]); | ||
}); | ||
test('should work with a "_.pluck" style `predicate`', 1, function() { | var actual = lodashStable.map(falsey, function(start) { | |
strictEqual(func(objects, 'b'), expected[3]); | var array = [1, 2, 3]; | |
return _.fill(array, 'a', start); | ||
}); | }); | |
test('should work with a "_.where" style `predicate`', 1, function() { | assert.deepEqual(actual, expected); | |
strictEqual(func(objects, { 'b': 2 }), expected[2]); | }); | |
}); | ||
test('should return `' + expected[1] + '` for empty collections', 1, funct | QUnit.test('should work with a negative `start`', function(assert) { | |
ion() { | assert.expect(1); | |
var actual = [], | ||
emptyValues = _.endsWith(methodName, 'Index') ? _.reject(empties, _. | ||
isPlainObject) : empties, | ||
expecting = _.map(emptyValues, function() { return expected[1]; }); | ||
_.each(emptyValues, function(value) { | var array = [1, 2, 3]; | |
try { | assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']); | |
actual.push(func(value, { 'a': 3 })); | }); | |
} catch(e) {} | ||
}); | ||
deepEqual(actual, expecting); | QUnit.test('should work with a negative `start` <= negative `array.length`', | |
function(assert) { | ||
assert.expect(3); | ||
lodashStable.each([-3, -4, -Infinity], function(start) { | ||
var array = [1, 2, 3]; | ||
assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']); | ||
}); | }); | |
}()); | }); | |
(function() { | QUnit.test('should work with `start` >= `end`', function(assert) { | |
var expected = ({ | assert.expect(2); | |
'find': 1, | ||
'findLast': 2, | ||
'findKey': 'a', | ||
'findLastKey': 'b' | ||
})[methodName]; | ||
if (expected != null) { | lodashStable.each([2, 3], function(start) { | |
test('should work with an object for `collection`', 1, function() { | var array = [1, 2, 3]; | |
var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(num) { | assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]); | |
return num < 3; | }); | |
}); | }); | |
strictEqual(actual, expected); | QUnit.test('should work with a positive `end`', function(assert) { | |
}); | assert.expect(1); | |
} | ||
}()); | ||
(function() { | var array = [1, 2, 3]; | |
var expected = ({ | assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]); | |
'find': 'a', | }); | |
'findLast': 'b', | ||
'findIndex': 0, | ||
'findLastIndex': 1 | ||
})[methodName]; | ||
if (expected != null) { | QUnit.test('should work with a `end` >= `array.length`', function(assert) { | |
test('should work with a string for `collection`', 1, function() { | assert.expect(4); | |
var actual = func('abc', function(chr, index) { | ||
return index < 2; | ||
}); | ||
strictEqual(actual, expected); | lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) { | |
}); | var array = [1, 2, 3]; | |
} | assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']); | |
if (methodName == 'find') { | }); | |
test('should be aliased', 1, function() { | }); | |
strictEqual(_.detect, func); | ||
}); | ||
} | ||
}()); | ||
}); | ||
/*--------------------------------------------------------------------------*/ | QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', f | |
unction(assert) { | ||
assert.expect(1); | ||
QUnit.module('lodash.findWhere'); | var expected = lodashStable.map(falsey, function(value) { | |
return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3]; | ||
}); | ||
(function() { | var actual = lodashStable.map(falsey, function(end) { | |
var objects = [ | var array = [1, 2, 3]; | |
{ 'a': 1 }, | return _.fill(array, 'a', 0, end); | |
{ 'a': 1 }, | }); | |
{ 'a': 1, 'b': 2 }, | ||
{ 'a': 2, 'b': 2 }, | ||
{ 'a': 3 } | ||
]; | ||
test('should filter by `source` properties', 6, function() { | assert.deepEqual(actual, expected); | |
strictEqual(_.findWhere(objects, { 'a': 1 }), objects[0]); | ||
strictEqual(_.findWhere(objects, { 'a': 2 }), objects[3]); | ||
strictEqual(_.findWhere(objects, { 'a': 3 }), objects[4]); | ||
strictEqual(_.findWhere(objects, { 'b': 1 }), undefined); | ||
strictEqual(_.findWhere(objects, { 'b': 2 }), objects[2]); | ||
strictEqual(_.findWhere(objects, { 'a': 1, 'b': 2 }), objects[2]); | ||
}); | }); | |
test('should work with a function for `source`', 1, function() { | QUnit.test('should work with a negative `end`', function(assert) { | |
function source() {} | assert.expect(1); | |
source.a = 2; | ||
strictEqual(_.findWhere(objects, source), objects[3]); | var array = [1, 2, 3]; | |
assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]); | ||
}); | }); | |
test('should match all elements when provided an empty `source`', 1, functio | QUnit.test('should work with a negative `end` <= negative `array.length`', f | |
n() { | unction(assert) { | |
var expected = _.map(empties, _.constant(true)); | assert.expect(3); | |
var actual = _.map(empties, function(value) { | lodashStable.each([-3, -4, -Infinity], function(end) { | |
return _.findWhere(objects, value) === objects[0]; | var array = [1, 2, 3]; | |
assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]); | ||
}); | }); | |
deepEqual(actual, expected); | ||
}); | }); | |
}()); | ||
/*--------------------------------------------------------------------------*/ | QUnit.test('should coerce `start` and `end` to integers', function(assert) { | |
assert.expect(1); | ||
QUnit.module('lodash.first'); | var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN] ]; | |
(function() { | var actual = lodashStable.map(positions, function(pos) { | |
var array = [1, 2, 3]; | var array = [1, 2, 3]; | |
return _.fill.apply(_, [array, 'a'].concat(pos)); | ||
}); | ||
test('should return the first element', 1, function() { | assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', | |
strictEqual(_.first(array), 1); | 'a'], ['a', 2, 3], [1, 2, 3]]); | |
}); | }); | |
test('should return `undefined` when querying empty arrays', 1, function() { | QUnit.test('should work as an iteratee for methods like `_.map`', function(a | |
var array = []; | ssert) { | |
array['-1'] = 1; | assert.expect(1); | |
strictEqual(_.first(array), undefined); | ||
}); | ||
test('should work as an iteratee for `_.map`', 1, function() { | var array = [[1, 2], [3, 4]], | |
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | actual = lodashStable.map(array, _.fill); | |
actual = _.map(array, _.first); | ||
deepEqual(actual, [1, 4, 7]); | assert.deepEqual(actual, [[0, 0], [1, 1]]); | |
}); | }); | |
test('should return an unwrapped value when chaining', 1, function() { | QUnit.test('should return a wrapped value when chaining', function(assert) { | |
if (!isNpm) { | assert.expect(3); | |
strictEqual(_(array).first(), 1); | ||
} | ||
else { | ||
skipTest(); | ||
} | ||
}); | ||
test('should work in a lazy chain sequence', 1, function() { | ||
if (!isNpm) { | if (!isNpm) { | |
var array = [1, 2, 3, 4]; | var array = [1, 2, 3], | |
wrapped = _(array).fill('a'), | ||
var wrapped = _(array).filter(function(value) { | actual = wrapped.value(); | |
return value % 2 == 0; | ||
}); | ||
strictEqual(wrapped.first(), 2); | assert.ok(wrapped instanceof _); | |
assert.deepEqual(actual, ['a', 'a', 'a']); | ||
assert.strictEqual(actual, array); | ||
} | } | |
else { | else { | |
skipTest(); | skipTest(assert, 3); | |
} | } | |
}); | }); | |
test('should be aliased', 1, function() { | ||
strictEqual(_.head, _.first); | ||
}); | ||
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.take'); | QUnit.module('lodash.filter'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | var array = [1, 2, 3]; | |
test('should take the first two elements', 1, function() { | QUnit.test('should return elements `predicate` returns truthy for', function | |
deepEqual(_.take(array, 2), [1, 2]); | (assert) { | |
}); | assert.expect(1); | |
test('should treat falsey `n` values, except nullish, as `0`', 1, function() | assert.deepEqual(_.filter(array, isEven), [2]); | |
{ | }); | |
var expected = _.map(falsey, function(value) { | ||
return value == null ? [1] : []; | ||
}); | ||
var actual = _.map(falsey, function(n) { | QUnit.test('should iterate over an object with numeric keys (test in Mobile | |
return _.take(array, n); | Safari 8)', function(assert) { | |
}); | assert.expect(1); | |
deepEqual(actual, expected); | // Trigger a Mobile Safari 8 JIT bug. | |
}); | // See https://github.com/lodash/lodash/issues/799. | |
var counter = 0, | ||
object = { '1': 'foo', '8': 'bar', '50': 'baz' }; | ||
test('should return an empty array when `n` < `1`', 3, function() { | lodashStable.times(1000, function(assert) { | |
_.each([0, -1, -Infinity], function(n) { | _.filter([], alwaysTrue); | |
deepEqual(_.take(array, n), []); | ||
}); | }); | |
}); | ||
test('should return all elements when `n` >= `array.length`', 4, function() | _.filter(object, function() { | |
{ | counter++; | |
_.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | return true; | |
deepEqual(_.take(array, n), array); | ||
}); | }); | |
}); | ||
test('should work as an iteratee for `_.map`', 1, function() { | assert.strictEqual(counter, 3); | |
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | ||
actual = _.map(array, _.take); | ||
deepEqual(actual, [[1], [4], [7]]); | ||
}); | }); | |
}()); | ||
test('should return a wrapped value when chaining', 2, function() { | /*--------------------------------------------------------------------------*/ | |
if (!isNpm) { | ||
var wrapped = _(array).take(2); | ||
ok(wrapped instanceof _); | ||
deepEqual(wrapped.value(), [1, 2]); | ||
} | ||
else { | ||
skipTest(2); | ||
} | ||
}); | ||
test('should work in a lazy chain sequence', 4, function() { | lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey' | |
if (!isNpm) { | , 'findLastKey'], function(methodName) { | |
var array = [1, 2, 3, 4, 5, 6, 7, 8], | QUnit.module('lodash.' + methodName); | |
predicate = function(value) { return value > 1; }, | ||
actual = _(array).take(2).take().value(); | ||
deepEqual(actual, [1]); | var func = _[methodName], | |
isFindKey = /Key$/.test(methodName); | ||
actual = _(array).filter(predicate).take(2).take().value(); | (function() { | |
deepEqual(actual, [2]); | var objects = [ | |
{ 'a': 0, 'b': 0 }, | ||
{ 'a': 1, 'b': 1 }, | ||
{ 'a': 2, 'b': 2 } | ||
]; | ||
actual = _(array).take(6).takeRight(4).take(2).takeRight().value(); | var expected = ({ | |
deepEqual(actual, [4]); | 'find': [objects[1], undefined, objects[2], objects[1]], | |
'findLast': [objects[2], undefined, objects[2], objects[2]], | ||
'findIndex': [1, -1, 2, 1], | ||
'findLastIndex': [2, -1, 2, 2], | ||
'findKey': ['1', undefined, '2', '1'], | ||
'findLastKey': ['2', undefined, '2', '2'] | ||
})[methodName]; | ||
actual = _(array).filter(predicate).take(6).takeRight(4).take(2).takeRig | QUnit.test('should return the found value', function(assert) { | |
ht().value(); | assert.expect(1); | |
deepEqual(actual, [5]); | ||
} | ||
else { | ||
skipTest(4); | ||
} | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | assert.strictEqual(func(objects, function(object) { return object.a; }), | |
expected[0]); | ||
}); | ||
QUnit.module('lodash.takeRight'); | QUnit.test('should return `' + expected[1] + '` if value is not found', fu | |
nction(assert) { | ||
assert.expect(1); | ||
(function() { | assert.strictEqual(func(objects, function(object) { return object.a === | |
var array = [1, 2, 3]; | 3; }), expected[1]); | |
}); | ||
test('should take the last two elements', 1, function() { | QUnit.test('should work with a "_.matches" style `predicate`', function(as | |
deepEqual(_.takeRight(array, 2), [2, 3]); | sert) { | |
}); | assert.expect(1); | |
test('should treat falsey `n` values, except nullish, as `0`', 1, function() | assert.strictEqual(func(objects, { 'b': 2 }), expected[2]); | |
{ | ||
var expected = _.map(falsey, function(value) { | ||
return value == null ? [3] : []; | ||
}); | }); | |
var actual = _.map(falsey, function(n) { | QUnit.test('should work with a "_.matchesProperty" style `predicate`', fun | |
return _.takeRight(array, n); | ction(assert) { | |
assert.expect(1); | ||
assert.strictEqual(func(objects, ['b', 2]), expected[2]); | ||
}); | }); | |
deepEqual(actual, expected); | QUnit.test('should work with a "_.property" style `predicate`', function(a | |
}); | ssert) { | |
assert.expect(1); | ||
test('should return an empty array when `n` < `1`', 3, function() { | assert.strictEqual(func(objects, 'b'), expected[3]); | |
_.each([0, -1, -Infinity], function(n) { | ||
deepEqual(_.takeRight(array, n), []); | ||
}); | }); | |
}); | ||
test('should return all elements when `n` >= `array.length`', 4, function() | QUnit.test('should return `' + expected[1] + '` for empty collections', fu | |
{ | nction(assert) { | |
_.each([3, 4, Math.pow(2, 32), Infinity], function(n) { | assert.expect(1); | |
deepEqual(_.takeRight(array, n), array); | ||
}); | ||
}); | ||
test('should work as an iteratee for `_.map`', 1, function() { | var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashSta | |
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], | ble.reject(empties, lodashStable.isPlainObject) : empties, | |
actual = _.map(array, _.takeRight); | expecting = lodashStable.map(emptyValues, lodashStable.constant(expe | |
cted[1])); | ||
deepEqual(actual, [[3], [6], [9]]); | var actual = lodashStable.map(emptyValues, function(value) { | |
}); | try { | |
return func(value, { 'a': 3 }); | ||
} catch (e) {} | ||
}); | ||
test('should return a wrapped value when chaining', 2, function() { | assert.deepEqual(actual, expecting); | |
if (!isNpm) { | }); | |
var wrapped = _(array).takeRight(2); | }()); | |
ok(wrapped instanceof _); | ||
deepEqual(wrapped.value(), [2, 3]); | ||
} | ||
else { | ||
skipTest(2); | ||
} | ||
}); | ||
test('should work in a lazy chain sequence', 4, function() { | (function() { | |
if (!isNpm) { | var array = [1, 2, 3, 4]; | |
var array = [1, 2, 3, 4, 5, 6, 7, 8], | ||
predicate = function(value) { return value < 8; }, | ||
actual = _(array).takeRight(2).takeRight().value(); | ||
deepEqual(actual, [8]); | var expected = ({ | |
'find': 1, | ||
'findLast': 4, | ||
'findIndex': 0, | ||
'findLastIndex': 3, | ||
'findKey': '0', | ||
'findLastKey': '3' | ||
})[methodName]; | ||
actual = _(array).filter(predicate).takeRight(2).takeRight().value(); | QUnit.test('should return an unwrapped value when implicitly chaining', fu | |
deepEqual(actual, [7]); | nction(assert) { | |
assert.expect(1); | ||
actual = _(array).takeRight(6).take(4).takeRight(2).take().value(); | if (!isNpm) { | |
deepEqual(actual, [5]); | assert.strictEqual(_(array)[methodName](), expected); | |
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).ta | QUnit.test('should return a wrapped value when explicitly chaining', funct | |
ke().value(); | ion(assert) { | |
deepEqual(actual, [4]); | assert.expect(1); | |
} | ||
else { | ||
skipTest(4); | ||
} | ||
}); | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | if (!isNpm) { | |
assert.ok(_(array).chain()[methodName]() instanceof _); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
QUnit.module('lodash.takeRightWhile'); | QUnit.test('should not execute immediately when explicitly chaining', func | |
tion(assert) { | ||
assert.expect(1); | ||
(function() { | if (!isNpm) { | |
var array = [1, 2, 3]; | var wrapped = _(array).chain()[methodName](); | |
assert.strictEqual(wrapped.__wrapped__, array); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
var objects = [ | QUnit.test('should work in a lazy sequence', function(assert) { | |
{ 'a': 0, 'b': 0 }, | assert.expect(2); | |
{ 'a': 1, 'b': 1 }, | ||
{ 'a': 2, 'b': 2 } | ||
]; | ||
test('should take elements while `predicate` returns truthy', 1, function() | if (!isNpm) { | |
{ | var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), | |
var actual = _.takeRightWhile(array, function(num) { | smallArray = array; | |
return num > 1; | ||
lodashStable.times(2, function(index) { | ||
var array = index ? largeArray : smallArray, | ||
wrapped = _(array).filter(isEven); | ||
assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(a | ||
rray, isEven))); | ||
}); | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | ||
}); | }); | |
}()); | ||
deepEqual(actual, [2, 3]); | (function() { | |
}); | var expected = ({ | |
'find': 1, | ||
'findLast': 2, | ||
'findKey': 'a', | ||
'findLastKey': 'b' | ||
})[methodName]; | ||
test('should provide the correct `predicate` arguments', 1, function() { | if (expected != null) { | |
var args; | QUnit.test('should work with an object for `collection`', function(asser | |
t) { | ||
assert.expect(1); | ||
_.takeRightWhile(array, function() { | var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(num) { | |
args = slice.call(arguments); | return num < 3; | |
}); | }); | |
deepEqual(args, [3, 2, array]); | assert.strictEqual(actual, expected); | |
}); | }); | |
} | ||
}()); | ||
}); | ||
test('should support the `thisArg` argument', 1, function() { | /*--------------------------------------------------------------------------*/ | |
var actual = _.takeRightWhile(array, function(num, index) { | ||
return this[index] > 1; | ||
}, array); | ||
deepEqual(actual, [2, 3]); | QUnit.module('lodash.find and lodash.findLast'); | |
}); | ||
test('should work with a "_.pluck" style `predicate`', 1, function() { | lodashStable.each(['find', 'findLast'], function(methodName) { | |
deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1)); | var isFind = methodName == 'find'; | |
}); | ||
test('should work with a "_.where" style `predicate`', 1, function() { | QUnit.test('`_.' + methodName + '` should support shortcut fusion', function | |
deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2)); | (assert) { | |
}); | assert.expect(3); | |
test('should return a wrapped value when chaining', 2, function() { | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(array).takeRightWhile(function(num) { | var findCount = 0, | |
return num > 1; | mapCount = 0, | |
}); | array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), | |
iteratee = function(value) { mapCount++; return square(value); }, | ||
predicate = function(value) { findCount++; return isEven(value); }, | ||
actual = _(array).map(iteratee)[methodName](predicate); | ||
ok(wrapped instanceof _); | assert.strictEqual(findCount, isFind ? 2 : 1); | |
deepEqual(wrapped.value(), [2, 3]); | assert.strictEqual(mapCount, isFind ? 2 : 1); | |
assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE)); | ||
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 3); | |
} | } | |
}); | }); | |
}()); | }); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.takeWhile'); | QUnit.module('lodash.flip'); | |
(function() { | (function() { | |
var array = [1, 2, 3]; | function fn() { | |
return slice.call(arguments); | ||
var objects = [ | } | |
{ 'a': 2, 'b': 2 }, | ||
{ 'a': 1, 'b': 1 }, | ||
{ 'a': 0, 'b': 0 } | ||
]; | ||
test('should take elements while `predicate` returns truthy', 1, function() | QUnit.test('should flip arguments provided to `func`', function(assert) { | |
{ | assert.expect(1); | |
var actual = _.takeWhile(array, function(num) { | ||
return num < 3; | ||
}); | ||
deepEqual(actual, [1, 2]); | var flipped = _.flip(fn); | |
assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']); | ||
}); | }); | |
}()); | ||
test('should provide the correct `predicate` arguments', 1, function() { | /*--------------------------------------------------------------------------*/ | |
var args; | ||
_.takeWhile(array, function() { | QUnit.module('lodash.flatMap'); | |
args = slice.call(arguments); | ||
}); | ||
deepEqual(args, [1, 0, array]); | (function() { | |
}); | var array = [1, 2, 3, 4]; | |
test('should support the `thisArg` argument', 1, function() { | function duplicate(n) { | |
var actual = _.takeWhile(array, function(num, index) { | return [n, n]; | |
return this[index] < 3; | } | |
}, array); | ||
deepEqual(actual, [1, 2]); | QUnit.test('should map values in `array` to a new flattened array', function | |
}); | (assert) { | |
assert.expect(1); | ||
test('should work with a "_.pluck" style `predicate`', 1, function() { | var actual = _.flatMap(array, duplicate), | |
deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2)); | expected = lodashStable.flatten(lodashStable.map(array, duplicate)); | |
}); | ||
test('should work with a "_.where" style `predicate`', 1, function() { | assert.deepEqual(actual, expected); | |
deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1)); | ||
}); | }); | |
test('should return a wrapped value when chaining', 2, function() { | QUnit.test('should work in a lazy sequence', function(assert) { | |
assert.expect(2); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _(array).takeWhile(function(num) { | var largeArray = lodashStable.range(LARGE_ARRAY_SIZE), | |
return num < 3; | smallArray = array; | |
}); | ||
lodashStable.times(2, function(index) { | ||
var array = index ? largeArray : smallArray, | ||
actual = _(array).filter(isEven).flatMap(duplicate).take(2).value( | ||
); | ||
ok(wrapped instanceof _); | assert.deepEqual(actual, _.take(_.flatMap(_.filter(array, isEven), dup | |
deepEqual(wrapped.value(), [1, 2]); | licate), 2)); | |
}); | ||
} | } | |
else { | else { | |
skipTest(2); | skipTest(assert, 2); | |
} | } | |
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('flatten methods'); | QUnit.module('flatten methods'); | |
(function() { | (function() { | |
var args = arguments; | var args = arguments; | |
test('should perform a shallow flatten', 1, function() { | QUnit.test('should perform a shallow flatten', function(assert) { | |
var array = [[['a']], [['b']]]; | assert.expect(1); | |
deepEqual(_.flatten(array), [['a'], ['b']]); | ||
}); | ||
test('should work with `isDeep`', 2, function() { | ||
var array = [[['a']], [['b']]], | ||
expected = ['a', 'b']; | ||
deepEqual(_.flatten(array, true), expected); | var array = [[['a']], [['b']]]; | |
deepEqual(_.flattenDeep(array), expected); | assert.deepEqual(_.flatten(array), [['a'], ['b']]); | |
}); | }); | |
test('should flatten `arguments` objects', 3, function() { | QUnit.test('should flatten `arguments` objects', function(assert) { | |
var array = [args, [args]], | assert.expect(2); | |
expected = [1, 2, 3, args]; | ||
deepEqual(_.flatten(array), expected); | var array = [args, [args]]; | |
expected = [1, 2, 3, 1, 2, 3]; | assert.deepEqual(_.flatten(array), [1, 2, 3, args]); | |
deepEqual(_.flatten(array, true), expected); | assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]); | |
deepEqual(_.flattenDeep(array), expected); | ||
}); | }); | |
test('should work as an iteratee for `_.map`', 2, function() { | QUnit.test('should treat sparse arrays as dense', function(assert) { | |
var array = [[[['a']]], [[['b']]]]; | assert.expect(6); | |
deepEqual(_.map(array, _.flatten), [[['a']], [['b']]]); | ||
deepEqual(_.map(array, _.flattenDeep), [['a'], ['b']]); | ||
}); | ||
test('should treat sparse arrays as dense', 6, function() { | ||
var array = [[1, 2, 3], Array(3)], | var array = [[1, 2, 3], Array(3)], | |
expected = [1, 2, 3]; | expected = [1, 2, 3]; | |
expected.push(undefined, undefined, undefined); | expected.push(undefined, undefined, undefined); | |
_.each([_.flatten(array), _.flatten(array, true), _.flattenDeep(array)], f | lodashStable.each([_.flatten(array), _.flatten(array, true), _.flattenDeep | |
unction(actual) { | (array)], function(actual) { | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
ok('4' in actual); | assert.ok('4' in actual); | |
}); | }); | |
}); | }); | |
test('should work with extremely large arrays', 3, function() { | QUnit.test('should work with extremely large arrays', function(assert) { | |
assert.expect(3); | ||
// Test in modern browsers only to avoid browser hangs. | // Test in modern browsers only to avoid browser hangs. | |
_.times(3, function(index) { | lodashStable.times(3, function(index) { | |
if (freeze) { | if (freeze) { | |
var expected = Array(5e5); | var expected = Array(5e5); | |
try { | try { | |
if (index) { | if (index) { | |
var actual = actual == 1 ? _.flatten([expected], true) : _.flatten Deep([expected]); | var actual = actual == 1 ? _.flatten([expected], true) : _.flatten Deep([expected]); | |
} else { | } else { | |
actual = _.flatten(expected); | actual = _.flatten(expected); | |
} | } | |
deepEqual(actual, expected); | assert.deepEqual(actual, expected); | |
} catch(e) { | } catch (e) { | |
ok(false, e.message); | assert.ok(false, e.message); | |
} | } | |
} | } | |
else { | else { | |
skipTest(); | skipTest(assert); | |
} | } | |
}); | }); | |
}); | }); | |
test('should work with empty arrays', 3, function() { | QUnit.test('should work with empty arrays', function(assert) { | |
var array = [[], [[]], [[], [[[]]]]], | assert.expect(2); | |
expected = [[], [], [[[]]]]; | ||
deepEqual(_.flatten(array), expected); | var array = [[], [[]], [[], [[[]]]]]; | |
expected = []; | assert.deepEqual(_.flatten(array), [[], [], [[[]]]]); | |
deepEqual(_.flatten(array, true), expected); | assert.deepEqual(_.flattenDeep(array), []); | |
deepEqual(_.flattenDeep(array), expected); | ||
}); | }); | |
test('should support flattening of nested arrays', 3, function() { | QUnit.test('should support flattening of nested arrays', function(assert) { | |
var array = [1, [2], [3, [4]]], | assert.expect(2); | |
expected = [1, 2, 3, [4]]; | ||
deepEqual(_.flatten(array), expected); | var array = [1, [2, 3], 4, [[5]]]; | |
expected = [1, 2, 3, 4]; | assert.deepEqual(_.flatten(array), [1, 2, 3, 4, [5]]); | |
deepEqual(_.flatten(array, true), expected); | assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]); | |
deepEqual(_.flattenDeep(array), expected); | ||
}); | }); | |
test('should return an empty array for non array-like objects', 3, function( | QUnit.test('should return an empty array for non array-like objects', functi | |
) { | on(assert) { | |
assert.expect(3); | ||
var expected = []; | var expected = []; | |
deepEqual(_.flatten({ 'a': 1 }), expected); | assert.deepEqual(_.flatten({ 'a': 1 }), expected); | |
deepEqual(_.flatten({ 'a': 1 }, true), expected); | assert.deepEqual(_.flatten({ 'a': 1 }, true), expected); | |
deepEqual(_.flattenDeep({ 'a': 1 }), expected); | assert.deepEqual(_.flattenDeep({ 'a': 1 }), expected); | |
}); | }); | |
test('should return a wrapped value when chaining', 6, function() { | QUnit.test('should return a wrapped value when chaining', function(assert) { | |
assert.expect(4); | ||
if (!isNpm) { | if (!isNpm) { | |
var wrapped = _([1, [2], [3, [4]]]), | var wrapped = _([1, [2], [3, [4]]]), | |
actual = wrapped.flatten(), | actual = wrapped.flatten(); | |
expected = [1, 2, 3, [4]]; | ||
ok(actual instanceof _); | ||
deepEqual(actual.value(), expected); | ||
expected = [1, 2, 3, 4]; | ||
actual = wrapped.flatten(true); | ||
ok(actual instanceof _); | assert.ok(actual instanceof _); | |
deepEqual(actual.value(), expected); | assert.deepEqual(actual.value(), [1, 2, 3, [4]]); | |
actual = wrapped.flattenDeep(); | actual = wrapped.flattenDeep(); | |
ok(actual instanceof _); | assert.ok(actual instanceof _); | |
deepEqual(actual.value(), expected); | assert.deepEqual(actual.value(), [1, 2, 3, 4]); | |
} | } | |
else { | else { | |
skipTest(6); | skipTest(assert, 4); | |
} | } | |
}); | }); | |
}(1, 2, 3)); | }(1, 2, 3)); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('flow methods'); | ||
lodashStable.each(['flow', 'flowRight'], function(methodName) { | ||
var func = _[methodName], | ||
isFlow = methodName == 'flow'; | ||
QUnit.test('`_.' + methodName + '` should supply each function with the retu | ||
rn value of the previous', function(assert) { | ||
assert.expect(1); | ||
var fixed = function(n) { return n.toFixed(1); }, | ||
combined = isFlow ? func(add, square, fixed) : func(fixed, square, add | ||
); | ||
assert.strictEqual(combined(1, 2), '9.0'); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should return a new function', function(a | ||
ssert) { | ||
assert.expect(1); | ||
assert.notStrictEqual(func(noop), noop); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should return an identity function when n | ||
o arguments are provided', function(assert) { | ||
assert.expect(3); | ||
var combined = func(); | ||
try { | ||
assert.strictEqual(combined('a'), 'a'); | ||
} catch (e) { | ||
assert.ok(false, e.message); | ||
} | ||
assert.strictEqual(combined.length, 0); | ||
assert.notStrictEqual(combined, identity); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should work with a curried function and ` | ||
_.head`', function(assert) { | ||
assert.expect(1); | ||
var curried = _.curry(identity); | ||
var combined = isFlow | ||
? func(_.head, curried) | ||
: func(curried, _.head); | ||
assert.strictEqual(combined([1]), 1); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should support shortcut fusion', function | ||
(assert) { | ||
assert.expect(6); | ||
var filterCount, | ||
mapCount, | ||
array = lodashStable.range(LARGE_ARRAY_SIZE), | ||
iteratee = function(value) { mapCount++; return square(value); }, | ||
predicate = function(value) { filterCount++; return isEven(value); }; | ||
lodashStable.times(2, function(index) { | ||
var filter1 = _.filter, | ||
filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2), | ||
filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate)) | ||
; | ||
var map1 = _.map, | ||
map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2), | ||
map3 = (_.map = index ? map2 : map1, map2(iteratee)); | ||
var take1 = _.take, | ||
take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2), | ||
take3 = (_.take = index ? take2 : take1, take2(2)); | ||
var combined = isFlow | ||
? func(map3, filter3, _.compact, take3) | ||
: func(take3, _.compact, filter3, map3); | ||
filterCount = mapCount = 0; | ||
assert.deepEqual(combined(array), [4, 16]); | ||
if (!isNpm && WeakMap && WeakMap.name) { | ||
assert.strictEqual(filterCount, 5, 'filterCount'); | ||
assert.strictEqual(mapCount, 5, 'mapCount'); | ||
} | ||
else { | ||
skipTest(assert, 2); | ||
} | ||
_.filter = filter1; | ||
_.map = map1; | ||
_.take = take1; | ||
}); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should work with curried functions with p | ||
laceholders', function(assert) { | ||
assert.expect(1); | ||
var curried = _.curry(_.ary(_.map, 2), 2), | ||
getProp = curried(curried.placeholder, 'a'), | ||
objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }]; | ||
var combined = isFlow | ||
? func(getProp, _.uniq) | ||
: func(_.uniq, getProp); | ||
assert.deepEqual(combined(objects), [1, 2]); | ||
}); | ||
QUnit.test('`_.' + methodName + '` should return a wrapped value when chaini | ||
ng', function(assert) { | ||
assert.expect(1); | ||
if (!isNpm) { | ||
var wrapped = _(noop)[methodName](); | ||
assert.ok(wrapped instanceof _); | ||
} | ||
else { | ||
skipTest(assert); | ||
} | ||
}); | ||
}); | ||
/*--------------------------------------------------------------------------*/ | ||
QUnit.module('lodash.forEach'); | QUnit.module('lodash.forEach'); | |
(function() { | (function() { | |
test('should be aliased', 1, function() { | QUnit.test('should be aliased', function(assert) { | |
strictEqual(_.each, _.forEach); | assert.expect(1); | |
assert.strictEqual(_.each, _.forEach); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('lodash.forEachRight'); | QUnit.module('lodash.forEachRight'); | |
(function() { | (function() { | |
test('should be aliased', 1, function() { | QUnit.test('should be aliased', function(assert) { | |
strictEqual(_.eachRight, _.forEachRight); | assert.expect(1); | |
assert.strictEqual(_.eachRight, _.forEachRight); | ||
}); | }); | |
}()); | }()); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('forIn methods'); | QUnit.module('forIn methods'); | |
_.each(['forIn', 'forInRight'], function(methodName) { | lodashStable.each(['forIn', 'forInRight'], function(methodName) { | |
var func = _[methodName]; | var func = _[methodName]; | |
test('`_.' + methodName + '` iterates over inherited properties', 1, functio | QUnit.test('`_.' + methodName + '` iterates over inherited properties', func | |
n() { | tion(assert) { | |
assert.expect(1); | ||
function Foo() { this.a = 1; } | function Foo() { this.a = 1; } | |
Foo.prototype.b = 2; | Foo.prototype.b = 2; | |
var keys = []; | var keys = []; | |
func(new Foo, function(value, key) { keys.push(key); }); | func(new Foo, function(value, key) { keys.push(key); }); | |
deepEqual(keys.sort(), ['a', 'b']); | assert.deepEqual(keys.sort(), ['a', 'b']); | |
}); | }); | |
}); | }); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('forOwn methods'); | QUnit.module('forOwn methods'); | |
_.each(['forOwn', 'forOwnRight'], function(methodName) { | lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) { | |
var func = _[methodName]; | var func = _[methodName]; | |
test('iterates over the `length` property', 1, function() { | QUnit.test('should iterate over `length` properties', function(assert) { | |
assert.expect(1); | ||
var object = { '0': 'zero', '1': 'one', 'length': 2 }, | var object = { '0': 'zero', '1': 'one', 'length': 2 }, | |
props = []; | props = []; | |
func(object, function(value, prop) { props.push(prop); }); | func(object, function(value, prop) { props.push(prop); }); | |
deepEqual(props.sort(), ['0', '1', 'length']); | assert.deepEqual(props.sort(), ['0', '1', 'length']); | |
}); | }); | |
}); | }); | |
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |
QUnit.module('iteration methods'); | QUnit.module('iteration methods'); | |
(function() { | (function() { | |
var methods = [ | var methods = [ | |
'_baseEach', | ||
'countBy', | 'countBy', | |
'every', | 'every', | |
'filter', | 'filter', | |
'find', | 'find', | |
'findIndex', | 'findIndex', | |
'findKey', | 'findKey', | |
'findLast', | 'findLast', | |
'findLastIndex', | 'findLastIndex', | |
'findLastKey', | 'findLastKey', | |
'forEach', | ||
'forEachRight', | 'forEachRight', | |
'forIn', | 'forIn', | |
'forInRight', | 'forInRight', | |
'forOwn', | 'forOwn', | |
'forOwnRight', | 'forOwnRight', | |
'groupBy', | 'groupBy', | |
'indexBy', | 'keyBy', | |
'map', | 'map', | |
'max', | 'mapKeys', | |
'min', | 'mapValues', | |
'maxBy', | ||
'minBy', | ||
'omitBy', | ||
'partition', | 'partition', | |
'pickBy', | ||
'reject', | 'reject', | |
'some' | 'some' | |
]; | ]; | |
var arrayMethods = [ | var arrayMethods = [ | |
'findIndex', | 'findIndex', | |
'findLastIndex' | 'findLastIndex', | |
'maxBy', | ||
'minBy' | ||
]; | ]; | |
var collectionMethods = [ | var collectionMethods = [ | |
'_baseEach', | ||
'countBy', | 'countBy', | |
'every', | 'every', | |
'filter', | 'filter', | |
'find', | 'find', | |
'findLast', | 'findLast', | |
'forEach', | 'forEach', | |
'forEachRight', | 'forEachRight', | |
'groupBy', | 'groupBy', | |
'indexBy', | 'keyBy', | |
'map', | 'map', | |
'max', | ||
'min', | ||
'partition', | 'partition', | |
'reduce', | 'reduce', | |
'reduceRight', | 'reduceRight', | |
'reject', | 'reject', | |
'some' | 'some' | |
]; | ]; | |
var forInMethods = [ | var forInMethods = [ | |
'forIn', | 'forIn', | |
'forInRight' | 'forInRight', | |
'omitBy', | ||
'pickBy' | ||
]; | ]; | |
var iterationMethods = [ | var iterationMethods = [ | |
'_baseEach', | ||
'forEach', | 'forEach', | |
'forEachRight', | 'forEachRight', | |
'forIn', |