Built motion from commit 1038d87.|0.0.141
[motion.git] / public / bower_components / lodash / test / test.js
1 ;(function() {
2
3   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
4   var undefined;
5
6   /** Used to detect when a function becomes hot. */
7   var HOT_COUNT = 150;
8
9   /** Used as the size to cover large array optimizations. */
10   var LARGE_ARRAY_SIZE = 200;
11
12   /** Used as the `TypeError` message for "Functions" methods. */
13   var FUNC_ERROR_TEXT = 'Expected a function';
14
15   /** Used as references for various `Number` constants. */
16   var MAX_SAFE_INTEGER = 9007199254740991,
17       MAX_INTEGER = 1.7976931348623157e+308;
18
19   /** Used as references for the maximum length and index of an array. */
20   var MAX_ARRAY_LENGTH = 4294967295,
21       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
22
23   /** `Object#toString` result references. */
24   var funcTag = '[object Function]',
25       numberTag = '[object Number]',
26       objectTag = '[object Object]';
27
28   /** Used as a reference to the global object. */
29   var root = (typeof global == 'object' && global) || this;
30
31   /** Used to store lodash to test for bad extensions/shims. */
32   var lodashBizarro = root.lodashBizarro;
33
34   /** Used for native method references. */
35   var arrayProto = Array.prototype,
36       errorProto = Error.prototype,
37       funcProto = Function.prototype,
38       objectProto = Object.prototype,
39       numberProto = Number.prototype,
40       stringProto = String.prototype;
41
42   /** Method and object shortcuts. */
43   var phantom = root.phantom,
44       process = root.process,
45       amd = root.define && define.amd,
46       argv = process && process.argv,
47       defineProperty = Object.defineProperty,
48       document = !phantom && root.document,
49       body = root.document && root.document.body,
50       create = Object.create,
51       fnToString = funcProto.toString,
52       freeze = Object.freeze,
53       identity = function(value) { return value; },
54       JSON = root.JSON,
55       noop = function() {},
56       objToString = objectProto.toString,
57       params = argv,
58       push = arrayProto.push,
59       realm = {},
60       slice = arrayProto.slice;
61
62   var ArrayBuffer = root.ArrayBuffer,
63       Buffer = root.Buffer,
64       Map = root.Map,
65       Set = root.Set,
66       Symbol = root.Symbol,
67       Uint8Array = root.Uint8Array,
68       WeakMap = root.WeakMap,
69       WeakSet = root.WeakSet;
70
71   var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
72       map = Map ? new Map : undefined,
73       set = Set ? new Set : undefined,
74       symbol = Symbol ? Symbol('a') : undefined,
75       weakMap = WeakMap ? new WeakMap : undefined,
76       weakSet = WeakSet ? new WeakSet : undefined;
77
78   /** Math helpers. */
79   var add = function(x, y) { return x + y; },
80       doubled = function(n) { return n * 2; },
81       isEven = function(n) { return n % 2 == 0; },
82       square = function(n) { return n * n; };
83
84   /** Constant functions. */
85   var alwaysA = function() { return 'a'; },
86       alwaysB = function() { return 'b'; },
87       alwaysC = function() { return 'c'; };
88
89   var alwaysTrue = function() { return true; },
90       alwaysFalse = function() { return false; };
91
92   var alwaysNaN = function() { return NaN; },
93       alwaysNull = function() { return null; },
94       alwaysUndefined = function() { return undefined; };
95
96   var alwaysZero = function() { return 0; },
97       alwaysOne = function() { return 1; },
98       alwaysTwo = function() { return 2; },
99       alwaysThree = function() { return 3; },
100       alwaysFour = function() { return 4; };
101
102   var alwaysEmptyArray = function() { return []; },
103       alwaysEmptyObject = function() { return {}; },
104       alwaysEmptyString = function() { return ''; };
105
106   /** The file path of the lodash file to test. */
107   var filePath = (function() {
108     var min = 2,
109         result = params || [];
110
111     if (phantom) {
112       min = 0;
113       result = params = phantom.args || require('system').args;
114     }
115     var last = result[result.length - 1];
116     result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
117
118     if (!amd) {
119       try {
120         result = require('fs').realpathSync(result);
121       } catch (e) {}
122
123       try {
124         result = require.resolve(result);
125       } catch (e) {}
126     }
127     return result;
128   }());
129
130   /** The `ui` object. */
131   var ui = root.ui || (root.ui = {
132     'buildPath': filePath,
133     'loaderPath': '',
134     'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath),
135     'isStrict': /\bes\b/.test(filePath),
136     'urlParams': {}
137   });
138
139   /** The basename of the lodash file to test. */
140   var basename = /[\w.-]+$/.exec(filePath)[0];
141
142   /** Used to indicate testing a modularized build. */
143   var isModularize = ui.isModularize;
144
145   /** Detect if testing `npm` modules. */
146   var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
147
148   /** Detect if running in PhantomJS. */
149   var isPhantom = phantom || (typeof callPhantom == 'function');
150
151   /** Detect if lodash is in strict mode. */
152   var isStrict = ui.isStrict;
153
154   /*--------------------------------------------------------------------------*/
155
156   // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
157   root.msWDfn = undefined;
158
159   // Exit early if going to run tests in a PhantomJS web page.
160   if (phantom && isModularize) {
161     var page = require('webpage').create();
162
163     page.onCallback = function(details) {
164       var coverage = details.coverage;
165       if (coverage) {
166         var fs = require('fs'),
167             cwd = fs.workingDirectory,
168             sep = fs.separator;
169
170         fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
171       }
172       phantom.exit(details.failed ? 1 : 0);
173     };
174
175     page.onConsoleMessage = function(message) {
176       console.log(message);
177     };
178
179     page.onInitialized = function() {
180       page.evaluate(function() {
181         document.addEventListener('DOMContentLoaded', function() {
182           QUnit.done(function(details) {
183             details.coverage = window.__coverage__;
184             callPhantom(details);
185           });
186         });
187       });
188     };
189
190     page.open(filePath, function(status) {
191       if (status != 'success') {
192         console.log('PhantomJS failed to load page: ' + filePath);
193         phantom.exit(1);
194       }
195     });
196
197     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
198     return;
199   }
200
201   /*--------------------------------------------------------------------------*/
202
203   /** Used to test Web Workers. */
204   var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
205     (document && document.origin != 'null') && root.Worker;
206
207   /** Used to test host objects in IE. */
208   try {
209     var xml = new ActiveXObject('Microsoft.XMLDOM');
210   } catch (e) {}
211
212   /** Poison the free variable `root` in Node.js */
213   try {
214     defineProperty(global.root, 'root', {
215       'configurable': false,
216       'enumerable': false,
217       'get': function() { throw new ReferenceError; }
218     });
219   } catch (e) {}
220
221   /** Use a single "load" function. */
222   var load = (!amd && typeof require == 'function')
223     ? require
224     : noop;
225
226   /** The unit testing framework. */
227   var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qunit.js'));
228
229   /** Load stable Lodash and QUnit Extras. */
230   var lodashStable = root.lodashStable;
231   if (!lodashStable) {
232     try {
233       lodashStable = load('../node_modules/lodash/lodash.js');
234     } catch (e) {
235       console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
236       return;
237     }
238     lodashStable = lodashStable.noConflict();
239   }
240   lodashStable = lodashStable.runInContext(root);
241
242   var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
243   if (QUnitExtras) {
244     QUnitExtras.runInContext(root);
245   }
246
247   /** The `lodash` function to test. */
248   var _ = root._ || (root._ = (
249     _ = load(filePath),
250     _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default']) || _,
251     (_.runInContext ? _.runInContext(root) : _)
252   ));
253
254   /** Used to detect instrumented istanbul code coverage runs. */
255   var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
256     return /^(?:\$\$cov_\d+\$\$)$/.test(key);
257   })];
258
259   /** Used to restore the `_` reference. */
260   var oldDash = root._;
261
262   /** Used to test generator functions. */
263   var generator = lodashStable.attempt(function() {
264     return Function('return function*(){}');
265   });
266
267   /** List of latin-1 supplementary letters to basic latin letters. */
268   var burredLetters = [
269     '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce',
270     '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
271     '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
272     '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
273   ];
274
275   /** List of combining diacritical marks. */
276   var comboMarks = [
277     '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
278     '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
279     '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
280     '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
281     '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
282     '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
283     '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
284     '\ufe20', '\ufe21', '\ufe22', '\ufe23'
285   ];
286
287   /** List of `burredLetters` translated to basic latin letters. */
288   var deburredLetters = [
289     'A',  'A', 'A', 'A', 'A', 'A', 'Ae', 'C',  'E', 'E', 'E', 'E', 'I', 'I', 'I',
290     'I',  'D', 'N', 'O', 'O', 'O', 'O',  'O',  'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
291     'ss', 'a', 'a', 'a', 'a', 'a', 'a',  'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i',  'i',
292     'i',  'd', 'n', 'o', 'o', 'o', 'o',  'o',  'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y'
293   ];
294
295   /** Used to specify the emoji style glyph variant of characters. */
296   var emojiVar = '\ufe0f';
297
298   /** Used to provide falsey values to methods. */
299   var falsey = [, '', 0, false, NaN, null, undefined];
300
301   /** Used to provide empty values to methods. */
302   var empties = [[], {}].concat(falsey.slice(1));
303
304   /** Used to test error objects. */
305   var errors = [
306     new Error,
307     new EvalError,
308     new RangeError,
309     new ReferenceError,
310     new SyntaxError,
311     new TypeError,
312     new URIError
313   ];
314
315   /** List of fitzpatrick modifiers. */
316   var fitzModifiers = [
317     '\ud83c\udffb',
318     '\ud83c\udffc',
319     '\ud83c\udffd',
320     '\ud83c\udffe',
321     '\ud83c\udfff'
322   ];
323
324   /** Used to check whether methods support typed arrays. */
325   var typedArrays = [
326     'Float32Array',
327     'Float64Array',
328     'Int8Array',
329     'Int16Array',
330     'Int32Array',
331     'Uint8Array',
332     'Uint8ClampedArray',
333     'Uint16Array',
334     'Uint32Array'
335   ];
336
337   /**
338    * Used to check for problems removing whitespace. For a whitespace reference,
339    * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
340    */
341   var whitespace = lodashStable.filter([
342     // Basic whitespace characters.
343     ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
344
345     // Line terminators.
346     '\n', '\r', '\u2028', '\u2029',
347
348     // Unicode category "Zs" space separators.
349     '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
350     '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
351   ],
352   function(chr) { return /\s/.exec(chr); })
353   .join('');
354
355   /**
356    * Creates a custom error object.
357    *
358    * @private
359    * @constructor
360    * @param {string} message The error message.
361    */
362   function CustomError(message) {
363     this.name = 'CustomError';
364     this.message = message;
365   }
366
367   CustomError.prototype = lodashStable.create(Error.prototype, {
368     'constructor': CustomError
369   });
370
371   /**
372    * Removes all own enumerable properties from a given object.
373    *
374    * @private
375    * @param {Object} object The object to empty.
376    */
377   function emptyObject(object) {
378     lodashStable.forOwn(object, function(value, key, object) {
379       delete object[key];
380     });
381   }
382
383   /**
384    * Extracts the unwrapped value from its wrapper.
385    *
386    * @private
387    * @param {Object} wrapper The wrapper to unwrap.
388    * @returns {*} Returns the unwrapped value.
389    */
390   function getUnwrappedValue(wrapper) {
391     var index = -1,
392         actions = wrapper.__actions__,
393         length = actions.length,
394         result = wrapper.__wrapped__;
395
396     while (++index < length) {
397       var args = [result],
398           action = actions[index];
399
400       push.apply(args, action.args);
401       result = action.func.apply(action.thisArg, args);
402     }
403     return result;
404   }
405
406   /**
407    * Sets a non-enumerable property value on `object`.
408    *
409    * Note: This function is used to avoid a bug in older versions of V8 where
410    * overwriting non-enumerable built-ins makes them enumerable.
411    * See https://code.google.com/p/v8/issues/detail?id=1623
412    *
413    * @private
414    * @param {Object} object The object modify.
415    * @param {string} key The name of the property to set.
416    * @param {*} value The property value.
417    */
418   function setProperty(object, key, value) {
419     try {
420       defineProperty(object, key, {
421         'configurable': true,
422         'enumerable': false,
423         'writable': true,
424         'value': value
425       });
426     } catch (e) {
427       object[key] = value;
428     }
429     return object;
430   }
431
432   /**
433    * Skips a given number of tests with a passing result.
434    *
435    * @private
436    * @param {Object} assert The QUnit assert object.
437    * @param {number} [count=1] The number of tests to skip.
438    */
439   function skipAssert(assert, count) {
440     count || (count = 1);
441     while (count--) {
442       assert.ok(true, 'test skipped');
443     }
444   }
445
446   /*--------------------------------------------------------------------------*/
447
448   // Add bizarro values.
449   (function() {
450     if (document || (typeof require != 'function')) {
451       return;
452     }
453     var nativeString = fnToString.call(toString),
454         reToString = /toString/g;
455
456     function createToString(funcName) {
457       return lodashStable.constant(nativeString.replace(reToString, funcName));
458     }
459
460     // Allow bypassing native checks.
461     setProperty(funcProto, 'toString', function wrapper() {
462       setProperty(funcProto, 'toString', fnToString);
463       var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
464       setProperty(funcProto, 'toString', wrapper);
465       return result;
466     });
467
468     // Add prototype extensions.
469     funcProto._method = noop;
470
471     // Set bad shims.
472     setProperty(Object, 'create', (function() {
473       function object() {}
474       return function(prototype) {
475         if (lodashStable.isObject(prototype)) {
476           object.prototype = prototype;
477           var result = new object;
478           object.prototype = undefined;
479         }
480         return result || {};
481       };
482     }()));
483
484     var _getOwnPropertySymbols = Object.getOwnPropertySymbols;
485     setProperty(Object, 'getOwnPropertySymbols', undefined);
486
487     var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
488     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
489       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
490     });
491
492     if (Buffer) {
493       defineProperty(root, 'Buffer', {
494         'configurable': true,
495         'enumerable': true,
496         'get': function get() {
497           var caller = get.caller,
498               name = caller ? caller.name : '';
499
500           if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
501             return Buffer;
502           }
503         }
504       });
505     }
506     if (Map) {
507       setProperty(root, 'Map', (function() {
508         var count = 0;
509         return function() {
510           if (count++) {
511             return new Map;
512           }
513           setProperty(root, 'Map', Map);
514           return {};
515         };
516       }()));
517
518       setProperty(root.Map, 'toString', createToString('Map'));
519     }
520     setProperty(root, 'Set', noop);
521     setProperty(root, 'Symbol', undefined);
522     setProperty(root, 'WeakMap', noop);
523
524     // Fake `WinRTError`.
525     setProperty(root, 'WinRTError', Error);
526
527     // Clear cache so lodash can be reloaded.
528     emptyObject(require.cache);
529
530     // Load lodash and expose it to the bad extensions/shims.
531     lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
532     root._ = oldDash;
533
534     // Restore built-in methods.
535     setProperty(Object, 'create', create);
536     setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
537     setProperty(root, 'Buffer', Buffer);
538
539     if (_getOwnPropertySymbols) {
540       Object.getOwnPropertySymbols = _getOwnPropertySymbols;
541     } else {
542       delete Object.getOwnPropertySymbols;
543     }
544     if (Map) {
545       setProperty(root, 'Map', Map);
546     } else {
547       delete root.Map;
548     }
549     if (Set) {
550       setProperty(root, 'Set', Set);
551     } else {
552       delete root.Set;
553     }
554     if (Symbol) {
555       setProperty(root, 'Symbol', Symbol);
556     } else {
557       delete root.Symbol;
558     }
559     if (WeakMap) {
560       setProperty(root, 'WeakMap', WeakMap);
561     } else {
562       delete root.WeakMap;
563     }
564     delete root.WinRTError;
565     delete funcProto._method;
566   }());
567
568   // Add other realm values from the `vm` module.
569   lodashStable.attempt(function() {
570     lodashStable.assign(realm, require('vm').runInNewContext([
571       '(function() {',
572       '  var noop = function() {},',
573       '      root = this;',
574       '',
575       '  var object = {',
576       "    'arguments': (function() { return arguments; }(1, 2, 3)),",
577       "    'array': [1],",
578       "    'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
579       "    'boolean': Object(false),",
580       "    'date': new Date,",
581       "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
582       "    'function': noop,",
583       "    'map': root.Map ? new root.Map : undefined,",
584       "    'nan': NaN,",
585       "    'null': null,",
586       "    'number': Object(0),",
587       "    'object': { 'a': 1 },",
588       "    'regexp': /x/,",
589       "    'set': root.Set ? new root.Set : undefined,",
590       "    'string': Object('a'),",
591       "    'symbol': root.Symbol ? root.Symbol() : undefined,",
592       "    'undefined': undefined,",
593       "    'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
594       "    'weakSet': root.WeakSet ? new root.WeakSet : undefined",
595       '  };',
596       '',
597       "  ['" + typedArrays.join("', '") + "'].forEach(function(type) {",
598       '    var Ctor = root[type]',
599       '    object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
600       '  });',
601       '',
602       '  return object;',
603       '}())'
604     ].join('\n')));
605   });
606
607   // Add other realm values from an iframe.
608   lodashStable.attempt(function() {
609     _._realm = realm;
610
611     var iframe = document.createElement('iframe');
612     iframe.frameBorder = iframe.height = iframe.width = 0;
613     body.appendChild(iframe);
614
615     var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
616     idoc.write([
617       '<script>',
618       'var _ = parent._;',
619       '',
620       '  var noop = function() {},',
621       '      root = this;',
622       '',
623       'var object = {',
624       "  'arguments': (function() { return arguments; }(1, 2, 3)),",
625       "  'array': [1],",
626       "  'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
627       "  'boolean': Object(false),",
628       "  'date': new Date,",
629       "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
630       "  'function': noop,",
631       "  'map': root.Map ? new root.Map : undefined,",
632       "  'nan': NaN,",
633       "  'null': null,",
634       "  'number': Object(0),",
635       "  'object': { 'a': 1 },",
636       "  'regexp': /x/,",
637       "  'set': root.Set ? new root.Set : undefined,",
638       "  'string': Object('a'),",
639       "  'symbol': root.Symbol ? root.Symbol() : undefined,",
640       "  'undefined': undefined,",
641       "  'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
642       "  'weakSet': root.WeakSet ? new root.WeakSet : undefined",
643       '};',
644       '',
645       "_.each(['" + typedArrays.join("', '") + "'], function(type) {",
646       '  var Ctor = root[type];',
647       '  object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
648       '});',
649       '',
650       '_.assign(_._realm, object);',
651       '<\/script>'
652     ].join('\n'));
653
654     idoc.close();
655     delete _._realm;
656   });
657
658   // Add a web worker.
659   lodashStable.attempt(function() {
660     var worker = new Worker('./asset/worker.js?t=' + (+new Date));
661     worker.addEventListener('message', function(e) {
662       _._VERSION = e.data || '';
663     }, false);
664
665     worker.postMessage(ui.buildPath);
666   });
667
668   // Expose internal modules for better code coverage.
669   lodashStable.attempt(function() {
670     var path = require('path'),
671         basePath = path.dirname(filePath);
672
673     if (isModularize && !(amd || isNpm)) {
674       lodashStable.each([
675         '_baseEach',
676         '_isIndex',
677         '_isIterateeCall'
678       ], function(relPath) {
679         var func = require(path.join(basePath, relPath)),
680             funcName = path.basename(relPath);
681
682         _['_' + funcName] = func[funcName] || func['default'] || func;
683       });
684     }
685   });
686
687   /*--------------------------------------------------------------------------*/
688
689   if (params) {
690     console.log('Running lodash tests.');
691     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
692   }
693
694   QUnit.module(basename);
695
696   (function() {
697     QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
698       assert.expect(1);
699
700       if (amd) {
701         assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
702       }
703       else {
704         skipAssert(assert);
705       }
706     });
707
708     QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
709       assert.expect(1);
710
711       if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
712         assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
713       } else {
714         skipAssert(assert);
715       }
716     });
717
718     QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
719       assert.expect(1);
720
721       if (amd) {
722         assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
723       }
724       else {
725         skipAssert(assert);
726       }
727     });
728
729     QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
730       assert.expect(1);
731
732       var done = assert.async();
733
734       if (Worker) {
735         var limit = 30000 / QUnit.config.asyncRetries,
736             start = +new Date;
737
738         var attempt = function() {
739           var actual = _._VERSION;
740           if ((new Date - start) < limit && typeof actual != 'string') {
741             setTimeout(attempt, 16);
742             return;
743           }
744           assert.strictEqual(actual, _.VERSION);
745           done();
746         };
747
748         attempt();
749       }
750       else {
751         skipAssert(assert);
752         done();
753       }
754     });
755
756     QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
757       assert.expect(1);
758
759       if (lodashBizarro) {
760         assert.notOk('_method' in lodashBizarro);
761       }
762       else {
763         skipAssert(assert);
764       }
765     });
766
767     QUnit.test('should avoid non-native built-ins', function(assert) {
768       assert.expect(6);
769
770       function message(lodashMethod, nativeMethod) {
771         return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
772       }
773
774       function Foo() { this.a = 1; }
775       Foo.prototype.b = 2;
776
777       var object = { 'a': 1 },
778           otherObject = { 'b': 2 },
779           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
780
781       if (lodashBizarro) {
782         try {
783           var actual = lodashBizarro.keysIn(new Foo).sort();
784         } catch (e) {
785           actual = null;
786         }
787         var label = message('_.keysIn', 'Object#propertyIsEnumerable');
788         assert.deepEqual(actual, ['a', 'b'], label);
789
790         try {
791           actual = [
792             lodashBizarro.difference([object, otherObject], largeArray),
793             lodashBizarro.intersection(largeArray, [object]),
794             lodashBizarro.uniq(largeArray)
795           ];
796         } catch (e) {
797           actual = null;
798         }
799         label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
800         assert.deepEqual(actual, [[otherObject], [object], [object]], label);
801
802         try {
803           if (Symbol) {
804             object[symbol] = {};
805           }
806           actual = [
807             lodashBizarro.clone(object),
808             lodashBizarro.cloneDeep(object)
809           ];
810         } catch (e) {
811           actual = null;
812         }
813         label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
814         assert.deepEqual(actual, [object, object], label);
815
816         try {
817           var symObject = Object(symbol);
818
819           // Avoid symbol detection in Babel's `typeof` helper.
820           symObject.constructor = Object;
821
822           actual = [
823             Symbol ? lodashBizarro.clone(symObject) : { 'constructor': Object },
824             Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
825             Symbol ? lodashBizarro.toString(symObject) : ''
826           ];
827         } catch (e) {
828           actual = null;
829         }
830         label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
831         assert.deepEqual(actual, [{ 'constructor': Object }, false, ''], label);
832
833         try {
834           var map = new lodashBizarro.memoize.Cache;
835           actual = map.set('a', 1).get('a');
836         } catch (e) {
837           actual = null;
838         }
839         label = message('_.memoize.Cache', 'Map');
840         assert.deepEqual(actual, 1, label);
841
842         try {
843           map = new (Map || Object);
844           if (Symbol && Symbol.iterator) {
845             map[Symbol.iterator] = null;
846           }
847           actual = lodashBizarro.toArray(map);
848         } catch (e) {
849           actual = null;
850         }
851         label = message('_.toArray', 'Map');
852         assert.deepEqual(actual, [], label);
853       }
854       else {
855         skipAssert(assert, 6);
856       }
857     });
858   }());
859
860   /*--------------------------------------------------------------------------*/
861
862   QUnit.module('isIndex');
863
864   (function() {
865     var func = _._isIndex;
866
867     QUnit.test('should return `true` for indexes', function(assert) {
868       assert.expect(1);
869
870       if (func) {
871         var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
872             expected = lodashStable.map(values, alwaysTrue);
873
874         var actual = lodashStable.map(values, function(args) {
875           return func.apply(undefined, args);
876         });
877
878         assert.deepEqual(actual, expected);
879       }
880       else {
881         skipAssert(assert);
882       }
883     });
884
885     QUnit.test('should return `false` for non-indexes', function(assert) {
886       assert.expect(1);
887
888       if (func) {
889         var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
890             expected = lodashStable.map(values, alwaysFalse);
891
892         var actual = lodashStable.map(values, function(args) {
893           return func.apply(undefined, args);
894         });
895
896         assert.deepEqual(actual, expected);
897       }
898       else {
899         skipAssert(assert);
900       }
901     });
902   }());
903
904   /*--------------------------------------------------------------------------*/
905
906   QUnit.module('isIterateeCall');
907
908   (function() {
909     var array = [1],
910         func = _._isIterateeCall,
911         object =  { 'a': 1 };
912
913     QUnit.test('should return `true` for iteratee calls', function(assert) {
914       assert.expect(3);
915
916       function Foo() {}
917       Foo.prototype.a = 1;
918
919       if (func) {
920         assert.strictEqual(func(1, 0, array), true);
921         assert.strictEqual(func(1, 'a', object), true);
922         assert.strictEqual(func(1, 'a', new Foo), true);
923       }
924       else {
925         skipAssert(assert, 3);
926       }
927     });
928
929     QUnit.test('should return `false` for non-iteratee calls', function(assert) {
930       assert.expect(4);
931
932       if (func) {
933         assert.strictEqual(func(2, 0, array), false);
934         assert.strictEqual(func(1, 1.1, array), false);
935         assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
936         assert.strictEqual(func(1, 'b', object), false);
937       }
938       else {
939         skipAssert(assert, 4);
940       }
941     });
942
943     QUnit.test('should work with `NaN` values', function(assert) {
944       assert.expect(2);
945
946       if (func) {
947         assert.strictEqual(func(NaN, 0, [NaN]), true);
948         assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
949       }
950       else {
951         skipAssert(assert, 2);
952       }
953     });
954
955     QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
956       assert.expect(1);
957
958       if (func) {
959         try {
960           var actual = func(1, { 'toString': null }, [1]);
961         } catch (e) {
962           var message = e.message;
963         }
964         assert.strictEqual(actual, false, message || '');
965       }
966       else {
967         skipAssert(assert);
968       }
969     });
970   }());
971
972   /*--------------------------------------------------------------------------*/
973
974   QUnit.module('lodash constructor');
975
976   (function() {
977     var values = empties.concat(true, 1, 'a'),
978         expected = lodashStable.map(values, alwaysTrue);
979
980     QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
981       assert.expect(1);
982
983       if (!isNpm) {
984         var actual = lodashStable.map(values, function(value) {
985           return _(value) instanceof _;
986         });
987
988         assert.deepEqual(actual, expected);
989       }
990       else {
991         skipAssert(assert);
992       }
993     });
994
995     QUnit.test('should return the given `lodash` instances', function(assert) {
996       assert.expect(1);
997
998       if (!isNpm) {
999         var actual = lodashStable.map(values, function(value) {
1000           var wrapped = _(value);
1001           return _(wrapped) === wrapped;
1002         });
1003
1004         assert.deepEqual(actual, expected);
1005       }
1006       else {
1007         skipAssert(assert);
1008       }
1009     });
1010
1011     QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
1012       assert.expect(1);
1013
1014       if (!isNpm && lodashBizarro) {
1015         var actual = lodashStable.map(values, function(value) {
1016           var wrapped = _(lodashBizarro(value)),
1017               unwrapped = wrapped.value();
1018
1019           return wrapped instanceof _ &&
1020             ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
1021         });
1022
1023         assert.deepEqual(actual, expected);
1024       }
1025       else {
1026         skipAssert(assert);
1027       }
1028     });
1029   }());
1030
1031   /*--------------------------------------------------------------------------*/
1032
1033   QUnit.module('lodash.add');
1034
1035   (function() {
1036     QUnit.test('should add two numbers', function(assert) {
1037       assert.expect(3);
1038
1039       assert.strictEqual(_.add(6, 4), 10);
1040       assert.strictEqual(_.add(-6, 4), -2);
1041       assert.strictEqual(_.add(-6, -4), -10);
1042     });
1043
1044     QUnit.test('should return `0` when no arguments are given', function(assert) {
1045       assert.expect(1);
1046
1047       assert.strictEqual(_.add(), 0);
1048     });
1049
1050     QUnit.test('should not coerce arguments to numbers', function(assert) {
1051       assert.expect(2);
1052
1053       assert.strictEqual(_.add('6', '4'), '64');
1054       assert.strictEqual(_.add('x', 'y'), 'xy');
1055     });
1056
1057     QUnit.test('should work with only an `augend` or `addend`', function(assert) {
1058       assert.expect(3);
1059
1060       assert.strictEqual(_.add(6), 6);
1061       assert.strictEqual(_.add(6, undefined), 6);
1062       assert.strictEqual(_.add(undefined, 4), 4);
1063     });
1064
1065     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1066       assert.expect(1);
1067
1068       if (!isNpm) {
1069         assert.strictEqual(_(1).add(2), 3);
1070       }
1071       else {
1072         skipAssert(assert);
1073       }
1074     });
1075
1076     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1077       assert.expect(1);
1078
1079       if (!isNpm) {
1080         assert.ok(_(1).chain().add(2) instanceof _);
1081       }
1082       else {
1083         skipAssert(assert);
1084       }
1085     });
1086   }());
1087
1088   /*--------------------------------------------------------------------------*/
1089
1090   QUnit.module('lodash.after');
1091
1092   (function() {
1093     function after(n, times) {
1094       var count = 0;
1095       lodashStable.times(times, _.after(n, function() { count++; }));
1096       return count;
1097     }
1098
1099     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1100       assert.expect(4);
1101
1102       assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1103       assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1104       assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1105       assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1106     });
1107
1108     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1109       assert.expect(1);
1110
1111       assert.strictEqual(after(NaN, 1), 1);
1112     });
1113
1114     QUnit.test('should not set a `this` binding', function(assert) {
1115       assert.expect(2);
1116
1117       var after = _.after(1, function(assert) { return ++this.count; }),
1118           object = { 'after': after, 'count': 0 };
1119
1120       object.after();
1121       assert.strictEqual(object.after(), 2);
1122       assert.strictEqual(object.count, 2);
1123     });
1124   }());
1125
1126   /*--------------------------------------------------------------------------*/
1127
1128   QUnit.module('lodash.ary');
1129
1130   (function() {
1131     function fn(a, b, c) {
1132       return slice.call(arguments);
1133     }
1134
1135     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1136       assert.expect(2);
1137
1138       var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1139       assert.deepEqual(actual, [6, 8, 10]);
1140
1141       var capped = _.ary(fn, 2);
1142       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1143     });
1144
1145     QUnit.test('should use `func.length` if `n` is not given', function(assert) {
1146       assert.expect(1);
1147
1148       var capped = _.ary(fn);
1149       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1150     });
1151
1152     QUnit.test('should treat a negative `n` as `0`', function(assert) {
1153       assert.expect(1);
1154
1155       var capped = _.ary(fn, -1);
1156
1157       try {
1158         var actual = capped('a');
1159       } catch (e) {}
1160
1161       assert.deepEqual(actual, []);
1162     });
1163
1164     QUnit.test('should coerce `n` to an integer', function(assert) {
1165       assert.expect(1);
1166
1167       var values = ['1', 1.6, 'xyz'],
1168           expected = [['a'], ['a'], []];
1169
1170       var actual = lodashStable.map(values, function(n) {
1171         var capped = _.ary(fn, n);
1172         return capped('a', 'b');
1173       });
1174
1175       assert.deepEqual(actual, expected);
1176     });
1177
1178     QUnit.test('should work when given less than the capped number of arguments', function(assert) {
1179       assert.expect(1);
1180
1181       var capped = _.ary(fn, 3);
1182       assert.deepEqual(capped('a'), ['a']);
1183     });
1184
1185     QUnit.test('should use the existing `ary` if smaller', function(assert) {
1186       assert.expect(1);
1187
1188       var capped = _.ary(_.ary(fn, 1), 2);
1189       assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1190     });
1191
1192     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1193       assert.expect(1);
1194
1195       var funcs = lodashStable.map([fn], _.ary),
1196           actual = funcs[0]('a', 'b', 'c');
1197
1198       assert.deepEqual(actual, ['a', 'b', 'c']);
1199     });
1200
1201     QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1202       assert.expect(2);
1203
1204       var array = ['a', 'b', 'c'],
1205           includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1206
1207       assert.strictEqual(includes('b')(array, 2), true);
1208
1209       if (!isNpm) {
1210         includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1211         assert.strictEqual(includes('b')(array, 2), true);
1212       }
1213       else {
1214         skipAssert(assert);
1215       }
1216     });
1217   }());
1218
1219   /*--------------------------------------------------------------------------*/
1220
1221   QUnit.module('lodash.assignIn');
1222
1223   (function() {
1224     QUnit.test('should be aliased', function(assert) {
1225       assert.expect(1);
1226
1227       assert.strictEqual(_.extend, _.assignIn);
1228     });
1229   }());
1230
1231   /*--------------------------------------------------------------------------*/
1232
1233   QUnit.module('lodash.assign and lodash.assignIn');
1234
1235   lodashStable.each(['assign', 'assignIn'], function(methodName) {
1236     var func = _[methodName];
1237
1238     QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1239       assert.expect(1);
1240
1241       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1242     });
1243
1244     QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1245       assert.expect(2);
1246
1247       var expected = { 'a': 1, 'b': 2, 'c': 3 };
1248       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1249       assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1250     });
1251
1252     QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1253       assert.expect(1);
1254
1255       var expected = { 'a': 3, 'b': 2, 'c': 1 };
1256       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1257     });
1258
1259     QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1260       assert.expect(1);
1261
1262       var expected = { 'a': null, 'b': undefined, 'c': null };
1263       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1264     });
1265
1266     QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1267       assert.expect(1);
1268
1269       var object = {};
1270
1271       var descriptor = {
1272         'configurable': true,
1273         'enumerable': true,
1274         'set': function() { throw new Error; }
1275       };
1276
1277       var source = {
1278         'a': 1,
1279         'b': undefined,
1280         'c': NaN,
1281         'd': undefined,
1282         'constructor': Object,
1283         'toString': lodashStable.constant('source')
1284       };
1285
1286       defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1287         'get': alwaysOne
1288       }));
1289
1290       defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1291         'get': alwaysUndefined
1292       }));
1293
1294       defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1295         'get': alwaysNaN
1296       }));
1297
1298       defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1299         'get': lodashStable.constant(Object)
1300       }));
1301
1302       try {
1303         var actual = func(object, source);
1304       } catch (e) {}
1305
1306       assert.deepEqual(actual, source);
1307     });
1308   });
1309
1310   /*--------------------------------------------------------------------------*/
1311
1312   QUnit.module('lodash.assignInWith');
1313
1314   (function() {
1315     QUnit.test('should be aliased', function(assert) {
1316       assert.expect(1);
1317
1318       assert.strictEqual(_.extendWith, _.assignInWith);
1319     });
1320   }());
1321
1322   /*--------------------------------------------------------------------------*/
1323
1324   QUnit.module('lodash.assignWith and lodash.assignInWith');
1325
1326   lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1327     var func = _[methodName];
1328
1329     QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1330       assert.expect(1);
1331
1332       var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1333         return a === undefined ? b : a;
1334       });
1335
1336       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1337     });
1338
1339     QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1340       assert.expect(1);
1341
1342       var expected = { 'a': undefined };
1343       assert.deepEqual(func({}, expected, alwaysUndefined), expected);
1344     });
1345   });
1346
1347   /*--------------------------------------------------------------------------*/
1348
1349   QUnit.module('lodash.at');
1350
1351   (function() {
1352     var args = arguments,
1353         array = ['a', 'b', 'c'],
1354         object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1355
1356     QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1357       assert.expect(1);
1358
1359       var actual = _.at(array, [0, 2]);
1360       assert.deepEqual(actual, ['a', 'c']);
1361     });
1362
1363     QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1364       assert.expect(1);
1365
1366       var actual = _.at(array, [2, 4, 0]);
1367       assert.deepEqual(actual, ['c', undefined, 'a']);
1368     });
1369
1370     QUnit.test('should work with non-index keys on array values', function(assert) {
1371       assert.expect(1);
1372
1373       var values = lodashStable.reject(empties, function(value) {
1374         return (value === 0) || lodashStable.isArray(value);
1375       }).concat(-1, 1.1);
1376
1377       var array = lodashStable.transform(values, function(result, value) {
1378         result[value] = 1;
1379       }, []);
1380
1381       var expected = lodashStable.map(values, alwaysOne),
1382           actual = _.at(array, values);
1383
1384       assert.deepEqual(actual, expected);
1385     });
1386
1387     QUnit.test('should return an empty array when no keys are given', function(assert) {
1388       assert.expect(2);
1389
1390       assert.deepEqual(_.at(array), []);
1391       assert.deepEqual(_.at(array, [], []), []);
1392     });
1393
1394     QUnit.test('should accept multiple key arguments', function(assert) {
1395       assert.expect(1);
1396
1397       var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1398       assert.deepEqual(actual, ['d', 'a', 'c']);
1399     });
1400
1401     QUnit.test('should work with a falsey `object` argument when keys are given', function(assert) {
1402       assert.expect(1);
1403
1404       var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1405
1406       var actual = lodashStable.map(falsey, function(object) {
1407         try {
1408           return _.at(object, 0, 1, 'pop', 'push');
1409         } catch (e) {}
1410       });
1411
1412       assert.deepEqual(actual, expected);
1413     });
1414
1415     QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1416       assert.expect(1);
1417
1418       var actual = _.at(args, [2, 0]);
1419       assert.deepEqual(actual, [3, 1]);
1420     });
1421
1422     QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1423       assert.expect(1);
1424
1425       var actual = _.at([1, 2, 3, 4, 5], args);
1426       assert.deepEqual(actual, [2, 3, 4]);
1427     });
1428
1429     QUnit.test('should work with an object for `object`', function(assert) {
1430       assert.expect(1);
1431
1432       var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1433       assert.deepEqual(actual, [3, 4]);
1434     });
1435
1436     QUnit.test('should pluck inherited property values', function(assert) {
1437       assert.expect(1);
1438
1439       function Foo() { this.a = 1; }
1440       Foo.prototype.b = 2;
1441
1442       var actual = _.at(new Foo, 'b');
1443       assert.deepEqual(actual, [2]);
1444     });
1445
1446     QUnit.test('should work in a lazy sequence', function(assert) {
1447       assert.expect(6);
1448
1449       if (!isNpm) {
1450         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1451             smallArray = array;
1452
1453         lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1454           lodashStable.times(2, function(index) {
1455             var array = index ? largeArray : smallArray,
1456                 wrapped = _(array).map(identity).at(paths);
1457
1458             assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1459           });
1460         });
1461       }
1462       else {
1463         skipAssert(assert, 6);
1464       }
1465     });
1466
1467     QUnit.test('should support shortcut fusion', function(assert) {
1468       assert.expect(8);
1469
1470       if (!isNpm) {
1471         var array = lodashStable.range(LARGE_ARRAY_SIZE),
1472             count = 0,
1473             iteratee = function(value) { count++; return square(value); },
1474             lastIndex = LARGE_ARRAY_SIZE - 1;
1475
1476         lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1477           count = 0;
1478           var actual = _(array).map(iteratee).at(n).value(),
1479               expected = index < 2 ? 1 : 0;
1480
1481           assert.strictEqual(count, expected);
1482
1483           expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1484           assert.deepEqual(actual, expected);
1485         });
1486       }
1487       else {
1488         skipAssert(assert, 8);
1489       }
1490     });
1491
1492     QUnit.test('work with an object for `object` when chaining', function(assert) {
1493       assert.expect(2);
1494
1495       if (!isNpm) {
1496         var paths = ['a[0].b.c', 'a[1]'],
1497             actual = _(object).map(identity).at(paths).value();
1498
1499         assert.deepEqual(actual, _.at(_.map(object, identity), paths));
1500
1501         var indexObject = { '0': 1 };
1502         actual = _(indexObject).at(0).value();
1503         assert.deepEqual(actual, _.at(indexObject, 0));
1504       }
1505       else {
1506         skipAssert(assert, 2);
1507       }
1508     });
1509   }(1, 2, 3));
1510
1511   /*--------------------------------------------------------------------------*/
1512
1513   QUnit.module('lodash.attempt');
1514
1515   (function() {
1516     QUnit.test('should return the result of `func`', function(assert) {
1517       assert.expect(1);
1518
1519       assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1520     });
1521
1522     QUnit.test('should provide additional arguments to `func`', function(assert) {
1523       assert.expect(1);
1524
1525       var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1526       assert.deepEqual(actual, [1, 2]);
1527     });
1528
1529     QUnit.test('should return the caught error', function(assert) {
1530       assert.expect(1);
1531
1532       var expected = lodashStable.map(errors, alwaysTrue);
1533
1534       var actual = lodashStable.map(errors, function(error) {
1535         return _.attempt(function() { throw error; }) === error;
1536       });
1537
1538       assert.deepEqual(actual, expected);
1539     });
1540
1541     QUnit.test('should coerce errors to error objects', function(assert) {
1542       assert.expect(1);
1543
1544       var actual = _.attempt(function() { throw 'x'; });
1545       assert.ok(lodashStable.isEqual(actual, Error('x')));
1546     });
1547
1548     QUnit.test('should preserve custom errors', function(assert) {
1549       assert.expect(1);
1550
1551       var actual = _.attempt(function() { throw new CustomError('x'); });
1552       assert.ok(actual instanceof CustomError);
1553     });
1554
1555     QUnit.test('should work with an error object from another realm', function(assert) {
1556       assert.expect(1);
1557
1558       if (realm.errors) {
1559         var expected = lodashStable.map(realm.errors, alwaysTrue);
1560
1561         var actual = lodashStable.map(realm.errors, function(error) {
1562           return _.attempt(function() { throw error; }) === error;
1563         });
1564
1565         assert.deepEqual(actual, expected);
1566       }
1567       else {
1568         skipAssert(assert);
1569       }
1570     });
1571
1572     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1573       assert.expect(1);
1574
1575       if (!isNpm) {
1576         assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1577       }
1578       else {
1579         skipAssert(assert);
1580       }
1581     });
1582
1583     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1584       assert.expect(1);
1585
1586       if (!isNpm) {
1587         assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1588       }
1589       else {
1590         skipAssert(assert);
1591       }
1592     });
1593   }());
1594
1595   /*--------------------------------------------------------------------------*/
1596
1597   QUnit.module('lodash.before');
1598
1599   (function() {
1600     function before(n, times) {
1601       var count = 0;
1602       lodashStable.times(times, _.before(n, function() { count++; }));
1603       return count;
1604     }
1605
1606     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1607       assert.expect(4);
1608
1609       assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1610       assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1611       assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1612       assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1613     });
1614
1615     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1616       assert.expect(1);
1617
1618       assert.strictEqual(before(NaN, 1), 0);
1619     });
1620
1621     QUnit.test('should not set a `this` binding', function(assert) {
1622       assert.expect(2);
1623
1624       var before = _.before(2, function(assert) { return ++this.count; }),
1625           object = { 'before': before, 'count': 0 };
1626
1627       object.before();
1628       assert.strictEqual(object.before(), 1);
1629       assert.strictEqual(object.count, 1);
1630     });
1631   }());
1632
1633   /*--------------------------------------------------------------------------*/
1634
1635   QUnit.module('lodash.bind');
1636
1637   (function() {
1638     function fn() {
1639       var result = [this];
1640       push.apply(result, arguments);
1641       return result;
1642     }
1643
1644     QUnit.test('should bind a function to an object', function(assert) {
1645       assert.expect(1);
1646
1647       var object = {},
1648           bound = _.bind(fn, object);
1649
1650       assert.deepEqual(bound('a'), [object, 'a']);
1651     });
1652
1653     QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
1654       assert.expect(1);
1655
1656       var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1657           expected = lodashStable.map(values, function(value) { return [value]; });
1658
1659       var actual = lodashStable.map(values, function(value) {
1660         try {
1661           var bound = _.bind(fn, value);
1662           return bound();
1663         } catch (e) {}
1664       });
1665
1666       assert.ok(lodashStable.every(actual, function(value, index) {
1667         return lodashStable.isEqual(value, expected[index]);
1668       }));
1669     });
1670
1671     QUnit.test('should bind a function to nullish values', function(assert) {
1672       assert.expect(6);
1673
1674       var bound = _.bind(fn, null),
1675           actual = bound('a');
1676
1677       assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1678       assert.strictEqual(actual[1], 'a');
1679
1680       lodashStable.times(2, function(index) {
1681         bound = index ? _.bind(fn, undefined) : _.bind(fn);
1682         actual = bound('b');
1683
1684         assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1685         assert.strictEqual(actual[1], 'b');
1686       });
1687     });
1688
1689     QUnit.test('should partially apply arguments ', function(assert) {
1690       assert.expect(4);
1691
1692       var object = {},
1693           bound = _.bind(fn, object, 'a');
1694
1695       assert.deepEqual(bound(), [object, 'a']);
1696
1697       bound = _.bind(fn, object, 'a');
1698       assert.deepEqual(bound('b'), [object, 'a', 'b']);
1699
1700       bound = _.bind(fn, object, 'a', 'b');
1701       assert.deepEqual(bound(), [object, 'a', 'b']);
1702       assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1703     });
1704
1705     QUnit.test('should support placeholders', function(assert) {
1706       assert.expect(4);
1707
1708       var object = {},
1709           ph = _.bind.placeholder,
1710           bound = _.bind(fn, object, ph, 'b', ph);
1711
1712       assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1713       assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1714       assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1715       assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1716     });
1717
1718     QUnit.test('should use `_.placeholder` when set', function(assert) {
1719       assert.expect(1);
1720
1721       if (!isModularize) {
1722         var _ph = _.placeholder = {},
1723             ph = _.bind.placeholder,
1724             object = {},
1725             bound = _.bind(fn, object, _ph, 'b', ph);
1726
1727         assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
1728         delete _.placeholder;
1729       }
1730       else {
1731         skipAssert(assert);
1732       }
1733     });
1734
1735     QUnit.test('should create a function with a `length` of `0`', function(assert) {
1736       assert.expect(2);
1737
1738       var fn = function(a, b, c) {},
1739           bound = _.bind(fn, {});
1740
1741       assert.strictEqual(bound.length, 0);
1742
1743       bound = _.bind(fn, {}, 1);
1744       assert.strictEqual(bound.length, 0);
1745     });
1746
1747     QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1748       assert.expect(3);
1749
1750       function Foo() {
1751         return this;
1752       }
1753
1754       var bound = _.bind(Foo, { 'a': 1 }),
1755           newBound = new bound;
1756
1757       assert.strictEqual(bound().a, 1);
1758       assert.strictEqual(newBound.a, undefined);
1759       assert.ok(newBound instanceof Foo);
1760     });
1761
1762     QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1763       assert.expect(1);
1764
1765       function Foo() {
1766         return this;
1767       }
1768
1769       function Bar() {}
1770
1771       var thisArg = { 'a': 1 },
1772           boundFoo = _.bind(Foo, thisArg),
1773           boundBar = _.bind(Bar, thisArg),
1774           count = 9,
1775           expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1776
1777       var actual = lodashStable.times(count, function(index) {
1778         try {
1779           switch (index) {
1780             case 0: return [new boundFoo().a, new boundBar().a];
1781             case 1: return [new boundFoo(1).a, new boundBar(1).a];
1782             case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1783             case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1784             case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1785             case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1786             case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1787             case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1788             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];
1789           }
1790         } catch (e) {}
1791       });
1792
1793       assert.deepEqual(actual, expected);
1794     });
1795
1796     QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1797       assert.expect(2);
1798
1799       function Foo(value) {
1800         return value && object;
1801       }
1802
1803       var bound = _.bind(Foo),
1804           object = {};
1805
1806       assert.ok(new bound instanceof Foo);
1807       assert.strictEqual(new bound(true), object);
1808     });
1809
1810     QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1811       assert.expect(1);
1812
1813       var object = {},
1814           bound = _.bind(fn, object, 'a');
1815
1816       assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1817     });
1818
1819     QUnit.test('should not rebind functions', function(assert) {
1820       assert.expect(3);
1821
1822       var object1 = {},
1823           object2 = {},
1824           object3 = {};
1825
1826       var bound1 = _.bind(fn, object1),
1827           bound2 = _.bind(bound1, object2, 'a'),
1828           bound3 = _.bind(bound1, object3, 'b');
1829
1830       assert.deepEqual(bound1(), [object1]);
1831       assert.deepEqual(bound2(), [object1, 'a']);
1832       assert.deepEqual(bound3(), [object1, 'b']);
1833     });
1834
1835     QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1836       assert.expect(2);
1837
1838       var Ctor = _.bind(Date, null),
1839           expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1840
1841       try {
1842         var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1843       } catch (e) {}
1844
1845       assert.deepEqual(actual, expected);
1846
1847       Ctor = _.bind(Date, null, 2012, 4, 23);
1848
1849       try {
1850         actual = new Ctor(0, 0, 0, 0);
1851       } catch (e) {}
1852
1853       assert.deepEqual(actual, expected);
1854     });
1855
1856     QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
1857       assert.expect(1);
1858
1859       var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
1860
1861       if (typeof createCtor == 'function') {
1862         var bound = _.bind(createCtor()),
1863             count = 8,
1864             expected = lodashStable.times(count, alwaysTrue);
1865
1866         var actual = lodashStable.times(count, function(index) {
1867           try {
1868             switch (index) {
1869               case 0: return !!(new bound);
1870               case 1: return !!(new bound(1));
1871               case 2: return !!(new bound(1, 2));
1872               case 3: return !!(new bound(1, 2, 3));
1873               case 4: return !!(new bound(1, 2, 3, 4));
1874               case 5: return !!(new bound(1, 2, 3, 4, 5));
1875               case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
1876               case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
1877             }
1878           } catch (e) {}
1879         });
1880
1881         assert.deepEqual(actual, expected);
1882       }
1883       else {
1884         skipAssert(assert);
1885       }
1886     });
1887
1888     QUnit.test('should return a wrapped value when chaining', function(assert) {
1889       assert.expect(2);
1890
1891       if (!isNpm) {
1892         var object = {},
1893             bound = _(fn).bind({}, 'a', 'b');
1894
1895         assert.ok(bound instanceof _);
1896
1897         var actual = bound.value()('c');
1898         assert.deepEqual(actual, [object, 'a', 'b', 'c']);
1899       }
1900       else {
1901         skipAssert(assert, 2);
1902       }
1903     });
1904   }());
1905
1906   /*--------------------------------------------------------------------------*/
1907
1908   QUnit.module('lodash.bindAll');
1909
1910   (function() {
1911     var args = arguments;
1912
1913     var source = {
1914       '_a': 1,
1915       '_b': 2,
1916       '_c': 3,
1917       '_d': 4,
1918       'a': function() { return this._a; },
1919       'b': function() { return this._b; },
1920       'c': function() { return this._c; },
1921       'd': function() { return this._d; }
1922     };
1923
1924     QUnit.test('should accept individual method names', function(assert) {
1925       assert.expect(1);
1926
1927       var object = lodashStable.cloneDeep(source);
1928       _.bindAll(object, 'a', 'b');
1929
1930       var actual = lodashStable.map(['a', 'b', 'c'], function(methodName) {
1931         return object[methodName].call({});
1932       });
1933
1934       assert.deepEqual(actual, [1, 2, undefined]);
1935     });
1936
1937     QUnit.test('should accept arrays of method names', function(assert) {
1938       assert.expect(1);
1939
1940       var object = lodashStable.cloneDeep(source);
1941       _.bindAll(object, ['a', 'b'], ['c']);
1942
1943       var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(methodName) {
1944         return object[methodName].call({});
1945       });
1946
1947       assert.deepEqual(actual, [1, 2, 3, undefined]);
1948     });
1949
1950     QUnit.test('should work with an array `object` argument', function(assert) {
1951       assert.expect(1);
1952
1953       var array = ['push', 'pop'];
1954       _.bindAll(array);
1955       assert.strictEqual(array.pop, arrayProto.pop);
1956     });
1957
1958     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
1959       assert.expect(1);
1960
1961       var object = lodashStable.cloneDeep(source);
1962       _.bindAll(object, args);
1963
1964       var actual = lodashStable.map(args, function(methodName) {
1965         return object[methodName].call({});
1966       });
1967
1968       assert.deepEqual(actual, [1]);
1969     });
1970   }('a'));
1971
1972   /*--------------------------------------------------------------------------*/
1973
1974   QUnit.module('lodash.bindKey');
1975
1976   (function() {
1977     QUnit.test('should work when the target function is overwritten', function(assert) {
1978       assert.expect(2);
1979
1980       var object = {
1981         'user': 'fred',
1982         'greet': function(greeting) {
1983           return this.user + ' says: ' + greeting;
1984         }
1985       };
1986
1987       var bound = _.bindKey(object, 'greet', 'hi');
1988       assert.strictEqual(bound(), 'fred says: hi');
1989
1990       object.greet = function(greeting) {
1991         return this.user + ' says: ' + greeting + '!';
1992       };
1993
1994       assert.strictEqual(bound(), 'fred says: hi!');
1995     });
1996
1997     QUnit.test('should support placeholders', function(assert) {
1998       assert.expect(4);
1999
2000       var object = {
2001         'fn': function() {
2002           return slice.call(arguments);
2003         }
2004       };
2005
2006       var ph = _.bindKey.placeholder,
2007           bound = _.bindKey(object, 'fn', ph, 'b', ph);
2008
2009       assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
2010       assert.deepEqual(bound('a'), ['a', 'b', undefined]);
2011       assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
2012       assert.deepEqual(bound(), [undefined, 'b', undefined]);
2013     });
2014
2015     QUnit.test('should use `_.placeholder` when set', function(assert) {
2016       assert.expect(1);
2017
2018       if (!isModularize) {
2019         var object = {
2020           'fn': function() {
2021             return slice.call(arguments);
2022           }
2023         };
2024
2025         var _ph = _.placeholder = {},
2026             ph = _.bindKey.placeholder,
2027             bound = _.bindKey(object, 'fn', _ph, 'b', ph);
2028
2029         assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
2030         delete _.placeholder;
2031       }
2032       else {
2033         skipAssert(assert);
2034       }
2035     });
2036
2037     QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
2038       assert.expect(2);
2039
2040       function Foo(value) {
2041         return value && object;
2042       }
2043
2044       var object = { 'Foo': Foo },
2045           bound = _.bindKey(object, 'Foo');
2046
2047       assert.ok(new bound instanceof Foo);
2048       assert.strictEqual(new bound(true), object);
2049     });
2050   }());
2051
2052   /*--------------------------------------------------------------------------*/
2053
2054   QUnit.module('case methods');
2055
2056   lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
2057     var methodName = caseName + 'Case',
2058         func = _[methodName];
2059
2060     var strings = [
2061       'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
2062       'FOO BAR', 'fooBar', '--foo-bar', '__foo_bar__'
2063     ];
2064
2065     var converted = (function() {
2066       switch (caseName) {
2067         case 'camel': return 'fooBar';
2068         case 'kebab': return 'foo-bar';
2069         case 'lower': return 'foo bar';
2070         case 'snake': return 'foo_bar';
2071         case 'start': return 'Foo Bar';
2072         case 'upper': return 'FOO BAR';
2073       }
2074     }());
2075
2076     QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
2077       assert.expect(1);
2078
2079       var actual = lodashStable.map(strings, function(string) {
2080         return func(string) === converted;
2081       });
2082
2083       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2084     });
2085
2086     QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
2087       assert.expect(1);
2088
2089       var actual = lodashStable.map(strings, function(string) {
2090         return func(func(string)) === converted;
2091       });
2092
2093       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2094     });
2095
2096     QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
2097       assert.expect(1);
2098
2099       var actual = lodashStable.map(burredLetters, function(burred, index) {
2100         var letter = deburredLetters[index];
2101         if (caseName == 'start') {
2102           letter = lodashStable.capitalize(letter);
2103         } else if (caseName == 'upper') {
2104           letter = letter.toUpperCase();
2105         } else {
2106           letter = letter.toLowerCase();
2107         }
2108         return func(burred) === letter;
2109       });
2110
2111       assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue));
2112     });
2113
2114     QUnit.test('`_.' + methodName + '` should trim latin-1 mathematical operators', function(assert) {
2115       assert.expect(1);
2116
2117       var actual = lodashStable.map(['\xd7', '\xf7'], func);
2118       assert.deepEqual(actual, ['', '']);
2119     });
2120
2121     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2122       assert.expect(2);
2123
2124       var string = 'foo bar';
2125       assert.strictEqual(func(Object(string)), converted);
2126       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2127     });
2128
2129     QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2130       assert.expect(1);
2131
2132       if (!isNpm) {
2133         assert.strictEqual(_('foo bar')[methodName](), converted);
2134       }
2135       else {
2136         skipAssert(assert);
2137       }
2138     });
2139
2140     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2141       assert.expect(1);
2142
2143       if (!isNpm) {
2144         assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2145       }
2146       else {
2147         skipAssert(assert);
2148       }
2149     });
2150   });
2151
2152   (function() {
2153     QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2154       assert.expect(1);
2155
2156       var funcs = [_.camelCase, _.kebabCase, _.snakeCase, _.startCase, _.camelCase];
2157
2158       var actual = lodashStable.reduce(funcs, function(result, func) {
2159         return func(result);
2160       }, 'enable 6h format');
2161
2162       assert.strictEqual(actual, 'enable6HFormat');
2163     });
2164   }());
2165
2166   /*--------------------------------------------------------------------------*/
2167
2168   QUnit.module('lodash.camelCase');
2169
2170   (function() {
2171     QUnit.test('should work with numbers', function(assert) {
2172       assert.expect(6);
2173
2174       assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2175       assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
2176       assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
2177       assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2178       assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2179       assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2180     });
2181
2182     QUnit.test('should handle acronyms', function(assert) {
2183       assert.expect(6);
2184
2185       lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2186         assert.strictEqual(_.camelCase(string), 'safeHtml');
2187       });
2188
2189       lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2190         assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2191       });
2192
2193       lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2194         assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2195       });
2196     });
2197   }());
2198
2199   /*--------------------------------------------------------------------------*/
2200
2201   QUnit.module('lodash.capitalize');
2202
2203   (function() {
2204     QUnit.test('should capitalize the first character of a string', function(assert) {
2205       assert.expect(3);
2206
2207       assert.strictEqual(_.capitalize('fred'), 'Fred');
2208       assert.strictEqual(_.capitalize('Fred'), 'Fred');
2209       assert.strictEqual(_.capitalize(' fred'), ' fred');
2210     });
2211   }());
2212
2213   /*--------------------------------------------------------------------------*/
2214
2215   QUnit.module('lodash.castArray');
2216
2217   (function() {
2218     QUnit.test('should wrap non array items in an array', function(assert) {
2219       assert.expect(1);
2220
2221       var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
2222           expected = lodashStable.map(values, function(value) { return [value]; }),
2223           actual = lodashStable.map(values, _.castArray);
2224
2225       assert.deepEqual(actual, expected);
2226     });
2227
2228     QUnit.test('should return array values by reference', function(assert) {
2229       assert.expect(1);
2230
2231       var array = [1];
2232       assert.strictEqual(_.castArray(array), array);
2233     });
2234
2235     QUnit.test('should return an empty array when no arguments are given', function(assert) {
2236       assert.expect(1);
2237
2238       assert.deepEqual(_.castArray(), []);
2239     });
2240   }());
2241
2242   /*--------------------------------------------------------------------------*/
2243
2244   QUnit.module('lodash.chain');
2245
2246   (function() {
2247     QUnit.test('should return a wrapped value', function(assert) {
2248       assert.expect(1);
2249
2250       if (!isNpm) {
2251         var actual = _.chain({ 'a': 0 });
2252         assert.ok(actual instanceof _);
2253       }
2254       else {
2255         skipAssert(assert);
2256       }
2257     });
2258
2259     QUnit.test('should return existing wrapped values', function(assert) {
2260       assert.expect(2);
2261
2262       if (!isNpm) {
2263         var wrapped = _({ 'a': 0 });
2264         assert.strictEqual(_.chain(wrapped), wrapped);
2265         assert.strictEqual(wrapped.chain(), wrapped);
2266       }
2267       else {
2268         skipAssert(assert, 2);
2269       }
2270     });
2271
2272     QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2273       assert.expect(6);
2274
2275       if (!isNpm) {
2276         var array = ['c', 'b', 'a'];
2277
2278         assert.ok(_.chain(array).head() instanceof _);
2279         assert.ok(_(array).chain().head() instanceof _);
2280
2281         assert.ok(_.chain(array).isArray() instanceof _);
2282         assert.ok(_(array).chain().isArray() instanceof _);
2283
2284         assert.ok(_.chain(array).sortBy().head() instanceof _);
2285         assert.ok(_(array).chain().sortBy().head() instanceof _);
2286       }
2287       else {
2288         skipAssert(assert, 6);
2289       }
2290     });
2291
2292     QUnit.test('should chain multiple methods', function(assert) {
2293       assert.expect(6);
2294
2295       if (!isNpm) {
2296         lodashStable.times(2, function(index) {
2297           var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2298               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 },
2299               wrapped = index ? _(array).chain() : _.chain(array);
2300
2301           var actual = wrapped
2302             .chain()
2303             .map(function(value) { return value.split(''); })
2304             .flatten()
2305             .reduce(function(object, chr) {
2306               object[chr] || (object[chr] = 0);
2307               object[chr]++;
2308               return object;
2309             }, {})
2310             .value();
2311
2312           assert.deepEqual(actual, expected);
2313
2314           array = [1, 2, 3, 4, 5, 6];
2315           wrapped = index ? _(array).chain() : _.chain(array);
2316           actual = wrapped
2317             .chain()
2318             .filter(function(n) { return n % 2 != 0; })
2319             .reject(function(n) { return n % 3 == 0; })
2320             .sortBy(function(n) { return -n; })
2321             .value();
2322
2323           assert.deepEqual(actual, [5, 1]);
2324
2325           array = [3, 4];
2326           wrapped = index ? _(array).chain() : _.chain(array);
2327           actual = wrapped
2328             .reverse()
2329             .concat([2, 1])
2330             .unshift(5)
2331             .tap(function(value) { value.pop(); })
2332             .map(square)
2333             .value();
2334
2335           assert.deepEqual(actual, [25, 16, 9, 4]);
2336         });
2337       }
2338       else {
2339         skipAssert(assert, 6);
2340       }
2341     });
2342   }());
2343
2344   /*--------------------------------------------------------------------------*/
2345
2346   QUnit.module('lodash.chunk');
2347
2348   (function() {
2349     var array = [0, 1, 2, 3, 4, 5];
2350
2351     QUnit.test('should return chunked arrays', function(assert) {
2352       assert.expect(1);
2353
2354       var actual = _.chunk(array, 3);
2355       assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2356     });
2357
2358     QUnit.test('should return the last chunk as remaining elements', function(assert) {
2359       assert.expect(1);
2360
2361       var actual = _.chunk(array, 4);
2362       assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2363     });
2364
2365     QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2366       assert.expect(1);
2367
2368       var values = falsey.concat(-1, -Infinity),
2369           expected = lodashStable.map(values, alwaysEmptyArray);
2370
2371       var actual = lodashStable.map(values, function(value, index) {
2372         return index ? _.chunk(array, value) : _.chunk(array);
2373       });
2374
2375       assert.deepEqual(actual, expected);
2376     });
2377
2378     QUnit.test('should coerce `size` to an integer', function(assert) {
2379       assert.expect(1);
2380
2381       assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2382     });
2383   }());
2384
2385   /*--------------------------------------------------------------------------*/
2386
2387   QUnit.module('lodash.clamp');
2388
2389   (function() {
2390     QUnit.test('should work with a `max` argument', function(assert) {
2391       assert.expect(2);
2392
2393       assert.strictEqual(_.clamp(5, 3), 3);
2394       assert.strictEqual(_.clamp(1, 3), 1);
2395     });
2396
2397     QUnit.test('should clamp negative numbers', function(assert) {
2398       assert.expect(3);
2399
2400       assert.strictEqual(_.clamp(-10, -5, 5), -5);
2401       assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2402       assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2403     });
2404
2405     QUnit.test('should clamp positive numbers', function(assert) {
2406       assert.expect(3);
2407
2408       assert.strictEqual(_.clamp(10, -5, 5), 5);
2409       assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2410       assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2411     });
2412
2413     QUnit.test('should not alter negative numbers in range', function(assert) {
2414       assert.expect(3);
2415
2416       assert.strictEqual(_.clamp(-4, -5, 5), -4);
2417       assert.strictEqual(_.clamp(-5, -5, 5), -5);
2418       assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2419     });
2420
2421     QUnit.test('should not alter positive numbers in range', function(assert) {
2422       assert.expect(3);
2423
2424       assert.strictEqual(_.clamp(4, -5, 5), 4);
2425       assert.strictEqual(_.clamp(5, -5, 5), 5);
2426       assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2427     });
2428
2429     QUnit.test('should not alter `0` in range', function(assert) {
2430       assert.expect(1);
2431
2432       assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2433     });
2434
2435     QUnit.test('should clamp to `0`', function(assert) {
2436       assert.expect(1);
2437
2438       assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2439     });
2440
2441     QUnit.test('should not alter `-0` in range', function(assert) {
2442       assert.expect(1);
2443
2444       assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2445     });
2446
2447     QUnit.test('should clamp to `-0`', function(assert) {
2448       assert.expect(1);
2449
2450       assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2451     });
2452
2453     QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2454       assert.expect(1);
2455
2456       assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2457     });
2458
2459     QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2460       assert.expect(2);
2461
2462       assert.deepEqual(_.clamp(1, -5, NaN), 0);
2463       assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2464     });
2465   }());
2466
2467   /*--------------------------------------------------------------------------*/
2468
2469   QUnit.module('clone methods');
2470
2471   (function() {
2472     function Foo() { this.a = 1; }
2473     Foo.prototype.b = 1;
2474     Foo.c = function() {};
2475
2476     if (Map) {
2477       var map = new Map;
2478       map.set('a', 1);
2479       map.set('b', 2);
2480     }
2481     if (Set) {
2482       var set = new Set;
2483       set.add(1);
2484       set.add(2);
2485     }
2486     var objects = {
2487       '`arguments` objects': arguments,
2488       'arrays': ['a', ''],
2489       'array-like-objects': { '0': 'a', '1': '', 'length': 3 },
2490       'booleans': false,
2491       'boolean objects': Object(false),
2492       'date objects': new Date,
2493       'Foo instances': new Foo,
2494       'objects': { 'a': 0, 'b': 1, 'c': 2 },
2495       'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2496       'objects from another document': realm.object || {},
2497       'maps': map,
2498       'null values': null,
2499       'numbers': 0,
2500       'number objects': Object(0),
2501       'regexes': /a/gim,
2502       'sets': set,
2503       'strings': 'a',
2504       'string objects': Object('a'),
2505       'undefined values': undefined
2506     };
2507
2508     objects.arrays.length = 3;
2509
2510     var uncloneable = {
2511       'DOM elements': body,
2512       'functions': Foo,
2513       'generators': generator
2514     };
2515
2516     lodashStable.each(errors, function(error) {
2517       uncloneable[error.name + 's'] = error;
2518     });
2519
2520     QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2521       assert.expect(2);
2522
2523       var array = [{ 'a': 0 }, { 'b': 1 }],
2524           actual = _.clone(array);
2525
2526       assert.deepEqual(actual, array);
2527       assert.ok(actual !== array && actual[0] === array[0]);
2528     });
2529
2530     QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2531       assert.expect(1);
2532
2533       var object = {
2534         'foo': { 'b': { 'c': { 'd': {} } } },
2535         'bar': {}
2536       };
2537
2538       object.foo.b.c.d = object;
2539       object.bar.b = object.foo.b;
2540
2541       var actual = _.cloneDeep(object);
2542       assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2543     });
2544
2545     QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2546       assert.expect(2);
2547
2548       var cyclical = {};
2549       lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2550         cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2551       });
2552
2553       var clone = _.cloneDeep(cyclical),
2554           actual = clone['v' + LARGE_ARRAY_SIZE][0];
2555
2556       assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2557       assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2558     });
2559
2560     QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2561       assert.expect(164);
2562
2563       var Stack,
2564           keys = [true, false, 1, -Infinity, NaN, {}, null, 'a', symbol || {}, undefined];
2565
2566       var pairs = lodashStable.map(keys, function(key, index) {
2567         var lastIndex = keys.length - 1;
2568         return [key, keys[lastIndex - index]];
2569       });
2570
2571       _.cloneDeepWith({ 'a': 1 }, function() {
2572         if (arguments.length > 1) {
2573           Stack || (Stack = _.last(arguments).constructor);
2574         }
2575       });
2576
2577       var stacks = [new Stack(pairs), new Stack(pairs)];
2578
2579       lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
2580         stacks[1].set({}, {});
2581       });
2582
2583       lodashStable.each(stacks, function(stack) {
2584         lodashStable.each(keys, function(key, index) {
2585           var value = pairs[index][1];
2586
2587           assert.deepEqual(stack.get(key), value);
2588           assert.strictEqual(stack.has(key), true);
2589           assert.strictEqual(stack['delete'](key), true);
2590           assert.strictEqual(stack.has(key), false);
2591           assert.strictEqual(stack.get(key), undefined);
2592           assert.strictEqual(stack['delete'](key), false);
2593           assert.strictEqual(stack.set(key, value), stack);
2594           assert.strictEqual(stack.has(key), true);
2595         });
2596
2597         assert.strictEqual(stack.clear(), undefined);
2598         assert.ok(lodashStable.every(keys, function(key) {
2599           return !stack.has(key);
2600         }));
2601       });
2602     });
2603
2604     lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2605       var func = _[methodName],
2606           isDeep = methodName == 'cloneDeep';
2607
2608       lodashStable.forOwn(objects, function(object, key) {
2609         QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
2610           assert.expect(2);
2611
2612           var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
2613               actual = func(object);
2614
2615           assert.ok(isEqual(actual, object));
2616
2617           if (lodashStable.isObject(object)) {
2618             assert.notStrictEqual(actual, object);
2619           } else {
2620             assert.strictEqual(actual, object);
2621           }
2622         });
2623       });
2624
2625       QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2626         assert.expect(2);
2627
2628         if (ArrayBuffer) {
2629           var actual = func(arrayBuffer);
2630           assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
2631           assert.notStrictEqual(actual, arrayBuffer);
2632         }
2633         else {
2634           skipAssert(assert, 2);
2635         }
2636       });
2637
2638       QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
2639         assert.expect(4);
2640
2641         if (Buffer) {
2642           var buffer = new Buffer([1, 2]),
2643               actual = func(buffer);
2644
2645           assert.strictEqual(actual.byteLength, buffer.byteLength);
2646           assert.strictEqual(actual.inspect(), buffer.inspect());
2647           assert.notStrictEqual(actual, buffer);
2648
2649           buffer[0] = 2;
2650           assert.strictEqual(actual[0], isDeep ? 2 : 1);
2651         }
2652         else {
2653           skipAssert(assert, 4);
2654         }
2655       });
2656
2657       QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2658         assert.expect(2);
2659
2660         var array = /c/.exec('abcde'),
2661             actual = func(array);
2662
2663         assert.strictEqual(actual.index, 2);
2664         assert.strictEqual(actual.input, 'abcde');
2665       });
2666
2667       QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2668         assert.expect(1);
2669
2670         // Avoid a regexp literal for older Opera and use `exec` for older Safari.
2671         var regexp = RegExp('c', 'g');
2672
2673         regexp.exec('abcde');
2674
2675         var actual = func(regexp);
2676         assert.strictEqual(actual.lastIndex, 3);
2677       });
2678
2679       QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
2680         assert.expect(1);
2681
2682         var values = lodashStable.map([true, false, 1, 'a'], function(value) {
2683           var object = Object(value);
2684           object.a = 1;
2685           return object;
2686         });
2687
2688         var expected = lodashStable.map(values, alwaysTrue);
2689
2690         var actual = lodashStable.map(values, function(value) {
2691           return func(value).a === 1;
2692         });
2693
2694         assert.deepEqual(actual, expected);
2695       });
2696
2697       QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
2698         assert.expect(2);
2699
2700         var actual = func(Foo.prototype);
2701
2702         assert.notOk(actual instanceof Foo);
2703         assert.deepEqual(actual, { 'b': 1 });
2704       });
2705
2706       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
2707         assert.expect(1);
2708
2709         assert.ok(func(new Foo) instanceof Foo);
2710       });
2711
2712       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
2713         assert.expect(1);
2714
2715         Foo.prototype.constructor = Object;
2716         assert.ok(func(new Foo) instanceof Foo);
2717         Foo.prototype.constructor = Foo;
2718       });
2719
2720       QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2721         assert.expect(1);
2722
2723         Foo.prototype.constructor = null;
2724         assert.notOk(func(new Foo) instanceof Foo);
2725         Foo.prototype.constructor = Foo;
2726       });
2727
2728       QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2729         assert.expect(2);
2730
2731         var object = {
2732           'constructor': objectProto.constructor,
2733           'hasOwnProperty': objectProto.hasOwnProperty,
2734           'isPrototypeOf': objectProto.isPrototypeOf,
2735           'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2736           'toLocaleString': objectProto.toLocaleString,
2737           'toString': objectProto.toString,
2738           'valueOf': objectProto.valueOf
2739         };
2740
2741         var actual = func(object);
2742
2743         assert.deepEqual(actual, object);
2744         assert.notStrictEqual(actual, object);
2745       });
2746
2747       QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2748         assert.expect(2);
2749
2750         if (Symbol) {
2751           var object = {};
2752           object[symbol] = {};
2753           assert.strictEqual(func(object)[symbol], object[symbol]);
2754
2755           if (isDeep) {
2756             object = { 'a': { 'b': {} } };
2757             object.a.b[symbol] = {};
2758             assert.strictEqual(func(object).a.b[symbol], object.a.b[symbol]);
2759           }
2760           else {
2761             skipAssert(assert);
2762           }
2763         }
2764         else {
2765           skipAssert(assert, 2);
2766         }
2767       });
2768
2769       QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2770         assert.expect(4);
2771
2772         if (Symbol) {
2773           assert.strictEqual(func(symbol), symbol);
2774
2775           var object = Object(symbol),
2776               actual = func(object);
2777
2778           assert.strictEqual(typeof actual, 'object');
2779           assert.strictEqual(typeof actual.valueOf(), 'symbol');
2780           assert.notStrictEqual(actual, object);
2781         }
2782         else {
2783           skipAssert(assert, 4);
2784         }
2785       });
2786
2787       QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2788         assert.expect(1);
2789
2790         if (Symbol) {
2791           assert.strictEqual(func(symbol), symbol);
2792         }
2793         else {
2794           skipAssert(assert);
2795         }
2796       });
2797
2798       QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2799         assert.expect(1);
2800
2801         if (document) {
2802           var element = document.createElement('div');
2803
2804           try {
2805             assert.deepEqual(func(element), {});
2806           } catch (e) {
2807             assert.ok(false, e.message);
2808           }
2809         }
2810         else {
2811           skipAssert(assert);
2812         }
2813       });
2814
2815       QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
2816         assert.expect(2);
2817
2818         var expected = [{ 'a': [0] }, { 'b': [1] }],
2819             actual = lodashStable.map(expected, func);
2820
2821         assert.deepEqual(actual, expected);
2822
2823         if (isDeep) {
2824           assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
2825         } else {
2826           assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
2827         }
2828       });
2829
2830       QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
2831         assert.expect(1);
2832
2833         var props = [];
2834
2835         var objects = lodashStable.transform(_, function(result, value, key) {
2836           if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
2837               !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
2838               !lodashStable.isFunction(value)) {
2839             props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
2840             result.push(value);
2841           }
2842         }, []);
2843
2844         var expected = lodashStable.map(objects, alwaysTrue);
2845
2846         var actual = lodashStable.map(objects, function(object) {
2847           var Ctor = object.constructor,
2848               result = func(object);
2849
2850           return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
2851         });
2852
2853         assert.deepEqual(actual, expected, props.join(', '));
2854       });
2855
2856       QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
2857         assert.expect(2);
2858
2859         if (!isNpm) {
2860           var object = objects.objects,
2861               actual = _(object)[methodName]();
2862
2863           assert.deepEqual(actual, object);
2864           assert.notStrictEqual(actual, object);
2865         }
2866         else {
2867           skipAssert(assert, 2);
2868         }
2869       });
2870
2871       lodashStable.each(typedArrays, function(type) {
2872         QUnit.test('`_.' + methodName + '` should clone ' + type + ' arrays', function(assert) {
2873           assert.expect(10);
2874
2875           var Ctor = root[type];
2876
2877           lodashStable.times(2, function(index) {
2878             if (Ctor) {
2879               var buffer = new ArrayBuffer(24),
2880                   array = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
2881                   actual = func(array);
2882
2883               assert.deepEqual(actual, array);
2884               assert.notStrictEqual(actual, array);
2885               assert.strictEqual(actual.buffer === array.buffer, !isDeep);
2886               assert.strictEqual(actual.byteOffset, array.byteOffset);
2887               assert.strictEqual(actual.length, array.length);
2888             }
2889             else {
2890               skipAssert(assert, 5);
2891             }
2892           });
2893         });
2894       });
2895
2896       lodashStable.forOwn(uncloneable, function(value, key) {
2897         QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
2898           assert.expect(3);
2899
2900           if (value) {
2901             var object = { 'a': value, 'b': { 'c': value } },
2902                 actual = func(object),
2903                 expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
2904
2905             assert.deepEqual(actual, object);
2906             assert.notStrictEqual(actual, object);
2907             assert.deepEqual(func(value), expected);
2908           }
2909           else {
2910             skipAssert(assert, 3);
2911           }
2912         });
2913       });
2914     });
2915
2916     lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
2917       var func = _[methodName],
2918           isDeep = methodName == 'cloneDeepWith';
2919
2920       QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
2921         assert.expect(1);
2922
2923         var argsList = [],
2924             foo = new Foo;
2925
2926         func(foo, function() {
2927           var length = arguments.length,
2928               args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
2929
2930           argsList.push(args);
2931         });
2932
2933         assert.deepEqual(argsList, isDeep ? [[foo], [1, 'a', foo]] : [[foo]]);
2934       });
2935
2936       QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` returns `undefined`', function(assert) {
2937         assert.expect(1);
2938
2939         var actual = func({ 'a': { 'b': 'c' } }, noop);
2940         assert.deepEqual(actual, { 'a': { 'b': 'c' } });
2941       });
2942
2943       lodashStable.forOwn(uncloneable, function(value, key) {
2944         QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
2945           assert.expect(4);
2946
2947           var customizer = function(value) {
2948             return lodashStable.isPlainObject(value) ? undefined : value;
2949           };
2950
2951           var actual = func(value, customizer);
2952
2953           assert.deepEqual(actual, value);
2954           assert.strictEqual(actual, value);
2955
2956           var object = { 'a': value, 'b': { 'c': value } };
2957           actual = func(object, customizer);
2958
2959           assert.deepEqual(actual, object);
2960           assert.notStrictEqual(actual, object);
2961         });
2962       });
2963     });
2964   }(1, 2, 3));
2965
2966   /*--------------------------------------------------------------------------*/
2967
2968   QUnit.module('lodash.compact');
2969
2970   (function() {
2971     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
2972
2973     QUnit.test('should filter falsey values', function(assert) {
2974       assert.expect(1);
2975
2976       var array = ['0', '1', '2'];
2977       assert.deepEqual(_.compact(falsey.concat(array)), array);
2978     });
2979
2980     QUnit.test('should work when in-between lazy operators', function(assert) {
2981       assert.expect(2);
2982
2983       if (!isNpm) {
2984         var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
2985         assert.deepEqual(actual, []);
2986
2987         actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
2988         assert.deepEqual(actual, [true, 1, 'a']);
2989       }
2990       else {
2991         skipAssert(assert, 2);
2992       }
2993     });
2994
2995     QUnit.test('should work in a lazy sequence', function(assert) {
2996       assert.expect(1);
2997
2998       if (!isNpm) {
2999         var actual = _(largeArray).slice(1).compact().reverse().take().value();
3000         assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
3001       }
3002       else {
3003         skipAssert(assert);
3004       }
3005     });
3006
3007     QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
3008       assert.expect(1);
3009
3010       if (!isModularize) {
3011         var iteratee = _.iteratee,
3012             pass = false;
3013
3014         _.iteratee = identity;
3015
3016         try {
3017           var actual = _(largeArray).slice(1).compact().value();
3018           pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
3019         } catch (e) {console.log(e);}
3020
3021         assert.ok(pass);
3022         _.iteratee = iteratee;
3023       }
3024       else {
3025         skipAssert(assert);
3026       }
3027     });
3028   }());
3029
3030   /*--------------------------------------------------------------------------*/
3031
3032   QUnit.module('lodash.concat');
3033
3034   (function() {
3035     QUnit.test('should concat arrays and values', function(assert) {
3036       assert.expect(2);
3037
3038       var array = [1],
3039           actual = _.concat(array, 2, [3], [[4]]);
3040
3041       assert.deepEqual(actual, [1, 2, 3, [4]]);
3042       assert.deepEqual(array, [1]);
3043     });
3044
3045     QUnit.test('should return an empty array when `array` is nullish', function(assert) {
3046       assert.expect(1);
3047
3048       var values = [, null, undefined],
3049           expected = lodashStable.map(values, alwaysEmptyArray);
3050
3051       var actual = lodashStable.map(values, function(value, index) {
3052         try {
3053           return index ? _.concat(value) : _.concat();
3054         } catch (e) {}
3055       });
3056
3057       assert.deepEqual(actual, expected);
3058     });
3059
3060     QUnit.test('should treat nullish `array` values as empty arrays', function(assert) {
3061       assert.expect(1);
3062
3063       var values = [null, undefined],
3064           expected = lodashStable.map(values, lodashStable.constant([1, 2, [3]]));
3065
3066       var actual = lodashStable.map(values, function(value) {
3067         try {
3068           return _.concat(value, 1, [2], [[3]]);
3069         } catch (e) {}
3070       });
3071
3072       assert.deepEqual(actual, expected);
3073     });
3074
3075     QUnit.test('should treat sparse arrays as dense', function(assert) {
3076       assert.expect(3);
3077
3078       var expected = [],
3079           actual = _.concat(Array(1), Array(1));
3080
3081       expected.push(undefined, undefined);
3082
3083       assert.ok('0'in actual);
3084       assert.ok('1' in actual);
3085       assert.deepEqual(actual, expected);
3086     });
3087
3088     QUnit.test('should return a new wrapped array', function(assert) {
3089       assert.expect(2);
3090
3091       if (!isNpm) {
3092         var array = [1],
3093             wrapped = _(array).concat([2, 3]),
3094             actual = wrapped.value();
3095
3096         assert.deepEqual(array, [1]);
3097         assert.deepEqual(actual, [1, 2, 3]);
3098       }
3099       else {
3100         skipAssert(assert, 2);
3101       }
3102     });
3103   }());
3104
3105   /*--------------------------------------------------------------------------*/
3106
3107   QUnit.module('lodash.cond');
3108
3109   (function() {
3110     QUnit.test('should create a conditional function', function(assert) {
3111       assert.expect(3);
3112
3113       var cond = _.cond([
3114         [lodashStable.matches({ 'a': 1 }),     alwaysA],
3115         [lodashStable.matchesProperty('b', 1), alwaysB],
3116         [lodashStable.property('c'),           alwaysC]
3117       ]);
3118
3119       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3120       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3121       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3122     });
3123
3124     QUnit.test('should provide arguments to functions', function(assert) {
3125       assert.expect(2);
3126
3127       var args1,
3128           args2,
3129           expected = ['a', 'b', 'c'];
3130
3131       var cond = _.cond([[
3132         function() { args1 || (args1 = slice.call(arguments)); return true; },
3133         function() { args2 || (args2 = slice.call(arguments)); }
3134       ]]);
3135
3136       cond('a', 'b', 'c');
3137
3138       assert.deepEqual(args1, expected);
3139       assert.deepEqual(args2, expected);
3140     });
3141
3142     QUnit.test('should work with predicate shorthands', function(assert) {
3143       assert.expect(3);
3144
3145       var cond = _.cond([
3146         [{ 'a': 1 }, alwaysA],
3147         [['b', 1],   alwaysB],
3148         ['c',        alwaysC]
3149       ]);
3150
3151       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3152       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3153       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3154     });
3155
3156     QUnit.test('should return `undefined` when no condition is met', function(assert) {
3157       assert.expect(1);
3158
3159       var cond = _.cond([[alwaysFalse, alwaysA]]);
3160       assert.strictEqual(cond({ 'a': 1 }), undefined);
3161     });
3162
3163     QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
3164       assert.expect(2);
3165
3166       lodashStable.each([true, false], function(value) {
3167         assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError);
3168       });
3169     });
3170
3171     QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
3172       assert.expect(1);
3173
3174       var cond = _.cond([
3175         [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
3176       ]);
3177
3178       var object = { 'cond': cond, 'a': 1, 'b': 2 };
3179       assert.strictEqual(object.cond('a', 'b'), 2);
3180     });
3181   }());
3182
3183   /*--------------------------------------------------------------------------*/
3184
3185   QUnit.module('lodash.conforms');
3186
3187   (function() {
3188     var objects = [
3189       { 'a': 1, 'b': 8 },
3190       { 'a': 2, 'b': 4 },
3191       { 'a': 3, 'b': 16 }
3192     ];
3193
3194     QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
3195       assert.expect(2);
3196
3197       var conforms = _.conforms({
3198         'b': function(value) { return value > 4; }
3199       });
3200
3201       var actual = lodashStable.filter(objects, conforms);
3202       assert.deepEqual(actual, [objects[0], objects[2]]);
3203
3204       conforms = _.conforms({
3205         'b': function(value) { return value > 8; },
3206         'a': function(value) { return value > 1; }
3207       });
3208
3209       actual = lodashStable.filter(objects, conforms);
3210       assert.deepEqual(actual, [objects[2]]);
3211     });
3212
3213     QUnit.test('should not match by inherited `source` properties', function(assert) {
3214       assert.expect(1);
3215
3216       function Foo() {
3217         this.a = function(value) {
3218           return value > 1;
3219         };
3220       }
3221
3222       Foo.prototype.b = function(value) {
3223         return value > 8;
3224       };
3225
3226       var conforms = _.conforms(new Foo),
3227           actual = lodashStable.filter(objects, conforms);
3228
3229       assert.deepEqual(actual, [objects[1], objects[2]]);
3230     });
3231
3232     QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
3233       assert.expect(2);
3234
3235       var count = 0;
3236
3237       var conforms = _.conforms({
3238         'a': function() { count++; return true; }
3239       });
3240
3241       assert.strictEqual(conforms({}), false);
3242       assert.strictEqual(count, 0);
3243     });
3244
3245     QUnit.test('should work with a function for `object`', function(assert) {
3246       assert.expect(2);
3247
3248       function Foo() {}
3249       Foo.a = 1;
3250
3251       function Bar() {}
3252       Bar.a = 2;
3253
3254       var conforms = _.conforms({
3255         'a': function(value) { return value > 1; }
3256       });
3257
3258       assert.strictEqual(conforms(Foo), false);
3259       assert.strictEqual(conforms(Bar), true);
3260     });
3261
3262     QUnit.test('should work with a function for `source`', function(assert) {
3263       assert.expect(1);
3264
3265       function Foo() {}
3266       Foo.a = function(value) { return value > 1; };
3267
3268       var objects = [{ 'a': 1 }, { 'a': 2 }],
3269           actual = lodashStable.filter(objects, _.conforms(Foo));
3270
3271       assert.deepEqual(actual, [objects[1]]);
3272     });
3273
3274     QUnit.test('should work with a non-plain `object`', function(assert) {
3275       assert.expect(1);
3276
3277       function Foo() {
3278         this.a = 1;
3279       }
3280       Foo.prototype.b = 2;
3281
3282       var conforms = _.conforms({
3283         'b': function(value) { return value > 1; }
3284       });
3285
3286       assert.strictEqual(conforms(new Foo), true);
3287     });
3288
3289     QUnit.test('should return `false` when `object` is nullish', function(assert) {
3290       assert.expect(1);
3291
3292       var values = [, null, undefined],
3293           expected = lodashStable.map(values, alwaysFalse);
3294
3295       var conforms = _.conforms({
3296         'a': function(value) { return value > 1; }
3297       });
3298
3299       var actual = lodashStable.map(values, function(value, index) {
3300         try {
3301           return index ? conforms(value) : conforms();
3302         } catch (e) {}
3303       });
3304
3305       assert.deepEqual(actual, expected);
3306     });
3307
3308     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3309       assert.expect(1);
3310
3311       var values = [, null, undefined],
3312           expected = lodashStable.map(values, alwaysTrue),
3313           conforms = _.conforms({});
3314
3315       var actual = lodashStable.map(values, function(value, index) {
3316         try {
3317           return index ? conforms(value) : conforms();
3318         } catch (e) {}
3319       });
3320
3321       assert.deepEqual(actual, expected);
3322     });
3323
3324     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
3325       assert.expect(1);
3326
3327       var object = { 'a': 1 },
3328           expected = lodashStable.map(empties, alwaysTrue);
3329
3330       var actual = lodashStable.map(empties, function(value) {
3331         var conforms = _.conforms(value);
3332         return conforms(object);
3333       });
3334
3335       assert.deepEqual(actual, expected);
3336     });
3337
3338     QUnit.test('should not change behavior if `source` is modified', function(assert) {
3339       assert.expect(2);
3340
3341       var source = {
3342         'a': function(value) { return value > 1; }
3343       };
3344
3345       var object = { 'a': 2 },
3346           conforms = _.conforms(source);
3347
3348       assert.strictEqual(conforms(object), true);
3349
3350       source.a = function(value) { return value < 2; };
3351       assert.strictEqual(conforms(object), true);
3352     });
3353   }());
3354
3355   /*--------------------------------------------------------------------------*/
3356
3357   QUnit.module('lodash.constant');
3358
3359   (function() {
3360     QUnit.test('should create a function that returns `value`', function(assert) {
3361       assert.expect(1);
3362
3363       var object = { 'a': 1 },
3364           values = Array(2).concat(empties, true, 1, 'a'),
3365           constant = _.constant(object),
3366           expected = lodashStable.map(values, function() { return true; });
3367
3368       var actual = lodashStable.map(values, function(value, index) {
3369         if (index == 0) {
3370           var result = constant();
3371         } else if (index == 1) {
3372           result = constant.call({});
3373         } else {
3374           result = constant(value);
3375         }
3376         return result === object;
3377       });
3378
3379       assert.deepEqual(actual, expected);
3380     });
3381
3382     QUnit.test('should work with falsey values', function(assert) {
3383       assert.expect(1);
3384
3385       var expected = lodashStable.map(falsey, function() { return true; });
3386
3387       var actual = lodashStable.map(falsey, function(value, index) {
3388         var constant = index ? _.constant(value) : _.constant(),
3389             result = constant();
3390
3391         return (result === value) || (result !== result && value !== value);
3392       });
3393
3394       assert.deepEqual(actual, expected);
3395     });
3396
3397     QUnit.test('should return a wrapped value when chaining', function(assert) {
3398       assert.expect(1);
3399
3400       if (!isNpm) {
3401         var wrapped = _(true).constant();
3402         assert.ok(wrapped instanceof _);
3403       }
3404       else {
3405         skipAssert(assert);
3406       }
3407     });
3408   }());
3409
3410   /*--------------------------------------------------------------------------*/
3411
3412   QUnit.module('lodash.countBy');
3413
3414   (function() {
3415     var array = [6.1, 4.2, 6.3];
3416
3417     QUnit.test('should transform keys by `iteratee`', function(assert) {
3418       assert.expect(1);
3419
3420       var actual = _.countBy(array, Math.floor);
3421       assert.deepEqual(actual, { '4': 1, '6': 2 });
3422     });
3423
3424     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3425       assert.expect(1);
3426
3427       var array = [4, 6, 6],
3428           values = [, null, undefined],
3429           expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
3430
3431       var actual = lodashStable.map(values, function(value, index) {
3432         return index ? _.countBy(array, value) : _.countBy(array);
3433       });
3434
3435       assert.deepEqual(actual, expected);
3436     });
3437
3438     QUnit.test('should work with "_.property" shorthands', function(assert) {
3439       assert.expect(1);
3440
3441       var actual = _.countBy(['one', 'two', 'three'], 'length');
3442       assert.deepEqual(actual, { '3': 2, '5': 1 });
3443     });
3444
3445     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3446       assert.expect(2);
3447
3448       var actual = _.countBy(array, function(n) {
3449         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
3450       });
3451
3452       assert.deepEqual(actual.constructor, 1);
3453       assert.deepEqual(actual.hasOwnProperty, 2);
3454     });
3455
3456     QUnit.test('should work with a number for `iteratee`', function(assert) {
3457       assert.expect(2);
3458
3459       var array = [
3460         [1, 'a'],
3461         [2, 'a'],
3462         [2, 'b']
3463       ];
3464
3465       assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3466       assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3467     });
3468
3469     QUnit.test('should work with an object for `collection`', function(assert) {
3470       assert.expect(1);
3471
3472       var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
3473       assert.deepEqual(actual, { '4': 1, '6': 2 });
3474     });
3475
3476     QUnit.test('should work in a lazy sequence', function(assert) {
3477       assert.expect(1);
3478
3479       if (!isNpm) {
3480         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3481           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3482           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3483         );
3484
3485         var actual = _(array).countBy().map(square).filter(isEven).take().value();
3486
3487         assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3488       }
3489       else {
3490         skipAssert(assert);
3491       }
3492     });
3493   }());
3494
3495   /*--------------------------------------------------------------------------*/
3496
3497   QUnit.module('lodash.create');
3498
3499   (function() {
3500     function Shape() {
3501       this.x = 0;
3502       this.y = 0;
3503     }
3504
3505     function Circle() {
3506       Shape.call(this);
3507     }
3508
3509     QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3510       assert.expect(3);
3511
3512       Circle.prototype = _.create(Shape.prototype);
3513       Circle.prototype.constructor = Circle;
3514
3515       var actual = new Circle;
3516
3517       assert.ok(actual instanceof Circle);
3518       assert.ok(actual instanceof Shape);
3519       assert.notStrictEqual(Circle.prototype, Shape.prototype);
3520     });
3521
3522     QUnit.test('should assign `properties` to the created object', function(assert) {
3523       assert.expect(3);
3524
3525       var expected = { 'constructor': Circle, 'radius': 0 };
3526       Circle.prototype = _.create(Shape.prototype, expected);
3527
3528       var actual = new Circle;
3529
3530       assert.ok(actual instanceof Circle);
3531       assert.ok(actual instanceof Shape);
3532       assert.deepEqual(Circle.prototype, expected);
3533     });
3534
3535     QUnit.test('should assign own properties', function(assert) {
3536       assert.expect(1);
3537
3538       function Foo() {
3539         this.a = 1;
3540         this.c = 3;
3541       }
3542       Foo.prototype.b = 2;
3543
3544       assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3545     });
3546
3547     QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
3548       assert.expect(1);
3549
3550       function Foo() {
3551         this.a = 1;
3552       }
3553       var object = _.create(new Foo, { 'a': 1 });
3554       assert.deepEqual(lodashStable.keys(object), ['a']);
3555     });
3556
3557     QUnit.test('should accept a falsey `prototype` argument', function(assert) {
3558       assert.expect(1);
3559
3560       var expected = lodashStable.map(falsey, alwaysEmptyObject);
3561
3562       var actual = lodashStable.map(falsey, function(prototype, index) {
3563         return index ? _.create(prototype) : _.create();
3564       });
3565
3566       assert.deepEqual(actual, expected);
3567     });
3568
3569     QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
3570       assert.expect(1);
3571
3572       var primitives = [true, null, 1, 'a', undefined],
3573           expected = lodashStable.map(primitives, alwaysTrue);
3574
3575       var actual = lodashStable.map(primitives, function(value, index) {
3576         return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3577       });
3578
3579       assert.deepEqual(actual, expected);
3580     });
3581
3582     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3583       assert.expect(1);
3584
3585       var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3586           expected = lodashStable.map(array, alwaysTrue),
3587           objects = lodashStable.map(array, _.create);
3588
3589       var actual = lodashStable.map(objects, function(object) {
3590         return object.a === 1 && !_.keys(object).length;
3591       });
3592
3593       assert.deepEqual(actual, expected);
3594     });
3595   }());
3596
3597   /*--------------------------------------------------------------------------*/
3598
3599   QUnit.module('lodash.curry');
3600
3601   (function() {
3602     function fn(a, b, c, d) {
3603       return slice.call(arguments);
3604     }
3605
3606     QUnit.test('should curry based on the number of arguments given', function(assert) {
3607       assert.expect(3);
3608
3609       var curried = _.curry(fn),
3610           expected = [1, 2, 3, 4];
3611
3612       assert.deepEqual(curried(1)(2)(3)(4), expected);
3613       assert.deepEqual(curried(1, 2)(3, 4), expected);
3614       assert.deepEqual(curried(1, 2, 3, 4), expected);
3615     });
3616
3617     QUnit.test('should allow specifying `arity`', function(assert) {
3618       assert.expect(3);
3619
3620       var curried = _.curry(fn, 3),
3621           expected = [1, 2, 3];
3622
3623       assert.deepEqual(curried(1)(2, 3), expected);
3624       assert.deepEqual(curried(1, 2)(3), expected);
3625       assert.deepEqual(curried(1, 2, 3), expected);
3626     });
3627
3628     QUnit.test('should coerce `arity` to an integer', function(assert) {
3629       assert.expect(2);
3630
3631       var values = ['0', 0.6, 'xyz'],
3632           expected = lodashStable.map(values, alwaysEmptyArray);
3633
3634       var actual = lodashStable.map(values, function(arity) {
3635         return _.curry(fn, arity)();
3636       });
3637
3638       assert.deepEqual(actual, expected);
3639       assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3640     });
3641
3642     QUnit.test('should support placeholders', function(assert) {
3643       assert.expect(4);
3644
3645       var curried = _.curry(fn),
3646           ph = curried.placeholder;
3647
3648       assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3649       assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3650       assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3651       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3652     });
3653
3654     QUnit.test('should persist placeholders', function(assert) {
3655       assert.expect(1);
3656
3657       var curried = _.curry(fn),
3658           ph = curried.placeholder,
3659           actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
3660
3661       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3662     });
3663
3664     QUnit.test('should use `_.placeholder` when set', function(assert) {
3665       assert.expect(1);
3666
3667       if (!isModularize) {
3668         var curried = _.curry(fn),
3669             _ph = _.placeholder = {},
3670             ph = curried.placeholder;
3671
3672         assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
3673         delete _.placeholder;
3674       }
3675       else {
3676         skipAssert(assert);
3677       }
3678     });
3679
3680     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3681       assert.expect(3);
3682
3683       var curried = _.curry(fn, 3);
3684       assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3685       assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3686       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3687     });
3688
3689     QUnit.test('should return a function with a `length` of `0`', function(assert) {
3690       assert.expect(6);
3691
3692       lodashStable.times(2, function(index) {
3693         var curried = index ? _.curry(fn, 4) : _.curry(fn);
3694         assert.strictEqual(curried.length, 0);
3695         assert.strictEqual(curried(1).length, 0);
3696         assert.strictEqual(curried(1, 2).length, 0);
3697       });
3698     });
3699
3700     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3701       assert.expect(2);
3702
3703       var Foo = function(value) {
3704         return value && object;
3705       };
3706
3707       var curried = _.curry(Foo),
3708           object = {};
3709
3710       assert.ok(new curried(false) instanceof Foo);
3711       assert.strictEqual(new curried(true), object);
3712     });
3713
3714     QUnit.test('should not set a `this` binding', function(assert) {
3715       assert.expect(9);
3716
3717       var fn = function(a, b, c) {
3718         var value = this || {};
3719         return [value[a], value[b], value[c]];
3720       };
3721
3722       var object = { 'a': 1, 'b': 2, 'c': 3 },
3723           expected = [1, 2, 3];
3724
3725       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3726       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3727       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3728
3729       assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3730       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3731       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3732
3733       object.curried = _.curry(fn);
3734       assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3735       assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3736       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3737     });
3738
3739     QUnit.test('should work with partialed methods', function(assert) {
3740       assert.expect(2);
3741
3742       var curried = _.curry(fn),
3743           expected = [1, 2, 3, 4];
3744
3745       var a = _.partial(curried, 1),
3746           b = _.bind(a, null, 2),
3747           c = _.partialRight(b, 4),
3748           d = _.partialRight(b(3), 4);
3749
3750       assert.deepEqual(c(3), expected);
3751       assert.deepEqual(d(), expected);
3752     });
3753   }());
3754
3755   /*--------------------------------------------------------------------------*/
3756
3757   QUnit.module('lodash.curryRight');
3758
3759   (function() {
3760     function fn(a, b, c, d) {
3761       return slice.call(arguments);
3762     }
3763
3764     QUnit.test('should curry based on the number of arguments given', function(assert) {
3765       assert.expect(3);
3766
3767       var curried = _.curryRight(fn),
3768           expected = [1, 2, 3, 4];
3769
3770       assert.deepEqual(curried(4)(3)(2)(1), expected);
3771       assert.deepEqual(curried(3, 4)(1, 2), expected);
3772       assert.deepEqual(curried(1, 2, 3, 4), expected);
3773     });
3774
3775     QUnit.test('should allow specifying `arity`', function(assert) {
3776       assert.expect(3);
3777
3778       var curried = _.curryRight(fn, 3),
3779           expected = [1, 2, 3];
3780
3781       assert.deepEqual(curried(3)(1, 2), expected);
3782       assert.deepEqual(curried(2, 3)(1), expected);
3783       assert.deepEqual(curried(1, 2, 3), expected);
3784     });
3785
3786     QUnit.test('should coerce `arity` to an integer', function(assert) {
3787       assert.expect(2);
3788
3789       var values = ['0', 0.6, 'xyz'],
3790           expected = lodashStable.map(values, alwaysEmptyArray);
3791
3792       var actual = lodashStable.map(values, function(arity) {
3793         return _.curryRight(fn, arity)();
3794       });
3795
3796       assert.deepEqual(actual, expected);
3797       assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
3798     });
3799
3800     QUnit.test('should support placeholders', function(assert) {
3801       assert.expect(4);
3802
3803       var curried = _.curryRight(fn),
3804           expected = [1, 2, 3, 4],
3805           ph = curried.placeholder;
3806
3807       assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
3808       assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
3809       assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
3810       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
3811     });
3812
3813     QUnit.test('should persist placeholders', function(assert) {
3814       assert.expect(1);
3815
3816       var curried = _.curryRight(fn),
3817           ph = curried.placeholder,
3818           actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
3819
3820       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3821     });
3822
3823     QUnit.test('should use `_.placeholder` when set', function(assert) {
3824       assert.expect(1);
3825
3826       if (!isModularize) {
3827         var curried = _.curryRight(fn),
3828             _ph = _.placeholder = {},
3829             ph = curried.placeholder;
3830
3831         assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
3832         delete _.placeholder;
3833       }
3834       else {
3835         skipAssert(assert);
3836       }
3837     });
3838
3839     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3840       assert.expect(3);
3841
3842       var curried = _.curryRight(fn, 3);
3843       assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
3844       assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
3845       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3846     });
3847
3848     QUnit.test('should return a function with a `length` of `0`', function(assert) {
3849       assert.expect(6);
3850
3851       lodashStable.times(2, function(index) {
3852         var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
3853         assert.strictEqual(curried.length, 0);
3854         assert.strictEqual(curried(4).length, 0);
3855         assert.strictEqual(curried(3, 4).length, 0);
3856       });
3857     });
3858
3859     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3860       assert.expect(2);
3861
3862       var Foo = function(value) {
3863         return value && object;
3864       };
3865
3866       var curried = _.curryRight(Foo),
3867           object = {};
3868
3869       assert.ok(new curried(false) instanceof Foo);
3870       assert.strictEqual(new curried(true), object);
3871     });
3872
3873     QUnit.test('should not set a `this` binding', function(assert) {
3874       assert.expect(9);
3875
3876       var fn = function(a, b, c) {
3877         var value = this || {};
3878         return [value[a], value[b], value[c]];
3879       };
3880
3881       var object = { 'a': 1, 'b': 2, 'c': 3 },
3882           expected = [1, 2, 3];
3883
3884       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
3885       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
3886       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3887
3888       assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
3889       assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
3890       assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
3891
3892       object.curried = _.curryRight(fn);
3893       assert.deepEqual(object.curried('c')('b')('a'), Array(3));
3894       assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
3895       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3896     });
3897
3898     QUnit.test('should work with partialed methods', function(assert) {
3899       assert.expect(2);
3900
3901       var curried = _.curryRight(fn),
3902           expected = [1, 2, 3, 4];
3903
3904       var a = _.partialRight(curried, 4),
3905           b = _.partialRight(a, 3),
3906           c = _.bind(b, null, 1),
3907           d = _.partial(b(2), 1);
3908
3909       assert.deepEqual(c(2), expected);
3910       assert.deepEqual(d(), expected);
3911     });
3912   }());
3913
3914   /*--------------------------------------------------------------------------*/
3915
3916   QUnit.module('curry methods');
3917
3918   lodashStable.each(['curry', 'curryRight'], function(methodName) {
3919     var func = _[methodName],
3920         fn = function(a, b) { return slice.call(arguments); },
3921         isCurry = methodName == 'curry';
3922
3923     QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
3924       assert.expect(1);
3925
3926       function run(a, b) {
3927         return a + b;
3928       }
3929
3930       var curried = func(run);
3931
3932       try {
3933         var actual = curried(1)(2);
3934       } catch (e) {}
3935
3936       assert.strictEqual(actual, 3);
3937     });
3938
3939     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
3940       assert.expect(2);
3941
3942       var array = [fn, fn, fn],
3943           object = { 'a': fn, 'b': fn, 'c': fn };
3944
3945       lodashStable.each([array, object], function(collection) {
3946         var curries = lodashStable.map(collection, func),
3947             expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
3948
3949         var actual = lodashStable.map(curries, function(curried) {
3950           return curried('a')('b');
3951         });
3952
3953         assert.deepEqual(actual, expected);
3954       });
3955     });
3956
3957     QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
3958       assert.expect(1);
3959
3960       var curried = _.curry(function hasOwnProperty(a, b, c) {
3961         return [a, b, c];
3962       });
3963
3964       var expected = [1, 2, 3];
3965
3966       assert.deepEqual(curried(1)(2)(3), expected);
3967     });
3968   });
3969
3970   /*--------------------------------------------------------------------------*/
3971
3972   QUnit.module('lodash.debounce');
3973
3974   (function() {
3975     QUnit.test('should debounce a function', function(assert) {
3976       assert.expect(2);
3977
3978       var done = assert.async();
3979
3980       var callCount = 0,
3981           debounced = _.debounce(function() { callCount++; }, 32);
3982
3983       debounced();
3984       debounced();
3985       debounced();
3986
3987       assert.strictEqual(callCount, 0);
3988
3989       setTimeout(function() {
3990         assert.strictEqual(callCount, 1);
3991         done();
3992       }, 96);
3993     });
3994
3995     QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
3996       assert.expect(2);
3997
3998       var done = assert.async();
3999
4000       var debounced = _.debounce(identity, 32);
4001       debounced('x');
4002
4003       setTimeout(function() {
4004         assert.notEqual(debounced('y'), 'y');
4005       }, 64);
4006
4007       setTimeout(function() {
4008         assert.notEqual(debounced('z'), 'z');
4009         done();
4010       }, 128);
4011     });
4012
4013     QUnit.test('subsequent "immediate" debounced calls return the last `func` result', function(assert) {
4014       assert.expect(2);
4015
4016       var done = assert.async();
4017
4018       var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
4019           result = [debounced('x'), debounced('y')];
4020
4021       assert.deepEqual(result, ['x', 'x']);
4022
4023       setTimeout(function() {
4024         var result = [debounced('a'), debounced('b')];
4025         assert.deepEqual(result, ['a', 'a']);
4026         done();
4027       }, 64);
4028     });
4029
4030     QUnit.test('should apply default options', function(assert) {
4031       assert.expect(2);
4032
4033       var done = assert.async();
4034
4035       var callCount = 0;
4036
4037       var debounced = _.debounce(function(value) {
4038         callCount++;
4039         return value;
4040       }, 32, {});
4041
4042       assert.strictEqual(debounced('a'), undefined);
4043
4044       setTimeout(function() {
4045         assert.strictEqual(callCount, 1);
4046         done();
4047       }, 64);
4048     });
4049
4050     QUnit.test('should support a `leading` option', function(assert) {
4051       assert.expect(5);
4052
4053       var done = assert.async();
4054
4055       var callCounts = [0, 0];
4056
4057       var withLeading = _.debounce(function(value) {
4058         callCounts[0]++;
4059         return value;
4060       }, 32, { 'leading': true });
4061
4062       assert.strictEqual(withLeading('a'), 'a');
4063
4064       var withoutLeading = _.debounce(identity, 32, { 'leading': false });
4065       assert.strictEqual(withoutLeading('a'), undefined);
4066
4067       var withLeadingAndTrailing = _.debounce(function() {
4068         callCounts[1]++;
4069       }, 32, { 'leading': true });
4070
4071       withLeadingAndTrailing();
4072       withLeadingAndTrailing();
4073
4074       assert.strictEqual(callCounts[1], 1);
4075
4076       setTimeout(function() {
4077         assert.deepEqual(callCounts, [1, 2]);
4078
4079         withLeading('a');
4080         assert.strictEqual(callCounts[0], 2);
4081
4082         done();
4083       }, 64);
4084     });
4085
4086     QUnit.test('should support a `trailing` option', function(assert) {
4087       assert.expect(4);
4088
4089       var done = assert.async();
4090
4091       var withCount = 0,
4092           withoutCount = 0;
4093
4094       var withTrailing = _.debounce(function(value) {
4095         withCount++;
4096         return value;
4097       }, 32, { 'trailing': true });
4098
4099       var withoutTrailing = _.debounce(function(value) {
4100         withoutCount++;
4101         return value;
4102       }, 32, { 'trailing': false });
4103
4104       assert.strictEqual(withTrailing('a'), undefined);
4105       assert.strictEqual(withoutTrailing('a'), undefined);
4106
4107       setTimeout(function() {
4108         assert.strictEqual(withCount, 1);
4109         assert.strictEqual(withoutCount, 0);
4110         done();
4111       }, 64);
4112     });
4113
4114     QUnit.test('should support a `maxWait` option', function(assert) {
4115       assert.expect(1);
4116
4117       var done = assert.async();
4118
4119       var limit = (argv || isPhantom) ? 1000 : 320,
4120           withCount = 0,
4121           withoutCount = 0;
4122
4123       var withMaxWait = _.debounce(function() {
4124         withCount++;
4125       }, 64, { 'maxWait': 128 });
4126
4127       var withoutMaxWait = _.debounce(function() {
4128         withoutCount++;
4129       }, 96);
4130
4131       var start = +new Date;
4132       while ((new Date - start) < limit) {
4133         withMaxWait();
4134         withoutMaxWait();
4135       }
4136       var actual = [Boolean(withCount), Boolean(withoutCount)];
4137
4138       setTimeout(function() {
4139         assert.deepEqual(actual, [true, false]);
4140         done();
4141       }, 1);
4142     });
4143
4144     QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
4145       assert.expect(2);
4146
4147       var done = assert.async();
4148
4149       var callCount = 0;
4150
4151       var debounced = _.debounce(function() {
4152         callCount++;
4153       }, 32, { 'maxWait': 64 });
4154
4155       debounced();
4156
4157       setTimeout(function() {
4158         debounced();
4159         assert.strictEqual(callCount, 1);
4160       }, 128);
4161
4162       setTimeout(function() {
4163         assert.strictEqual(callCount, 2);
4164         done();
4165       }, 192);
4166     });
4167
4168     QUnit.test('should invoke the `trailing` call with the correct arguments and `this` binding', function(assert) {
4169       assert.expect(2);
4170
4171       var done = assert.async();
4172
4173       var actual,
4174           callCount = 0,
4175           object = {};
4176
4177       var debounced = _.debounce(function(value) {
4178         actual = [this];
4179         push.apply(actual, arguments);
4180         return ++callCount != 2;
4181       }, 32, { 'leading': true, 'maxWait': 64 });
4182
4183       while (true) {
4184         if (!debounced.call(object, 'a')) {
4185           break;
4186         }
4187       }
4188       setTimeout(function() {
4189         assert.strictEqual(callCount, 2);
4190         assert.deepEqual(actual, [object, 'a']);
4191         done();
4192       }, 64);
4193     });
4194   }());
4195
4196   /*--------------------------------------------------------------------------*/
4197
4198   QUnit.module('lodash.deburr');
4199
4200   (function() {
4201     QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
4202       assert.expect(1);
4203
4204       var actual = lodashStable.map(burredLetters, _.deburr);
4205       assert.deepEqual(actual, deburredLetters);
4206     });
4207
4208     QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
4209       assert.expect(1);
4210
4211       var operators = ['\xd7', '\xf7'],
4212           actual = lodashStable.map(operators, _.deburr);
4213
4214       assert.deepEqual(actual, operators);
4215     });
4216
4217     QUnit.test('should deburr combining diacritical marks', function(assert) {
4218       assert.expect(1);
4219
4220       var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
4221
4222       var actual = lodashStable.map(comboMarks, function(chr) {
4223         return _.deburr('e' + chr + 'i');
4224       });
4225
4226       assert.deepEqual(actual, expected);
4227     });
4228   }());
4229
4230   /*--------------------------------------------------------------------------*/
4231
4232   QUnit.module('lodash.defaults');
4233
4234   (function() {
4235     QUnit.test('should assign source properties if missing on `object`', function(assert) {
4236       assert.expect(1);
4237
4238       assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
4239     });
4240
4241     QUnit.test('should accept multiple sources', function(assert) {
4242       assert.expect(2);
4243
4244       var expected = { 'a': 1, 'b': 2, 'c': 3 };
4245       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
4246       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
4247     });
4248
4249     QUnit.test('should not overwrite `null` values', function(assert) {
4250       assert.expect(1);
4251
4252       var actual = _.defaults({ 'a': null }, { 'a': 1 });
4253       assert.strictEqual(actual.a, null);
4254     });
4255
4256     QUnit.test('should overwrite `undefined` values', function(assert) {
4257       assert.expect(1);
4258
4259       var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
4260       assert.strictEqual(actual.a, 1);
4261     });
4262
4263     QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
4264       assert.expect(2);
4265
4266       var object = {
4267         'constructor': objectProto.constructor,
4268         'hasOwnProperty': objectProto.hasOwnProperty,
4269         'isPrototypeOf': objectProto.isPrototypeOf,
4270         'propertyIsEnumerable': objectProto.propertyIsEnumerable,
4271         'toLocaleString': objectProto.toLocaleString,
4272         'toString': objectProto.toString,
4273         'valueOf': objectProto.valueOf
4274       };
4275
4276       var source = {
4277         'constructor': 1,
4278         'hasOwnProperty': 2,
4279         'isPrototypeOf': 3,
4280         'propertyIsEnumerable': 4,
4281         'toLocaleString': 5,
4282         'toString': 6,
4283         'valueOf': 7
4284       };
4285
4286       assert.deepEqual(_.defaults({}, source), source);
4287       assert.deepEqual(_.defaults({}, object, source), object);
4288     });
4289   }());
4290
4291   /*--------------------------------------------------------------------------*/
4292
4293   QUnit.module('lodash.defaultsDeep');
4294
4295   (function() {
4296     QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
4297       assert.expect(1);
4298
4299       var object = { 'a': { 'b': 2 }, 'd': 4 },
4300           source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 },
4301           expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
4302
4303       assert.deepEqual(_.defaultsDeep(object, source), expected);
4304     });
4305
4306     QUnit.test('should accept multiple sources', function(assert) {
4307       assert.expect(2);
4308
4309       var source1 = { 'a': { 'b': 3 } },
4310           source2 = { 'a': { 'c': 3 } },
4311           source3 = { 'a': { 'b': 3, 'c': 3 } },
4312           source4 = { 'a': { 'c': 4 } },
4313           expected = { 'a': { 'b': 2, 'c': 3 } };
4314
4315       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
4316       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
4317     });
4318
4319     QUnit.test('should not overwrite `null` values', function(assert) {
4320       assert.expect(1);
4321
4322       var object = { 'a': { 'b': null } },
4323           source = { 'a': { 'b': 2 } },
4324           actual = _.defaultsDeep(object, source);
4325
4326       assert.strictEqual(actual.a.b, null);
4327     });
4328
4329     QUnit.test('should not convert function properties to objects', function(assert) {
4330       assert.expect(2);
4331
4332       var actual = _.defaultsDeep({}, { 'a': noop });
4333       assert.strictEqual(actual.a, noop);
4334
4335       actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
4336       assert.strictEqual(actual.a.b, noop);
4337     });
4338
4339     QUnit.test('should overwrite `undefined` values', function(assert) {
4340       assert.expect(1);
4341
4342       var object = { 'a': { 'b': undefined } },
4343           source = { 'a': { 'b': 2 } },
4344           actual = _.defaultsDeep(object, source);
4345
4346       assert.strictEqual(actual.a.b, 2);
4347     });
4348
4349     QUnit.test('should merge sources containing circular references', function(assert) {
4350       assert.expect(1);
4351
4352       var object = {
4353         'foo': { 'b': { 'c': { 'd': {} } } },
4354         'bar': { 'a': 2 }
4355       };
4356
4357       var source = {
4358         'foo': { 'b': { 'c': { 'd': {} } } },
4359         'bar': {}
4360       };
4361
4362       object.foo.b.c.d = object;
4363       source.foo.b.c.d = source;
4364       source.bar.b = source.foo.b;
4365
4366       var actual = _.defaultsDeep(object, source);
4367       assert.ok(actual.bar.b === actual.foo.b && actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
4368     });
4369
4370     QUnit.test('should not modify sources', function(assert) {
4371       assert.expect(3);
4372
4373       var source1 = { 'a': 1, 'b': { 'c': 2 } },
4374           source2 = { 'b': { 'c': 3, 'd': 3 } },
4375           actual = _.defaultsDeep({}, source1, source2);
4376
4377       assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4378       assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4379       assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4380     });
4381
4382     QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4383       assert.expect(1);
4384
4385       var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4386       assert.deepEqual(actual, { 'a': ['abc'] });
4387     });
4388   }());
4389
4390   /*--------------------------------------------------------------------------*/
4391
4392   QUnit.module('lodash.defer');
4393
4394   (function() {
4395     QUnit.test('should defer `func` execution', function(assert) {
4396       assert.expect(1);
4397
4398       var done = assert.async();
4399
4400       var pass = false;
4401       _.defer(function() { pass = true; });
4402
4403       setTimeout(function() {
4404         assert.ok(pass);
4405         done();
4406       }, 32);
4407     });
4408
4409     QUnit.test('should provide additional arguments to `func`', function(assert) {
4410       assert.expect(1);
4411
4412       var done = assert.async();
4413
4414       var args;
4415
4416       _.defer(function() {
4417         args = slice.call(arguments);
4418       }, 1, 2);
4419
4420       setTimeout(function() {
4421         assert.deepEqual(args, [1, 2]);
4422         done();
4423       }, 32);
4424     });
4425
4426     QUnit.test('should be cancelable', function(assert) {
4427       assert.expect(1);
4428
4429       var done = assert.async();
4430
4431       var pass = true;
4432
4433       var timerId = _.defer(function() {
4434         pass = false;
4435       });
4436
4437       clearTimeout(timerId);
4438
4439       setTimeout(function() {
4440         assert.ok(pass);
4441         done();
4442       }, 32);
4443     });
4444   }());
4445
4446   /*--------------------------------------------------------------------------*/
4447
4448   QUnit.module('lodash.delay');
4449
4450   (function() {
4451     QUnit.test('should delay `func` execution', function(assert) {
4452       assert.expect(2);
4453
4454       var done = assert.async();
4455
4456       var pass = false;
4457       _.delay(function() { pass = true; }, 32);
4458
4459       setTimeout(function() {
4460         assert.notOk(pass);
4461       }, 1);
4462
4463       setTimeout(function() {
4464         assert.ok(pass);
4465         done();
4466       }, 64);
4467     });
4468
4469     QUnit.test('should provide additional arguments to `func`', function(assert) {
4470       assert.expect(1);
4471
4472       var done = assert.async();
4473
4474       var args;
4475
4476       _.delay(function() {
4477         args = slice.call(arguments);
4478       }, 32, 1, 2);
4479
4480       setTimeout(function() {
4481         assert.deepEqual(args, [1, 2]);
4482         done();
4483       }, 64);
4484     });
4485
4486     QUnit.test('should use a default `wait` of `0`', function(assert) {
4487       assert.expect(2);
4488
4489       var done = assert.async();
4490
4491       var pass = false;
4492
4493       _.delay(function() {
4494         pass = true;
4495       });
4496
4497       assert.notOk(pass);
4498
4499       setTimeout(function() {
4500         assert.ok(pass);
4501         done();
4502       }, 0);
4503     });
4504
4505     QUnit.test('should be cancelable', function(assert) {
4506       assert.expect(1);
4507
4508       var done = assert.async();
4509
4510       var pass = true;
4511
4512       var timerId = _.delay(function() {
4513         pass = false;
4514       }, 32);
4515
4516       clearTimeout(timerId);
4517
4518       setTimeout(function() {
4519         assert.ok(pass);
4520         done();
4521       }, 64);
4522     });
4523   }());
4524
4525   /*--------------------------------------------------------------------------*/
4526
4527   QUnit.module('difference methods');
4528
4529   lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4530     var args = (function() { return arguments; }(1, 2, 3)),
4531         func = _[methodName];
4532
4533     QUnit.test('`_.' + methodName + '` should return the difference of the given arrays', function(assert) {
4534       assert.expect(2);
4535
4536       var actual = func([1, 2, 3, 4, 5], [5, 2, 10]);
4537       assert.deepEqual(actual, [1, 3, 4]);
4538
4539       actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]);
4540       assert.deepEqual(actual, [1, 3]);
4541     });
4542
4543     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4544       assert.expect(1);
4545
4546       assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4547     });
4548
4549     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4550       assert.expect(1);
4551
4552       var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4553           array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4554           a = {},
4555           b = {},
4556           c = {};
4557
4558       array1.push(a, b, c);
4559       array2.push(b, c, a);
4560
4561       assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4562     });
4563
4564     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4565       assert.expect(1);
4566
4567       var object1 = {},
4568           object2 = {},
4569           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4570
4571       assert.deepEqual(func([object1, object2], largeArray), [object2]);
4572     });
4573
4574     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4575       assert.expect(1);
4576
4577       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
4578       assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4579     });
4580
4581     QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4582       assert.expect(3);
4583
4584       var array = [1, null, 3];
4585       assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4586       assert.deepEqual(func(null, array, 1), []);
4587       assert.deepEqual(func(array, args, null), [null]);
4588     });
4589   });
4590
4591   /*--------------------------------------------------------------------------*/
4592
4593   QUnit.module('lodash.differenceBy');
4594
4595   (function() {
4596     QUnit.test('should accept an `iteratee` argument', function(assert) {
4597       assert.expect(2);
4598
4599       var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
4600       assert.deepEqual(actual, [3.1, 1.3]);
4601
4602       actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4603       assert.deepEqual(actual, [{ 'x': 2 }]);
4604     });
4605
4606     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
4607       assert.expect(1);
4608
4609       var args;
4610
4611       _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() {
4612         args || (args = slice.call(arguments));
4613       });
4614
4615       assert.deepEqual(args, [4.4]);
4616     });
4617   }());
4618
4619   /*--------------------------------------------------------------------------*/
4620
4621   QUnit.module('lodash.differenceWith');
4622
4623   (function() {
4624     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
4625
4626     QUnit.test('should work with a `comparator` argument', function(assert) {
4627       assert.expect(1);
4628
4629       var actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
4630       assert.deepEqual(actual, [{ 'x': 2, 'y': 1 }]);
4631     });
4632   }());
4633
4634   /*--------------------------------------------------------------------------*/
4635
4636   QUnit.module('lodash.drop');
4637
4638   (function() {
4639     var array = [1, 2, 3];
4640
4641     QUnit.test('should drop the first two elements', function(assert) {
4642       assert.expect(1);
4643
4644       assert.deepEqual(_.drop(array, 2), [3]);
4645     });
4646
4647     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4648       assert.expect(1);
4649
4650       var expected = lodashStable.map(falsey, function(value) {
4651         return value === undefined ? [2, 3] : array;
4652       });
4653
4654       var actual = lodashStable.map(falsey, function(n) {
4655         return _.drop(array, n);
4656       });
4657
4658       assert.deepEqual(actual, expected);
4659     });
4660
4661     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4662       assert.expect(3);
4663
4664       lodashStable.each([0, -1, -Infinity], function(n) {
4665         assert.deepEqual(_.drop(array, n), array);
4666       });
4667     });
4668
4669     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4670       assert.expect(4);
4671
4672       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4673         assert.deepEqual(_.drop(array, n), []);
4674       });
4675     });
4676
4677     QUnit.test('should coerce `n` to an integer', function(assert) {
4678       assert.expect(1);
4679
4680       assert.deepEqual(_.drop(array, 1.6), [2, 3]);
4681     });
4682
4683     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4684       assert.expect(1);
4685
4686       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4687           actual = lodashStable.map(array, _.drop);
4688
4689       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
4690     });
4691
4692     QUnit.test('should work in a lazy sequence', function(assert) {
4693       assert.expect(6);
4694
4695       if (!isNpm) {
4696         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4697             predicate = function(value) { values.push(value); return isEven(value); },
4698             values = [],
4699             actual = _(array).drop(2).drop().value();
4700
4701         assert.deepEqual(actual, array.slice(3));
4702
4703         actual = _(array).filter(predicate).drop(2).drop().value();
4704         assert.deepEqual(values, array);
4705         assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
4706
4707         actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
4708         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
4709
4710         values = [];
4711
4712         actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
4713         assert.deepEqual(values, array.slice(1));
4714         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
4715       }
4716       else {
4717         skipAssert(assert, 6);
4718       }
4719     });
4720   }());
4721
4722   /*--------------------------------------------------------------------------*/
4723
4724   QUnit.module('lodash.dropRight');
4725
4726   (function() {
4727     var array = [1, 2, 3];
4728
4729     QUnit.test('should drop the last two elements', function(assert) {
4730       assert.expect(1);
4731
4732       assert.deepEqual(_.dropRight(array, 2), [1]);
4733     });
4734
4735     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4736       assert.expect(1);
4737
4738       var expected = lodashStable.map(falsey, function(value) {
4739         return value === undefined ? [1, 2] : array;
4740       });
4741
4742       var actual = lodashStable.map(falsey, function(n) {
4743         return _.dropRight(array, n);
4744       });
4745
4746       assert.deepEqual(actual, expected);
4747     });
4748
4749     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4750       assert.expect(3);
4751
4752       lodashStable.each([0, -1, -Infinity], function(n) {
4753         assert.deepEqual(_.dropRight(array, n), array);
4754       });
4755     });
4756
4757     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4758       assert.expect(4);
4759
4760       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4761         assert.deepEqual(_.dropRight(array, n), []);
4762       });
4763     });
4764
4765     QUnit.test('should coerce `n` to an integer', function(assert) {
4766       assert.expect(1);
4767
4768       assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
4769     });
4770
4771     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4772       assert.expect(1);
4773
4774       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4775           actual = lodashStable.map(array, _.dropRight);
4776
4777       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
4778     });
4779
4780     QUnit.test('should work in a lazy sequence', function(assert) {
4781       assert.expect(6);
4782
4783       if (!isNpm) {
4784         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4785             predicate = function(value) { values.push(value); return isEven(value); },
4786             values = [],
4787             actual = _(array).dropRight(2).dropRight().value();
4788
4789         assert.deepEqual(actual, array.slice(0, -3));
4790
4791         actual = _(array).filter(predicate).dropRight(2).dropRight().value();
4792         assert.deepEqual(values, array);
4793         assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
4794
4795         actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
4796         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
4797
4798         values = [];
4799
4800         actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
4801         assert.deepEqual(values, array.slice(0, -1));
4802         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
4803       }
4804       else {
4805         skipAssert(assert, 6);
4806       }
4807     });
4808   }());
4809
4810   /*--------------------------------------------------------------------------*/
4811
4812   QUnit.module('lodash.dropRightWhile');
4813
4814   (function() {
4815     var array = [1, 2, 3, 4];
4816
4817     var objects = [
4818       { 'a': 0, 'b': 0 },
4819       { 'a': 1, 'b': 1 },
4820       { 'a': 2, 'b': 2 }
4821     ];
4822
4823     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
4824       assert.expect(1);
4825
4826       var actual = _.dropRightWhile(array, function(n) {
4827         return n > 2;
4828       });
4829
4830       assert.deepEqual(actual, [1, 2]);
4831     });
4832
4833     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
4834       assert.expect(1);
4835
4836       var args;
4837
4838       _.dropRightWhile(array, function() {
4839         args = slice.call(arguments);
4840       });
4841
4842       assert.deepEqual(args, [4, 3, array]);
4843     });
4844
4845     QUnit.test('should work with "_.matches" shorthands', function(assert) {
4846       assert.expect(1);
4847
4848       assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
4849     });
4850
4851     QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
4852       assert.expect(1);
4853
4854       assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
4855     });
4856
4857     QUnit.test('should work with "_.property" shorthands', function(assert) {
4858       assert.expect(1);
4859
4860       assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
4861     });
4862
4863     QUnit.test('should return a wrapped value when chaining', function(assert) {
4864       assert.expect(2);
4865
4866       if (!isNpm) {
4867         var wrapped = _(array).dropRightWhile(function(n) {
4868           return n > 2;
4869         });
4870
4871         assert.ok(wrapped instanceof _);
4872         assert.deepEqual(wrapped.value(), [1, 2]);
4873       }
4874       else {
4875         skipAssert(assert, 2);
4876       }
4877     });
4878   }());
4879
4880   /*--------------------------------------------------------------------------*/
4881
4882   QUnit.module('lodash.dropWhile');
4883
4884   (function() {
4885     var array = [1, 2, 3, 4];
4886
4887     var objects = [
4888       { 'a': 2, 'b': 2 },
4889       { 'a': 1, 'b': 1 },
4890       { 'a': 0, 'b': 0 }
4891     ];
4892
4893     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
4894       assert.expect(1);
4895
4896       var actual = _.dropWhile(array, function(n) {
4897         return n < 3;
4898       });
4899
4900       assert.deepEqual(actual, [3, 4]);
4901     });
4902
4903     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
4904       assert.expect(1);
4905
4906       var args;
4907
4908       _.dropWhile(array, function() {
4909         args = slice.call(arguments);
4910       });
4911
4912       assert.deepEqual(args, [1, 0, array]);
4913     });
4914
4915     QUnit.test('should work with "_.matches" shorthands', function(assert) {
4916       assert.expect(1);
4917
4918       assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
4919     });
4920
4921     QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
4922       assert.expect(1);
4923
4924       assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
4925     });
4926
4927     QUnit.test('should work with "_.property" shorthands', function(assert) {
4928       assert.expect(1);
4929
4930       assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
4931     });
4932
4933     QUnit.test('should work in a lazy sequence', function(assert) {
4934       assert.expect(3);
4935
4936       if (!isNpm) {
4937         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
4938             predicate = function(n) { return n < 3; },
4939             expected = _.dropWhile(array, predicate),
4940             wrapped = _(array).dropWhile(predicate);
4941
4942         assert.deepEqual(wrapped.value(), expected);
4943         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
4944         assert.strictEqual(wrapped.last(), _.last(expected));
4945       }
4946       else {
4947         skipAssert(assert, 3);
4948       }
4949     });
4950
4951     QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
4952       assert.expect(1);
4953
4954       if (!isNpm) {
4955         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
4956
4957         var actual = _(array)
4958           .dropWhile(function(n) { return n == 1; })
4959           .drop()
4960           .dropWhile(function(n) { return n == 3; })
4961           .value();
4962
4963         assert.deepEqual(actual, array.slice(3));
4964       }
4965       else {
4966         skipAssert(assert);
4967       }
4968     });
4969   }());
4970
4971   /*--------------------------------------------------------------------------*/
4972
4973   QUnit.module('lodash.endsWith');
4974
4975   (function() {
4976     var string = 'abc';
4977
4978     QUnit.test('should return `true` if a string ends with `target`', function(assert) {
4979       assert.expect(1);
4980
4981       assert.strictEqual(_.endsWith(string, 'c'), true);
4982     });
4983
4984     QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
4985       assert.expect(1);
4986
4987       assert.strictEqual(_.endsWith(string, 'b'), false);
4988     });
4989
4990     QUnit.test('should work with a `position` argument', function(assert) {
4991       assert.expect(1);
4992
4993       assert.strictEqual(_.endsWith(string, 'b', 2), true);
4994     });
4995
4996     QUnit.test('should work with `position` >= `string.length`', function(assert) {
4997       assert.expect(4);
4998
4999       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5000         assert.strictEqual(_.endsWith(string, 'c', position), true);
5001       });
5002     });
5003
5004     QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5005       assert.expect(1);
5006
5007       var expected = lodashStable.map(falsey, alwaysTrue);
5008
5009       var actual = lodashStable.map(falsey, function(position) {
5010         return _.endsWith(string, position === undefined ? 'c' : '', position);
5011       });
5012
5013       assert.deepEqual(actual, expected);
5014     });
5015
5016     QUnit.test('should treat a negative `position` as `0`', function(assert) {
5017       assert.expect(6);
5018
5019       lodashStable.each([-1, -3, -Infinity], function(position) {
5020         assert.ok(lodashStable.every(string, function(chr) {
5021           return _.endsWith(string, chr, position) === false;
5022         }));
5023         assert.strictEqual(_.endsWith(string, '', position), true);
5024       });
5025     });
5026
5027     QUnit.test('should coerce `position` to an integer', function(assert) {
5028       assert.expect(1);
5029
5030       assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5031     });
5032
5033     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
5034       assert.expect(1);
5035
5036       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5037         return _.endsWith(string, '', position, true);
5038       }));
5039     });
5040   }());
5041
5042   /*--------------------------------------------------------------------------*/
5043
5044   QUnit.module('lodash.eq');
5045
5046   (function() {
5047     QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5048       assert.expect(11);
5049
5050       assert.strictEqual(_.eq(), true);
5051       assert.strictEqual(_.eq(undefined), true);
5052       assert.strictEqual(_.eq(0, -0), true);
5053       assert.strictEqual(_.eq(NaN, NaN), true);
5054       assert.strictEqual(_.eq(1, 1), true);
5055
5056       assert.strictEqual(_.eq(null, undefined), false);
5057       assert.strictEqual(_.eq(1, Object(1)), false);
5058       assert.strictEqual(_.eq(1, '1'), false);
5059       assert.strictEqual(_.eq(1, '1'), false);
5060
5061       var object = { 'a': 1 };
5062       assert.strictEqual(_.eq(object, object), true);
5063       assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5064     });
5065   }());
5066
5067   /*--------------------------------------------------------------------------*/
5068
5069   QUnit.module('lodash.escape');
5070
5071   (function() {
5072     var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
5073         unescaped = '&<>"\'`\/';
5074
5075     escaped += escaped;
5076     unescaped += unescaped;
5077
5078     QUnit.test('should escape values', function(assert) {
5079       assert.expect(1);
5080
5081       assert.strictEqual(_.escape(unescaped), escaped);
5082     });
5083
5084     QUnit.test('should not escape the "/" character', function(assert) {
5085       assert.expect(1);
5086
5087       assert.strictEqual(_.escape('/'), '/');
5088     });
5089
5090     QUnit.test('should handle strings with nothing to escape', function(assert) {
5091       assert.expect(1);
5092
5093       assert.strictEqual(_.escape('abc'), 'abc');
5094     });
5095
5096     QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5097       assert.expect(1);
5098
5099       assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5100     });
5101   }());
5102
5103   /*--------------------------------------------------------------------------*/
5104
5105   QUnit.module('lodash.escapeRegExp');
5106
5107   (function() {
5108     var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5109         unescaped = '^$.*+?()[]{}|\\';
5110
5111     QUnit.test('should escape values', function(assert) {
5112       assert.expect(1);
5113
5114       assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5115     });
5116
5117     QUnit.test('should handle strings with nothing to escape', function(assert) {
5118       assert.expect(1);
5119
5120       assert.strictEqual(_.escapeRegExp('ghi'), 'ghi');
5121     });
5122
5123     QUnit.test('should return an empty string for empty values', function(assert) {
5124       assert.expect(1);
5125
5126       var values = [, null, undefined, ''],
5127           expected = lodashStable.map(values, alwaysEmptyString);
5128
5129       var actual = lodashStable.map(values, function(value, index) {
5130         return index ? _.escapeRegExp(value) : _.escapeRegExp();
5131       });
5132
5133       assert.deepEqual(actual, expected);
5134     });
5135   }());
5136
5137   /*--------------------------------------------------------------------------*/
5138
5139   QUnit.module('lodash.every');
5140
5141   (function() {
5142     QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5143       assert.expect(1);
5144
5145       assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5146     });
5147
5148     QUnit.test('should return `true` for empty collections', function(assert) {
5149       assert.expect(1);
5150
5151       var expected = lodashStable.map(empties, alwaysTrue);
5152
5153       var actual = lodashStable.map(empties, function(value) {
5154         try {
5155           return _.every(value, identity);
5156         } catch (e) {}
5157       });
5158
5159       assert.deepEqual(actual, expected);
5160     });
5161
5162     QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5163       assert.expect(2);
5164
5165       var count = 0;
5166
5167       assert.strictEqual(_.every([true, null, true], function(value) {
5168         count++;
5169         return value;
5170       }), false);
5171
5172       assert.strictEqual(count, 2);
5173     });
5174
5175     QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5176       assert.expect(1);
5177
5178       assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5179     });
5180
5181     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5182       assert.expect(2);
5183
5184       var values = [, null, undefined],
5185           expected = lodashStable.map(values, alwaysFalse);
5186
5187       var actual = lodashStable.map(values, function(value, index) {
5188         var array = [0];
5189         return index ? _.every(array, value) : _.every(array);
5190       });
5191
5192       assert.deepEqual(actual, expected);
5193
5194       expected = lodashStable.map(values, alwaysTrue);
5195       actual = lodashStable.map(values, function(value, index) {
5196         var array = [1];
5197         return index ? _.every(array, value) : _.every(array);
5198       });
5199
5200       assert.deepEqual(actual, expected);
5201     });
5202
5203     QUnit.test('should work with "_.property" shorthands', function(assert) {
5204       assert.expect(2);
5205
5206       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5207       assert.strictEqual(_.every(objects, 'a'), false);
5208       assert.strictEqual(_.every(objects, 'b'), true);
5209     });
5210
5211     QUnit.test('should work with "_.matches" shorthands', function(assert) {
5212       assert.expect(2);
5213
5214       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5215       assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5216       assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5217     });
5218
5219     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5220       assert.expect(1);
5221
5222       var actual = lodashStable.map([[1]], _.every);
5223       assert.deepEqual(actual, [true]);
5224     });
5225   }());
5226
5227   /*--------------------------------------------------------------------------*/
5228
5229   QUnit.module('strict mode checks');
5230
5231   lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
5232     var func = _[methodName],
5233         isBindAll = methodName == 'bindAll';
5234
5235     QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5236       assert.expect(1);
5237
5238       if (freeze) {
5239         var object = freeze({ 'a': undefined, 'b': function() {} }),
5240             pass = !isStrict;
5241
5242         try {
5243           func(object, isBindAll ? 'b' : { 'a': 1 });
5244         } catch (e) {
5245           pass = !pass;
5246         }
5247         assert.ok(pass);
5248       }
5249       else {
5250         skipAssert(assert);
5251       }
5252     });
5253   });
5254
5255   /*--------------------------------------------------------------------------*/
5256
5257   QUnit.module('lodash.fill');
5258
5259   (function() {
5260     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
5261       assert.expect(1);
5262
5263       var array = [1, 2, 3];
5264       assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5265     });
5266
5267     QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5268       assert.expect(2);
5269
5270       var array = [1, 2, 3],
5271           actual = _.fill(array);
5272
5273       assert.deepEqual(actual, Array(3));
5274       assert.ok(lodashStable.every(actual, function(value, index) {
5275         return index in actual;
5276       }));
5277     });
5278
5279     QUnit.test('should work with a positive `start`', function(assert) {
5280       assert.expect(1);
5281
5282       var array = [1, 2, 3];
5283       assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5284     });
5285
5286     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
5287       assert.expect(4);
5288
5289       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5290         var array = [1, 2, 3];
5291         assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5292       });
5293     });
5294
5295     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5296       assert.expect(1);
5297
5298       var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5299
5300       var actual = lodashStable.map(falsey, function(start) {
5301         var array = [1, 2, 3];
5302         return _.fill(array, 'a', start);
5303       });
5304
5305       assert.deepEqual(actual, expected);
5306     });
5307
5308     QUnit.test('should work with a negative `start`', function(assert) {
5309       assert.expect(1);
5310
5311       var array = [1, 2, 3];
5312       assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5313     });
5314
5315     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
5316       assert.expect(3);
5317
5318       lodashStable.each([-3, -4, -Infinity], function(start) {
5319         var array = [1, 2, 3];
5320         assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5321       });
5322     });
5323
5324     QUnit.test('should work with `start` >= `end`', function(assert) {
5325       assert.expect(2);
5326
5327       lodashStable.each([2, 3], function(start) {
5328         var array = [1, 2, 3];
5329         assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5330       });
5331     });
5332
5333     QUnit.test('should work with a positive `end`', function(assert) {
5334       assert.expect(1);
5335
5336       var array = [1, 2, 3];
5337       assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5338     });
5339
5340     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
5341       assert.expect(4);
5342
5343       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5344         var array = [1, 2, 3];
5345         assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5346       });
5347     });
5348
5349     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5350       assert.expect(1);
5351
5352       var expected = lodashStable.map(falsey, function(value) {
5353         return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5354       });
5355
5356       var actual = lodashStable.map(falsey, function(end) {
5357         var array = [1, 2, 3];
5358         return _.fill(array, 'a', 0, end);
5359       });
5360
5361       assert.deepEqual(actual, expected);
5362     });
5363
5364     QUnit.test('should work with a negative `end`', function(assert) {
5365       assert.expect(1);
5366
5367       var array = [1, 2, 3];
5368       assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5369     });
5370
5371     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
5372       assert.expect(3);
5373
5374       lodashStable.each([-3, -4, -Infinity], function(end) {
5375         var array = [1, 2, 3];
5376         assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5377       });
5378     });
5379
5380     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5381       assert.expect(1);
5382
5383       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5384
5385       var actual = lodashStable.map(positions, function(pos) {
5386         var array = [1, 2, 3];
5387         return _.fill.apply(_, [array, 'a'].concat(pos));
5388       });
5389
5390       assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5391     });
5392
5393     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5394       assert.expect(1);
5395
5396       var array = [[1, 2], [3, 4]],
5397           actual = lodashStable.map(array, _.fill);
5398
5399       assert.deepEqual(actual, [[0, 0], [1, 1]]);
5400     });
5401
5402     QUnit.test('should return a wrapped value when chaining', function(assert) {
5403       assert.expect(3);
5404
5405       if (!isNpm) {
5406         var array = [1, 2, 3],
5407             wrapped = _(array).fill('a'),
5408             actual = wrapped.value();
5409
5410         assert.ok(wrapped instanceof _);
5411         assert.deepEqual(actual, ['a', 'a', 'a']);
5412         assert.strictEqual(actual, array);
5413       }
5414       else {
5415         skipAssert(assert, 3);
5416       }
5417     });
5418   }());
5419
5420   /*--------------------------------------------------------------------------*/
5421
5422   QUnit.module('lodash.filter');
5423
5424   (function() {
5425     var array = [1, 2, 3];
5426
5427     QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5428       assert.expect(1);
5429
5430       assert.deepEqual(_.filter(array, isEven), [2]);
5431     });
5432
5433     QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
5434       assert.expect(1);
5435
5436       // Trigger a Mobile Safari 8 JIT bug.
5437       // See https://github.com/lodash/lodash/issues/799.
5438       var counter = 0,
5439           object = { '1': 'foo', '8': 'bar', '50': 'baz' };
5440
5441       lodashStable.times(1000, function(assert) {
5442         _.filter([], alwaysTrue);
5443       });
5444
5445       _.filter(object, function() {
5446         counter++;
5447         return true;
5448       });
5449
5450       assert.strictEqual(counter, 3);
5451     });
5452   }());
5453
5454   /*--------------------------------------------------------------------------*/
5455
5456   lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
5457     QUnit.module('lodash.' + methodName);
5458
5459     var func = _[methodName],
5460         isFindKey = /Key$/.test(methodName);
5461
5462     (function() {
5463       var objects = [
5464         { 'a': 0, 'b': 0 },
5465         { 'a': 1, 'b': 1 },
5466         { 'a': 2, 'b': 2 }
5467       ];
5468
5469       var expected = ({
5470         'find': [objects[1], undefined, objects[2], objects[1]],
5471         'findLast': [objects[2], undefined, objects[2], objects[2]],
5472         'findIndex': [1, -1, 2, 1],
5473         'findLastIndex': [2, -1, 2, 2],
5474         'findKey': ['1', undefined, '2', '1'],
5475         'findLastKey': ['2', undefined, '2', '2']
5476       })[methodName];
5477
5478       QUnit.test('should return the found value', function(assert) {
5479         assert.expect(1);
5480
5481         assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5482       });
5483
5484       QUnit.test('should return `' + expected[1] + '` if value is not found', function(assert) {
5485         assert.expect(1);
5486
5487         assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5488       });
5489
5490       QUnit.test('should work with "_.matches" shorthands', function(assert) {
5491         assert.expect(1);
5492
5493         assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5494       });
5495
5496       QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
5497         assert.expect(1);
5498
5499         assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5500       });
5501
5502       QUnit.test('should work with "_.property" shorthands', function(assert) {
5503         assert.expect(1);
5504
5505         assert.strictEqual(func(objects, 'b'), expected[3]);
5506       });
5507
5508       QUnit.test('should return `' + expected[1] + '` for empty collections', function(assert) {
5509         assert.expect(1);
5510
5511         var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5512             expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5513
5514         var actual = lodashStable.map(emptyValues, function(value) {
5515           try {
5516             return func(value, { 'a': 3 });
5517           } catch (e) {}
5518         });
5519
5520         assert.deepEqual(actual, expecting);
5521       });
5522     }());
5523
5524     (function() {
5525       var array = [1, 2, 3, 4];
5526
5527       var expected = ({
5528         'find': 1,
5529         'findLast': 4,
5530         'findIndex': 0,
5531         'findLastIndex': 3,
5532         'findKey': '0',
5533         'findLastKey': '3'
5534       })[methodName];
5535
5536       QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
5537         assert.expect(1);
5538
5539         if (!isNpm) {
5540           assert.strictEqual(_(array)[methodName](), expected);
5541         }
5542         else {
5543           skipAssert(assert);
5544         }
5545       });
5546
5547       QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
5548         assert.expect(1);
5549
5550         if (!isNpm) {
5551           assert.ok(_(array).chain()[methodName]() instanceof _);
5552         }
5553         else {
5554           skipAssert(assert);
5555         }
5556       });
5557
5558       QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
5559         assert.expect(1);
5560
5561         if (!isNpm) {
5562           var wrapped = _(array).chain()[methodName]();
5563           assert.strictEqual(wrapped.__wrapped__, array);
5564         }
5565         else {
5566           skipAssert(assert);
5567         }
5568       });
5569
5570       QUnit.test('should work in a lazy sequence', function(assert) {
5571         assert.expect(2);
5572
5573         if (!isNpm) {
5574           var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5575               smallArray = array;
5576
5577           lodashStable.times(2, function(index) {
5578             var array = index ? largeArray : smallArray,
5579                 wrapped = _(array).filter(isEven);
5580
5581             assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5582           });
5583         }
5584         else {
5585           skipAssert(assert, 2);
5586         }
5587       });
5588     }());
5589
5590     (function() {
5591       var expected = ({
5592         'find': 1,
5593         'findLast': 2,
5594         'findKey': 'a',
5595         'findLastKey': 'b'
5596       })[methodName];
5597
5598       if (expected != null) {
5599         QUnit.test('should work with an object for `collection`', function(assert) {
5600           assert.expect(1);
5601
5602           var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
5603             return n < 3;
5604           });
5605
5606           assert.strictEqual(actual, expected);
5607         });
5608       }
5609     }());
5610   });
5611
5612   /*--------------------------------------------------------------------------*/
5613
5614   QUnit.module('lodash.find and lodash.findLast');
5615
5616   lodashStable.each(['find', 'findLast'], function(methodName) {
5617     var isFind = methodName == 'find';
5618
5619     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5620       assert.expect(3);
5621
5622       if (!isNpm) {
5623         var findCount = 0,
5624             mapCount = 0,
5625             array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5626             iteratee = function(value) { mapCount++; return square(value); },
5627             predicate = function(value) { findCount++; return isEven(value); },
5628             actual = _(array).map(iteratee)[methodName](predicate);
5629
5630         assert.strictEqual(findCount, isFind ? 2 : 1);
5631         assert.strictEqual(mapCount, isFind ? 2 : 1);
5632         assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
5633       }
5634       else {
5635         skipAssert(assert, 3);
5636       }
5637     });
5638   });
5639
5640   /*--------------------------------------------------------------------------*/
5641
5642   QUnit.module('lodash.flip');
5643
5644   (function() {
5645     function fn() {
5646       return slice.call(arguments);
5647     }
5648
5649     QUnit.test('should flip arguments provided to `func`', function(assert) {
5650       assert.expect(1);
5651
5652       var flipped = _.flip(fn);
5653       assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
5654     });
5655   }());
5656
5657   /*--------------------------------------------------------------------------*/
5658
5659   QUnit.module('lodash.flatMap');
5660
5661   (function() {
5662     var array = [1, 2, 3, 4];
5663
5664     function duplicate(n) {
5665       return [n, n];
5666     }
5667
5668     QUnit.test('should map values in `array` to a new flattened array', function(assert) {
5669       assert.expect(1);
5670
5671       var actual = _.flatMap(array, duplicate),
5672           expected = lodashStable.flatten(lodashStable.map(array, duplicate));
5673
5674       assert.deepEqual(actual, expected);
5675     });
5676
5677     QUnit.test('should work with "_.property" shorthands', function(assert) {
5678       assert.expect(1);
5679
5680       var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
5681       assert.deepEqual(_.flatMap(objects, 'a'), array);
5682     });
5683
5684     QUnit.test('should iterate over own properties of objects', function(assert) {
5685       assert.expect(1);
5686
5687       function Foo() { this.a = [1, 2]; }
5688       Foo.prototype.b = [3, 4];
5689
5690       var actual = _.flatMap(new Foo, identity);
5691       assert.deepEqual(actual, [1, 2]);
5692     });
5693
5694     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
5695       assert.expect(1);
5696
5697       var array = [[1, 2], [3, 4]],
5698           values = [, null, undefined],
5699           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
5700
5701       var actual = lodashStable.map(values, function(value, index) {
5702         return index ? _.flatMap(array, value) : _.flatMap(array);
5703       });
5704
5705       assert.deepEqual(actual, expected);
5706     });
5707
5708     QUnit.test('should work on an object with no `iteratee`', function(assert) {
5709       assert.expect(1);
5710
5711       var actual = _.flatMap({ 'a': [1, 2], 'b': [3, 4] });
5712       assert.deepEqual(actual, array);
5713     });
5714
5715     QUnit.test('should handle object arguments with non-number length properties', function(assert) {
5716       assert.expect(1);
5717
5718       var object = { 'length': [1, 2] };
5719       assert.deepEqual(_.flatMap(object, identity), [1, 2]);
5720     });
5721
5722     QUnit.test('should accept a falsey `collection` argument', function(assert) {
5723       assert.expect(1);
5724
5725       var expected = lodashStable.map(falsey, alwaysEmptyArray);
5726
5727       var actual = lodashStable.map(falsey, function(collection, index) {
5728         try {
5729           return index ? _.flatMap(collection) : _.flatMap();
5730         } catch (e) {}
5731       });
5732
5733       assert.deepEqual(actual, expected);
5734     });
5735
5736     QUnit.test('should treat number values for `collection` as empty', function(assert) {
5737       assert.expect(1);
5738
5739       assert.deepEqual(_.flatMap(1), []);
5740     });
5741
5742     QUnit.test('should work in a lazy sequence', function(assert) {
5743       assert.expect(2);
5744
5745       if (!isNpm) {
5746         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
5747             smallArray = array;
5748
5749         lodashStable.times(2, function(index) {
5750           var array = index ? largeArray : smallArray,
5751               actual = _(array).filter(isEven).flatMap(duplicate).take(2).value();
5752
5753           assert.deepEqual(actual, _.take(_.flatMap(_.filter(array, isEven), duplicate), 2));
5754         });
5755       }
5756       else {
5757         skipAssert(assert, 2);
5758       }
5759     });
5760   }());
5761
5762   /*--------------------------------------------------------------------------*/
5763
5764   QUnit.module('lodash.flattenDepth');
5765
5766   (function() {
5767     var array = [1, [2, [3, [4]], 5]];
5768
5769     QUnit.test('should use a default `depth` of `1`', function(assert) {
5770       assert.expect(1);
5771
5772       assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
5773     });
5774
5775     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
5776       assert.expect(2);
5777
5778       lodashStable.each([-1, 0], function(depth) {
5779         assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
5780       });
5781     });
5782
5783     QUnit.test('should coerce `depth` to an integer', function(assert) {
5784       assert.expect(1);
5785
5786       assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
5787     });
5788   }());
5789
5790   /*--------------------------------------------------------------------------*/
5791
5792   QUnit.module('flatten methods');
5793
5794   (function() {
5795     var args = arguments,
5796         array = [1, [2, [3, [4]], 5]];
5797
5798     QUnit.test('should flatten `arguments` objects', function(assert) {
5799       assert.expect(3);
5800
5801       var array = [args, [args]];
5802
5803       assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
5804       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
5805       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
5806     });
5807
5808     QUnit.test('should treat sparse arrays as dense', function(assert) {
5809       assert.expect(6);
5810
5811       var array = [[1, 2, 3], Array(3)],
5812           expected = [1, 2, 3];
5813
5814       expected.push(undefined, undefined, undefined);
5815
5816       lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) {
5817         assert.deepEqual(actual, expected);
5818         assert.ok('4' in actual);
5819       });
5820     });
5821
5822     QUnit.test('should work with extremely large arrays', function(assert) {
5823       assert.expect(3);
5824
5825       lodashStable.times(3, function(index) {
5826         var expected = Array(5e5);
5827         try {
5828           var func = _.flatten;
5829           if (index == 1) {
5830             func = _.flattenDeep;
5831           } else if (index == 2) {
5832             func = _.flattenDepth;
5833           }
5834           assert.deepEqual(func([expected]), expected);
5835         } catch (e) {
5836           assert.ok(false, e.message);
5837         }
5838       });
5839     });
5840
5841     QUnit.test('should work with empty arrays', function(assert) {
5842       assert.expect(3);
5843
5844       var array = [[], [[]], [[], [[[]]]]];
5845
5846       assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
5847       assert.deepEqual(_.flattenDeep(array), []);
5848       assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
5849     });
5850
5851     QUnit.test('should support flattening of nested arrays', function(assert) {
5852       assert.expect(3);
5853
5854       assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
5855       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
5856       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
5857     });
5858
5859     QUnit.test('should return an empty array for non array-like objects', function(assert) {
5860       assert.expect(3);
5861
5862       var expected = [],
5863           nonArray = { 'a': 1 };
5864
5865       assert.deepEqual(_.flatten(nonArray), expected);
5866       assert.deepEqual(_.flattenDeep(nonArray), expected);
5867       assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
5868     });
5869
5870     QUnit.test('should return a wrapped value when chaining', function(assert) {
5871       assert.expect(6);
5872
5873       if (!isNpm) {
5874         var wrapped = _(array),
5875             actual = wrapped.flatten();
5876
5877         assert.ok(actual instanceof _);
5878         assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
5879
5880         actual = wrapped.flattenDeep();
5881
5882         assert.ok(actual instanceof _);
5883         assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
5884
5885         actual = wrapped.flattenDepth(2);
5886
5887         assert.ok(actual instanceof _);
5888         assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
5889       }
5890       else {
5891         skipAssert(assert, 6);
5892       }
5893     });
5894   }(1, 2, 3));
5895
5896   /*--------------------------------------------------------------------------*/
5897
5898   QUnit.module('flow methods');
5899
5900   lodashStable.each(['flow', 'flowRight'], function(methodName) {
5901     var func = _[methodName],
5902         isFlow = methodName == 'flow';
5903
5904     QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
5905       assert.expect(1);
5906
5907       var fixed = function(n) { return n.toFixed(1); },
5908           combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
5909
5910       assert.strictEqual(combined(1, 2), '9.0');
5911     });
5912
5913     QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
5914       assert.expect(1);
5915
5916       assert.notStrictEqual(func(noop), noop);
5917     });
5918
5919     QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
5920       assert.expect(3);
5921
5922       var combined = func();
5923
5924       try {
5925         assert.strictEqual(combined('a'), 'a');
5926       } catch (e) {
5927         assert.ok(false, e.message);
5928       }
5929       assert.strictEqual(combined.length, 0);
5930       assert.notStrictEqual(combined, identity);
5931     });
5932
5933     QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
5934       assert.expect(1);
5935
5936       var curried = _.curry(identity);
5937
5938       var combined = isFlow
5939         ? func(_.head, curried)
5940         : func(curried, _.head);
5941
5942       assert.strictEqual(combined([1]), 1);
5943     });
5944
5945     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5946       assert.expect(6);
5947
5948       var filterCount,
5949           mapCount,
5950           array = lodashStable.range(LARGE_ARRAY_SIZE),
5951           iteratee = function(value) { mapCount++; return square(value); },
5952           predicate = function(value) { filterCount++; return isEven(value); };
5953
5954       lodashStable.times(2, function(index) {
5955         var filter1 = _.filter,
5956             filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
5957             filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
5958
5959         var map1 = _.map,
5960             map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
5961             map3 = (_.map = index ? map2 : map1, map2(iteratee));
5962
5963         var take1 = _.take,
5964             take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
5965             take3 = (_.take = index ? take2 : take1, take2(2));
5966
5967         var combined = isFlow
5968           ? func(map3, filter3, _.compact, take3)
5969           : func(take3, _.compact, filter3, map3);
5970
5971         filterCount = mapCount = 0;
5972         assert.deepEqual(combined(array), [4, 16]);
5973
5974         if (!isNpm && WeakMap && WeakMap.name) {
5975           assert.strictEqual(filterCount, 5, 'filterCount');
5976           assert.strictEqual(mapCount, 5, 'mapCount');
5977         }
5978         else {
5979           skipAssert(assert, 2);
5980         }
5981         _.filter = filter1;
5982         _.map = map1;
5983         _.take = take1;
5984       });
5985     });
5986
5987     QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
5988       assert.expect(1);
5989
5990       var curried = _.curry(_.ary(_.map, 2), 2),
5991           getProp = curried(curried.placeholder, 'a'),
5992           objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
5993
5994       var combined = isFlow
5995         ? func(getProp, _.uniq)
5996         : func(_.uniq, getProp);
5997
5998       assert.deepEqual(combined(objects), [1, 2]);
5999     });
6000
6001     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6002       assert.expect(1);
6003
6004       if (!isNpm) {
6005         var wrapped = _(noop)[methodName]();
6006         assert.ok(wrapped instanceof _);
6007       }
6008       else {
6009         skipAssert(assert);
6010       }
6011     });
6012   });
6013
6014   /*--------------------------------------------------------------------------*/
6015
6016   QUnit.module('lodash.forEach');
6017
6018   (function() {
6019     QUnit.test('should be aliased', function(assert) {
6020       assert.expect(1);
6021
6022       assert.strictEqual(_.each, _.forEach);
6023     });
6024   }());
6025
6026   /*--------------------------------------------------------------------------*/
6027
6028   QUnit.module('lodash.forEachRight');
6029
6030   (function() {
6031     QUnit.test('should be aliased', function(assert) {
6032       assert.expect(1);
6033
6034       assert.strictEqual(_.eachRight, _.forEachRight);
6035     });
6036   }());
6037
6038   /*--------------------------------------------------------------------------*/
6039
6040   QUnit.module('forIn methods');
6041
6042   lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6043     var func = _[methodName];
6044
6045     QUnit.test('`_.' + methodName + '` iterates over inherited properties', function(assert) {
6046       assert.expect(1);
6047
6048       function Foo() { this.a = 1; }
6049       Foo.prototype.b = 2;
6050
6051       var keys = [];
6052       func(new Foo, function(value, key) { keys.push(key); });
6053       assert.deepEqual(keys.sort(), ['a', 'b']);
6054     });
6055   });
6056
6057   /*--------------------------------------------------------------------------*/
6058
6059   QUnit.module('forOwn methods');
6060
6061   lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6062     var func = _[methodName];
6063
6064     QUnit.test('should iterate over `length` properties', function(assert) {
6065       assert.expect(1);
6066
6067       var object = { '0': 'zero', '1': 'one', 'length': 2 },
6068           props = [];
6069
6070       func(object, function(value, prop) { props.push(prop); });
6071       assert.deepEqual(props.sort(), ['0', '1', 'length']);
6072     });
6073   });
6074
6075   /*--------------------------------------------------------------------------*/
6076
6077   QUnit.module('iteration methods');
6078
6079   (function() {
6080     var methods = [
6081       '_baseEach',
6082       'countBy',
6083       'every',
6084       'filter',
6085       'find',
6086       'findIndex',
6087       'findKey',
6088       'findLast',
6089       'findLastIndex',
6090       'findLastKey',
6091       'forEach',
6092       'forEachRight',
6093       'forIn',
6094       'forInRight',
6095       'forOwn',
6096       'forOwnRight',
6097       'groupBy',
6098       'keyBy',
6099       'map',
6100       'mapKeys',
6101       'mapValues',
6102       'maxBy',
6103       'minBy',
6104       'omitBy',
6105       'partition',
6106       'pickBy',
6107       'reject',
6108       'some'
6109     ];
6110
6111     var arrayMethods = [
6112       'findIndex',
6113       'findLastIndex',
6114       'maxBy',
6115       'minBy'
6116     ];
6117
6118     var collectionMethods = [
6119       '_baseEach',
6120       'countBy',
6121       'every',
6122       'filter',
6123       'find',
6124       'findLast',
6125       'forEach',
6126       'forEachRight',
6127       'groupBy',
6128       'keyBy',
6129       'map',
6130       'partition',
6131       'reduce',
6132       'reduceRight',
6133       'reject',
6134       'some'
6135     ];
6136
6137     var forInMethods = [
6138       'forIn',
6139       'forInRight',
6140       'omitBy',
6141       'pickBy'
6142     ];
6143
6144     var iterationMethods = [
6145       '_baseEach',
6146       'forEach',
6147       'forEachRight',
6148       'forIn',
6149       'forInRight',
6150       'forOwn',
6151       'forOwnRight'
6152     ];
6153
6154     var objectMethods = [
6155       'findKey',
6156       'findLastKey',
6157       'forIn',
6158       'forInRight',
6159       'forOwn',
6160       'forOwnRight',
6161       'mapKeys',
6162       'mapValues',
6163       'omitBy',
6164       'pickBy'
6165     ];
6166
6167     var rightMethods = [
6168       'findLast',
6169       'findLastIndex',
6170       'findLastKey',
6171       'forEachRight',
6172       'forInRight',
6173       'forOwnRight'
6174     ];
6175
6176     var unwrappedMethods = [
6177       'each',
6178       'eachRight',
6179       'every',
6180       'find',
6181       'findIndex',
6182       'findKey',
6183       'findLast',
6184       'findLastIndex',
6185       'findLastKey',
6186       'forEach',
6187       'forEachRight',
6188       'forIn',
6189       'forInRight',
6190       'forOwn',
6191       'forOwnRight',
6192       'max',
6193       'maxBy',
6194       'min',
6195       'minBy',
6196       'some'
6197     ];
6198
6199     lodashStable.each(methods, function(methodName) {
6200       var array = [1, 2, 3],
6201           func = _[methodName],
6202           isBy = /(^partition|By)$/.test(methodName),
6203           isFind = /^find/.test(methodName),
6204           isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6205           isSome = methodName == 'some';
6206
6207       QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
6208         assert.expect(1);
6209
6210         if (func) {
6211           var args,
6212               expected = [1, 0, array];
6213
6214           func(array, function() {
6215             args || (args = slice.call(arguments));
6216           });
6217
6218           if (lodashStable.includes(rightMethods, methodName)) {
6219             expected[0] = 3;
6220             expected[1] = 2;
6221           }
6222           if (lodashStable.includes(objectMethods, methodName)) {
6223             expected[1] += '';
6224           }
6225           if (isBy) {
6226             expected.length = isOmitPick ? 2 : 1;
6227           }
6228           assert.deepEqual(args, expected);
6229         }
6230         else {
6231           skipAssert(assert);
6232         }
6233       });
6234
6235       QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
6236         assert.expect(1);
6237
6238         if (func) {
6239           var array = [1];
6240           array[2] = 3;
6241
6242           var expected = lodashStable.includes(objectMethods, methodName)
6243             ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
6244             : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
6245
6246           if (isBy) {
6247             expected = lodashStable.map(expected, function(args) {
6248               return args.slice(0, isOmitPick ? 2 : 1);
6249             });
6250           }
6251           else if (lodashStable.includes(objectMethods, methodName)) {
6252             expected = lodashStable.map(expected, function(args) {
6253               args[1] += '';
6254               return args;
6255             });
6256           }
6257           if (lodashStable.includes(rightMethods, methodName)) {
6258             expected.reverse();
6259           }
6260           var argsList = [];
6261           func(array, function() {
6262             argsList.push(slice.call(arguments));
6263             return !(isFind || isSome);
6264           });
6265
6266           assert.deepEqual(argsList, expected);
6267         }
6268         else {
6269           skipAssert(assert);
6270         }
6271       });
6272     });
6273
6274     lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
6275       var array = [1, 2, 3],
6276           func = _[methodName],
6277           isEvery = methodName == 'every';
6278
6279       array.a = 1;
6280
6281       QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
6282         assert.expect(1);
6283
6284         if (func) {
6285           var keys = [];
6286           func(array, function(value, key) {
6287             keys.push(key);
6288             return isEvery;
6289           });
6290
6291           assert.notOk(lodashStable.includes(keys, 'a'));
6292         }
6293         else {
6294           skipAssert(assert);
6295         }
6296       });
6297     });
6298
6299     lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
6300       var array = [1, 2, 3],
6301           func = _[methodName],
6302           isBaseEach = methodName == '_baseEach';
6303
6304       QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
6305         assert.expect(1);
6306
6307         if (!(isBaseEach || isNpm)) {
6308           var wrapped = _(array)[methodName](noop);
6309           assert.ok(wrapped instanceof _);
6310         }
6311         else {
6312           skipAssert(assert);
6313         }
6314       });
6315     });
6316
6317     lodashStable.each(unwrappedMethods, function(methodName) {
6318       var array = [1, 2, 3],
6319           func = _[methodName];
6320
6321       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
6322         assert.expect(1);
6323
6324         if (!isNpm) {
6325           var actual = _(array)[methodName](noop);
6326           assert.notOk(actual instanceof _);
6327         }
6328         else {
6329           skipAssert(assert);
6330         }
6331       });
6332
6333       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
6334         assert.expect(2);
6335
6336         if (!isNpm) {
6337           var wrapped = _(array).chain(),
6338               actual = wrapped[methodName](noop);
6339
6340           assert.ok(actual instanceof _);
6341           assert.notStrictEqual(actual, wrapped);
6342         }
6343         else {
6344           skipAssert(assert, 2);
6345         }
6346       });
6347     });
6348
6349     lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
6350       var array = [1, 2, 3],
6351           func = _[methodName];
6352
6353       QUnit.test('`_.' + methodName + '` iterates over own properties of objects', function(assert) {
6354         assert.expect(1);
6355
6356         function Foo() { this.a = 1; }
6357         Foo.prototype.b = 2;
6358
6359         if (func) {
6360           var values = [];
6361           func(new Foo, function(value) { values.push(value); });
6362           assert.deepEqual(values, [1]);
6363         }
6364         else {
6365           skipAssert(assert);
6366         }
6367       });
6368     });
6369
6370     lodashStable.each(iterationMethods, function(methodName) {
6371       var array = [1, 2, 3],
6372           func = _[methodName];
6373
6374       QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
6375         assert.expect(1);
6376
6377         if (func) {
6378           assert.strictEqual(func(array, Boolean), array);
6379         }
6380         else {
6381           skipAssert(assert);
6382         }
6383       });
6384     });
6385
6386     lodashStable.each(collectionMethods, function(methodName) {
6387       var func = _[methodName];
6388
6389       QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
6390         assert.expect(3);
6391
6392         if (func) {
6393           var isIteratedAsObject = function(object) {
6394             var result = false;
6395             func(object, function() { result = true; }, 0);
6396             return result;
6397           };
6398
6399           var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
6400               expected = lodashStable.map(values, alwaysTrue);
6401
6402           var actual = lodashStable.map(values, function(length) {
6403             return isIteratedAsObject({ 'length': length });
6404           });
6405
6406           var Foo = function(a) {};
6407           Foo.a = 1;
6408
6409           assert.deepEqual(actual, expected);
6410           assert.ok(isIteratedAsObject(Foo));
6411           assert.notOk(isIteratedAsObject({ 'length': 0 }));
6412         }
6413         else {
6414           skipAssert(assert, 3);
6415         }
6416       });
6417     });
6418
6419     lodashStable.each(methods, function(methodName) {
6420       var array = [1, 2, 3],
6421           func = _[methodName],
6422           isFind = /^find/.test(methodName),
6423           isSome = methodName == 'some',
6424           isReduce = /^reduce/.test(methodName);
6425
6426       QUnit.test('`_.' + methodName + '` should ignore changes to `array.length`', function(assert) {
6427         assert.expect(1);
6428
6429         if (func) {
6430           var count = 0,
6431               array = [1];
6432
6433           func(array, function() {
6434             if (++count == 1) {
6435               array.push(2);
6436             }
6437             return !(isFind || isSome);
6438           }, isReduce ? array : null);
6439
6440           assert.strictEqual(count, 1);
6441         }
6442         else {
6443           skipAssert(assert);
6444         }
6445       });
6446     });
6447
6448     lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
6449       var func = _[methodName],
6450           isFind = /^find/.test(methodName),
6451           isSome = methodName == 'some',
6452           isReduce = /^reduce/.test(methodName);
6453
6454       QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
6455         assert.expect(1);
6456
6457         if (func) {
6458           var count = 0,
6459               object = { 'a': 1 };
6460
6461           func(object, function() {
6462             if (++count == 1) {
6463               object.b = 2;
6464             }
6465             return !(isFind || isSome);
6466           }, isReduce ? object : null);
6467
6468           assert.strictEqual(count, 1);
6469         }
6470         else {
6471           skipAssert(assert);
6472         }
6473       });
6474     });
6475   }());
6476
6477   /*--------------------------------------------------------------------------*/
6478
6479   QUnit.module('object assignments');
6480
6481   lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
6482     var func = _[methodName],
6483         isAssign = methodName == 'assign',
6484         isDefaults = methodName == 'defaults';
6485
6486     QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
6487       assert.expect(1);
6488
6489       var expected = lodashStable.map(falsey, alwaysTrue);
6490
6491       var actual = lodashStable.map(falsey, function(object, index) {
6492         var result = index ? func(object) : func();
6493         return lodashStable.isEqual(result, Object(object));
6494       });
6495
6496       assert.deepEqual(actual, expected);
6497     });
6498
6499     QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'source properties', function(assert) {
6500       assert.expect(1);
6501
6502       function Foo() { this.a = 1; }
6503       Foo.prototype.b = 2;
6504
6505       var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
6506       assert.deepEqual(func({}, new Foo), expected);
6507     });
6508
6509     QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
6510       assert.expect(1);
6511
6512       try {
6513         assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
6514       } catch (e) {
6515         assert.ok(false, e.message);
6516       }
6517     });
6518
6519     QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
6520       assert.expect(2);
6521
6522       var source = { 'a': 1 },
6523           values = [null, undefined],
6524           expected = lodashStable.map(values, alwaysTrue);
6525
6526       var actual = lodashStable.map(values, function(value) {
6527         var object = func(value, source);
6528         return object !== source && lodashStable.isEqual(object, source);
6529       });
6530
6531       assert.deepEqual(actual, expected);
6532
6533       actual = lodashStable.map(values, function(value) {
6534         return lodashStable.isEqual(func(value), {});
6535       });
6536
6537       assert.deepEqual(actual, expected);
6538     });
6539
6540     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
6541       assert.expect(2);
6542
6543       var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
6544           expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
6545
6546       assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
6547
6548       var fn = function() {};
6549       fn.a = array[0];
6550       fn.b = array[1];
6551       fn.c = array[2];
6552
6553       assert.deepEqual(_.reduce(fn, func, { 'a': 0 }), expected);
6554     });
6555
6556     QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
6557       assert.expect(1);
6558
6559       if (!isNpm) {
6560         var wrapped = _({ 'a': 1 }),
6561             actual = wrapped[methodName]({ 'b': 2 });
6562
6563         assert.notStrictEqual(actual, wrapped);
6564       }
6565       else {
6566         skipAssert(assert);
6567       }
6568     });
6569   });
6570
6571   lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
6572     var func = _[methodName];
6573
6574     QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
6575       assert.expect(1);
6576
6577       function Foo() {}
6578       Foo.prototype.a = 1;
6579
6580       var actual = func(new Foo, { 'b': 2 });
6581       assert.notOk(_.has(actual, 'a'));
6582     });
6583   });
6584
6585   lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
6586     var func = _[methodName];
6587
6588     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
6589       assert.expect(4);
6590
6591       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
6592         if (defineProperty) {
6593           var object = {},
6594               pass = true;
6595
6596           defineProperty(object, 'a', {
6597             'enumerable': true,
6598             'configurable': true,
6599             'get': lodashStable.constant(value),
6600             'set': function() { pass = false; }
6601           });
6602
6603           func(object, { 'a': value });
6604           assert.ok(pass);
6605         }
6606         else {
6607           skipAssert(assert);
6608         }
6609       });
6610     });
6611   });
6612
6613   lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
6614     var func = _[methodName],
6615         isMergeWith = methodName == 'mergeWith';
6616
6617     QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
6618       assert.expect(3);
6619
6620       var args,
6621           object = { 'a': 1 },
6622           source = { 'a': 2 },
6623           expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
6624
6625       func(object, source, function() {
6626         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6627       });
6628
6629       assert.deepEqual(args, expected, 'primitive property values');
6630
6631       args = undefined;
6632       object = { 'a': 1 };
6633       source = { 'b': 2 };
6634       expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
6635
6636       func(object, source, function() {
6637         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6638       });
6639
6640       assert.deepEqual(args, expected, 'missing destination property');
6641
6642       var argsList = [],
6643           objectValue = [1, 2],
6644           sourceValue = { 'b': 2 };
6645
6646       object = { 'a': objectValue };
6647       source = { 'a': sourceValue };
6648       expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
6649
6650       if (isMergeWith) {
6651         expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
6652       }
6653       func(object, source, function() {
6654         argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6655       });
6656
6657       assert.deepEqual(argsList, expected, 'object property values');
6658     });
6659
6660     QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
6661       assert.expect(2);
6662
6663       function callback() {}
6664       callback.b = 2;
6665
6666       var actual = func({ 'a': 1 }, callback);
6667       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
6668
6669       actual = func({ 'a': 1 }, callback, { 'c': 3 });
6670       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
6671     });
6672   });
6673
6674   /*--------------------------------------------------------------------------*/
6675
6676   QUnit.module('exit early');
6677
6678   lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
6679     var func = _[methodName];
6680
6681     QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
6682       assert.expect(1);
6683
6684       if (func) {
6685         var array = [1, 2, 3],
6686             values = [];
6687
6688         func(array, function(value, other) {
6689           values.push(lodashStable.isArray(value) ? other : value);
6690           return false;
6691         });
6692
6693         assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
6694       }
6695       else {
6696         skipAssert(assert);
6697       }
6698     });
6699
6700     QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
6701       assert.expect(1);
6702
6703       if (func) {
6704         var object = { 'a': 1, 'b': 2, 'c': 3 },
6705             values = [];
6706
6707         func(object, function(value, other) {
6708           values.push(lodashStable.isArray(value) ? other : value);
6709           return false;
6710         });
6711
6712         assert.strictEqual(values.length, 1);
6713       }
6714       else {
6715         skipAssert(assert);
6716       }
6717     });
6718   });
6719
6720   /*--------------------------------------------------------------------------*/
6721
6722   QUnit.module('`__proto__` property bugs');
6723
6724   (function() {
6725     QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
6726       assert.expect(4);
6727
6728       var stringLiteral = '__proto__',
6729           stringObject = Object(stringLiteral),
6730           expected = [stringLiteral, stringObject];
6731
6732       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
6733         return isEven(count) ? stringLiteral : stringObject;
6734       });
6735
6736       assert.deepEqual(_.difference(largeArray, largeArray), []);
6737       assert.deepEqual(_.intersection(largeArray, largeArray), expected);
6738       assert.deepEqual(_.uniq(largeArray), expected);
6739       assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
6740     });
6741   }());
6742
6743   /*--------------------------------------------------------------------------*/
6744
6745   QUnit.module('lodash.fromPairs');
6746
6747   (function() {
6748     QUnit.test('should accept a two dimensional array', function(assert) {
6749       assert.expect(1);
6750
6751       var array = [['a', 1], ['b', 2]],
6752           object = { 'a': 1, 'b': 2 },
6753           actual = _.fromPairs(array);
6754
6755       assert.deepEqual(actual, object);
6756     });
6757
6758     QUnit.test('should accept a falsey `array` argument', function(assert) {
6759       assert.expect(1);
6760
6761       var expected = lodashStable.map(falsey, alwaysEmptyObject);
6762
6763       var actual = lodashStable.map(falsey, function(array, index) {
6764         try {
6765           return index ? _.fromPairs(array) : _.fromPairs();
6766         } catch (e) {}
6767       });
6768
6769       assert.deepEqual(actual, expected);
6770     });
6771
6772     QUnit.test('should not support deep paths', function(assert) {
6773       assert.expect(1);
6774
6775       var actual = _.fromPairs([['a.b.c', 1]]);
6776       assert.deepEqual(actual, { 'a.b.c': 1 });
6777     });
6778
6779     QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
6780       assert.expect(1);
6781
6782       var object = { 'a.b.c': 1 };
6783       assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
6784     });
6785
6786     QUnit.test('should work in a lazy sequence', function(assert) {
6787       assert.expect(1);
6788
6789       if (!isNpm) {
6790         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
6791           return ['key' + index, index];
6792         });
6793
6794         var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
6795
6796         assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
6797       }
6798       else {
6799         skipAssert(assert);
6800       }
6801     });
6802   }());
6803
6804   /*--------------------------------------------------------------------------*/
6805
6806   QUnit.module('lodash.functions');
6807
6808   (function() {
6809     QUnit.test('should return the function names of an object', function(assert) {
6810       assert.expect(1);
6811
6812       var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': lodashStable.each };
6813       assert.deepEqual(_.functions(object).sort(), ['b', 'd']);
6814     });
6815
6816     QUnit.test('should not include inherited functions', function(assert) {
6817       assert.expect(1);
6818
6819       function Foo() {
6820         this.a = identity;
6821         this.b = 'b';
6822       }
6823       Foo.prototype.c = noop;
6824       assert.deepEqual(_.functions(new Foo).sort(), ['a']);
6825     });
6826   }());
6827
6828   /*--------------------------------------------------------------------------*/
6829
6830   QUnit.module('lodash.groupBy');
6831
6832   (function() {
6833     var array = [6.1, 4.2, 6.3];
6834
6835     QUnit.test('should transform keys by `iteratee`', function(assert) {
6836       assert.expect(1);
6837
6838       var actual = _.groupBy(array, Math.floor);
6839       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
6840     });
6841
6842     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
6843       assert.expect(1);
6844
6845       var array = [6, 4, 6],
6846           values = [, null, undefined],
6847           expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
6848
6849       var actual = lodashStable.map(values, function(value, index) {
6850         return index ? _.groupBy(array, value) : _.groupBy(array);
6851       });
6852
6853       assert.deepEqual(actual, expected);
6854     });
6855
6856     QUnit.test('should work with "_.property" shorthands', function(assert) {
6857       assert.expect(1);
6858
6859       var actual = _.groupBy(['one', 'two', 'three'], 'length');
6860       assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
6861     });
6862
6863     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
6864       assert.expect(2);
6865
6866       var actual = _.groupBy(array, function(n) {
6867         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
6868       });
6869
6870       assert.deepEqual(actual.constructor, [4.2]);
6871       assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
6872     });
6873
6874     QUnit.test('should work with a number for `iteratee`', function(assert) {
6875       assert.expect(2);
6876
6877       var array = [
6878         [1, 'a'],
6879         [2, 'a'],
6880         [2, 'b']
6881       ];
6882
6883       assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
6884       assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
6885     });
6886
6887     QUnit.test('should work with an object for `collection`', function(assert) {
6888       assert.expect(1);
6889
6890       var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
6891       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
6892     });
6893
6894     QUnit.test('should work in a lazy sequence', function(assert) {
6895       assert.expect(1);
6896
6897       if (!isNpm) {
6898         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
6899           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
6900           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
6901         );
6902
6903         var iteratee = function(value) { value.push(value[0]); return value; },
6904             predicate = function(value) { return isEven(value[0]); },
6905             actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
6906
6907         assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
6908       }
6909       else {
6910         skipAssert(assert);
6911       }
6912     });
6913   }());
6914
6915   /*--------------------------------------------------------------------------*/
6916
6917   QUnit.module('lodash.gt');
6918
6919   (function() {
6920     QUnit.test('should return `true` if `value` > `other`', function(assert) {
6921       assert.expect(2);
6922
6923       assert.strictEqual(_.gt(3, 1), true);
6924       assert.strictEqual(_.gt('def', 'abc'), true);
6925     });
6926
6927     QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
6928       assert.expect(4);
6929
6930       assert.strictEqual(_.gt(1, 3), false);
6931       assert.strictEqual(_.gt(3, 3), false);
6932       assert.strictEqual(_.gt('abc', 'def'), false);
6933       assert.strictEqual(_.gt('def', 'def'), false);
6934     });
6935   }());
6936
6937   /*--------------------------------------------------------------------------*/
6938
6939   QUnit.module('lodash.gte');
6940
6941   (function() {
6942     QUnit.test('should return `true` if `value` >= `other`', function(assert) {
6943       assert.expect(4);
6944
6945       assert.strictEqual(_.gte(3, 1), true);
6946       assert.strictEqual(_.gte(3, 3), true);
6947       assert.strictEqual(_.gte('def', 'abc'), true);
6948       assert.strictEqual(_.gte('def', 'def'), true);
6949     });
6950
6951     QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
6952       assert.expect(2);
6953
6954       assert.strictEqual(_.gte(1, 3), false);
6955       assert.strictEqual(_.gte('abc', 'def'), false);
6956     });
6957   }());
6958
6959   /*--------------------------------------------------------------------------*/
6960
6961   QUnit.module('has methods');
6962
6963   lodashStable.each(['has', 'hasIn'], function(methodName) {
6964     var args = (function() { return arguments; }(1, 2, 3)),
6965         func = _[methodName],
6966         isHas = methodName == 'has';
6967
6968     QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
6969       assert.expect(2);
6970
6971       var object = { 'a': 1 };
6972
6973       lodashStable.each(['a', ['a']], function(path) {
6974         assert.strictEqual(func(object, path), true);
6975       });
6976     });
6977
6978     QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
6979       assert.expect(1);
6980
6981       var object = { 'hasOwnProperty': null, 'a': 1 };
6982       assert.strictEqual(func(object, 'a'), true);
6983     });
6984
6985     QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
6986       assert.expect(2);
6987
6988       var object = { 'a': { 'b': { 'c': 3 } } };
6989
6990       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
6991         assert.strictEqual(func(object, path), true);
6992       });
6993     });
6994
6995     QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
6996       assert.expect(1);
6997
6998       function fn() {}
6999       fn.toString = lodashStable.constant('fn');
7000
7001       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
7002           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
7003           values = [null, undefined, fn, {}];
7004
7005       var actual = lodashStable.transform(objects, function(result, object, index) {
7006         var key = values[index];
7007         lodashStable.each([key, [key]], function(path) {
7008           var prop = _.property(key);
7009           result.push(prop(object));
7010         });
7011       });
7012
7013       assert.deepEqual(actual, expected);
7014     });
7015
7016     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7017       assert.expect(1);
7018
7019       assert.strictEqual(func(args, 1), true);
7020     });
7021
7022     QUnit.test('`_.' + methodName + '` should work with non-string `path` arguments', function(assert) {
7023       assert.expect(2);
7024
7025       var array = [1, 2, 3];
7026
7027       lodashStable.each([1, [1]], function(path) {
7028         assert.strictEqual(func(array, path), true);
7029       });
7030     });
7031
7032     QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
7033       assert.expect(1);
7034
7035       if (create)  {
7036         var object = create(null);
7037         object[1] = 'a';
7038         assert.strictEqual(func(object, 1), true);
7039       }
7040       else {
7041         skipAssert(assert);
7042       }
7043     });
7044
7045     QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7046       assert.expect(2);
7047
7048       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
7049
7050       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
7051         assert.strictEqual(func(object, path), true);
7052       });
7053     });
7054
7055     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7056       assert.expect(2);
7057
7058       function Foo() {}
7059       Foo.prototype.a = 1;
7060
7061       lodashStable.each(['a', ['a']], function(path) {
7062         assert.strictEqual(func(new Foo, path), !isHas);
7063       });
7064     });
7065
7066     QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
7067       assert.expect(1);
7068
7069       var string = Object('abc');
7070       delete args[0];
7071       delete string[0];
7072
7073       var values = [Array(3), args, string],
7074           expected = lodashStable.map(values, alwaysTrue);
7075
7076       var actual = lodashStable.map(values, function(value) {
7077         return func(value, 0);
7078       });
7079
7080       assert.deepEqual(actual, expected);
7081       args[0] = 1;
7082     });
7083
7084     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7085       assert.expect(2);
7086
7087       var values = [null, undefined],
7088           expected = lodashStable.map(values, alwaysFalse);
7089
7090       lodashStable.each(['constructor', ['constructor']], function(path) {
7091         var actual = lodashStable.map(values, function(value) {
7092           return func(value, path);
7093         });
7094
7095         assert.deepEqual(actual, expected);
7096       });
7097     });
7098
7099     QUnit.test('`_.' + methodName + '` should return `false` with deep paths when `object` is nullish', function(assert) {
7100       assert.expect(2);
7101
7102       var values = [null, undefined],
7103           expected = lodashStable.map(values, alwaysFalse);
7104
7105       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
7106         var actual = lodashStable.map(values, function(value) {
7107           return func(value, path);
7108         });
7109
7110         assert.deepEqual(actual, expected);
7111       });
7112     });
7113
7114     QUnit.test('`_.' + methodName + '` should return `false` if parts of `path` are missing', function(assert) {
7115       assert.expect(4);
7116
7117       var object = {};
7118
7119       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
7120         assert.strictEqual(func(object, path), false);
7121       });
7122     });
7123   });
7124
7125   /*--------------------------------------------------------------------------*/
7126
7127   QUnit.module('lodash.head');
7128
7129   (function() {
7130     var array = [1, 2, 3, 4];
7131
7132     QUnit.test('should return the first element', function(assert) {
7133       assert.expect(1);
7134
7135       assert.strictEqual(_.head(array), 1);
7136     });
7137
7138     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
7139       assert.expect(1);
7140
7141       var array = [];
7142       array['-1'] = 1;
7143
7144       assert.strictEqual(_.head(array), undefined);
7145     });
7146
7147     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7148       assert.expect(1);
7149
7150       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7151           actual = lodashStable.map(array, _.head);
7152
7153       assert.deepEqual(actual, [1, 4, 7]);
7154     });
7155
7156     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7157       assert.expect(1);
7158
7159       if (!isNpm) {
7160         assert.strictEqual(_(array).head(), 1);
7161       }
7162       else {
7163         skipAssert(assert);
7164       }
7165     });
7166
7167     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7168       assert.expect(1);
7169
7170       if (!isNpm) {
7171         assert.ok(_(array).chain().head() instanceof _);
7172       }
7173       else {
7174         skipAssert(assert);
7175       }
7176     });
7177
7178     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
7179       assert.expect(1);
7180
7181       if (!isNpm) {
7182         var wrapped = _(array).chain().head();
7183         assert.strictEqual(wrapped.__wrapped__, array);
7184       }
7185       else {
7186         skipAssert(assert);
7187       }
7188     });
7189
7190     QUnit.test('should work in a lazy sequence', function(assert) {
7191       assert.expect(2);
7192
7193       if (!isNpm) {
7194         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
7195             smallArray = array;
7196
7197         lodashStable.times(2, function(index) {
7198           var array = index ? largeArray : smallArray,
7199               wrapped = _(array).filter(isEven);
7200
7201           assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
7202         });
7203       }
7204       else {
7205         skipAssert(assert, 2);
7206       }
7207     });
7208
7209     QUnit.test('should be aliased', function(assert) {
7210       assert.expect(1);
7211
7212       assert.strictEqual(_.first, _.head);
7213     });
7214   }());
7215
7216   /*--------------------------------------------------------------------------*/
7217
7218   QUnit.module('lodash.identity');
7219
7220   (function() {
7221     QUnit.test('should return the first argument given', function(assert) {
7222       assert.expect(1);
7223
7224       var object = { 'name': 'fred' };
7225       assert.strictEqual(_.identity(object), object);
7226     });
7227   }());
7228
7229   /*--------------------------------------------------------------------------*/
7230
7231   QUnit.module('lodash.includes');
7232
7233   (function() {
7234     lodashStable.each({
7235       'an `arguments` object': arguments,
7236       'an array': [1, 2, 3, 4],
7237       'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
7238       'a string': '1234'
7239     },
7240     function(collection, key) {
7241       var isStr = typeof collection == 'string',
7242           values = _.toArray(collection),
7243           length = values.length;
7244
7245       QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
7246         assert.expect(1);
7247
7248         assert.strictEqual(_.includes(collection, 3), true);
7249       });
7250
7251       QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
7252         assert.expect(1);
7253
7254         assert.strictEqual(_.includes(collection, 5), false);
7255       });
7256
7257       QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
7258         assert.expect(2);
7259
7260         assert.strictEqual(_.includes(collection, values[2], 2), true);
7261         assert.strictEqual(_.includes(collection, values[1], 2), false);
7262       });
7263
7264       QUnit.test('should work with ' + key + ' and a `fromIndex` >= `collection.length`', function(assert) {
7265         assert.expect(12);
7266
7267         lodashStable.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) {
7268           assert.strictEqual(_.includes(collection, 1, fromIndex), false);
7269           assert.strictEqual(_.includes(collection, undefined, fromIndex), false);
7270           assert.strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length));
7271         });
7272       });
7273
7274       QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
7275         assert.expect(1);
7276
7277         var expected = lodashStable.map(falsey, alwaysTrue);
7278
7279         var actual = lodashStable.map(falsey, function(fromIndex) {
7280           return _.includes(collection, values[0], fromIndex);
7281         });
7282
7283         assert.deepEqual(actual, expected);
7284       });
7285
7286       QUnit.test('should work with ' + key + ' and coerce non-integer `fromIndex` values to integers', function(assert) {
7287         assert.expect(3);
7288
7289         assert.strictEqual(_.includes(collection, values[0], '1'), false);
7290         assert.strictEqual(_.includes(collection, values[0], 0.1), true);
7291         assert.strictEqual(_.includes(collection, values[0], NaN), true);
7292       });
7293
7294       QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
7295         assert.expect(2);
7296
7297         assert.strictEqual(_.includes(collection, values[2], -2), true);
7298         assert.strictEqual(_.includes(collection, values[1], -2), false);
7299       });
7300
7301       QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= negative `collection.length`', function(assert) {
7302         assert.expect(3);
7303
7304         lodashStable.each([-4, -6, -Infinity], function(fromIndex) {
7305           assert.strictEqual(_.includes(collection, values[0], fromIndex), true);
7306         });
7307       });
7308
7309       QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
7310         assert.expect(1);
7311
7312         assert.strictEqual(_.includes(collection, 2, 1.2), true);
7313       });
7314
7315       QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
7316         assert.expect(1);
7317
7318         if (!isNpm) {
7319           assert.strictEqual(_(collection).includes(3), true);
7320         }
7321         else {
7322           skipAssert(assert);
7323         }
7324       });
7325
7326       QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
7327         assert.expect(1);
7328
7329         if (!isNpm) {
7330           assert.ok(_(collection).chain().includes(3) instanceof _);
7331         }
7332         else {
7333           skipAssert(assert);
7334         }
7335       });
7336     });
7337
7338     lodashStable.each({
7339       'literal': 'abc',
7340       'object': Object('abc')
7341     },
7342     function(collection, key) {
7343       QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
7344         assert.expect(2);
7345
7346         assert.strictEqual(_.includes(collection, 'bc'), true);
7347         assert.strictEqual(_.includes(collection, 'd'), false);
7348       });
7349     });
7350
7351     QUnit.test('should return `false` for empty collections', function(assert) {
7352       assert.expect(1);
7353
7354       var expected = lodashStable.map(empties, alwaysFalse);
7355
7356       var actual = lodashStable.map(empties, function(value) {
7357         try {
7358           return _.includes(value);
7359         } catch (e) {}
7360       });
7361
7362       assert.deepEqual(actual, expected);
7363     });
7364
7365     QUnit.test('should match `NaN`', function(assert) {
7366       assert.expect(1);
7367
7368       assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
7369     });
7370
7371     QUnit.test('should match `-0` as `0`', function(assert) {
7372       assert.expect(2);
7373
7374       assert.strictEqual(_.includes([-0], 0), true);
7375       assert.strictEqual(_.includes([0], -0), true);
7376     });
7377
7378     QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
7379       assert.expect(1);
7380
7381       var array1 = [1, 2, 3],
7382           array2 = [2, 3, 1];
7383
7384       assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
7385     });
7386   }(1, 2, 3, 4));
7387
7388   /*--------------------------------------------------------------------------*/
7389
7390   QUnit.module('lodash.indexOf');
7391
7392   (function() {
7393     var array = [1, 2, 3, 1, 2, 3];
7394
7395     QUnit.test('should return the index of the first matched value', function(assert) {
7396       assert.expect(1);
7397
7398       assert.strictEqual(_.indexOf(array, 3), 2);
7399     });
7400
7401     QUnit.test('should work with a positive `fromIndex`', function(assert) {
7402       assert.expect(1);
7403
7404       assert.strictEqual(_.indexOf(array, 1, 2), 3);
7405     });
7406
7407     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
7408       assert.expect(1);
7409
7410       var values = [6, 8, Math.pow(2, 32), Infinity],
7411           expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
7412
7413       var actual = lodashStable.map(values, function(fromIndex) {
7414         return [
7415           _.indexOf(array, undefined, fromIndex),
7416           _.indexOf(array, 1, fromIndex),
7417           _.indexOf(array, '', fromIndex)
7418         ];
7419       });
7420
7421       assert.deepEqual(actual, expected);
7422     });
7423
7424     QUnit.test('should work with a negative `fromIndex`', function(assert) {
7425       assert.expect(1);
7426
7427       assert.strictEqual(_.indexOf(array, 2, -3), 4);
7428     });
7429
7430     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
7431       assert.expect(1);
7432
7433       var values = [-6, -8, -Infinity],
7434           expected = lodashStable.map(values, alwaysZero);
7435
7436       var actual = lodashStable.map(values, function(fromIndex) {
7437         return _.indexOf(array, 1, fromIndex);
7438       });
7439
7440       assert.deepEqual(actual, expected);
7441     });
7442
7443     QUnit.test('should treat falsey `fromIndex` values as `0`', function(assert) {
7444       assert.expect(1);
7445
7446       var expected = lodashStable.map(falsey, alwaysZero);
7447
7448       var actual = lodashStable.map(falsey, function(fromIndex) {
7449         return _.indexOf(array, 1, fromIndex);
7450       });
7451
7452       assert.deepEqual(actual, expected);
7453     });
7454
7455     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
7456       assert.expect(1);
7457
7458       assert.strictEqual(_.indexOf(array, 2, 1.2), 1);
7459     });
7460   }());
7461
7462   /*--------------------------------------------------------------------------*/
7463
7464   QUnit.module('lodash.initial');
7465
7466   (function() {
7467     var array = [1, 2, 3];
7468
7469     QUnit.test('should accept a falsey `array` argument', function(assert) {
7470       assert.expect(1);
7471
7472       var expected = lodashStable.map(falsey, alwaysEmptyArray);
7473
7474       var actual = lodashStable.map(falsey, function(array, index) {
7475         try {
7476           return index ? _.initial(array) : _.initial();
7477         } catch (e) {}
7478       });
7479
7480       assert.deepEqual(actual, expected);
7481     });
7482
7483     QUnit.test('should exclude last element', function(assert) {
7484       assert.expect(1);
7485
7486       assert.deepEqual(_.initial(array), [1, 2]);
7487     });
7488
7489     QUnit.test('should return an empty when querying empty arrays', function(assert) {
7490       assert.expect(1);
7491
7492       assert.deepEqual(_.initial([]), []);
7493     });
7494
7495     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7496       assert.expect(1);
7497
7498       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7499           actual = lodashStable.map(array, _.initial);
7500
7501       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
7502     });
7503
7504     QUnit.test('should work in a lazy sequence', function(assert) {
7505       assert.expect(4);
7506
7507       if (!isNpm) {
7508         var array = lodashStable.range(LARGE_ARRAY_SIZE),
7509             values = [];
7510
7511         var actual = _(array).initial().filter(function(value) {
7512           values.push(value);
7513           return false;
7514         })
7515         .value();
7516
7517         assert.deepEqual(actual, []);
7518         assert.deepEqual(values, _.initial(array));
7519
7520         values = [];
7521
7522         actual = _(array).filter(function(value) {
7523           values.push(value);
7524           return isEven(value);
7525         })
7526         .initial()
7527         .value();
7528
7529         assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
7530         assert.deepEqual(values, array);
7531       }
7532       else {
7533         skipAssert(assert, 4);
7534       }
7535     });
7536   }());
7537
7538   /*--------------------------------------------------------------------------*/
7539
7540   QUnit.module('lodash.inRange');
7541
7542   (function() {
7543     QUnit.test('should work with an `end` argument', function(assert) {
7544       assert.expect(3);
7545
7546       assert.strictEqual(_.inRange(3, 5), true);
7547       assert.strictEqual(_.inRange(5, 5), false);
7548       assert.strictEqual(_.inRange(6, 5), false);
7549     });
7550
7551     QUnit.test('should work with `start` and `end` arguments', function(assert) {
7552       assert.expect(4);
7553
7554       assert.strictEqual(_.inRange(1, 1, 5), true);
7555       assert.strictEqual(_.inRange(3, 1, 5), true);
7556       assert.strictEqual(_.inRange(0, 1, 5), false);
7557       assert.strictEqual(_.inRange(5, 1, 5), false);
7558     });
7559
7560     QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
7561       assert.expect(13);
7562
7563       lodashStable.each(falsey, function(value, index) {
7564         if (index) {
7565           assert.strictEqual(_.inRange(0, value), false);
7566           assert.strictEqual(_.inRange(0, value, 1), true);
7567         } else {
7568           assert.strictEqual(_.inRange(0), false);
7569         }
7570       });
7571     });
7572
7573     QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
7574       assert.expect(2);
7575
7576       assert.strictEqual(_.inRange(2, 5, 1), true);
7577       assert.strictEqual(_.inRange(-3, -2, -6), true);
7578     });
7579
7580     QUnit.test('should work with a floating point `n` value', function(assert) {
7581       assert.expect(4);
7582
7583       assert.strictEqual(_.inRange(0.5, 5), true);
7584       assert.strictEqual(_.inRange(1.2, 1, 5), true);
7585       assert.strictEqual(_.inRange(5.2, 5), false);
7586       assert.strictEqual(_.inRange(0.5, 1, 5), false);
7587     });
7588
7589     QUnit.test('should coerce arguments to finite numbers', function(assert) {
7590       assert.expect(1);
7591
7592       var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
7593           expected = lodashStable.map(actual, alwaysTrue);
7594
7595       assert.deepEqual(actual, expected);
7596     });
7597   }());
7598
7599   /*--------------------------------------------------------------------------*/
7600
7601   QUnit.module('intersection methods');
7602
7603   lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
7604     var args = (function() { return arguments; }(1, 2, 3)),
7605         func = _[methodName];
7606
7607     QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
7608       assert.expect(2);
7609
7610       var actual = func([1, 3, 2], [5, 2, 1, 4]);
7611       assert.deepEqual(actual, [1, 2]);
7612
7613       actual = func([5, 2, 1, 4], [1, 3, 2]);
7614       assert.deepEqual(actual, [2, 1]);
7615     });
7616
7617     QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
7618       assert.expect(2);
7619
7620       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
7621       assert.deepEqual(actual, [1, 2]);
7622
7623       actual = func([5, 2, 1, 4], [2, 1], [1, 3, 2]);
7624       assert.deepEqual(actual, [2, 1]);
7625     });
7626
7627     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
7628       assert.expect(1);
7629
7630       var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
7631       assert.deepEqual(actual, [1, 2]);
7632     });
7633
7634     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
7635       assert.expect(1);
7636
7637       var actual = func([1, NaN, 3], [NaN, 5, NaN]);
7638       assert.deepEqual(actual, [NaN]);
7639     });
7640
7641     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
7642       assert.expect(2);
7643
7644       var object = {},
7645           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
7646
7647       assert.deepEqual(func([object], largeArray), [object]);
7648       assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
7649     });
7650
7651     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
7652       assert.expect(1);
7653
7654       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
7655       assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
7656     });
7657
7658     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7659       assert.expect(2);
7660
7661       var array = [0, 1, null, 3],
7662           expected = [1, 3];
7663
7664       assert.deepEqual(func(array, args), expected);
7665       assert.deepEqual(func(args, array), expected);
7666     });
7667
7668     QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
7669       assert.expect(1);
7670
7671       var actual = func([1, 1, 3, 2, 2]);
7672       assert.deepEqual(actual, [1, 3, 2]);
7673     });
7674
7675     QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
7676       assert.expect(3);
7677
7678       var array = [0, 1, null, 3];
7679       assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
7680       assert.deepEqual(func(null, array, null, [2, 3]), []);
7681       assert.deepEqual(func(array, null, args, null), []);
7682     });
7683
7684     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
7685       assert.expect(2);
7686
7687       if (!isNpm) {
7688         var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
7689         assert.ok(wrapped instanceof _);
7690         assert.deepEqual(wrapped.value(), [1, 2]);
7691       }
7692       else {
7693         skipAssert(assert, 2);
7694       }
7695     });
7696   });
7697
7698   /*--------------------------------------------------------------------------*/
7699
7700   QUnit.module('lodash.intersectionBy');
7701
7702   (function() {
7703     QUnit.test('should accept an `iteratee` argument', function(assert) {
7704       assert.expect(2);
7705
7706       var actual = _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7707       assert.deepEqual(actual, [2.1]);
7708
7709       actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7710       assert.deepEqual(actual, [{ 'x': 1 }]);
7711     });
7712
7713     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
7714       assert.expect(1);
7715
7716       var args;
7717
7718       _.intersectionBy([2.1, 1.2], [4.3, 2.4], function() {
7719         args || (args = slice.call(arguments));
7720       });
7721
7722       assert.deepEqual(args, [4.3]);
7723     });
7724   }());
7725
7726   /*--------------------------------------------------------------------------*/
7727
7728   QUnit.module('lodash.intersectionWith');
7729
7730   (function() {
7731     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7732
7733     QUnit.test('should work with a `comparator` argument', function(assert) {
7734       assert.expect(1);
7735
7736       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
7737           actual = _.intersectionWith(objects, others, lodashStable.isEqual);
7738
7739       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }]);
7740     });
7741   }());
7742
7743   /*--------------------------------------------------------------------------*/
7744
7745   QUnit.module('lodash.invert');
7746
7747   (function() {
7748     QUnit.test('should invert an object', function(assert) {
7749       assert.expect(2);
7750
7751       var object = { 'a': 1, 'b': 2 },
7752           actual = _.invert(object);
7753
7754       assert.deepEqual(actual, { '1': 'a', '2': 'b' });
7755       assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
7756     });
7757
7758     QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
7759       assert.expect(1);
7760
7761       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
7762       assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
7763     });
7764
7765     QUnit.test('should work with an object that has a `length` property', function(assert) {
7766       assert.expect(1);
7767
7768       var object = { '0': 'a', '1': 'b', 'length': 2 };
7769       assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
7770     });
7771
7772     QUnit.test('should return a wrapped value when chaining', function(assert) {
7773       assert.expect(2);
7774
7775       if (!isNpm) {
7776         var object = { 'a': 1, 'b': 2 },
7777             wrapped = _(object).invert();
7778
7779         assert.ok(wrapped instanceof _);
7780         assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
7781       }
7782       else {
7783         skipAssert(assert, 2);
7784       }
7785     });
7786   }());
7787
7788   /*--------------------------------------------------------------------------*/
7789
7790   QUnit.module('lodash.invertBy');
7791
7792   (function() {
7793     var object = { 'a': 1, 'b': 2, 'c': 1 };
7794
7795     QUnit.test('should transform keys by `iteratee`', function(assert) {
7796       assert.expect(1);
7797
7798       var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
7799
7800       var actual = _.invertBy(object, function(value) {
7801         return 'group' + value;
7802       });
7803
7804       assert.deepEqual(actual, expected);
7805     });
7806
7807     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7808       assert.expect(1);
7809
7810       var values = [, null, undefined],
7811           expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
7812
7813       var actual = lodashStable.map(values, function(value, index) {
7814         return index ? _.invertBy(object, value) : _.invertBy(object);
7815       });
7816
7817       assert.deepEqual(actual, expected);
7818     });
7819
7820     QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
7821       assert.expect(1);
7822
7823       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
7824           expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
7825
7826       assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
7827     });
7828
7829     QUnit.test('should return a wrapped value when chaining', function(assert) {
7830       assert.expect(2);
7831
7832       if (!isNpm) {
7833         var wrapped = _(object).invertBy();
7834
7835         assert.ok(wrapped instanceof _);
7836         assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
7837       }
7838       else {
7839         skipAssert(assert, 2);
7840       }
7841     });
7842   }());
7843
7844   /*--------------------------------------------------------------------------*/
7845
7846   QUnit.module('lodash.invoke');
7847
7848   (function() {
7849     QUnit.test('should invoke a method on `object`', function(assert) {
7850       assert.expect(1);
7851
7852       var object = { 'a': lodashStable.constant('A') },
7853           actual = _.invoke(object, 'a');
7854
7855       assert.strictEqual(actual, 'A');
7856     });
7857
7858     QUnit.test('should support invoking with arguments', function(assert) {
7859       assert.expect(1);
7860
7861       var object = { 'a': function(a, b) { return [a, b]; } },
7862           actual = _.invoke(object, 'a', 1, 2);
7863
7864       assert.deepEqual(actual, [1, 2]);
7865     });
7866
7867     QUnit.test('should not error on nullish elements', function(assert) {
7868       assert.expect(1);
7869
7870       var values = [null, undefined],
7871           expected = lodashStable.map(values, alwaysUndefined);
7872
7873       var actual = lodashStable.map(values, function(value) {
7874         try {
7875           return _.invoke(value, 'a.b.c', 1, 2);
7876         } catch (e) {}
7877       });
7878
7879       assert.deepEqual(actual, expected);
7880     });
7881
7882     QUnit.test('should support deep paths', function(assert) {
7883       assert.expect(2);
7884
7885       var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
7886
7887       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7888         var actual = _.invoke(object, path, 1, 2);
7889         assert.deepEqual(actual, [1, 2]);
7890       });
7891     });
7892
7893     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
7894       assert.expect(2);
7895
7896       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
7897
7898       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7899         assert.deepEqual(_.invoke(object, path), 1);
7900       });
7901     });
7902
7903     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7904       assert.expect(1);
7905
7906       if (!isNpm) {
7907         var object = { 'a': alwaysOne };
7908         assert.strictEqual(_(object).invoke('a'), 1);
7909       }
7910       else {
7911         skipAssert(assert);
7912       }
7913     });
7914
7915     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7916       assert.expect(1);
7917
7918       if (!isNpm) {
7919         var object = { 'a': alwaysOne };
7920         assert.ok(_(object).chain().invoke('a') instanceof _);
7921       }
7922       else {
7923         skipAssert(assert);
7924       }
7925     });
7926   }());
7927
7928   /*--------------------------------------------------------------------------*/
7929
7930   QUnit.module('lodash.invokeMap');
7931
7932   (function() {
7933     QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
7934       assert.expect(1);
7935
7936       var array = ['a', 'b', 'c'],
7937           actual = _.invokeMap(array, 'toUpperCase');
7938
7939       assert.deepEqual(actual, ['A', 'B', 'C']);
7940     });
7941
7942     QUnit.test('should support invoking with arguments', function(assert) {
7943       assert.expect(1);
7944
7945       var array = [function() { return slice.call(arguments); }],
7946           actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
7947
7948       assert.deepEqual(actual, [['a', 'b', 'c']]);
7949     });
7950
7951     QUnit.test('should work with a function for `methodName`', function(assert) {
7952       assert.expect(1);
7953
7954       var array = ['a', 'b', 'c'];
7955
7956       var actual = _.invokeMap(array, function(left, right) {
7957         return left + this.toUpperCase() + right;
7958       }, '(', ')');
7959
7960       assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
7961     });
7962
7963     QUnit.test('should work with an object for `collection`', function(assert) {
7964       assert.expect(1);
7965
7966       var object = { 'a': 1, 'b': 2, 'c': 3 },
7967           actual = _.invokeMap(object, 'toFixed', 1);
7968
7969       assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
7970     });
7971
7972     QUnit.test('should treat number values for `collection` as empty', function(assert) {
7973       assert.expect(1);
7974
7975       assert.deepEqual(_.invokeMap(1), []);
7976     });
7977
7978     QUnit.test('should not error on nullish elements', function(assert) {
7979       assert.expect(1);
7980
7981       var array = ['a', null, undefined, 'd'];
7982
7983       try {
7984         var actual = _.invokeMap(array, 'toUpperCase');
7985       } catch (e) {}
7986
7987       assert.deepEqual(_.invokeMap(array, 'toUpperCase'), ['A', undefined, undefined, 'D']);
7988     });
7989
7990     QUnit.test('should not error on elements with missing properties', function(assert) {
7991       assert.expect(1);
7992
7993       var objects = lodashStable.map([null, undefined, alwaysOne], function(value) {
7994         return { 'a': value };
7995       });
7996
7997       var expected = lodashStable.map(objects, function(object) {
7998         return object.a ? object.a() : undefined;
7999       });
8000
8001       try {
8002         var actual = _.invokeMap(objects, 'a');
8003       } catch (e) {}
8004
8005       assert.deepEqual(actual, expected);
8006     });
8007
8008     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8009       assert.expect(2);
8010
8011       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8012
8013       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8014         assert.deepEqual(_.invokeMap([object], path), [1]);
8015       });
8016     });
8017
8018     QUnit.test('should return a wrapped value when chaining', function(assert) {
8019       assert.expect(4);
8020
8021       if (!isNpm) {
8022         var array = ['a', 'b', 'c'],
8023             wrapped = _(array),
8024             actual = wrapped.invokeMap('toUpperCase');
8025
8026         assert.ok(actual instanceof _);
8027         assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8028
8029         actual = wrapped.invokeMap(function(left, right) {
8030           return left + this.toUpperCase() + right;
8031         }, '(', ')');
8032
8033         assert.ok(actual instanceof _);
8034         assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8035       }
8036       else {
8037         skipAssert(assert, 4);
8038       }
8039     });
8040
8041     QUnit.test('should support shortcut fusion', function(assert) {
8042       assert.expect(2);
8043
8044       if (!isNpm) {
8045         var count = 0,
8046             method = function() { count++; return this.index; };
8047
8048         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8049           return { 'index': index, 'method': method };
8050         });
8051
8052         var actual = _(array).invokeMap('method').take(1).value();
8053
8054         assert.strictEqual(count, 1);
8055         assert.deepEqual(actual, [0]);
8056       }
8057       else {
8058         skipAssert(assert, 2);
8059       }
8060     });
8061   }());
8062
8063   /*--------------------------------------------------------------------------*/
8064
8065   QUnit.module('lodash.isArguments');
8066
8067   (function() {
8068     var args = (function() { return arguments; }(1, 2, 3)),
8069         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
8070
8071     QUnit.test('should return `true` for `arguments` objects', function(assert) {
8072       assert.expect(2);
8073
8074       assert.strictEqual(_.isArguments(args), true);
8075       assert.strictEqual(_.isArguments(strictArgs), true);
8076     });
8077
8078     QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8079       assert.expect(12);
8080
8081       var expected = lodashStable.map(falsey, alwaysFalse);
8082
8083       var actual = lodashStable.map(falsey, function(value, index) {
8084         return index ? _.isArguments(value) : _.isArguments();
8085       });
8086
8087       assert.deepEqual(actual, expected);
8088
8089       assert.strictEqual(_.isArguments([1, 2, 3]), false);
8090       assert.strictEqual(_.isArguments(true), false);
8091       assert.strictEqual(_.isArguments(new Date), false);
8092       assert.strictEqual(_.isArguments(new Error), false);
8093       assert.strictEqual(_.isArguments(_), false);
8094       assert.strictEqual(_.isArguments(slice), false);
8095       assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8096       assert.strictEqual(_.isArguments(1), false);
8097       assert.strictEqual(_.isArguments(/x/), false);
8098       assert.strictEqual(_.isArguments('a'), false);
8099       assert.strictEqual(_.isArguments(symbol), false);
8100     });
8101
8102     QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8103       assert.expect(1);
8104
8105       if (realm.arguments) {
8106         assert.strictEqual(_.isArguments(realm.arguments), true);
8107       }
8108       else {
8109         skipAssert(assert);
8110       }
8111     });
8112   }());
8113
8114   /*--------------------------------------------------------------------------*/
8115
8116   QUnit.module('lodash.isArray');
8117
8118   (function() {
8119     var args = arguments;
8120
8121     QUnit.test('should return `true` for arrays', function(assert) {
8122       assert.expect(1);
8123
8124       assert.strictEqual(_.isArray([1, 2, 3]), true);
8125     });
8126
8127     QUnit.test('should return `false` for non-arrays', function(assert) {
8128       assert.expect(12);
8129
8130       var expected = lodashStable.map(falsey, alwaysFalse);
8131
8132       var actual = lodashStable.map(falsey, function(value, index) {
8133         return index ? _.isArray(value) : _.isArray();
8134       });
8135
8136       assert.deepEqual(actual, expected);
8137
8138       assert.strictEqual(_.isArray(args), false);
8139       assert.strictEqual(_.isArray(true), false);
8140       assert.strictEqual(_.isArray(new Date), false);
8141       assert.strictEqual(_.isArray(new Error), false);
8142       assert.strictEqual(_.isArray(_), false);
8143       assert.strictEqual(_.isArray(slice), false);
8144       assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
8145       assert.strictEqual(_.isArray(1), false);
8146       assert.strictEqual(_.isArray(/x/), false);
8147       assert.strictEqual(_.isArray('a'), false);
8148       assert.strictEqual(_.isArray(symbol), false);
8149     });
8150
8151     QUnit.test('should work with an array from another realm', function(assert) {
8152       assert.expect(1);
8153
8154       if (realm.array) {
8155         assert.strictEqual(_.isArray(realm.array), true);
8156       }
8157       else {
8158         skipAssert(assert);
8159       }
8160     });
8161   }(1, 2, 3));
8162
8163   /*--------------------------------------------------------------------------*/
8164
8165   QUnit.module('lodash.isArrayBuffer');
8166
8167   (function() {
8168     var args = arguments;
8169
8170     QUnit.test('should return `true` for array buffers', function(assert) {
8171       assert.expect(1);
8172
8173       if (ArrayBuffer) {
8174         assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
8175       }
8176       else {
8177         skipAssert(assert);
8178       }
8179     });
8180
8181     QUnit.test('should return `false` for non array buffers', function(assert) {
8182       assert.expect(13);
8183
8184       var expected = lodashStable.map(falsey, alwaysFalse);
8185
8186       var actual = lodashStable.map(falsey, function(value, index) {
8187         return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
8188       });
8189
8190       assert.deepEqual(actual, expected);
8191
8192       assert.strictEqual(_.isArrayBuffer(args), false);
8193       assert.strictEqual(_.isArrayBuffer([1, 2, 3]), false);
8194       assert.strictEqual(_.isArrayBuffer(true), false);
8195       assert.strictEqual(_.isArrayBuffer(new Date), false);
8196       assert.strictEqual(_.isArrayBuffer(new Error), false);
8197       assert.strictEqual(_.isArrayBuffer(_), false);
8198       assert.strictEqual(_.isArrayBuffer(slice), false);
8199       assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
8200       assert.strictEqual(_.isArrayBuffer(1), false);
8201       assert.strictEqual(_.isArrayBuffer(/x/), false);
8202       assert.strictEqual(_.isArrayBuffer('a'), false);
8203       assert.strictEqual(_.isArrayBuffer(symbol), false);
8204     });
8205
8206     QUnit.test('should work with array buffers from another realm', function(assert) {
8207       assert.expect(1);
8208
8209       if (realm.arrayBuffer) {
8210         assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
8211       }
8212       else {
8213         skipAssert(assert);
8214       }
8215     });
8216   }(1, 2, 3));
8217
8218   /*--------------------------------------------------------------------------*/
8219
8220   QUnit.module('lodash.isArrayLike');
8221
8222   (function() {
8223     var args = arguments;
8224
8225     QUnit.test('should return `true` for array-like values', function(assert) {
8226       assert.expect(1);
8227
8228       var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
8229           expected = lodashStable.map(values, alwaysTrue),
8230           actual = lodashStable.map(values, _.isArrayLike);
8231
8232       assert.deepEqual(actual, expected);
8233     });
8234
8235     QUnit.test('should return `false` for non-arrays', function(assert) {
8236       assert.expect(11);
8237
8238       var expected = lodashStable.map(falsey, function(value) {
8239         return value === '';
8240       });
8241
8242       var actual = lodashStable.map(falsey, function(value, index) {
8243         return index ? _.isArrayLike(value) : _.isArrayLike();
8244       });
8245
8246       assert.deepEqual(actual, expected);
8247
8248       assert.strictEqual(_.isArrayLike(true), false);
8249       assert.strictEqual(_.isArrayLike(new Date), false);
8250       assert.strictEqual(_.isArrayLike(new Error), false);
8251       assert.strictEqual(_.isArrayLike(_), false);
8252       assert.strictEqual(_.isArrayLike(generator), false);
8253       assert.strictEqual(_.isArrayLike(slice), false);
8254       assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
8255       assert.strictEqual(_.isArrayLike(1), false);
8256       assert.strictEqual(_.isArrayLike(/x/), false);
8257       assert.strictEqual(_.isArrayLike(symbol), false);
8258     });
8259
8260     QUnit.test('should work with an array from another realm', function(assert) {
8261       assert.expect(1);
8262
8263       if (realm.object) {
8264         var values = [realm.arguments, realm.array, realm.string],
8265             expected = lodashStable.map(values, alwaysTrue),
8266             actual = lodashStable.map(values, _.isArrayLike);
8267
8268         assert.deepEqual(actual, expected);
8269       }
8270       else {
8271         skipAssert(assert);
8272       }
8273     });
8274   }(1, 2, 3));
8275
8276   /*--------------------------------------------------------------------------*/
8277
8278   QUnit.module('lodash.isBoolean');
8279
8280   (function() {
8281     var args = arguments;
8282
8283     QUnit.test('should return `true` for booleans', function(assert) {
8284       assert.expect(4);
8285
8286       assert.strictEqual(_.isBoolean(true), true);
8287       assert.strictEqual(_.isBoolean(false), true);
8288       assert.strictEqual(_.isBoolean(Object(true)), true);
8289       assert.strictEqual(_.isBoolean(Object(false)), true);
8290     });
8291
8292     QUnit.test('should return `false` for non-booleans', function(assert) {
8293       assert.expect(12);
8294
8295       var expected = lodashStable.map(falsey, function(value) {
8296         return value === false;
8297       });
8298
8299       var actual = lodashStable.map(falsey, function(value, index) {
8300         return index ? _.isBoolean(value) : _.isBoolean();
8301       });
8302
8303       assert.deepEqual(actual, expected);
8304
8305       assert.strictEqual(_.isBoolean(args), false);
8306       assert.strictEqual(_.isBoolean([1, 2, 3]), false);
8307       assert.strictEqual(_.isBoolean(new Date), false);
8308       assert.strictEqual(_.isBoolean(new Error), false);
8309       assert.strictEqual(_.isBoolean(_), false);
8310       assert.strictEqual(_.isBoolean(slice), false);
8311       assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
8312       assert.strictEqual(_.isBoolean(1), false);
8313       assert.strictEqual(_.isBoolean(/x/), false);
8314       assert.strictEqual(_.isBoolean('a'), false);
8315       assert.strictEqual(_.isBoolean(symbol), false);
8316     });
8317
8318     QUnit.test('should work with a boolean from another realm', function(assert) {
8319       assert.expect(1);
8320
8321       if (realm.boolean) {
8322         assert.strictEqual(_.isBoolean(realm.boolean), true);
8323       }
8324       else {
8325         skipAssert(assert);
8326       }
8327     });
8328   }(1, 2, 3));
8329
8330   /*--------------------------------------------------------------------------*/
8331
8332   QUnit.module('lodash.isBuffer');
8333
8334   (function() {
8335     var args = arguments;
8336
8337     QUnit.test('should return `true` for buffers', function(assert) {
8338       assert.expect(1);
8339
8340       if (Buffer) {
8341         assert.strictEqual(_.isBuffer(new Buffer(2)), true);
8342       }
8343       else {
8344         skipAssert(assert);
8345       }
8346     });
8347
8348     QUnit.test('should return `false` for non buffers', function(assert) {
8349       assert.expect(13);
8350
8351       var expected = lodashStable.map(falsey, alwaysFalse);
8352
8353       var actual = lodashStable.map(falsey, function(value, index) {
8354         return index ? _.isBuffer(value) : _.isBuffer();
8355       });
8356
8357       assert.deepEqual(actual, expected);
8358
8359       assert.strictEqual(_.isBuffer(args), false);
8360       assert.strictEqual(_.isBuffer([1, 2, 3]), false);
8361       assert.strictEqual(_.isBuffer(true), false);
8362       assert.strictEqual(_.isBuffer(new Date), false);
8363       assert.strictEqual(_.isBuffer(new Error), false);
8364       assert.strictEqual(_.isBuffer(_), false);
8365       assert.strictEqual(_.isBuffer(slice), false);
8366       assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
8367       assert.strictEqual(_.isBuffer(1), false);
8368       assert.strictEqual(_.isBuffer(/x/), false);
8369       assert.strictEqual(_.isBuffer('a'), false);
8370       assert.strictEqual(_.isBuffer(symbol), false);
8371     });
8372
8373     QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
8374       assert.expect(1);
8375
8376       if (!isStrict && Buffer && lodashBizarro) {
8377         assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
8378       }
8379       else {
8380         skipAssert(assert);
8381       }
8382     });
8383   }(1, 2, 3));
8384
8385   /*--------------------------------------------------------------------------*/
8386
8387   QUnit.module('lodash.isDate');
8388
8389   (function() {
8390     var args = arguments;
8391
8392     QUnit.test('should return `true` for dates', function(assert) {
8393       assert.expect(1);
8394
8395       assert.strictEqual(_.isDate(new Date), true);
8396     });
8397
8398     QUnit.test('should return `false` for non-dates', function(assert) {
8399       assert.expect(12);
8400
8401       var expected = lodashStable.map(falsey, alwaysFalse);
8402
8403       var actual = lodashStable.map(falsey, function(value, index) {
8404         return index ? _.isDate(value) : _.isDate();
8405       });
8406
8407       assert.deepEqual(actual, expected);
8408
8409       assert.strictEqual(_.isDate(args), false);
8410       assert.strictEqual(_.isDate([1, 2, 3]), false);
8411       assert.strictEqual(_.isDate(true), false);
8412       assert.strictEqual(_.isDate(new Error), false);
8413       assert.strictEqual(_.isDate(_), false);
8414       assert.strictEqual(_.isDate(slice), false);
8415       assert.strictEqual(_.isDate({ 'a': 1 }), false);
8416       assert.strictEqual(_.isDate(1), false);
8417       assert.strictEqual(_.isDate(/x/), false);
8418       assert.strictEqual(_.isDate('a'), false);
8419       assert.strictEqual(_.isDate(symbol), false);
8420     });
8421
8422     QUnit.test('should work with a date object from another realm', function(assert) {
8423       assert.expect(1);
8424
8425       if (realm.date) {
8426         assert.strictEqual(_.isDate(realm.date), true);
8427       }
8428       else {
8429         skipAssert(assert);
8430       }
8431     });
8432   }(1, 2, 3));
8433
8434   /*--------------------------------------------------------------------------*/
8435
8436   QUnit.module('lodash.isElement');
8437
8438   (function() {
8439     var args = arguments;
8440
8441     function Element() {
8442       this.nodeType = 1;
8443     }
8444
8445     QUnit.test('should return `false` for plain objects', function(assert) {
8446       assert.expect(7);
8447
8448       var element = body || new Element;
8449
8450       assert.strictEqual(_.isElement(element), true);
8451       assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
8452       assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
8453       assert.strictEqual(_.isElement({ 'nodeType': true }), false);
8454       assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
8455       assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
8456       assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
8457     });
8458
8459     QUnit.test('should return `false` for non DOM elements', function(assert) {
8460       assert.expect(13);
8461
8462       var expected = lodashStable.map(falsey, alwaysFalse);
8463
8464       var actual = lodashStable.map(falsey, function(value, index) {
8465         return index ? _.isElement(value) : _.isElement();
8466       });
8467
8468       assert.deepEqual(actual, expected);
8469
8470       assert.strictEqual(_.isElement(args), false);
8471       assert.strictEqual(_.isElement([1, 2, 3]), false);
8472       assert.strictEqual(_.isElement(true), false);
8473       assert.strictEqual(_.isElement(new Date), false);
8474       assert.strictEqual(_.isElement(new Error), false);
8475       assert.strictEqual(_.isElement(_), false);
8476       assert.strictEqual(_.isElement(slice), false);
8477       assert.strictEqual(_.isElement({ 'a': 1 }), false);
8478       assert.strictEqual(_.isElement(1), false);
8479       assert.strictEqual(_.isElement(/x/), false);
8480       assert.strictEqual(_.isElement('a'), false);
8481       assert.strictEqual(_.isElement(symbol), false);
8482     });
8483
8484     QUnit.test('should work with a DOM element from another realm', function(assert) {
8485       assert.expect(1);
8486
8487       if (realm.element) {
8488         assert.strictEqual(_.isElement(realm.element), true);
8489       }
8490       else {
8491         skipAssert(assert);
8492       }
8493     });
8494   }(1, 2, 3));
8495
8496   /*--------------------------------------------------------------------------*/
8497
8498   QUnit.module('lodash.isEmpty');
8499
8500   (function() {
8501     var args = arguments;
8502
8503     QUnit.test('should return `true` for empty values', function(assert) {
8504       assert.expect(8);
8505
8506       var expected = lodashStable.map(empties, alwaysTrue),
8507           actual = lodashStable.map(empties, _.isEmpty);
8508
8509       assert.deepEqual(actual, expected);
8510
8511       assert.strictEqual(_.isEmpty(true), true);
8512       assert.strictEqual(_.isEmpty(slice), true);
8513       assert.strictEqual(_.isEmpty(1), true);
8514       assert.strictEqual(_.isEmpty(NaN), true);
8515       assert.strictEqual(_.isEmpty(/x/), true);
8516       assert.strictEqual(_.isEmpty(symbol), true);
8517       assert.strictEqual(_.isEmpty(), true);
8518     });
8519
8520     QUnit.test('should return `false` for non-empty values', function(assert) {
8521       assert.expect(3);
8522
8523       assert.strictEqual(_.isEmpty([0]), false);
8524       assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
8525       assert.strictEqual(_.isEmpty('a'), false);
8526     });
8527
8528     QUnit.test('should work with an object that has a `length` property', function(assert) {
8529       assert.expect(1);
8530
8531       assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
8532     });
8533
8534     QUnit.test('should work with `arguments` objects', function(assert) {
8535       assert.expect(1);
8536
8537       assert.strictEqual(_.isEmpty(args), false);
8538     });
8539
8540     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
8541       assert.expect(1);
8542
8543       function Foo(elements) { push.apply(this, elements); }
8544       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
8545
8546       assert.strictEqual(_.isEmpty(new Foo([])), true);
8547     });
8548
8549     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
8550       assert.expect(1);
8551
8552       function Foo() {}
8553       Foo.prototype.length = -1;
8554
8555       assert.strictEqual(_.isEmpty(new Foo), true);
8556     });
8557
8558     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
8559       assert.expect(1);
8560
8561       function Foo() {}
8562       Foo.prototype.length = MAX_SAFE_INTEGER + 1;
8563
8564       assert.strictEqual(_.isEmpty(new Foo), true);
8565     });
8566
8567     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
8568       assert.expect(1);
8569
8570       assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
8571     });
8572
8573     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8574       assert.expect(1);
8575
8576       if (!isNpm) {
8577         assert.strictEqual(_({}).isEmpty(), true);
8578       }
8579       else {
8580         skipAssert(assert);
8581       }
8582     });
8583
8584     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8585       assert.expect(1);
8586
8587       if (!isNpm) {
8588         assert.ok(_({}).chain().isEmpty() instanceof _);
8589       }
8590       else {
8591         skipAssert(assert);
8592       }
8593     });
8594   }(1, 2, 3));
8595
8596   /*--------------------------------------------------------------------------*/
8597
8598   QUnit.module('lodash.isEqual');
8599
8600   (function() {
8601     var symbol1 = Symbol ? Symbol('a') : true,
8602         symbol2 = Symbol ? Symbol('b') : false;
8603
8604     QUnit.test('should compare primitives', function(assert) {
8605       assert.expect(1);
8606
8607       var pairs = [
8608         [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
8609         [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
8610         [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
8611         ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
8612         [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
8613         [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
8614         [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
8615         [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
8616         [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
8617       ];
8618
8619       var expected = lodashStable.map(pairs, function(pair) {
8620         return pair[2];
8621       });
8622
8623       var actual = lodashStable.map(pairs, function(pair) {
8624         return _.isEqual(pair[0], pair[1]);
8625       });
8626
8627       assert.deepEqual(actual, expected);
8628     });
8629
8630     QUnit.test('should compare arrays', function(assert) {
8631       assert.expect(6);
8632
8633       var array1 = [true, null, 1, 'a', undefined],
8634           array2 = [true, null, 1, 'a', undefined];
8635
8636       assert.strictEqual(_.isEqual(array1, array2), true);
8637
8638       array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
8639       array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
8640
8641       assert.strictEqual(_.isEqual(array1, array2), true);
8642
8643       array1 = [1];
8644       array1[2] = 3;
8645
8646       array2 = [1];
8647       array2[1] = undefined;
8648       array2[2] = 3;
8649
8650       assert.strictEqual(_.isEqual(array1, array2), true);
8651
8652       array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
8653       array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
8654
8655       assert.strictEqual(_.isEqual(array1, array2), true);
8656
8657       array1 = [1, 2, 3];
8658       array2 = [3, 2, 1];
8659
8660       assert.strictEqual(_.isEqual(array1, array2), false);
8661
8662       array1 = [1, 2];
8663       array2 = [1, 2, 3];
8664
8665       assert.strictEqual(_.isEqual(array1, array2), false);
8666     });
8667
8668     QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
8669       assert.expect(3);
8670
8671       var array1 = [1, 2, 3],
8672           array2 = [1, 2, 3];
8673
8674       array1.every = array1.filter = array1.forEach =
8675       array1.indexOf = array1.lastIndexOf = array1.map =
8676       array1.some = array1.reduce = array1.reduceRight = null;
8677
8678       array2.concat = array2.join = array2.pop =
8679       array2.reverse = array2.shift = array2.slice =
8680       array2.sort = array2.splice = array2.unshift = null;
8681
8682       assert.strictEqual(_.isEqual(array1, array2), true);
8683
8684       array1 = [1, 2, 3];
8685       array1.a = 1;
8686
8687       array2 = [1, 2, 3];
8688       array2.b = 1;
8689
8690       assert.strictEqual(_.isEqual(array1, array2), true);
8691
8692       array1 = /c/.exec('abcde');
8693       array2 = ['c'];
8694
8695       assert.strictEqual(_.isEqual(array1, array2), true);
8696     });
8697
8698     QUnit.test('should compare sparse arrays', function(assert) {
8699       assert.expect(3);
8700
8701       var array = Array(1);
8702
8703       assert.strictEqual(_.isEqual(array, Array(1)), true);
8704       assert.strictEqual(_.isEqual(array, [undefined]), true);
8705       assert.strictEqual(_.isEqual(array, Array(2)), false);
8706     });
8707
8708     QUnit.test('should compare plain objects', function(assert) {
8709       assert.expect(5);
8710
8711       var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
8712           object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
8713
8714       assert.strictEqual(_.isEqual(object1, object2), true);
8715
8716       object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
8717       object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
8718
8719       assert.strictEqual(_.isEqual(object1, object2), true);
8720
8721       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8722       object2 = { 'a': 3, 'b': 2, 'c': 1 };
8723
8724       assert.strictEqual(_.isEqual(object1, object2), false);
8725
8726       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8727       object2 = { 'd': 1, 'e': 2, 'f': 3 };
8728
8729       assert.strictEqual(_.isEqual(object1, object2), false);
8730
8731       object1 = { 'a': 1, 'b': 2 };
8732       object2 = { 'a': 1, 'b': 2, 'c': 3 };
8733
8734       assert.strictEqual(_.isEqual(object1, object2), false);
8735     });
8736
8737     QUnit.test('should compare objects regardless of key order', function(assert) {
8738       assert.expect(1);
8739
8740       var object1 = { 'a': 1, 'b': 2, 'c': 3 },
8741           object2 = { 'c': 3, 'a': 1, 'b': 2 };
8742
8743       assert.strictEqual(_.isEqual(object1, object2), true);
8744     });
8745
8746     QUnit.test('should compare nested objects', function(assert) {
8747       assert.expect(1);
8748
8749       var object1 = {
8750         'a': [1, 2, 3],
8751         'b': true,
8752         'c': Object(1),
8753         'd': 'a',
8754         'e': {
8755           'f': ['a', Object('b'), 'c'],
8756           'g': Object(false),
8757           'h': new Date(2012, 4, 23),
8758           'i': noop,
8759           'j': 'a'
8760         }
8761       };
8762
8763       var object2 = {
8764         'a': [1, Object(2), 3],
8765         'b': Object(true),
8766         'c': 1,
8767         'd': Object('a'),
8768         'e': {
8769           'f': ['a', 'b', 'c'],
8770           'g': false,
8771           'h': new Date(2012, 4, 23),
8772           'i': noop,
8773           'j': 'a'
8774         }
8775       };
8776
8777       assert.strictEqual(_.isEqual(object1, object2), true);
8778     });
8779
8780     QUnit.test('should compare object instances', function(assert) {
8781       assert.expect(4);
8782
8783       function Foo() { this.a = 1; }
8784       Foo.prototype.a = 1;
8785
8786       function Bar() { this.a = 1; }
8787       Bar.prototype.a = 2;
8788
8789       assert.strictEqual(_.isEqual(new Foo, new Foo), true);
8790       assert.strictEqual(_.isEqual(new Foo, new Bar), false);
8791       assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
8792       assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
8793     });
8794
8795     QUnit.test('should compare objects with constructor properties', function(assert) {
8796       assert.expect(5);
8797
8798       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
8799       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
8800       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
8801       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
8802       assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
8803     });
8804
8805     QUnit.test('should compare arrays with circular references', function(assert) {
8806       assert.expect(4);
8807
8808       var array1 = [],
8809           array2 = [];
8810
8811       array1.push(array1);
8812       array2.push(array2);
8813
8814       assert.strictEqual(_.isEqual(array1, array2), true);
8815
8816       array1.push('b');
8817       array2.push('b');
8818
8819       assert.strictEqual(_.isEqual(array1, array2), true);
8820
8821       array1.push('c');
8822       array2.push('d');
8823
8824       assert.strictEqual(_.isEqual(array1, array2), false);
8825
8826       array1 = ['a', 'b', 'c'];
8827       array1[1] = array1;
8828       array2 = ['a', ['a', 'b', 'c'], 'c'];
8829
8830       assert.strictEqual(_.isEqual(array1, array2), false);
8831     });
8832
8833     QUnit.test('should compare objects with circular references', function(assert) {
8834       assert.expect(4);
8835
8836       var object1 = {},
8837           object2 = {};
8838
8839       object1.a = object1;
8840       object2.a = object2;
8841
8842       assert.strictEqual(_.isEqual(object1, object2), true);
8843
8844       object1.b = 0;
8845       object2.b = Object(0);
8846
8847       assert.strictEqual(_.isEqual(object1, object2), true);
8848
8849       object1.c = Object(1);
8850       object2.c = Object(2);
8851
8852       assert.strictEqual(_.isEqual(object1, object2), false);
8853
8854       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8855       object1.b = object1;
8856       object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
8857
8858       assert.strictEqual(_.isEqual(object1, object2), false);
8859     });
8860
8861     QUnit.test('should compare objects with multiple circular references', function(assert) {
8862       assert.expect(3);
8863
8864       var array1 = [{}],
8865           array2 = [{}];
8866
8867       (array1[0].a = array1).push(array1);
8868       (array2[0].a = array2).push(array2);
8869
8870       assert.strictEqual(_.isEqual(array1, array2), true);
8871
8872       array1[0].b = 0;
8873       array2[0].b = Object(0);
8874
8875       assert.strictEqual(_.isEqual(array1, array2), true);
8876
8877       array1[0].c = Object(1);
8878       array2[0].c = Object(2);
8879
8880       assert.strictEqual(_.isEqual(array1, array2), false);
8881     });
8882
8883     QUnit.test('should compare objects with complex circular references', function(assert) {
8884       assert.expect(1);
8885
8886       var object1 = {
8887         'foo': { 'b': { 'c': { 'd': {} } } },
8888         'bar': { 'a': 2 }
8889       };
8890
8891       var object2 = {
8892         'foo': { 'b': { 'c': { 'd': {} } } },
8893         'bar': { 'a': 2 }
8894       };
8895
8896       object1.foo.b.c.d = object1;
8897       object1.bar.b = object1.foo.b;
8898
8899       object2.foo.b.c.d = object2;
8900       object2.bar.b = object2.foo.b;
8901
8902       assert.strictEqual(_.isEqual(object1, object2), true);
8903     });
8904
8905     QUnit.test('should compare objects with shared property values', function(assert) {
8906       assert.expect(1);
8907
8908       var object1 = {
8909         'a': [1, 2]
8910       };
8911
8912       var object2 = {
8913         'a': [1, 2],
8914         'b': [1, 2]
8915       };
8916
8917       object1.b = object1.a;
8918
8919       assert.strictEqual(_.isEqual(object1, object2), true);
8920     });
8921
8922     QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
8923       assert.expect(2);
8924
8925       function Foo() { this.a = 1; }
8926       Foo.prototype.constructor = null;
8927
8928       var object2 = { 'a': 1 };
8929       assert.strictEqual(_.isEqual(new Foo, object2), false);
8930
8931       if (create)  {
8932         var object1 = create(null);
8933         object1.a = 1;
8934         assert.strictEqual(_.isEqual(object1, object2), true);
8935       }
8936       else {
8937         skipAssert(assert);
8938       }
8939     });
8940
8941     QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
8942       assert.expect(1);
8943
8944       var primitive,
8945           object = { 'toString': function() { return primitive; } },
8946           values = [true, null, 1, 'a', undefined],
8947           expected = lodashStable.map(values, alwaysFalse);
8948
8949       var actual = lodashStable.map(values, function(value) {
8950         primitive = value;
8951         return _.isEqual(object, value);
8952       });
8953
8954       assert.deepEqual(actual, expected);
8955     });
8956
8957     QUnit.test('should avoid common type coercions', function(assert) {
8958       assert.expect(9);
8959
8960       assert.strictEqual(_.isEqual(true, Object(false)), false);
8961       assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
8962       assert.strictEqual(_.isEqual(false, Object('')), false);
8963       assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
8964       assert.strictEqual(_.isEqual(0, ''), false);
8965       assert.strictEqual(_.isEqual(1, true), false);
8966       assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
8967       assert.strictEqual(_.isEqual('36', 36), false);
8968       assert.strictEqual(_.isEqual(36, '36'), false);
8969     });
8970
8971     QUnit.test('should compare `arguments` objects', function(assert) {
8972       assert.expect(2);
8973
8974       var args1 = (function() { return arguments; }(1, 2, 3)),
8975           args2 = (function() { return arguments; }(1, 2, 3)),
8976           args3 = (function() { return arguments; }(1, 2));
8977
8978       assert.strictEqual(_.isEqual(args1, args2), true);
8979       assert.strictEqual(_.isEqual(args1, args3), false);
8980     });
8981
8982     QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
8983       assert.expect(4);
8984
8985       var args = (function() { return arguments; }(1, 2, 3)),
8986           object = { '0': 1, '1': 2, '2': 3 };
8987
8988       function Foo() {}
8989       Foo.prototype = object;
8990
8991       assert.strictEqual(_.isEqual(args, object), true);
8992       assert.strictEqual(_.isEqual(object, args), true);
8993
8994       assert.strictEqual(_.isEqual(args, new Foo), false);
8995       assert.strictEqual(_.isEqual(new Foo, args), false);
8996     });
8997
8998     QUnit.test('should compare array buffers', function(assert) {
8999       assert.expect(2);
9000
9001       if (ArrayBuffer) {
9002         var buffer1 = new ArrayBuffer(4),
9003             buffer2 = new ArrayBuffer(8);
9004
9005         assert.strictEqual(_.isEqual(buffer1, buffer2), false);
9006
9007         buffer1 = new Int8Array([-1]).buffer;
9008         buffer2 = new Uint8Array([255]).buffer;
9009
9010         assert.strictEqual(_.isEqual(buffer1, buffer2), true);
9011       }
9012       else {
9013         skipAssert(assert, 2);
9014       }
9015     });
9016
9017     QUnit.test('should compare date objects', function(assert) {
9018       assert.expect(4);
9019
9020       var date = new Date(2012, 4, 23);
9021
9022       assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
9023       assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
9024       assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
9025       assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
9026     });
9027
9028     QUnit.test('should compare error objects', function(assert) {
9029       assert.expect(1);
9030
9031       var pairs = lodashStable.map([
9032         'Error',
9033         'EvalError',
9034         'RangeError',
9035         'ReferenceError',
9036         'SyntaxError',
9037         'TypeError',
9038         'URIError'
9039       ], function(type, index, errorTypes) {
9040         var otherType = errorTypes[++index % errorTypes.length],
9041             CtorA = root[type],
9042             CtorB = root[otherType];
9043
9044         return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
9045       });
9046
9047       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9048
9049       var actual = lodashStable.map(pairs, function(pair) {
9050         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9051       });
9052
9053       assert.deepEqual(actual, expected);
9054     });
9055
9056     QUnit.test('should compare functions', function(assert) {
9057       assert.expect(2);
9058
9059       function a() { return 1 + 2; }
9060       function b() { return 1 + 2; }
9061
9062       assert.strictEqual(_.isEqual(a, a), true);
9063       assert.strictEqual(_.isEqual(a, b), false);
9064     });
9065
9066     QUnit.test('should compare maps', function(assert) {
9067       assert.expect(4);
9068
9069       if (Map) {
9070         var map1 = new Map,
9071             map2 = new Map;
9072
9073         map1.set('a', 1);
9074         map2.set('b', 2);
9075         assert.strictEqual(_.isEqual(map1, map2), false);
9076
9077         map1.set('b', 2);
9078         map2.set('a', 1);
9079         assert.strictEqual(_.isEqual(map1, map2), true);
9080
9081         map1['delete']('a');
9082         map1.set('a', 1);
9083         assert.strictEqual(_.isEqual(map1, map2), true);
9084
9085         map2['delete']('a');
9086         assert.strictEqual(_.isEqual(map1, map2), false);
9087       }
9088       else {
9089         skipAssert(assert, 4);
9090       }
9091     });
9092
9093     QUnit.test('should compare regexes', function(assert) {
9094       assert.expect(5);
9095
9096       assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
9097       assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
9098       assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
9099       assert.strictEqual(_.isEqual(/x/, /y/), false);
9100       assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
9101     });
9102
9103     QUnit.test('should compare sets', function(assert) {
9104       assert.expect(4);
9105
9106       if (Set) {
9107         var set1 = new Set,
9108             set2 = new Set;
9109
9110         set1.add(1);
9111         set2.add(2);
9112         assert.strictEqual(_.isEqual(set1, set2), false);
9113
9114         set1.add(2);
9115         set2.add(1);
9116         assert.strictEqual(_.isEqual(set1, set2), true);
9117
9118         set1['delete'](1);
9119         set1.add(1);
9120         assert.strictEqual(_.isEqual(set1, set2), true);
9121
9122         set2['delete'](1);
9123         assert.strictEqual(_.isEqual(set1, set2), false);
9124       }
9125       else {
9126         skipAssert(assert, 4);
9127       }
9128     });
9129
9130     QUnit.test('should compare typed arrays', function(assert) {
9131       assert.expect(1);
9132
9133       var pairs = lodashStable.map(typedArrays, function(type, index) {
9134         var otherType = typedArrays[(index + 1) % typedArrays.length],
9135             CtorA = root[type] || function(n) { this.n = n; },
9136             CtorB = root[otherType] || function(n) { this.n = n; },
9137             bufferA = root[type] ? new ArrayBuffer(8) : 8,
9138             bufferB = root[otherType] ? new ArrayBuffer(8) : 8,
9139             bufferC = root[otherType] ? new ArrayBuffer(16) : 16;
9140
9141         return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
9142       });
9143
9144       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9145
9146       var actual = lodashStable.map(pairs, function(pair) {
9147         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9148       });
9149
9150       assert.deepEqual(actual, expected);
9151     });
9152
9153     QUnit.test('should work as an iteratee for `_.every`', function(assert) {
9154       assert.expect(1);
9155
9156       var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
9157       assert.ok(actual);
9158     });
9159
9160     QUnit.test('should return `true` for like-objects from different documents', function(assert) {
9161       assert.expect(4);
9162
9163       if (realm.object) {
9164         assert.strictEqual(_.isEqual([1], realm.array), true);
9165         assert.strictEqual(_.isEqual([2], realm.array), false);
9166         assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
9167         assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
9168       }
9169       else {
9170         skipAssert(assert, 4);
9171       }
9172     });
9173
9174     QUnit.test('should not error on DOM elements', function(assert) {
9175       assert.expect(1);
9176
9177       if (document) {
9178         var element1 = document.createElement('div'),
9179             element2 = element1.cloneNode(true);
9180
9181         try {
9182           assert.strictEqual(_.isEqual(element1, element2), false);
9183         } catch (e) {
9184           assert.ok(false, e.message);
9185         }
9186       }
9187       else {
9188         skipAssert(assert);
9189       }
9190     });
9191
9192     QUnit.test('should compare wrapped values', function(assert) {
9193       assert.expect(32);
9194
9195       var stamp = +new Date;
9196
9197       var values = [
9198         [[1, 2], [1, 2], [1, 2, 3]],
9199         [true, true, false],
9200         [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
9201         [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
9202         [1, 1, 2],
9203         [NaN, NaN, Infinity],
9204         [/x/, /x/, /x/i],
9205         ['a', 'a', 'A']
9206       ];
9207
9208       lodashStable.each(values, function(vals) {
9209         if (!isNpm) {
9210           var wrapped1 = _(vals[0]),
9211               wrapped2 = _(vals[1]),
9212               actual = wrapped1.isEqual(wrapped2);
9213
9214           assert.strictEqual(actual, true);
9215           assert.strictEqual(_.isEqual(_(actual), _(true)), true);
9216
9217           wrapped1 = _(vals[0]);
9218           wrapped2 = _(vals[2]);
9219
9220           actual = wrapped1.isEqual(wrapped2);
9221           assert.strictEqual(actual, false);
9222           assert.strictEqual(_.isEqual(_(actual), _(false)), true);
9223         }
9224         else {
9225           skipAssert(assert, 4);
9226         }
9227       });
9228     });
9229
9230     QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
9231       assert.expect(4);
9232
9233       if (!isNpm) {
9234         var object1 = _({ 'a': 1, 'b': 2 }),
9235             object2 = { 'a': 1, 'b': 2 };
9236
9237         assert.strictEqual(object1.isEqual(object2), true);
9238         assert.strictEqual(_.isEqual(object1, object2), true);
9239
9240         object1 = _({ 'a': 1, 'b': 2 });
9241         object2 = { 'a': 1, 'b': 1 };
9242
9243         assert.strictEqual(object1.isEqual(object2), false);
9244         assert.strictEqual(_.isEqual(object1, object2), false);
9245       }
9246       else {
9247         skipAssert(assert, 4);
9248       }
9249     });
9250
9251     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9252       assert.expect(1);
9253
9254       if (!isNpm) {
9255         assert.strictEqual(_('a').isEqual('a'), true);
9256       }
9257       else {
9258         skipAssert(assert);
9259       }
9260     });
9261
9262     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9263       assert.expect(1);
9264
9265       if (!isNpm) {
9266         assert.ok(_('a').chain().isEqual('a') instanceof _);
9267       }
9268       else {
9269         skipAssert(assert);
9270       }
9271     });
9272   }());
9273
9274   /*--------------------------------------------------------------------------*/
9275
9276   QUnit.module('lodash.isEqualWith');
9277
9278   (function() {
9279     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
9280       assert.expect(1);
9281
9282       var argsList = [],
9283           object1 = { 'a': [1, 2], 'b': null },
9284           object2 = { 'a': [1, 2], 'b': null };
9285
9286       object1.b = object2;
9287       object2.b = object1;
9288
9289       var expected = [
9290         [object1, object2],
9291         [object1.a, object2.a, 'a', object1, object2],
9292         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
9293         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
9294         [object1.b, object2.b, 'b', object1.b, object2.b],
9295         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
9296         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
9297         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
9298         [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
9299       ];
9300
9301       _.isEqualWith(object1, object2, function(assert) {
9302         var length = arguments.length,
9303             args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9304
9305         argsList.push(args);
9306       });
9307
9308       assert.deepEqual(argsList, expected);
9309     });
9310
9311     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
9312       assert.expect(3);
9313
9314       assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
9315       assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
9316       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
9317     });
9318
9319     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
9320       assert.expect(3);
9321
9322       var customizer = function(value) {
9323         return _.isString(value) || undefined;
9324       };
9325
9326       assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
9327       assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
9328       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
9329     });
9330
9331     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
9332       assert.expect(3);
9333
9334       var customizer = function(value) {
9335         return _.isString(value) ? false : undefined;
9336       };
9337
9338       assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
9339       assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
9340       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
9341     });
9342
9343     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
9344       assert.expect(2);
9345
9346       var actual = _.isEqualWith('a', 'b', alwaysC);
9347       assert.strictEqual(actual, true);
9348
9349       var values = _.without(falsey, undefined),
9350           expected = lodashStable.map(values, alwaysFalse);
9351
9352       actual = [];
9353       lodashStable.each(values, function(value) {
9354         actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
9355       });
9356
9357       assert.deepEqual(actual, expected);
9358     });
9359
9360     QUnit.test('should ensure `customizer` is a function', function(assert) {
9361       assert.expect(1);
9362
9363       var array = [1, 2, 3],
9364           eq = _.partial(_.isEqualWith, array),
9365           actual = lodashStable.map([array, [1, 0, 3]], eq);
9366
9367       assert.deepEqual(actual, [true, false]);
9368     });
9369
9370     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
9371       assert.expect(2);
9372
9373       var value = { 'a': { 'b': 2 } };
9374
9375       if (Map) {
9376         var map1 = new Map;
9377         map1.set('a', value);
9378
9379         var map2 = new Map;
9380         map2.set('a', value);
9381       }
9382       if (Set) {
9383         var set1 = new Set;
9384         set1.add(value);
9385
9386         var set2 = new Set;
9387         set2.add(value);
9388       }
9389       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
9390         if (pair[0]) {
9391           var argsList = [],
9392               array = _.toArray(pair[0]);
9393
9394           var expected = [
9395             [pair[0], pair[1]],
9396             [array[0], array[0], 0, array, array],
9397             [array[0][0], array[0][0], 0, array[0], array[0]],
9398             [array[0][1], array[0][1], 1, array[0], array[0]]
9399           ];
9400
9401           if (index) {
9402             expected.length = 2;
9403           }
9404           _.isEqualWith(pair[0], pair[1], function() {
9405             var length = arguments.length,
9406                 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9407
9408             argsList.push(args);
9409           });
9410
9411           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
9412         }
9413         else {
9414           skipAssert(assert);
9415         }
9416       });
9417     });
9418   }());
9419
9420   /*--------------------------------------------------------------------------*/
9421
9422   QUnit.module('lodash.isError');
9423
9424   (function() {
9425     var args = arguments;
9426
9427     QUnit.test('should return `true` for error objects', function(assert) {
9428       assert.expect(1);
9429
9430       var expected = lodashStable.map(errors, alwaysTrue);
9431
9432       var actual = lodashStable.map(errors, function(error) {
9433         return _.isError(error) === true;
9434       });
9435
9436       assert.deepEqual(actual, expected);
9437     });
9438
9439     QUnit.test('should return `true` for subclassed values', function(assert) {
9440       assert.expect(1);
9441
9442       assert.strictEqual(_.isError(new CustomError('x')), true);
9443     });
9444
9445     QUnit.test('should return `false` for non error objects', function(assert) {
9446       assert.expect(12);
9447
9448       var expected = lodashStable.map(falsey, alwaysFalse);
9449
9450       var actual = lodashStable.map(falsey, function(value, index) {
9451         return index ? _.isError(value) : _.isError();
9452       });
9453
9454       assert.deepEqual(actual, expected);
9455
9456       assert.strictEqual(_.isError(args), false);
9457       assert.strictEqual(_.isError([1, 2, 3]), false);
9458       assert.strictEqual(_.isError(true), false);
9459       assert.strictEqual(_.isError(new Date), false);
9460       assert.strictEqual(_.isError(_), false);
9461       assert.strictEqual(_.isError(slice), false);
9462       assert.strictEqual(_.isError({ 'a': 1 }), false);
9463       assert.strictEqual(_.isError(1), false);
9464       assert.strictEqual(_.isError(/x/), false);
9465       assert.strictEqual(_.isError('a'), false);
9466       assert.strictEqual(_.isError(symbol), false);
9467     });
9468
9469     QUnit.test('should work with an error object from another realm', function(assert) {
9470       assert.expect(1);
9471
9472       if (realm.errors) {
9473         var expected = lodashStable.map(realm.errors, alwaysTrue);
9474
9475         var actual = lodashStable.map(realm.errors, function(error) {
9476           return _.isError(error) === true;
9477         });
9478
9479         assert.deepEqual(actual, expected);
9480       }
9481       else {
9482         skipAssert(assert);
9483       }
9484     });
9485   }(1, 2, 3));
9486
9487   /*--------------------------------------------------------------------------*/
9488
9489   QUnit.module('lodash.isFinite');
9490
9491   (function() {
9492     var args = arguments;
9493
9494     QUnit.test('should return `true` for finite values', function(assert) {
9495       assert.expect(1);
9496
9497       var values = [0, 1, 3.14, -1],
9498           expected = lodashStable.map(values, alwaysTrue),
9499           actual = lodashStable.map(values, _.isFinite);
9500
9501       assert.deepEqual(actual, expected);
9502     });
9503
9504     QUnit.test('should return `false` for non-finite values', function(assert) {
9505       assert.expect(1);
9506
9507       var values = [NaN, Infinity, -Infinity, Object(1)],
9508           expected = lodashStable.map(values, alwaysFalse),
9509           actual = lodashStable.map(values, _.isFinite);
9510
9511       assert.deepEqual(actual, expected);
9512     });
9513
9514     QUnit.test('should return `false` for non-numeric values', function(assert) {
9515       assert.expect(10);
9516
9517       var values = [undefined, [], true, '', ' ', '2px'],
9518           expected = lodashStable.map(values, alwaysFalse),
9519           actual = lodashStable.map(values, _.isFinite);
9520
9521       assert.deepEqual(actual, expected);
9522
9523       assert.strictEqual(_.isFinite(args), false);
9524       assert.strictEqual(_.isFinite([1, 2, 3]), false);
9525       assert.strictEqual(_.isFinite(true), false);
9526       assert.strictEqual(_.isFinite(new Date), false);
9527       assert.strictEqual(_.isFinite(new Error), false);
9528       assert.strictEqual(_.isFinite({ 'a': 1 }), false);
9529       assert.strictEqual(_.isFinite(/x/), false);
9530       assert.strictEqual(_.isFinite('a'), false);
9531       assert.strictEqual(_.isFinite(symbol), false);
9532     });
9533
9534     QUnit.test('should return `false` for numeric string values', function(assert) {
9535       assert.expect(1);
9536
9537       var values = ['2', '0', '08'],
9538           expected = lodashStable.map(values, alwaysFalse),
9539           actual = lodashStable.map(values, _.isFinite);
9540
9541       assert.deepEqual(actual, expected);
9542     });
9543   }(1, 2, 3));
9544
9545   /*--------------------------------------------------------------------------*/
9546
9547   QUnit.module('lodash.isFunction');
9548
9549   (function() {
9550     var args = arguments;
9551
9552     QUnit.test('should return `true` for functions', function(assert) {
9553       assert.expect(2);
9554
9555       assert.strictEqual(_.isFunction(_), true);
9556       assert.strictEqual(_.isFunction(slice), true);
9557     });
9558
9559     QUnit.test('should return `true` for generator functions', function(assert) {
9560       assert.expect(1);
9561
9562       assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
9563     });
9564
9565     QUnit.test('should return `true` for typed array constructors', function(assert) {
9566       assert.expect(1);
9567
9568       var expected = lodashStable.map(typedArrays, function(type) {
9569         return objToString.call(root[type]) == funcTag;
9570       });
9571
9572       var actual = lodashStable.map(typedArrays, function(type) {
9573         return _.isFunction(root[type]);
9574       });
9575
9576       assert.deepEqual(actual, expected);
9577     });
9578
9579     QUnit.test('should return `false` for non-functions', function(assert) {
9580       assert.expect(12);
9581
9582       var expected = lodashStable.map(falsey, alwaysFalse);
9583
9584       var actual = lodashStable.map(falsey, function(value, index) {
9585         return index ? _.isFunction(value) : _.isFunction();
9586       });
9587
9588       assert.deepEqual(actual, expected);
9589
9590       assert.strictEqual(_.isFunction(args), false);
9591       assert.strictEqual(_.isFunction([1, 2, 3]), false);
9592       assert.strictEqual(_.isFunction(true), false);
9593       assert.strictEqual(_.isFunction(new Date), false);
9594       assert.strictEqual(_.isFunction(new Error), false);
9595       assert.strictEqual(_.isFunction({ 'a': 1 }), false);
9596       assert.strictEqual(_.isFunction(1), false);
9597       assert.strictEqual(_.isFunction(/x/), false);
9598       assert.strictEqual(_.isFunction('a'), false);
9599       assert.strictEqual(_.isFunction(symbol), false);
9600
9601       if (document) {
9602         assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
9603       } else {
9604         skipAssert(assert);
9605       }
9606     });
9607
9608     QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
9609       assert.expect(2);
9610
9611       // Trigger a Chakra JIT bug.
9612       // See https://github.com/jashkenas/underscore/issues/1621.
9613       lodashStable.each([body, xml], function(object) {
9614         if (object) {
9615           lodashStable.times(100, _.isFunction);
9616           assert.strictEqual(_.isFunction(object), false);
9617         }
9618         else {
9619           skipAssert(assert);
9620         }
9621       });
9622     });
9623
9624     QUnit.test('should work with a function from another realm', function(assert) {
9625       assert.expect(1);
9626
9627       if (realm.function) {
9628         assert.strictEqual(_.isFunction(realm.function), true);
9629       }
9630       else {
9631         skipAssert(assert);
9632       }
9633     });
9634   }(1, 2, 3));
9635
9636   /*--------------------------------------------------------------------------*/
9637
9638   QUnit.module('isInteger methods');
9639
9640   lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
9641     var args = arguments,
9642         func = _[methodName],
9643         isSafe = methodName == 'isSafeInteger';
9644
9645     QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
9646       assert.expect(2);
9647
9648       var values = [-1, 0, 1],
9649           expected = lodashStable.map(values, alwaysTrue);
9650
9651       var actual = lodashStable.map(values, function(value) {
9652         return func(value);
9653       });
9654
9655       assert.deepEqual(actual, expected);
9656       assert.strictEqual(func(MAX_INTEGER), !isSafe);
9657     });
9658
9659     QUnit.test('should return `false` for non-integer number values', function(assert) {
9660       assert.expect(1);
9661
9662       var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
9663           expected = lodashStable.map(values, alwaysFalse);
9664
9665       var actual = lodashStable.map(values, function(value) {
9666         return func(value);
9667       });
9668
9669       assert.deepEqual(actual, expected);
9670     });
9671
9672     QUnit.test('should return `false` for non-numeric values', function(assert) {
9673       assert.expect(10);
9674
9675       var expected = lodashStable.map(falsey, function(value) {
9676         return value === 0;
9677       });
9678
9679       var actual = lodashStable.map(falsey, function(value, index) {
9680         return index ? func(value) : func();
9681       });
9682
9683       assert.deepEqual(actual, expected);
9684
9685       assert.strictEqual(func(args), false);
9686       assert.strictEqual(func([1, 2, 3]), false);
9687       assert.strictEqual(func(true), false);
9688       assert.strictEqual(func(new Date), false);
9689       assert.strictEqual(func(new Error), false);
9690       assert.strictEqual(func({ 'a': 1 }), false);
9691       assert.strictEqual(func(/x/), false);
9692       assert.strictEqual(func('a'), false);
9693       assert.strictEqual(func(symbol), false);
9694     });
9695   });
9696
9697   /*--------------------------------------------------------------------------*/
9698
9699   QUnit.module('lodash.isLength');
9700
9701   (function() {
9702     QUnit.test('should return `true` for lengths', function(assert) {
9703       assert.expect(1);
9704
9705       var values = [0, 3, MAX_SAFE_INTEGER],
9706           expected = lodashStable.map(values, alwaysTrue),
9707           actual = lodashStable.map(values, _.isLength);
9708
9709       assert.deepEqual(actual, expected);
9710     });
9711
9712     QUnit.test('should return `false` for non-lengths', function(assert) {
9713       assert.expect(1);
9714
9715       var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
9716           expected = lodashStable.map(values, alwaysFalse),
9717           actual = lodashStable.map(values, _.isLength);
9718
9719       assert.deepEqual(actual, expected);
9720     });
9721   }());
9722
9723   /*--------------------------------------------------------------------------*/
9724
9725   QUnit.module('lodash.isMap');
9726
9727   (function() {
9728     var args = arguments;
9729
9730     QUnit.test('should return `true` for maps', function(assert) {
9731       assert.expect(1);
9732
9733       if (Map) {
9734         assert.strictEqual(_.isMap(map), true);
9735       }
9736       else {
9737         skipAssert(assert);
9738       }
9739     });
9740
9741     QUnit.test('should return `false` for non maps', function(assert) {
9742       assert.expect(14);
9743
9744       var expected = lodashStable.map(falsey, alwaysFalse);
9745
9746       var actual = lodashStable.map(falsey, function(value, index) {
9747         return index ? _.isMap(value) : _.isMap();
9748       });
9749
9750       assert.deepEqual(actual, expected);
9751
9752       assert.strictEqual(_.isMap(args), false);
9753       assert.strictEqual(_.isMap([1, 2, 3]), false);
9754       assert.strictEqual(_.isMap(true), false);
9755       assert.strictEqual(_.isMap(new Date), false);
9756       assert.strictEqual(_.isMap(new Error), false);
9757       assert.strictEqual(_.isMap(_), false);
9758       assert.strictEqual(_.isMap(slice), false);
9759       assert.strictEqual(_.isMap({ 'a': 1 }), false);
9760       assert.strictEqual(_.isMap(1), false);
9761       assert.strictEqual(_.isMap(/x/), false);
9762       assert.strictEqual(_.isMap('a'), false);
9763       assert.strictEqual(_.isMap(symbol), false);
9764       assert.strictEqual(_.isMap(weakMap), false);
9765     });
9766
9767     QUnit.test('should work with maps from another realm', function(assert) {
9768       assert.expect(1);
9769
9770       if (realm.map) {
9771         assert.strictEqual(_.isMap(realm.map), true);
9772       }
9773       else {
9774         skipAssert(assert);
9775       }
9776     });
9777   }(1, 2, 3));
9778
9779   /*--------------------------------------------------------------------------*/
9780
9781   QUnit.module('lodash.isMatch');
9782
9783   (function() {
9784     QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
9785       assert.expect(5);
9786
9787       var object = { 'a': 1, 'b': 2, 'c': 3 };
9788       assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
9789       assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
9790       assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
9791       assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
9792
9793       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
9794       assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
9795     });
9796
9797     QUnit.test('should match inherited `object` properties', function(assert) {
9798       assert.expect(1);
9799
9800       function Foo() { this.a = 1; }
9801       Foo.prototype.b = 2;
9802
9803       assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
9804     });
9805
9806     QUnit.test('should not match by inherited `source` properties', function(assert) {
9807       assert.expect(1);
9808
9809       function Foo() { this.a = 1; }
9810       Foo.prototype.b = 2;
9811
9812       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
9813           source = new Foo,
9814           expected = lodashStable.map(objects, alwaysTrue);
9815
9816       var actual = lodashStable.map(objects, function(object) {
9817         return _.isMatch(object, source);
9818       });
9819
9820       assert.deepEqual(actual, expected);
9821     });
9822
9823     QUnit.test('should compare a variety of `source` property values', function(assert) {
9824       assert.expect(2);
9825
9826       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
9827           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
9828
9829       assert.strictEqual(_.isMatch(object1, object1), true);
9830       assert.strictEqual(_.isMatch(object1, object2), false);
9831     });
9832
9833     QUnit.test('should match `-0` as `0`', function(assert) {
9834       assert.expect(2);
9835
9836       var object1 = { 'a': -0 },
9837           object2 = { 'a': 0 };
9838
9839       assert.strictEqual(_.isMatch(object1, object2), true);
9840       assert.strictEqual(_.isMatch(object2, object1), true);
9841     });
9842
9843     QUnit.test('should compare functions by reference', function(assert) {
9844       assert.expect(3);
9845
9846       var object1 = { 'a': lodashStable.noop },
9847           object2 = { 'a': noop },
9848           object3 = { 'a': {} };
9849
9850       assert.strictEqual(_.isMatch(object1, object1), true);
9851       assert.strictEqual(_.isMatch(object2, object1), false);
9852       assert.strictEqual(_.isMatch(object3, object1), false);
9853     });
9854
9855     QUnit.test('should work with a function for `object`', function(assert) {
9856       assert.expect(1);
9857
9858       function Foo() {}
9859       Foo.a = { 'b': 1, 'c': 2 };
9860
9861       assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 1 } }), true);
9862     });
9863
9864     QUnit.test('should work with a function for `source`', function(assert) {
9865       assert.expect(1);
9866
9867       function Foo() {}
9868       Foo.a = 1;
9869       Foo.b = function() {};
9870       Foo.c = 3;
9871
9872       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
9873
9874       var actual = lodashStable.map(objects, function(object) {
9875         return _.isMatch(object, Foo);
9876       });
9877
9878       assert.deepEqual(actual, [false, true]);
9879     });
9880
9881     QUnit.test('should work with a non-plain `object`', function(assert) {
9882       assert.expect(1);
9883
9884       function Foo(object) { lodashStable.assign(this, object); }
9885
9886       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) });
9887       assert.strictEqual(_.isMatch(object, { 'a': { 'b': 1 } }), true);
9888     });
9889
9890     QUnit.test('should partial match arrays', function(assert) {
9891       assert.expect(3);
9892
9893       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
9894           source = { 'a': ['d'] },
9895           predicate = function(object) { return _.isMatch(object, source); },
9896           actual = lodashStable.filter(objects, predicate);
9897
9898       assert.deepEqual(actual, [objects[1]]);
9899
9900       source = { 'a': ['b', 'd'] };
9901       actual = lodashStable.filter(objects, predicate);
9902
9903       assert.deepEqual(actual, []);
9904
9905       source = { 'a': ['d', 'b'] };
9906       actual = lodashStable.filter(objects, predicate);
9907       assert.deepEqual(actual, []);
9908     });
9909
9910     QUnit.test('should partial match arrays of objects', function(assert) {
9911       assert.expect(1);
9912
9913       var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
9914
9915       var objects = [
9916         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
9917         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
9918       ];
9919
9920       var actual = lodashStable.filter(objects, function(object) {
9921         return _.isMatch(object, source);
9922       });
9923
9924       assert.deepEqual(actual, [objects[0]]);
9925     });
9926
9927     QUnit.test('should partial match maps', function(assert) {
9928       assert.expect(3);
9929
9930       if (Map) {
9931         var objects = [{ 'a': new Map }, { 'a': new Map }];
9932         objects[0].a.set('a', 1);
9933         objects[1].a.set('a', 1);
9934         objects[1].a.set('b', 2);
9935
9936         var map = new Map;
9937         map.set('b', 2);
9938
9939         var source = { 'a': map },
9940             predicate = function(object) { return _.isMatch(object, source); },
9941             actual = lodashStable.filter(objects, predicate);
9942
9943         assert.deepEqual(actual, [objects[1]]);
9944
9945         map['delete']('b');
9946         actual = lodashStable.filter(objects, predicate);
9947
9948         assert.deepEqual(actual, objects);
9949
9950         map.set('c', 3);
9951         actual = lodashStable.filter(objects, predicate);
9952
9953         assert.deepEqual(actual, []);
9954       }
9955       else {
9956         skipAssert(assert, 3);
9957       }
9958     });
9959
9960     QUnit.test('should partial match sets', function(assert) {
9961       assert.expect(3);
9962
9963       if (Set) {
9964         var objects = [{ 'a': new Set }, { 'a': new Set }];
9965         objects[0].a.add(1);
9966         objects[1].a.add(1);
9967         objects[1].a.add(2);
9968
9969         var set = new Set;
9970         set.add(2);
9971
9972         var source = { 'a': set },
9973             predicate = function(object) { return _.isMatch(object, source); },
9974             actual = lodashStable.filter(objects, predicate);
9975
9976         assert.deepEqual(actual, [objects[1]]);
9977
9978         set['delete'](2);
9979         actual = lodashStable.filter(objects, predicate);
9980
9981         assert.deepEqual(actual, objects);
9982
9983         set.add(3);
9984         actual = lodashStable.filter(objects, predicate);
9985
9986         assert.deepEqual(actual, []);
9987       }
9988       else {
9989         skipAssert(assert, 3);
9990       }
9991     });
9992
9993     QUnit.test('should match `undefined` values', function(assert) {
9994       assert.expect(3);
9995
9996       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
9997           source = { 'b': undefined },
9998           predicate = function(object) { return _.isMatch(object, source); },
9999           actual = lodashStable.map(objects, predicate),
10000           expected = [false, false, true];
10001
10002       assert.deepEqual(actual, expected);
10003
10004       source = { 'a': 1, 'b': undefined };
10005       actual = lodashStable.map(objects, predicate);
10006
10007       assert.deepEqual(actual, expected);
10008
10009       objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
10010       source = { 'a': { 'c': undefined } };
10011       actual = lodashStable.map(objects, predicate);
10012
10013       assert.deepEqual(actual, expected);
10014     });
10015
10016     QUnit.test('should match `undefined` values on primitives', function(assert) {
10017       assert.expect(3);
10018
10019       numberProto.a = 1;
10020       numberProto.b = undefined;
10021
10022       try {
10023         assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
10024       } catch (e) {
10025         assert.ok(false, e.message);
10026       }
10027       try {
10028         assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
10029       } catch (e) {
10030         assert.ok(false, e.message);
10031       }
10032       numberProto.a = { 'b': 1, 'c': undefined };
10033       try {
10034         assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
10035       } catch (e) {
10036         assert.ok(false, e.message);
10037       }
10038       delete numberProto.a;
10039       delete numberProto.b;
10040     });
10041
10042     QUnit.test('should return `false` when `object` is nullish', function(assert) {
10043       assert.expect(1);
10044
10045       var values = [null, undefined],
10046           expected = lodashStable.map(values, alwaysFalse),
10047           source = { 'a': 1 };
10048
10049       var actual = lodashStable.map(values, function(value) {
10050         try {
10051           return _.isMatch(value, source);
10052         } catch (e) {}
10053       });
10054
10055       assert.deepEqual(actual, expected);
10056     });
10057
10058     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
10059       assert.expect(1);
10060
10061       var values = [null, undefined],
10062           expected = lodashStable.map(values, alwaysTrue),
10063           source = {};
10064
10065       var actual = lodashStable.map(values, function(value) {
10066         try {
10067           return _.isMatch(value, source);
10068         } catch (e) {}
10069       });
10070
10071       assert.deepEqual(actual, expected);
10072     });
10073
10074     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
10075       assert.expect(1);
10076
10077       var object = { 'a': 1 },
10078           expected = lodashStable.map(empties, alwaysTrue);
10079
10080       var actual = lodashStable.map(empties, function(value) {
10081         return _.isMatch(object, value);
10082       });
10083
10084       assert.deepEqual(actual, expected);
10085     });
10086
10087     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
10088       assert.expect(1);
10089
10090       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
10091           source = { 'a': [], 'b': {} };
10092
10093       var actual = lodashStable.filter(objects, function(object) {
10094         return _.isMatch(object, source);
10095       });
10096
10097       assert.deepEqual(actual, objects);
10098     });
10099   }());
10100
10101   /*--------------------------------------------------------------------------*/
10102
10103   QUnit.module('lodash.isMatchWith');
10104
10105   (function() {
10106     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
10107       assert.expect(1);
10108
10109       var argsList = [],
10110           object1 = { 'a': [1, 2], 'b': null },
10111           object2 = { 'a': [1, 2], 'b': null };
10112
10113       object1.b = object2;
10114       object2.b = object1;
10115
10116       var expected = [
10117         [object1.a, object2.a, 'a', object1, object2],
10118         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10119         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10120         [object1.b, object2.b, 'b', object1, object2],
10121         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10122         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10123         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10124         [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
10125         [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
10126         [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
10127         [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
10128         [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
10129       ];
10130
10131       _.isMatchWith(object1, object2, function(assert) {
10132         argsList.push(slice.call(arguments, 0, -1));
10133       });
10134
10135       assert.deepEqual(argsList, expected);
10136     });
10137
10138     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
10139       assert.expect(1);
10140
10141       assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10142     });
10143
10144     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
10145       assert.expect(2);
10146
10147       var customizer = function(value) {
10148         return _.isString(value) || undefined;
10149       };
10150
10151       assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10152       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10153     });
10154
10155     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
10156       assert.expect(2);
10157
10158       var customizer = function(value) {
10159         return _.isString(value) ? false : undefined;
10160       };
10161
10162       assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10163       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10164     });
10165
10166     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
10167       assert.expect(2);
10168
10169       var object = { 'a': 1 },
10170           actual = _.isMatchWith(object, { 'a': 1 }, alwaysA);
10171
10172       assert.strictEqual(actual, true);
10173
10174       var expected = lodashStable.map(falsey, alwaysFalse);
10175
10176       actual = [];
10177       lodashStable.each(falsey, function(value) {
10178         actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
10179       });
10180
10181       assert.deepEqual(actual, expected);
10182     });
10183
10184     QUnit.test('should ensure `customizer` is a function', function(assert) {
10185       assert.expect(1);
10186
10187       var object = { 'a': 1 },
10188           matches = _.partial(_.isMatchWith, object),
10189           actual = lodashStable.map([object, { 'a': 2 }], matches);
10190
10191       assert.deepEqual(actual, [true, false]);
10192     });
10193
10194     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10195       assert.expect(2);
10196
10197       var value = { 'a': { 'b': 2 } };
10198
10199       if (Map) {
10200         var map1 = new Map;
10201         map1.set('a', value);
10202
10203         var map2 = new Map;
10204         map2.set('a', value);
10205       }
10206       if (Set) {
10207         var set1 = new Set;
10208         set1.add(value);
10209
10210         var set2 = new Set;
10211         set2.add(value);
10212       }
10213       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10214         if (pair[0]) {
10215           var argsList = [],
10216               array = _.toArray(pair[0]),
10217               object1 = { 'a': pair[0] },
10218               object2 = { 'a': pair[1] };
10219
10220           var expected = [
10221             [pair[0], pair[1], 'a', object1, object2],
10222             [array[0], array[0], 0, array, array],
10223             [array[0][0], array[0][0], 0, array[0], array[0]],
10224             [array[0][1], array[0][1], 1, array[0], array[0]]
10225           ];
10226
10227           if (index) {
10228             expected.length = 2;
10229           }
10230           _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
10231             argsList.push(slice.call(arguments, 0, -1));
10232           });
10233
10234           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10235         }
10236         else {
10237           skipAssert(assert);
10238         }
10239       });
10240     });
10241   }());
10242
10243   /*--------------------------------------------------------------------------*/
10244
10245   QUnit.module('lodash.isNaN');
10246
10247   (function() {
10248     var args = arguments;
10249
10250     QUnit.test('should return `true` for NaNs', function(assert) {
10251       assert.expect(2);
10252
10253       assert.strictEqual(_.isNaN(NaN), true);
10254       assert.strictEqual(_.isNaN(Object(NaN)), true);
10255     });
10256
10257     QUnit.test('should return `false` for non-NaNs', function(assert) {
10258       assert.expect(14);
10259
10260       var expected = lodashStable.map(falsey, function(value) {
10261         return value !== value;
10262       });
10263
10264       var actual = lodashStable.map(falsey, function(value, index) {
10265         return index ? _.isNaN(value) : _.isNaN();
10266       });
10267
10268       assert.deepEqual(actual, expected);
10269
10270       assert.strictEqual(_.isNaN(args), false);
10271       assert.strictEqual(_.isNaN([1, 2, 3]), false);
10272       assert.strictEqual(_.isNaN(true), false);
10273       assert.strictEqual(_.isNaN(new Date), false);
10274       assert.strictEqual(_.isNaN(new Error), false);
10275       assert.strictEqual(_.isNaN(_), false);
10276       assert.strictEqual(_.isNaN(slice), false);
10277       assert.strictEqual(_.isNaN({ 'a': 1 }), false);
10278       assert.strictEqual(_.isNaN(1), false);
10279       assert.strictEqual(_.isNaN(Object(1)), false);
10280       assert.strictEqual(_.isNaN(/x/), false);
10281       assert.strictEqual(_.isNaN('a'), false);
10282       assert.strictEqual(_.isNaN(symbol), false);
10283     });
10284
10285     QUnit.test('should work with `NaN` from another realm', function(assert) {
10286       assert.expect(1);
10287
10288       if (realm.object) {
10289         assert.strictEqual(_.isNaN(realm.nan), true);
10290       }
10291       else {
10292         skipAssert(assert);
10293       }
10294     });
10295   }(1, 2, 3));
10296
10297   /*--------------------------------------------------------------------------*/
10298
10299   QUnit.module('lodash.isNative');
10300
10301   (function() {
10302     var args = arguments;
10303
10304     QUnit.test('should return `true` for native methods', function(assert) {
10305       assert.expect(6);
10306
10307       lodashStable.each([Array, create, root.encodeURI, slice, Uint8Array], function(func) {
10308         if (func) {
10309           assert.strictEqual(_.isNative(func), true);
10310         }
10311         else {
10312           skipAssert(assert);
10313         }
10314       });
10315
10316       if (body) {
10317         assert.strictEqual(_.isNative(body.cloneNode), true);
10318       }
10319       else {
10320         skipAssert(assert);
10321       }
10322     });
10323
10324     QUnit.test('should return `false` for non-native methods', function(assert) {
10325       assert.expect(12);
10326
10327       var expected = lodashStable.map(falsey, alwaysFalse);
10328
10329       var actual = lodashStable.map(falsey, function(value, index) {
10330         return index ? _.isNative(value) : _.isNative();
10331       });
10332
10333       assert.deepEqual(actual, expected);
10334
10335       assert.strictEqual(_.isNative(args), false);
10336       assert.strictEqual(_.isNative([1, 2, 3]), false);
10337       assert.strictEqual(_.isNative(true), false);
10338       assert.strictEqual(_.isNative(new Date), false);
10339       assert.strictEqual(_.isNative(new Error), false);
10340       assert.strictEqual(_.isNative(_), false);
10341       assert.strictEqual(_.isNative({ 'a': 1 }), false);
10342       assert.strictEqual(_.isNative(1), false);
10343       assert.strictEqual(_.isNative(/x/), false);
10344       assert.strictEqual(_.isNative('a'), false);
10345       assert.strictEqual(_.isNative(symbol), false);
10346     });
10347
10348     QUnit.test('should work with native functions from another realm', function(assert) {
10349       assert.expect(2);
10350
10351       if (realm.element) {
10352         assert.strictEqual(_.isNative(realm.element.cloneNode), true);
10353       }
10354       else {
10355         skipAssert(assert);
10356       }
10357       if (realm.object) {
10358         assert.strictEqual(_.isNative(realm.object.valueOf), true);
10359       }
10360       else {
10361         skipAssert(assert);
10362       }
10363     });
10364   }(1, 2, 3));
10365
10366   /*--------------------------------------------------------------------------*/
10367
10368   QUnit.module('lodash.isNil');
10369
10370   (function() {
10371     var args = arguments;
10372
10373     QUnit.test('should return `true` for nullish values', function(assert) {
10374       assert.expect(3);
10375
10376       assert.strictEqual(_.isNil(null), true);
10377       assert.strictEqual(_.isNil(), true);
10378       assert.strictEqual(_.isNil(undefined), true);
10379     });
10380
10381     QUnit.test('should return `false` for non-nullish values', function(assert) {
10382       assert.expect(13);
10383
10384       var expected = lodashStable.map(falsey, function(value) {
10385         return value == null;
10386       });
10387
10388       var actual = lodashStable.map(falsey, function(value, index) {
10389         return index ? _.isNil(value) : _.isNil();
10390       });
10391
10392       assert.deepEqual(actual, expected);
10393
10394       assert.strictEqual(_.isNil(args), false);
10395       assert.strictEqual(_.isNil([1, 2, 3]), false);
10396       assert.strictEqual(_.isNil(true), false);
10397       assert.strictEqual(_.isNil(new Date), false);
10398       assert.strictEqual(_.isNil(new Error), false);
10399       assert.strictEqual(_.isNil(_), false);
10400       assert.strictEqual(_.isNil(slice), false);
10401       assert.strictEqual(_.isNil({ 'a': 1 }), false);
10402       assert.strictEqual(_.isNil(1), false);
10403       assert.strictEqual(_.isNil(/x/), false);
10404       assert.strictEqual(_.isNil('a'), false);
10405
10406       if (Symbol) {
10407         assert.strictEqual(_.isNil(symbol), false);
10408       }
10409       else {
10410         skipAssert(assert);
10411       }
10412     });
10413
10414     QUnit.test('should work with nulls from another realm', function(assert) {
10415       assert.expect(2);
10416
10417       if (realm.object) {
10418         assert.strictEqual(_.isNil(realm.null), true);
10419         assert.strictEqual(_.isNil(realm.undefined), true);
10420       }
10421       else {
10422         skipAssert(assert, 2);
10423       }
10424     });
10425   }(1, 2, 3));
10426
10427   /*--------------------------------------------------------------------------*/
10428
10429   QUnit.module('lodash.isNull');
10430
10431   (function() {
10432     var args = arguments;
10433
10434     QUnit.test('should return `true` for `null` values', function(assert) {
10435       assert.expect(1);
10436
10437       assert.strictEqual(_.isNull(null), true);
10438     });
10439
10440     QUnit.test('should return `false` for non `null` values', function(assert) {
10441       assert.expect(13);
10442
10443       var expected = lodashStable.map(falsey, function(value) {
10444         return value === null;
10445       });
10446
10447       var actual = lodashStable.map(falsey, function(value, index) {
10448         return index ? _.isNull(value) : _.isNull();
10449       });
10450
10451       assert.deepEqual(actual, expected);
10452
10453       assert.strictEqual(_.isNull(args), false);
10454       assert.strictEqual(_.isNull([1, 2, 3]), false);
10455       assert.strictEqual(_.isNull(true), false);
10456       assert.strictEqual(_.isNull(new Date), false);
10457       assert.strictEqual(_.isNull(new Error), false);
10458       assert.strictEqual(_.isNull(_), false);
10459       assert.strictEqual(_.isNull(slice), false);
10460       assert.strictEqual(_.isNull({ 'a': 1 }), false);
10461       assert.strictEqual(_.isNull(1), false);
10462       assert.strictEqual(_.isNull(/x/), false);
10463       assert.strictEqual(_.isNull('a'), false);
10464       assert.strictEqual(_.isNull(symbol), false);
10465     });
10466
10467     QUnit.test('should work with nulls from another realm', function(assert) {
10468       assert.expect(1);
10469
10470       if (realm.object) {
10471         assert.strictEqual(_.isNull(realm.null), true);
10472       }
10473       else {
10474         skipAssert(assert);
10475       }
10476     });
10477   }(1, 2, 3));
10478
10479   /*--------------------------------------------------------------------------*/
10480
10481   QUnit.module('lodash.isNumber');
10482
10483   (function() {
10484     var args = arguments;
10485
10486     QUnit.test('should return `true` for numbers', function(assert) {
10487       assert.expect(3);
10488
10489       assert.strictEqual(_.isNumber(0), true);
10490       assert.strictEqual(_.isNumber(Object(0)), true);
10491       assert.strictEqual(_.isNumber(NaN), true);
10492     });
10493
10494     QUnit.test('should return `false` for non-numbers', function(assert) {
10495       assert.expect(12);
10496
10497       var expected = lodashStable.map(falsey, function(value) {
10498         return typeof value == 'number';
10499       });
10500
10501       var actual = lodashStable.map(falsey, function(value, index) {
10502         return index ? _.isNumber(value) : _.isNumber();
10503       });
10504
10505       assert.deepEqual(actual, expected);
10506
10507       assert.strictEqual(_.isNumber(args), false);
10508       assert.strictEqual(_.isNumber([1, 2, 3]), false);
10509       assert.strictEqual(_.isNumber(true), false);
10510       assert.strictEqual(_.isNumber(new Date), false);
10511       assert.strictEqual(_.isNumber(new Error), false);
10512       assert.strictEqual(_.isNumber(_), false);
10513       assert.strictEqual(_.isNumber(slice), false);
10514       assert.strictEqual(_.isNumber({ 'a': 1 }), false);
10515       assert.strictEqual(_.isNumber(/x/), false);
10516       assert.strictEqual(_.isNumber('a'), false);
10517       assert.strictEqual(_.isNumber(symbol), false);
10518     });
10519
10520     QUnit.test('should work with numbers from another realm', function(assert) {
10521       assert.expect(1);
10522
10523       if (realm.number) {
10524         assert.strictEqual(_.isNumber(realm.number), true);
10525       }
10526       else {
10527         skipAssert(assert);
10528       }
10529     });
10530
10531     QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
10532       assert.expect(1);
10533
10534       assert.strictEqual(_.isNumber(+'2'), true);
10535     });
10536   }(1, 2, 3));
10537
10538   /*--------------------------------------------------------------------------*/
10539
10540   QUnit.module('lodash.isObject');
10541
10542   (function() {
10543     var args = arguments;
10544
10545     QUnit.test('should return `true` for objects', function(assert) {
10546       assert.expect(13);
10547
10548       assert.strictEqual(_.isObject(args), true);
10549       assert.strictEqual(_.isObject([1, 2, 3]), true);
10550       assert.strictEqual(_.isObject(Object(false)), true);
10551       assert.strictEqual(_.isObject(new Date), true);
10552       assert.strictEqual(_.isObject(new Error), true);
10553       assert.strictEqual(_.isObject(_), true);
10554       assert.strictEqual(_.isObject(slice), true);
10555       assert.strictEqual(_.isObject({ 'a': 1 }), true);
10556       assert.strictEqual(_.isObject(Object(0)), true);
10557       assert.strictEqual(_.isObject(/x/), true);
10558       assert.strictEqual(_.isObject(Object('a')), true);
10559
10560       if (document) {
10561         assert.strictEqual(_.isObject(body), true);
10562       }
10563       else {
10564         skipAssert(assert);
10565       }
10566       if (Symbol) {
10567         assert.strictEqual(_.isObject(Object(symbol)), true);
10568       }
10569       else {
10570         skipAssert(assert);
10571       }
10572     });
10573
10574     QUnit.test('should return `false` for non-objects', function(assert) {
10575       assert.expect(1);
10576
10577       var values = falsey.concat(true, 1, 'a', symbol),
10578           expected = lodashStable.map(values, alwaysFalse);
10579
10580       var actual = lodashStable.map(values, function(value, index) {
10581         return index ? _.isObject(value) : _.isObject();
10582       });
10583
10584       assert.deepEqual(actual, expected);
10585     });
10586
10587     QUnit.test('should work with objects from another realm', function(assert) {
10588       assert.expect(8);
10589
10590       if (realm.element) {
10591         assert.strictEqual(_.isObject(realm.element), true);
10592       }
10593       else {
10594         skipAssert(assert);
10595       }
10596       if (realm.object) {
10597         assert.strictEqual(_.isObject(realm.boolean), true);
10598         assert.strictEqual(_.isObject(realm.date), true);
10599         assert.strictEqual(_.isObject(realm.function), true);
10600         assert.strictEqual(_.isObject(realm.number), true);
10601         assert.strictEqual(_.isObject(realm.object), true);
10602         assert.strictEqual(_.isObject(realm.regexp), true);
10603         assert.strictEqual(_.isObject(realm.string), true);
10604       }
10605       else {
10606         skipAssert(assert, 7);
10607       }
10608     });
10609
10610     QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
10611       assert.expect(1);
10612
10613       // Trigger a V8 JIT bug.
10614       // See https://code.google.com/p/v8/issues/detail?id=2291.
10615       var object = {};
10616
10617       // 1: Useless comparison statement, this is half the trigger.
10618       object == object;
10619
10620       // 2: Initial check with object, this is the other half of the trigger.
10621       _.isObject(object);
10622
10623       assert.strictEqual(_.isObject('a'), false);
10624     });
10625   }(1, 2, 3));
10626
10627   /*--------------------------------------------------------------------------*/
10628
10629   QUnit.module('lodash.isObjectLike');
10630
10631   (function() {
10632     var args = arguments;
10633
10634     QUnit.test('should return `true` for objects', function(assert) {
10635       assert.expect(9);
10636
10637       assert.strictEqual(_.isObjectLike(args), true);
10638       assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
10639       assert.strictEqual(_.isObjectLike(Object(false)), true);
10640       assert.strictEqual(_.isObjectLike(new Date), true);
10641       assert.strictEqual(_.isObjectLike(new Error), true);
10642       assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
10643       assert.strictEqual(_.isObjectLike(Object(0)), true);
10644       assert.strictEqual(_.isObjectLike(/x/), true);
10645       assert.strictEqual(_.isObjectLike(Object('a')), true);
10646     });
10647
10648     QUnit.test('should return `false` for non-objects', function(assert) {
10649       assert.expect(1);
10650
10651       var values = falsey.concat(true, _, slice, 1, 'a', symbol),
10652           expected = lodashStable.map(values, alwaysFalse);
10653
10654       var actual = lodashStable.map(values, function(value, index) {
10655         return index ? _.isObjectLike(value) : _.isObjectLike();
10656       });
10657
10658       assert.deepEqual(actual, expected);
10659     });
10660
10661     QUnit.test('should work with objects from another realm', function(assert) {
10662       assert.expect(6);
10663
10664       if (realm.object) {
10665         assert.strictEqual(_.isObjectLike(realm.boolean), true);
10666         assert.strictEqual(_.isObjectLike(realm.date), true);
10667         assert.strictEqual(_.isObjectLike(realm.number), true);
10668         assert.strictEqual(_.isObjectLike(realm.object), true);
10669         assert.strictEqual(_.isObjectLike(realm.regexp), true);
10670         assert.strictEqual(_.isObjectLike(realm.string), true);
10671       }
10672       else {
10673         skipAssert(assert, 6);
10674       }
10675     });
10676   }(1, 2, 3));
10677
10678   /*--------------------------------------------------------------------------*/
10679
10680   QUnit.module('lodash.isPlainObject');
10681
10682   (function() {
10683     var element = document && document.createElement('div');
10684
10685     QUnit.test('should detect plain objects', function(assert) {
10686       assert.expect(5);
10687
10688       function Foo(a) {
10689         this.a = 1;
10690       }
10691
10692       assert.strictEqual(_.isPlainObject({}), true);
10693       assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
10694       assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
10695       assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
10696       assert.strictEqual(_.isPlainObject(new Foo(1)), false);
10697     });
10698
10699     QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
10700       assert.expect(2);
10701
10702       if (create) {
10703         var object = create(null);
10704         assert.strictEqual(_.isPlainObject(object), true);
10705
10706         object.constructor = objectProto.constructor;
10707         assert.strictEqual(_.isPlainObject(object), true);
10708       }
10709       else {
10710         skipAssert(assert, 2);
10711       }
10712     });
10713
10714     QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
10715       assert.expect(2);
10716
10717       assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
10718
10719       if (element) {
10720         var valueOf = element.valueOf;
10721         element.valueOf = 0;
10722
10723         assert.strictEqual(_.isPlainObject(element), false);
10724         element.valueOf = valueOf;
10725       }
10726       else {
10727         skipAssert(assert);
10728       }
10729     });
10730
10731     QUnit.test('should return `false` for DOM elements', function(assert) {
10732       assert.expect(1);
10733
10734       if (element) {
10735         assert.strictEqual(_.isPlainObject(element), false);
10736       } else {
10737         skipAssert(assert);
10738       }
10739     });
10740
10741     QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
10742       assert.expect(3);
10743
10744       assert.strictEqual(_.isPlainObject(arguments), false);
10745       assert.strictEqual(_.isPlainObject(Error), false);
10746       assert.strictEqual(_.isPlainObject(Math), false);
10747     });
10748
10749     QUnit.test('should return `false` for non-objects', function(assert) {
10750       assert.expect(4);
10751
10752       var expected = lodashStable.map(falsey, alwaysFalse);
10753
10754       var actual = lodashStable.map(falsey, function(value, index) {
10755         return index ? _.isPlainObject(value) : _.isPlainObject();
10756       });
10757
10758       assert.deepEqual(actual, expected);
10759
10760       assert.strictEqual(_.isPlainObject(true), false);
10761       assert.strictEqual(_.isPlainObject('a'), false);
10762       assert.strictEqual(_.isPlainObject(symbol), false);
10763     });
10764
10765     QUnit.test('should work with objects from another realm', function(assert) {
10766       assert.expect(1);
10767
10768       if (realm.object) {
10769         assert.strictEqual(_.isPlainObject(realm.object), true);
10770       }
10771       else {
10772         skipAssert(assert);
10773       }
10774     });
10775   }());
10776
10777   /*--------------------------------------------------------------------------*/
10778
10779   QUnit.module('lodash.isRegExp');
10780
10781   (function() {
10782     var args = arguments;
10783
10784     QUnit.test('should return `true` for regexes', function(assert) {
10785       assert.expect(2);
10786
10787       assert.strictEqual(_.isRegExp(/x/), true);
10788       assert.strictEqual(_.isRegExp(RegExp('x')), true);
10789     });
10790
10791     QUnit.test('should return `false` for non-regexes', function(assert) {
10792       assert.expect(12);
10793
10794       var expected = lodashStable.map(falsey, alwaysFalse);
10795
10796       var actual = lodashStable.map(falsey, function(value, index) {
10797         return index ? _.isRegExp(value) : _.isRegExp();
10798       });
10799
10800       assert.deepEqual(actual, expected);
10801
10802       assert.strictEqual(_.isRegExp(args), false);
10803       assert.strictEqual(_.isRegExp([1, 2, 3]), false);
10804       assert.strictEqual(_.isRegExp(true), false);
10805       assert.strictEqual(_.isRegExp(new Date), false);
10806       assert.strictEqual(_.isRegExp(new Error), false);
10807       assert.strictEqual(_.isRegExp(_), false);
10808       assert.strictEqual(_.isRegExp(slice), false);
10809       assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
10810       assert.strictEqual(_.isRegExp(1), false);
10811       assert.strictEqual(_.isRegExp('a'), false);
10812       assert.strictEqual(_.isRegExp(symbol), false);
10813     });
10814
10815     QUnit.test('should work with regexes from another realm', function(assert) {
10816       assert.expect(1);
10817
10818       if (realm.regexp) {
10819         assert.strictEqual(_.isRegExp(realm.regexp), true);
10820       }
10821       else {
10822         skipAssert(assert);
10823       }
10824     });
10825   }(1, 2, 3));
10826
10827   /*--------------------------------------------------------------------------*/
10828
10829   QUnit.module('lodash.isSet');
10830
10831   (function() {
10832     var args = arguments;
10833
10834     QUnit.test('should return `true` for sets', function(assert) {
10835       assert.expect(1);
10836
10837       if (Set) {
10838         assert.strictEqual(_.isSet(set), true);
10839       }
10840       else {
10841         skipAssert(assert);
10842       }
10843     });
10844
10845     QUnit.test('should return `false` for non sets', function(assert) {
10846       assert.expect(14);
10847
10848       var expected = lodashStable.map(falsey, alwaysFalse);
10849
10850       var actual = lodashStable.map(falsey, function(value, index) {
10851         return index ? _.isSet(value) : _.isSet();
10852       });
10853
10854       assert.deepEqual(actual, expected);
10855
10856       assert.strictEqual(_.isSet(args), false);
10857       assert.strictEqual(_.isSet([1, 2, 3]), false);
10858       assert.strictEqual(_.isSet(true), false);
10859       assert.strictEqual(_.isSet(new Date), false);
10860       assert.strictEqual(_.isSet(new Error), false);
10861       assert.strictEqual(_.isSet(_), false);
10862       assert.strictEqual(_.isSet(slice), false);
10863       assert.strictEqual(_.isSet({ 'a': 1 }), false);
10864       assert.strictEqual(_.isSet(1), false);
10865       assert.strictEqual(_.isSet(/x/), false);
10866       assert.strictEqual(_.isSet('a'), false);
10867       assert.strictEqual(_.isSet(symbol), false);
10868       assert.strictEqual(_.isSet(weakSet), false);
10869     });
10870
10871     QUnit.test('should work with weak sets from another realm', function(assert) {
10872       assert.expect(1);
10873
10874       if (realm.set) {
10875         assert.strictEqual(_.isSet(realm.set), true);
10876       }
10877       else {
10878         skipAssert(assert);
10879       }
10880     });
10881   }(1, 2, 3));
10882
10883   /*--------------------------------------------------------------------------*/
10884
10885   QUnit.module('lodash.isString');
10886
10887   (function() {
10888     var args = arguments;
10889
10890     QUnit.test('should return `true` for strings', function(assert) {
10891       assert.expect(2);
10892
10893       assert.strictEqual(_.isString('a'), true);
10894       assert.strictEqual(_.isString(Object('a')), true);
10895     });
10896
10897     QUnit.test('should return `false` for non-strings', function(assert) {
10898       assert.expect(12);
10899
10900       var expected = lodashStable.map(falsey, function(value) {
10901         return value === '';
10902       });
10903
10904       var actual = lodashStable.map(falsey, function(value, index) {
10905         return index ? _.isString(value) : _.isString();
10906       });
10907
10908       assert.deepEqual(actual, expected);
10909
10910       assert.strictEqual(_.isString(args), false);
10911       assert.strictEqual(_.isString([1, 2, 3]), false);
10912       assert.strictEqual(_.isString(true), false);
10913       assert.strictEqual(_.isString(new Date), false);
10914       assert.strictEqual(_.isString(new Error), false);
10915       assert.strictEqual(_.isString(_), false);
10916       assert.strictEqual(_.isString(slice), false);
10917       assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
10918       assert.strictEqual(_.isString(1), false);
10919       assert.strictEqual(_.isString(/x/), false);
10920       assert.strictEqual(_.isString(symbol), false);
10921     });
10922
10923     QUnit.test('should work with strings from another realm', function(assert) {
10924       assert.expect(1);
10925
10926       if (realm.string) {
10927         assert.strictEqual(_.isString(realm.string), true);
10928       }
10929       else {
10930         skipAssert(assert);
10931       }
10932     });
10933   }(1, 2, 3));
10934
10935   /*--------------------------------------------------------------------------*/
10936
10937   QUnit.module('lodash.isSymbol');
10938
10939   (function() {
10940     var args = arguments;
10941
10942     QUnit.test('should return `true` for symbols', function(assert) {
10943       assert.expect(2);
10944
10945       if (Symbol) {
10946         assert.strictEqual(_.isSymbol(symbol), true);
10947         assert.strictEqual(_.isSymbol(Object(symbol)), true);
10948       }
10949       else {
10950         skipAssert(assert, 2);
10951       }
10952     });
10953
10954     QUnit.test('should return `false` for non-symbols', function(assert) {
10955       assert.expect(12);
10956
10957       var expected = lodashStable.map(falsey, alwaysFalse);
10958
10959       var actual = lodashStable.map(falsey, function(value, index) {
10960         return index ? _.isSymbol(value) : _.isSymbol();
10961       });
10962
10963       assert.deepEqual(actual, expected);
10964
10965       assert.strictEqual(_.isSymbol(args), false);
10966       assert.strictEqual(_.isSymbol([1, 2, 3]), false);
10967       assert.strictEqual(_.isSymbol(true), false);
10968       assert.strictEqual(_.isSymbol(new Date), false);
10969       assert.strictEqual(_.isSymbol(new Error), false);
10970       assert.strictEqual(_.isSymbol(_), false);
10971       assert.strictEqual(_.isSymbol(slice), false);
10972       assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
10973       assert.strictEqual(_.isSymbol(1), false);
10974       assert.strictEqual(_.isSymbol(/x/), false);
10975       assert.strictEqual(_.isSymbol('a'), false);
10976     });
10977
10978     QUnit.test('should work with symbols from another realm', function(assert) {
10979       assert.expect(1);
10980
10981       if (Symbol && realm.symbol) {
10982         assert.strictEqual(_.isSymbol(realm.symbol), true);
10983       }
10984       else {
10985         skipAssert(assert);
10986       }
10987     });
10988   }(1, 2, 3));
10989
10990   /*--------------------------------------------------------------------------*/
10991
10992   QUnit.module('lodash.isTypedArray');
10993
10994   (function() {
10995     var args = arguments;
10996
10997     QUnit.test('should return `true` for typed arrays', function(assert) {
10998       assert.expect(1);
10999
11000       var expected = lodashStable.map(typedArrays, function(type) {
11001         return type in root;
11002       });
11003
11004       var actual = lodashStable.map(typedArrays, function(type) {
11005         var Ctor = root[type];
11006         return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11007       });
11008
11009       assert.deepEqual(actual, expected);
11010     });
11011
11012     QUnit.test('should return `false` for non typed arrays', function(assert) {
11013       assert.expect(13);
11014
11015       var expected = lodashStable.map(falsey, alwaysFalse);
11016
11017       var actual = lodashStable.map(falsey, function(value, index) {
11018         return index ? _.isTypedArray(value) : _.isTypedArray();
11019       });
11020
11021       assert.deepEqual(actual, expected);
11022
11023       assert.strictEqual(_.isTypedArray(args), false);
11024       assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11025       assert.strictEqual(_.isTypedArray(true), false);
11026       assert.strictEqual(_.isTypedArray(new Date), false);
11027       assert.strictEqual(_.isTypedArray(new Error), false);
11028       assert.strictEqual(_.isTypedArray(_), false);
11029       assert.strictEqual(_.isTypedArray(slice), false);
11030       assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11031       assert.strictEqual(_.isTypedArray(1), false);
11032       assert.strictEqual(_.isTypedArray(/x/), false);
11033       assert.strictEqual(_.isTypedArray('a'), false);
11034       assert.strictEqual(_.isTypedArray(symbol), false);
11035     });
11036
11037     QUnit.test('should work with typed arrays from another realm', function(assert) {
11038       assert.expect(1);
11039
11040       if (realm.object) {
11041         var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11042
11043         var expected = lodashStable.map(props, function(key) {
11044           return realm[key] !== undefined;
11045         });
11046
11047         var actual = lodashStable.map(props, function(key) {
11048           var value = realm[key];
11049           return value ? _.isTypedArray(value) : false;
11050         });
11051
11052         assert.deepEqual(actual, expected);
11053       }
11054       else {
11055         skipAssert(assert);
11056       }
11057     });
11058   }(1, 2, 3));
11059
11060   /*--------------------------------------------------------------------------*/
11061
11062   QUnit.module('lodash.isUndefined');
11063
11064   (function() {
11065     var args = arguments;
11066
11067     QUnit.test('should return `true` for `undefined` values', function(assert) {
11068       assert.expect(2);
11069
11070       assert.strictEqual(_.isUndefined(), true);
11071       assert.strictEqual(_.isUndefined(undefined), true);
11072     });
11073
11074     QUnit.test('should return `false` for non `undefined` values', function(assert) {
11075       assert.expect(13);
11076
11077       var expected = lodashStable.map(falsey, function(value) {
11078         return value === undefined;
11079       });
11080
11081       var actual = lodashStable.map(falsey, function(value, index) {
11082         return index ? _.isUndefined(value) : _.isUndefined();
11083       });
11084
11085       assert.deepEqual(actual, expected);
11086
11087       assert.strictEqual(_.isUndefined(args), false);
11088       assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11089       assert.strictEqual(_.isUndefined(true), false);
11090       assert.strictEqual(_.isUndefined(new Date), false);
11091       assert.strictEqual(_.isUndefined(new Error), false);
11092       assert.strictEqual(_.isUndefined(_), false);
11093       assert.strictEqual(_.isUndefined(slice), false);
11094       assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11095       assert.strictEqual(_.isUndefined(1), false);
11096       assert.strictEqual(_.isUndefined(/x/), false);
11097       assert.strictEqual(_.isUndefined('a'), false);
11098
11099       if (Symbol) {
11100         assert.strictEqual(_.isUndefined(symbol), false);
11101       }
11102       else {
11103         skipAssert(assert);
11104       }
11105     });
11106
11107     QUnit.test('should work with `undefined` from another realm', function(assert) {
11108       assert.expect(1);
11109
11110       if (realm.object) {
11111         assert.strictEqual(_.isUndefined(realm.undefined), true);
11112       }
11113       else {
11114         skipAssert(assert);
11115       }
11116     });
11117   }(1, 2, 3));
11118
11119   /*--------------------------------------------------------------------------*/
11120
11121   QUnit.module('lodash.isWeakMap');
11122
11123   (function() {
11124     var args = arguments;
11125
11126     QUnit.test('should return `true` for weak maps', function(assert) {
11127       assert.expect(1);
11128
11129       if (WeakMap) {
11130         assert.strictEqual(_.isWeakMap(weakMap), true);
11131       }
11132       else {
11133         skipAssert(assert);
11134       }
11135     });
11136
11137     QUnit.test('should return `false` for non weak maps', function(assert) {
11138       assert.expect(14);
11139
11140       var expected = lodashStable.map(falsey, alwaysFalse);
11141
11142       var actual = lodashStable.map(falsey, function(value, index) {
11143         return index ? _.isWeakMap(value) : _.isWeakMap();
11144       });
11145
11146       assert.deepEqual(actual, expected);
11147
11148       assert.strictEqual(_.isWeakMap(args), false);
11149       assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
11150       assert.strictEqual(_.isWeakMap(true), false);
11151       assert.strictEqual(_.isWeakMap(new Date), false);
11152       assert.strictEqual(_.isWeakMap(new Error), false);
11153       assert.strictEqual(_.isWeakMap(_), false);
11154       assert.strictEqual(_.isWeakMap(slice), false);
11155       assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
11156       assert.strictEqual(_.isWeakMap(map), false);
11157       assert.strictEqual(_.isWeakMap(1), false);
11158       assert.strictEqual(_.isWeakMap(/x/), false);
11159       assert.strictEqual(_.isWeakMap('a'), false);
11160       assert.strictEqual(_.isWeakMap(symbol), false);
11161     });
11162
11163     QUnit.test('should work with weak maps from another realm', function(assert) {
11164       assert.expect(1);
11165
11166       if (realm.weakMap) {
11167         assert.strictEqual(_.isWeakMap(realm.weakMap), true);
11168       }
11169       else {
11170         skipAssert(assert);
11171       }
11172     });
11173   }(1, 2, 3));
11174
11175   /*--------------------------------------------------------------------------*/
11176
11177   QUnit.module('lodash.isWeakSet');
11178
11179   (function() {
11180     var args = arguments;
11181
11182     QUnit.test('should return `true` for weak sets', function(assert) {
11183       assert.expect(1);
11184
11185       if (WeakSet) {
11186         assert.strictEqual(_.isWeakSet(weakSet), true);
11187       }
11188       else {
11189         skipAssert(assert);
11190       }
11191     });
11192
11193     QUnit.test('should return `false` for non weak sets', function(assert) {
11194       assert.expect(14);
11195
11196       var expected = lodashStable.map(falsey, alwaysFalse);
11197
11198       var actual = lodashStable.map(falsey, function(value, index) {
11199         return index ? _.isWeakSet(value) : _.isWeakSet();
11200       });
11201
11202       assert.deepEqual(actual, expected);
11203
11204       assert.strictEqual(_.isWeakSet(args), false);
11205       assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
11206       assert.strictEqual(_.isWeakSet(true), false);
11207       assert.strictEqual(_.isWeakSet(new Date), false);
11208       assert.strictEqual(_.isWeakSet(new Error), false);
11209       assert.strictEqual(_.isWeakSet(_), false);
11210       assert.strictEqual(_.isWeakSet(slice), false);
11211       assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
11212       assert.strictEqual(_.isWeakSet(1), false);
11213       assert.strictEqual(_.isWeakSet(/x/), false);
11214       assert.strictEqual(_.isWeakSet('a'), false);
11215       assert.strictEqual(_.isWeakSet(set), false);
11216       assert.strictEqual(_.isWeakSet(symbol), false);
11217     });
11218
11219     QUnit.test('should work with weak sets from another realm', function(assert) {
11220       assert.expect(1);
11221
11222       if (realm.weakSet) {
11223         assert.strictEqual(_.isWeakSet(realm.weakSet), true);
11224       }
11225       else {
11226         skipAssert(assert);
11227       }
11228     });
11229   }(1, 2, 3));
11230
11231   /*--------------------------------------------------------------------------*/
11232
11233   QUnit.module('isType checks');
11234
11235   (function() {
11236     QUnit.test('should return `false` for subclassed values', function(assert) {
11237       assert.expect(7);
11238
11239       var funcs = [
11240         'isArray', 'isBoolean', 'isDate', 'isFunction',
11241         'isNumber', 'isRegExp', 'isString'
11242       ];
11243
11244       lodashStable.each(funcs, function(methodName) {
11245         function Foo() {}
11246         Foo.prototype = root[methodName.slice(2)].prototype;
11247
11248         var object = new Foo;
11249         if (objToString.call(object) == objectTag) {
11250           assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
11251         } else {
11252           skipAssert(assert);
11253         }
11254       });
11255     });
11256
11257     QUnit.test('should not error on host objects (test in IE)', function(assert) {
11258       assert.expect(26);
11259
11260       var funcs = [
11261         'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
11262         'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
11263         'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
11264         'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
11265         'isUndefined', 'isWeakMap', 'isWeakSet'
11266       ];
11267
11268       lodashStable.each(funcs, function(methodName) {
11269         if (xml) {
11270           var pass = true;
11271
11272           try {
11273             _[methodName](xml);
11274           } catch (e) {
11275             pass = false;
11276           }
11277           assert.ok(pass, '`_.' + methodName + '` should not error');
11278         }
11279         else {
11280           skipAssert(assert);
11281         }
11282       });
11283     });
11284   }());
11285
11286   /*--------------------------------------------------------------------------*/
11287
11288   QUnit.module('lodash.iteratee');
11289
11290   (function() {
11291     QUnit.test('should provide arguments to `func`', function(assert) {
11292       assert.expect(1);
11293
11294       var fn = function() { return slice.call(arguments); },
11295           iteratee = _.iteratee(fn),
11296           actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
11297
11298       assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
11299     });
11300
11301     QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
11302       assert.expect(1);
11303
11304       var object = {},
11305           values = [, null, undefined],
11306           expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
11307
11308       var actual = lodashStable.map(values, function(value, index) {
11309         var identity = index ? _.iteratee(value) : _.iteratee();
11310         return [!isNpm && identity, identity(object)];
11311       });
11312
11313       assert.deepEqual(actual, expected);
11314     });
11315
11316     QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
11317       assert.expect(2);
11318
11319       var matches = _.iteratee({ 'a': 1, 'b': 2 });
11320       assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
11321       assert.strictEqual(matches({ 'b': 2 }), false);
11322     });
11323
11324     QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
11325       assert.expect(9);
11326
11327       var sources = [
11328         { 'a': { 'b': 2, 'c': 3 } },
11329         { 'a': 1, 'b': 2 },
11330         { 'a': 1 }
11331       ];
11332
11333       lodashStable.each(sources, function(source, index) {
11334         var object = lodashStable.cloneDeep(source),
11335             matches = _.iteratee(source);
11336
11337         assert.strictEqual(matches(object), true);
11338
11339         if (index) {
11340           source.a = 2;
11341           source.b = 1;
11342           source.c = 3;
11343         } else {
11344           source.a.b = 1;
11345           source.a.c = 2;
11346           source.a.d = 3;
11347         }
11348         assert.strictEqual(matches(object), true);
11349         assert.strictEqual(matches(source), false);
11350       });
11351     });
11352
11353     QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
11354       assert.expect(3);
11355
11356       var array = ['a', undefined],
11357           matches = _.iteratee([0, 'a']);
11358
11359       assert.strictEqual(matches(array), true);
11360
11361       matches = _.iteratee(['0', 'a']);
11362       assert.strictEqual(matches(array), true);
11363
11364       matches = _.iteratee([1, undefined]);
11365       assert.strictEqual(matches(array), true);
11366     });
11367
11368     QUnit.test('should support deep paths for "_.matchesProperty" shorthands', function(assert) {
11369       assert.expect(1);
11370
11371       var object = { 'a': { 'b': { 'c': { 'd': 1, 'e': 2 } } } },
11372           matches = _.iteratee(['a.b.c', { 'e': 2 }]);
11373
11374       assert.strictEqual(matches(object), true);
11375     });
11376
11377     QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
11378       assert.expect(9);
11379
11380       var sources = [
11381         { 'a': { 'b': 2, 'c': 3 } },
11382         { 'a': 1, 'b': 2 },
11383         { 'a': 1 }
11384       ];
11385
11386       lodashStable.each(sources, function(source, index) {
11387         var object = { 'a': lodashStable.cloneDeep(source) },
11388             matches = _.iteratee(['a', source]);
11389
11390         assert.strictEqual(matches(object), true);
11391
11392         if (index) {
11393           source.a = 2;
11394           source.b = 1;
11395           source.c = 3;
11396         } else {
11397           source.a.b = 1;
11398           source.a.c = 2;
11399           source.a.d = 3;
11400         }
11401         assert.strictEqual(matches(object), true);
11402         assert.strictEqual(matches({ 'a': source }), false);
11403       });
11404     });
11405
11406     QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
11407       assert.expect(2);
11408
11409       var array = ['a'],
11410           prop = _.iteratee(0);
11411
11412       assert.strictEqual(prop(array), 'a');
11413
11414       prop = _.iteratee('0');
11415       assert.strictEqual(prop(array), 'a');
11416     });
11417
11418     QUnit.test('should support deep paths for "_.property" shorthands', function(assert) {
11419       assert.expect(1);
11420
11421       var object = { 'a': { 'b': { 'c': 3 } } },
11422           prop = _.iteratee('a.b.c');
11423
11424       assert.strictEqual(prop(object), 3);
11425     });
11426
11427     QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
11428       assert.expect(2);
11429
11430       var fn = function() {
11431         var result = [this.a];
11432         push.apply(result, arguments);
11433         return result;
11434       };
11435
11436       var expected = [1, 2, 3],
11437           object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
11438
11439       assert.deepEqual(object.iteratee(3), expected);
11440
11441       object.iteratee = _.iteratee(_.partialRight(fn, 3));
11442       assert.deepEqual(object.iteratee(2), expected);
11443     });
11444
11445     QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
11446       assert.expect(1);
11447
11448       var iteratee = _.iteratee;
11449       delete _.iteratee;
11450
11451       assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
11452
11453       _.iteratee = iteratee;
11454     });
11455
11456     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
11457       assert.expect(1);
11458
11459       var fn = function() { return this instanceof Number; },
11460           array = [fn, fn, fn],
11461           iteratees = lodashStable.map(array, _.iteratee),
11462           expected = lodashStable.map(array, alwaysFalse);
11463
11464       var actual = lodashStable.map(iteratees, function(iteratee) {
11465         return iteratee();
11466       });
11467
11468       assert.deepEqual(actual, expected);
11469     });
11470   }());
11471
11472   /*--------------------------------------------------------------------------*/
11473
11474   QUnit.module('custom `_.iteratee` methods');
11475
11476   (function() {
11477     var array = ['one', 'two', 'three'],
11478         getPropA = _.partial(_.property, 'a'),
11479         getPropB = _.partial(_.property, 'b'),
11480         getLength = _.partial(_.property, 'length'),
11481         iteratee = _.iteratee;
11482
11483     var getSum = function() {
11484       return function(result, object) {
11485         return result + object.a;
11486       };
11487     };
11488
11489     var objects = [
11490       { 'a': 0, 'b': 0 },
11491       { 'a': 1, 'b': 0 },
11492       { 'a': 1, 'b': 1 }
11493     ];
11494
11495     QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
11496       assert.expect(1);
11497
11498       if (!isModularize) {
11499         _.iteratee = getLength;
11500         assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
11501         _.iteratee = iteratee;
11502       }
11503       else {
11504         skipAssert(assert);
11505       }
11506     });
11507
11508     QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
11509       assert.expect(1);
11510
11511       if (!isModularize) {
11512         _.iteratee = getPropA;
11513         assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
11514         _.iteratee = iteratee;
11515       }
11516       else {
11517         skipAssert(assert);
11518       }
11519     });
11520
11521     QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
11522       assert.expect(1);
11523
11524       if (!isModularize) {
11525         _.iteratee = getPropB;
11526         assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
11527         _.iteratee = iteratee;
11528       }
11529       else {
11530         skipAssert(assert);
11531       }
11532     });
11533
11534     QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
11535       assert.expect(1);
11536
11537       if (!isModularize) {
11538         _.iteratee = getPropB;
11539         assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
11540         _.iteratee = iteratee;
11541       }
11542       else {
11543         skipAssert(assert);
11544       }
11545     });
11546
11547     QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
11548       assert.expect(1);
11549
11550       if (!isModularize) {
11551         _.iteratee = getPropA;
11552         assert.strictEqual(_.every(objects.slice(1)), true);
11553         _.iteratee = iteratee;
11554       }
11555       else {
11556         skipAssert(assert);
11557       }
11558     });
11559
11560     QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
11561       assert.expect(1);
11562
11563       if (!isModularize) {
11564         var objects = [{ 'a': 0 }, { 'a': 1 }];
11565
11566         _.iteratee = getPropA;
11567         assert.deepEqual(_.filter(objects), [objects[1]]);
11568         _.iteratee = iteratee;
11569       }
11570       else {
11571         skipAssert(assert);
11572       }
11573     });
11574
11575     QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
11576       assert.expect(1);
11577
11578       if (!isModularize) {
11579         _.iteratee = getPropA;
11580         assert.strictEqual(_.find(objects), objects[1]);
11581         _.iteratee = iteratee;
11582       }
11583       else {
11584         skipAssert(assert);
11585       }
11586     });
11587
11588     QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
11589       assert.expect(1);
11590
11591       if (!isModularize) {
11592         _.iteratee = getPropA;
11593         assert.strictEqual(_.findIndex(objects), 1);
11594         _.iteratee = iteratee;
11595       }
11596       else {
11597         skipAssert(assert);
11598       }
11599     });
11600
11601     QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
11602       assert.expect(1);
11603
11604       if (!isModularize) {
11605         _.iteratee = getPropA;
11606         assert.strictEqual(_.findLast(objects), objects[2]);
11607         _.iteratee = iteratee;
11608       }
11609       else {
11610         skipAssert(assert);
11611       }
11612     });
11613
11614     QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
11615       assert.expect(1);
11616
11617       if (!isModularize) {
11618         _.iteratee = getPropA;
11619         assert.strictEqual(_.findLastIndex(objects), 2);
11620         _.iteratee = iteratee;
11621       }
11622       else {
11623         skipAssert(assert);
11624       }
11625     });
11626
11627     QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
11628       assert.expect(1);
11629
11630       if (!isModularize) {
11631         _.iteratee = getPropB;
11632         assert.strictEqual(_.findKey(objects), '2');
11633         _.iteratee = iteratee;
11634       }
11635       else {
11636         skipAssert(assert);
11637       }
11638     });
11639
11640     QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
11641       assert.expect(1);
11642
11643       if (!isModularize) {
11644         _.iteratee = getPropB;
11645         assert.strictEqual(_.findLastKey(objects), '2');
11646         _.iteratee = iteratee;
11647       }
11648       else {
11649         skipAssert(assert);
11650       }
11651     });
11652
11653     QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
11654       assert.expect(1);
11655
11656       if (!isModularize) {
11657         _.iteratee = getLength;
11658         assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
11659         _.iteratee = iteratee;
11660       }
11661       else {
11662         skipAssert(assert);
11663       }
11664     });
11665
11666     QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
11667       assert.expect(1);
11668
11669       if (!isModularize) {
11670         _.iteratee = getPropA;
11671         assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
11672         _.iteratee = iteratee;
11673       }
11674       else {
11675         skipAssert(assert);
11676       }
11677     });
11678
11679     QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
11680       assert.expect(1);
11681
11682       if (!isModularize) {
11683         _.iteratee = getLength;
11684         assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
11685         _.iteratee = iteratee;
11686       }
11687       else {
11688         skipAssert(assert);
11689       }
11690     });
11691
11692     QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
11693       assert.expect(1);
11694
11695       if (!isModularize) {
11696         _.iteratee = getPropA;
11697         assert.deepEqual(_.map(objects), [0, 1, 1]);
11698         _.iteratee = iteratee;
11699       }
11700       else {
11701         skipAssert(assert);
11702       }
11703     });
11704
11705     QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
11706       assert.expect(1);
11707
11708       if (!isModularize) {
11709         _.iteratee = getPropB;
11710         assert.deepEqual(_.mapKeys({ 'a': { 'b': 1 } }), { '1':  { 'b': 1 } });
11711         _.iteratee = iteratee;
11712       }
11713       else {
11714         skipAssert(assert);
11715       }
11716     });
11717
11718     QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
11719       assert.expect(1);
11720
11721       if (!isModularize) {
11722         _.iteratee = getPropB;
11723         assert.deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 });
11724         _.iteratee = iteratee;
11725       }
11726       else {
11727         skipAssert(assert);
11728       }
11729     });
11730
11731     QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
11732       assert.expect(1);
11733
11734       if (!isModularize) {
11735         _.iteratee = getPropB;
11736         assert.deepEqual(_.maxBy(objects), objects[2]);
11737         _.iteratee = iteratee;
11738       }
11739       else {
11740         skipAssert(assert);
11741       }
11742     });
11743
11744     QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
11745       assert.expect(1);
11746
11747       if (!isModularize) {
11748         _.iteratee = getPropB;
11749         assert.deepEqual(_.minBy(objects), objects[0]);
11750         _.iteratee = iteratee;
11751       }
11752       else {
11753         skipAssert(assert);
11754       }
11755     });
11756
11757     QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
11758       assert.expect(1);
11759
11760       if (!isModularize) {
11761         var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
11762
11763         _.iteratee = getPropA;
11764         assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
11765         _.iteratee = iteratee;
11766       }
11767       else {
11768         skipAssert(assert);
11769       }
11770     });
11771
11772     QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
11773       assert.expect(1);
11774
11775       if (!isModularize) {
11776         _.iteratee = getPropA;
11777         assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
11778         _.iteratee = iteratee;
11779       }
11780       else {
11781         skipAssert(assert);
11782       }
11783     });
11784
11785     QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
11786       assert.expect(1);
11787
11788       if (!isModularize) {
11789         _.iteratee = getSum;
11790         assert.strictEqual(_.reduce(objects, undefined, 0), 2);
11791         _.iteratee = iteratee;
11792       }
11793       else {
11794         skipAssert(assert);
11795       }
11796     });
11797
11798     QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
11799       assert.expect(1);
11800
11801       if (!isModularize) {
11802         _.iteratee = getSum;
11803         assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
11804         _.iteratee = iteratee;
11805       }
11806       else {
11807         skipAssert(assert);
11808       }
11809     });
11810
11811     QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
11812       assert.expect(1);
11813
11814       if (!isModularize) {
11815         var objects = [{ 'a': 0 }, { 'a': 1 }];
11816
11817         _.iteratee = getPropA;
11818         assert.deepEqual(_.reject(objects), [objects[0]]);
11819         _.iteratee = iteratee;
11820       }
11821       else {
11822         skipAssert(assert);
11823       }
11824     });
11825
11826     QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
11827       assert.expect(1);
11828
11829       if (!isModularize) {
11830         var objects = [{ 'a': 0 }, { 'a': 1 }];
11831
11832         _.iteratee = getPropA;
11833         _.remove(objects);
11834         assert.deepEqual(objects, [{ 'a': 0 }]);
11835         _.iteratee = iteratee;
11836       }
11837       else {
11838         skipAssert(assert);
11839       }
11840     });
11841
11842     QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
11843       assert.expect(1);
11844
11845       if (!isModularize) {
11846         _.iteratee = getPropB;
11847         assert.strictEqual(_.some(objects), true);
11848         _.iteratee = iteratee;
11849       }
11850       else {
11851         skipAssert(assert);
11852       }
11853     });
11854
11855     QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
11856       assert.expect(1);
11857
11858       if (!isModularize) {
11859         _.iteratee = getPropA;
11860         assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
11861         _.iteratee = iteratee;
11862       }
11863       else {
11864         skipAssert(assert);
11865       }
11866     });
11867
11868     QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
11869       assert.expect(1);
11870
11871       if (!isModularize) {
11872         var objects = [{ 'a': 30 }, { 'a': 50 }];
11873
11874         _.iteratee = getPropA;
11875         assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
11876         _.iteratee = iteratee;
11877       }
11878       else {
11879         skipAssert(assert);
11880       }
11881     });
11882
11883     QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
11884       assert.expect(1);
11885
11886       if (!isModularize) {
11887         var objects = [{ 'a': 30 }, { 'a': 50 }];
11888
11889         _.iteratee = getPropA;
11890         assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
11891         _.iteratee = iteratee;
11892       }
11893       else {
11894         skipAssert(assert);
11895       }
11896     });
11897
11898     QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
11899       assert.expect(1);
11900
11901       if (!isModularize) {
11902         _.iteratee = getPropB;
11903         assert.strictEqual(_.sumBy(objects), 1);
11904         _.iteratee = iteratee;
11905       }
11906       else {
11907         skipAssert(assert);
11908       }
11909     });
11910
11911     QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
11912       assert.expect(1);
11913
11914       if (!isModularize) {
11915         _.iteratee = getPropB;
11916         assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
11917         _.iteratee = iteratee;
11918       }
11919       else {
11920         skipAssert(assert);
11921       }
11922     });
11923
11924     QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
11925       assert.expect(1);
11926
11927       if (!isModularize) {
11928         _.iteratee = getPropB;
11929         assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
11930         _.iteratee = iteratee;
11931       }
11932       else {
11933         skipAssert(assert);
11934       }
11935     });
11936
11937     QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
11938       assert.expect(1);
11939
11940       if (!isModularize) {
11941         _.iteratee = function() {
11942           return function(result, object) {
11943             result.sum += object.a;
11944           };
11945         };
11946
11947         assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
11948         _.iteratee = iteratee;
11949       }
11950       else {
11951         skipAssert(assert);
11952       }
11953     });
11954
11955     QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
11956       assert.expect(1);
11957
11958       if (!isModularize) {
11959         _.iteratee = getPropB;
11960         assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
11961         _.iteratee = iteratee;
11962       }
11963       else {
11964         skipAssert(assert);
11965       }
11966     });
11967
11968     QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
11969       assert.expect(1);
11970
11971       if (!isModularize) {
11972         _.iteratee = getPropB;
11973         assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
11974         _.iteratee = iteratee;
11975       }
11976       else {
11977         skipAssert(assert);
11978       }
11979     });
11980
11981     QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
11982       assert.expect(1);
11983
11984       if (!isModularize) {
11985         _.iteratee = getPropA;
11986         assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
11987         _.iteratee = iteratee;
11988       }
11989       else {
11990         skipAssert(assert);
11991       }
11992     });
11993   }());
11994
11995   /*--------------------------------------------------------------------------*/
11996
11997   QUnit.module('lodash.join');
11998
11999   (function() {
12000     var array = ['a', 'b', 'c'];
12001
12002     QUnit.test('should return join all array elements into a string', function(assert) {
12003       assert.expect(1);
12004
12005       assert.strictEqual(_.join(array, '~'), 'a~b~c');
12006     });
12007
12008     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12009       assert.expect(2);
12010
12011       if (!isNpm) {
12012         var wrapped = _(array);
12013         assert.strictEqual(wrapped.join('~'), 'a~b~c');
12014         assert.strictEqual(wrapped.value(), array);
12015       }
12016       else {
12017         skipAssert(assert, 2);
12018       }
12019     });
12020
12021     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12022       assert.expect(1);
12023
12024       if (!isNpm) {
12025         assert.ok(_(array).chain().join('~') instanceof _);
12026       }
12027       else {
12028         skipAssert(assert);
12029       }
12030     });
12031   }());
12032
12033   /*--------------------------------------------------------------------------*/
12034
12035   QUnit.module('lodash.keyBy');
12036
12037   (function() {
12038     var array = [
12039       { 'dir': 'left', 'code': 97 },
12040       { 'dir': 'right', 'code': 100 }
12041     ];
12042
12043     QUnit.test('should transform keys by `iteratee`', function(assert) {
12044       assert.expect(1);
12045
12046       var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12047
12048       var actual = _.keyBy(array, function(object) {
12049         return String.fromCharCode(object.code);
12050       });
12051
12052       assert.deepEqual(actual, expected);
12053     });
12054
12055     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12056       assert.expect(1);
12057
12058       var array = [4, 6, 6],
12059           values = [, null, undefined],
12060           expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12061
12062       var actual = lodashStable.map(values, function(value, index) {
12063         return index ? _.keyBy(array, value) : _.keyBy(array);
12064       });
12065
12066       assert.deepEqual(actual, expected);
12067     });
12068
12069     QUnit.test('should work with "_.property" shorthands', function(assert) {
12070       assert.expect(1);
12071
12072       var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
12073           actual = _.keyBy(array, 'dir');
12074
12075       assert.deepEqual(actual, expected);
12076     });
12077
12078     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
12079       assert.expect(2);
12080
12081       var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
12082         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
12083       });
12084
12085       assert.deepEqual(actual.constructor, 4.2);
12086       assert.deepEqual(actual.hasOwnProperty, 6.3);
12087     });
12088
12089     QUnit.test('should work with a number for `iteratee`', function(assert) {
12090       assert.expect(2);
12091
12092       var array = [
12093         [1, 'a'],
12094         [2, 'a'],
12095         [2, 'b']
12096       ];
12097
12098       assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
12099       assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
12100     });
12101
12102     QUnit.test('should work with an object for `collection`', function(assert) {
12103       assert.expect(1);
12104
12105       var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
12106       assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
12107     });
12108
12109     QUnit.test('should work in a lazy sequence', function(assert) {
12110       assert.expect(1);
12111
12112       if (!isNpm) {
12113         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
12114           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
12115           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
12116         );
12117
12118         var actual = _(array).keyBy().map(square).filter(isEven).take().value();
12119
12120         assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
12121       }
12122       else {
12123         skipAssert(assert);
12124       }
12125     });
12126   }());
12127
12128   /*--------------------------------------------------------------------------*/
12129
12130   QUnit.module('keys methods');
12131
12132   lodashStable.each(['keys', 'keysIn'], function(methodName) {
12133     var args = (function() { return arguments; }(1, 2, 3)),
12134         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
12135         func = _[methodName],
12136         isKeys = methodName == 'keys';
12137
12138     QUnit.test('`_.' + methodName + '` should return the keys of an object', function(assert) {
12139       assert.expect(1);
12140
12141       assert.deepEqual(func({ 'a': 1, 'b': 1 }).sort(), ['a', 'b']);
12142     });
12143
12144     QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
12145       assert.expect(2);
12146
12147       assert.deepEqual(func('abc').sort(), ['0', '1', '2']);
12148
12149       // IE 9 doesn't box numbers in for-in loops.
12150       numberProto.a = 1;
12151       assert.deepEqual(func(0), isKeys ? [] : ['a']);
12152       delete numberProto.a;
12153     });
12154
12155     QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
12156       assert.expect(1);
12157
12158       var array = [1];
12159       array[2] = 3;
12160
12161       assert.deepEqual(func(array).sort(), ['0', '1', '2']);
12162     });
12163
12164     QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
12165       assert.expect(2);
12166
12167       objectProto.a = 1;
12168       lodashStable.each([null, undefined], function(value) {
12169         assert.deepEqual(func(value), []);
12170       });
12171       delete objectProto.a;
12172     });
12173
12174     QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
12175       assert.expect(1);
12176
12177       var array = [1];
12178       array.a = 1;
12179
12180       assert.deepEqual(func(array).sort(), ['0', 'a']);
12181     });
12182
12183     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of arrays', function(assert) {
12184       assert.expect(1);
12185
12186       var expected = isKeys ? ['0'] : ['0', 'a'];
12187
12188       arrayProto.a = 1;
12189       assert.deepEqual(func([1]).sort(), expected);
12190       delete arrayProto.a;
12191     });
12192
12193     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
12194       assert.expect(1);
12195
12196       var values = [args, strictArgs],
12197           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2'])),
12198           actual = lodashStable.map(values, func);
12199
12200       assert.deepEqual(actual, expected);
12201     });
12202
12203     QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
12204       assert.expect(1);
12205
12206       var values = [args, strictArgs],
12207           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
12208
12209       var actual = lodashStable.map(values, function(value) {
12210         value.a = 1;
12211         var result = func(value).sort();
12212         delete value.a;
12213         return result;
12214       });
12215
12216       assert.deepEqual(actual, expected);
12217     });
12218
12219     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of `arguments` objects', function(assert) {
12220       assert.expect(1);
12221
12222       var values = [args, strictArgs],
12223           expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
12224
12225       var actual = lodashStable.map(values, function(value) {
12226         objectProto.a = 1;
12227         var result = func(value).sort();
12228         delete objectProto.a;
12229         return result;
12230       });
12231
12232       assert.deepEqual(actual, expected);
12233     });
12234
12235     QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
12236       assert.expect(1);
12237
12238       assert.deepEqual(func(Object('abc')).sort(), ['0', '1', '2']);
12239     });
12240
12241     QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
12242       assert.expect(1);
12243
12244       var object = Object('a');
12245       object.a = 1;
12246
12247       assert.deepEqual(func(object).sort(), ['0', 'a']);
12248     });
12249
12250     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of string objects', function(assert) {
12251       assert.expect(1);
12252
12253       var expected = isKeys ? ['0'] : ['0', 'a'];
12254
12255       stringProto.a = 1;
12256       assert.deepEqual(func(Object('a')).sort(), expected);
12257       delete stringProto.a;
12258     });
12259
12260     QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
12261       assert.expect(3);
12262
12263       function Foo() {}
12264       Foo.prototype.a = 1;
12265
12266       var expected = ['a'];
12267       assert.deepEqual(func(Foo.prototype), expected);
12268
12269       Foo.prototype = { 'constructor': Foo, 'a': 1 };
12270       assert.deepEqual(func(Foo.prototype), expected);
12271
12272       var Fake = { 'prototype': {} };
12273       Fake.prototype.constructor = Fake;
12274       assert.deepEqual(func(Fake.prototype), ['constructor']);
12275     });
12276
12277     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties', function(assert) {
12278       assert.expect(1);
12279
12280       function Foo() { this.a = 1; }
12281       Foo.prototype.b = 2;
12282
12283       var expected = isKeys ? ['a'] : ['a', 'b'];
12284       assert.deepEqual(func(new Foo).sort(), expected);
12285     });
12286   });
12287
12288   /*--------------------------------------------------------------------------*/
12289
12290   QUnit.module('lodash.last');
12291
12292   (function() {
12293     var array = [1, 2, 3, 4];
12294
12295     QUnit.test('should return the last element', function(assert) {
12296       assert.expect(1);
12297
12298       assert.strictEqual(_.last(array), 4);
12299     });
12300
12301     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
12302       assert.expect(1);
12303
12304       var array = [];
12305       array['-1'] = 1;
12306
12307       assert.strictEqual(_.last([]), undefined);
12308     });
12309
12310     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12311       assert.expect(1);
12312
12313       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
12314           actual = lodashStable.map(array, _.last);
12315
12316       assert.deepEqual(actual, [3, 6, 9]);
12317     });
12318
12319     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12320       assert.expect(1);
12321
12322       if (!isNpm) {
12323         assert.strictEqual(_(array).last(), 4);
12324       }
12325       else {
12326         skipAssert(assert);
12327       }
12328     });
12329
12330     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12331       assert.expect(1);
12332
12333       if (!isNpm) {
12334         assert.ok(_(array).chain().last() instanceof _);
12335       }
12336       else {
12337         skipAssert(assert);
12338       }
12339     });
12340
12341     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
12342       assert.expect(1);
12343
12344       if (!isNpm) {
12345         var wrapped = _(array).chain().last();
12346         assert.strictEqual(wrapped.__wrapped__, array);
12347       }
12348       else {
12349         skipAssert(assert);
12350       }
12351     });
12352
12353     QUnit.test('should work in a lazy sequence', function(assert) {
12354       assert.expect(2);
12355
12356       if (!isNpm) {
12357         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
12358             smallArray = array;
12359
12360         lodashStable.times(2, function(index) {
12361           var array = index ? largeArray : smallArray,
12362               wrapped = _(array).filter(isEven);
12363
12364           assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
12365         });
12366       }
12367       else {
12368         skipAssert(assert, 2);
12369       }
12370     });
12371   }());
12372
12373   /*--------------------------------------------------------------------------*/
12374
12375   QUnit.module('lodash.lowerCase');
12376
12377   (function() {
12378     QUnit.test('should lowercase as space-separated words', function(assert) {
12379       assert.expect(3);
12380
12381       assert.strictEqual(_.lowerCase('--Foo-Bar'), 'foo bar');
12382       assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
12383       assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
12384     });
12385   }());
12386
12387   /*--------------------------------------------------------------------------*/
12388
12389   QUnit.module('lodash.lowerFirst');
12390
12391   (function() {
12392     QUnit.test('should lowercase only the first character', function(assert) {
12393       assert.expect(3);
12394
12395       assert.strictEqual(_.lowerFirst('fred'), 'fred');
12396       assert.strictEqual(_.lowerFirst('Fred'), 'fred');
12397       assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
12398     });
12399   }());
12400
12401   /*--------------------------------------------------------------------------*/
12402
12403   QUnit.module('lodash.lt');
12404
12405   (function() {
12406     QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
12407       assert.expect(2);
12408
12409       assert.strictEqual(_.lt(1, 3), true);
12410       assert.strictEqual(_.lt('abc', 'def'), true);
12411     });
12412
12413     QUnit.test('should return `false` if `value` >= `other`', function(assert) {
12414       assert.expect(4);
12415
12416       assert.strictEqual(_.lt(3, 1), false);
12417       assert.strictEqual(_.lt(3, 3), false);
12418       assert.strictEqual(_.lt('def', 'abc'), false);
12419       assert.strictEqual(_.lt('def', 'def'), false);
12420     });
12421   }());
12422
12423   /*--------------------------------------------------------------------------*/
12424
12425   QUnit.module('lodash.lte');
12426
12427   (function() {
12428     QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
12429       assert.expect(4);
12430
12431       assert.strictEqual(_.lte(1, 3), true);
12432       assert.strictEqual(_.lte(3, 3), true);
12433       assert.strictEqual(_.lte('abc', 'def'), true);
12434       assert.strictEqual(_.lte('def', 'def'), true);
12435     });
12436
12437     QUnit.test('should return `false` if `value` > `other`', function(assert) {
12438       assert.expect(2);
12439
12440       assert.strictEqual(_.lt(3, 1), false);
12441       assert.strictEqual(_.lt('def', 'abc'), false);
12442     });
12443   }());
12444
12445   /*--------------------------------------------------------------------------*/
12446
12447   QUnit.module('lodash.lastIndexOf');
12448
12449   (function() {
12450     var array = [1, 2, 3, 1, 2, 3];
12451
12452     QUnit.test('should return the index of the last matched value', function(assert) {
12453       assert.expect(1);
12454
12455       assert.strictEqual(_.lastIndexOf(array, 3), 5);
12456     });
12457
12458     QUnit.test('should work with a positive `fromIndex`', function(assert) {
12459       assert.expect(1);
12460
12461       assert.strictEqual(_.lastIndexOf(array, 1, 2), 0);
12462     });
12463
12464     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
12465       assert.expect(1);
12466
12467       var values = [6, 8, Math.pow(2, 32), Infinity],
12468           expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
12469
12470       var actual = lodashStable.map(values, function(fromIndex) {
12471         return [
12472           _.lastIndexOf(array, undefined, fromIndex),
12473           _.lastIndexOf(array, 1, fromIndex),
12474           _.lastIndexOf(array, '', fromIndex)
12475         ];
12476       });
12477
12478       assert.deepEqual(actual, expected);
12479     });
12480
12481     QUnit.test('should work with a negative `fromIndex`', function(assert) {
12482       assert.expect(1);
12483
12484       assert.strictEqual(_.lastIndexOf(array, 2, -3), 1);
12485     });
12486
12487     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
12488       assert.expect(1);
12489
12490       var values = [-6, -8, -Infinity],
12491           expected = lodashStable.map(values, alwaysZero);
12492
12493       var actual = lodashStable.map(values, function(fromIndex) {
12494         return _.lastIndexOf(array, 1, fromIndex);
12495       });
12496
12497       assert.deepEqual(actual, expected);
12498     });
12499
12500     QUnit.test('should treat falsey `fromIndex` values correctly', function(assert) {
12501       assert.expect(1);
12502
12503       var expected = lodashStable.map(falsey, function(value) {
12504         return value === undefined ? 5 : -1;
12505       });
12506
12507       var actual = lodashStable.map(falsey, function(fromIndex) {
12508         return _.lastIndexOf(array, 3, fromIndex);
12509       });
12510
12511       assert.deepEqual(actual, expected);
12512     });
12513
12514     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
12515       assert.expect(1);
12516
12517       assert.strictEqual(_.lastIndexOf(array, 2, 4.2), 4);
12518     });
12519   }());
12520
12521   /*--------------------------------------------------------------------------*/
12522
12523   QUnit.module('indexOf methods');
12524
12525   lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
12526     var func = _[methodName],
12527         isIndexOf = !/last/i.test(methodName),
12528         isSorted = /^sorted/.test(methodName);
12529
12530     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
12531       assert.expect(1);
12532
12533       var expected = lodashStable.map(falsey, lodashStable.constant(-1));
12534
12535       var actual = lodashStable.map(falsey, function(array, index) {
12536         try {
12537           return index ? func(array) : func();
12538         } catch (e) {}
12539       });
12540
12541       assert.deepEqual(actual, expected);
12542     });
12543
12544     QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
12545       assert.expect(5);
12546
12547       var array = [1, 2, 3],
12548           empty = [];
12549
12550       assert.strictEqual(func(array, 4), -1);
12551       assert.strictEqual(func(array, 4, true), -1);
12552       assert.strictEqual(func(array, undefined, true), -1);
12553
12554       assert.strictEqual(func(empty, undefined), -1);
12555       assert.strictEqual(func(empty, undefined, true), -1);
12556     });
12557
12558     QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
12559       assert.expect(2);
12560
12561       var array = [];
12562       array[-1] = 0;
12563
12564       assert.strictEqual(func(array, undefined), -1);
12565       assert.strictEqual(func(array, 0, true), -1);
12566     });
12567
12568     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
12569       assert.expect(4);
12570
12571       var array = isSorted
12572         ? [1, 2, NaN, NaN]
12573         : [1, NaN, 3, NaN, 5, NaN];
12574
12575       if (isSorted) {
12576         assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
12577         skipAssert(assert, 3);
12578       }
12579       else {
12580         assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
12581         assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
12582         assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
12583         skipAssert(assert);
12584       }
12585     });
12586
12587     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
12588       assert.expect(2);
12589
12590       assert.strictEqual(func([-0], 0), 0);
12591       assert.strictEqual(func([0], -0), 0);
12592     });
12593   });
12594
12595   /*--------------------------------------------------------------------------*/
12596
12597   QUnit.module('lodash.map');
12598
12599   (function() {
12600     var array = [1, 2];
12601
12602     QUnit.test('should map values in `collection` to a new array', function(assert) {
12603       assert.expect(2);
12604
12605       var object = { 'a': 1, 'b': 2 },
12606           expected = ['1', '2'];
12607
12608       assert.deepEqual(_.map(array, String), expected);
12609       assert.deepEqual(_.map(object, String), expected);
12610     });
12611
12612     QUnit.test('should work with "_.property" shorthands', function(assert) {
12613       assert.expect(1);
12614
12615       var objects = [{ 'a': 'x' }, { 'a': 'y' }];
12616       assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
12617     });
12618
12619     QUnit.test('should iterate over own properties of objects', function(assert) {
12620       assert.expect(1);
12621
12622       function Foo() { this.a = 1; }
12623       Foo.prototype.b = 2;
12624
12625       var actual = _.map(new Foo, identity);
12626       assert.deepEqual(actual, [1]);
12627     });
12628
12629     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12630       assert.expect(1);
12631
12632       var values = [, null, undefined],
12633           expected = lodashStable.map(values, lodashStable.constant([1, 2]));
12634
12635       var actual = lodashStable.map(values, function(value, index) {
12636         return index ? _.map(array, value) : _.map(array);
12637       });
12638
12639       assert.deepEqual(actual, expected);
12640     });
12641
12642     QUnit.test('should work on an object with no `iteratee`', function(assert) {
12643       assert.expect(1);
12644
12645       var actual = _.map({ 'a': 1, 'b': 2 });
12646       assert.deepEqual(actual, array);
12647     });
12648
12649     QUnit.test('should handle object arguments with non-number length properties', function(assert) {
12650       assert.expect(1);
12651
12652       var value = { 'value': 'x' },
12653           object = { 'length': { 'value': 'x' } };
12654
12655       assert.deepEqual(_.map(object, identity), [value]);
12656     });
12657
12658     QUnit.test('should treat a nodelist as an array-like object', function(assert) {
12659       assert.expect(1);
12660
12661       if (document) {
12662         var actual = _.map(document.getElementsByTagName('body'), function(element) {
12663           return element.nodeName.toLowerCase();
12664         });
12665
12666         assert.deepEqual(actual, ['body']);
12667       }
12668       else {
12669         skipAssert(assert);
12670       }
12671     });
12672
12673     QUnit.test('should accept a falsey `collection` argument', function(assert) {
12674       assert.expect(1);
12675
12676       var expected = lodashStable.map(falsey, alwaysEmptyArray);
12677
12678       var actual = lodashStable.map(falsey, function(collection, index) {
12679         try {
12680           return index ? _.map(collection) : _.map();
12681         } catch (e) {}
12682       });
12683
12684       assert.deepEqual(actual, expected);
12685     });
12686
12687     QUnit.test('should treat number values for `collection` as empty', function(assert) {
12688       assert.expect(1);
12689
12690       assert.deepEqual(_.map(1), []);
12691     });
12692
12693     QUnit.test('should return a wrapped value when chaining', function(assert) {
12694       assert.expect(1);
12695
12696       if (!isNpm) {
12697         assert.ok(_(array).map(noop) instanceof _);
12698       }
12699       else {
12700         skipAssert(assert);
12701       }
12702     });
12703
12704     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
12705       assert.expect(5);
12706
12707       if (!isNpm) {
12708         var args,
12709             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
12710             expected = [1, 0, _.map(array.slice(1), square)];
12711
12712         _(array).slice(1).map(function(value, index, array) {
12713           args || (args = slice.call(arguments));
12714         }).value();
12715
12716         assert.deepEqual(args, [1, 0, array.slice(1)]);
12717
12718         args = undefined;
12719         _(array).slice(1).map(square).map(function(value, index, array) {
12720           args || (args = slice.call(arguments));
12721         }).value();
12722
12723         assert.deepEqual(args, expected);
12724
12725         args = undefined;
12726         _(array).slice(1).map(square).map(function(value, index) {
12727           args || (args = slice.call(arguments));
12728         }).value();
12729
12730         assert.deepEqual(args, expected);
12731
12732         args = undefined;
12733         _(array).slice(1).map(square).map(function(value) {
12734           args || (args = slice.call(arguments));
12735         }).value();
12736
12737         assert.deepEqual(args, [1]);
12738
12739         args = undefined;
12740         _(array).slice(1).map(square).map(function() {
12741           args || (args = slice.call(arguments));
12742         }).value();
12743
12744         assert.deepEqual(args, expected);
12745       }
12746       else {
12747         skipAssert(assert, 5);
12748       }
12749     });
12750   }());
12751
12752   /*--------------------------------------------------------------------------*/
12753
12754   QUnit.module('lodash.mapKeys');
12755
12756   (function() {
12757     var array = [1, 2],
12758         object = { 'a': 1, 'b': 2 };
12759
12760     QUnit.test('should map keys in `object` to a new object', function(assert) {
12761       assert.expect(1);
12762
12763       var actual = _.mapKeys(object, String);
12764       assert.deepEqual(actual, { '1': 1, '2': 2 });
12765     });
12766
12767     QUnit.test('should treat arrays like objects', function(assert) {
12768       assert.expect(1);
12769
12770       var actual = _.mapKeys(array, String);
12771       assert.deepEqual(actual, { '1': 1, '2': 2 });
12772     });
12773
12774     QUnit.test('should work with "_.property" shorthands', function(assert) {
12775       assert.expect(1);
12776
12777       var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
12778       assert.deepEqual(actual, { 'c': { 'b': 'c' } });
12779     });
12780
12781     QUnit.test('should work on an object with no `iteratee`', function(assert) {
12782       assert.expect(1);
12783
12784       var actual = _.mapKeys({ 'a': 1, 'b': 2 });
12785       assert.deepEqual(actual, { '1': 1, '2': 2 });
12786     });
12787   }());
12788
12789   /*--------------------------------------------------------------------------*/
12790
12791   QUnit.module('lodash.mapValues');
12792
12793   (function() {
12794     var array = [1, 2],
12795         object = { 'a': 1, 'b': 2 };
12796
12797     QUnit.test('should map values in `object` to a new object', function(assert) {
12798       assert.expect(1);
12799
12800       var actual = _.mapValues(object, String);
12801       assert.deepEqual(actual, { 'a': '1', 'b': '2' });
12802     });
12803
12804     QUnit.test('should treat arrays like objects', function(assert) {
12805       assert.expect(1);
12806
12807       var actual = _.mapValues(array, String);
12808       assert.deepEqual(actual, { '0': '1', '1': '2' });
12809     });
12810
12811     QUnit.test('should work with "_.property" shorthands', function(assert) {
12812       assert.expect(1);
12813
12814       var actual = _.mapValues({ 'a': { 'b': 1 } }, 'b');
12815       assert.deepEqual(actual, { 'a': 1 });
12816     });
12817
12818     QUnit.test('should work on an object with no `iteratee`', function(assert) {
12819       assert.expect(2);
12820
12821       var actual = _.mapValues({ 'a': 1, 'b': 2 });
12822       assert.deepEqual(actual, object);
12823       assert.notStrictEqual(actual, object);
12824     });
12825   }());
12826
12827   /*--------------------------------------------------------------------------*/
12828
12829   QUnit.module('lodash.mapKeys and lodash.mapValues');
12830
12831   lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
12832     var array = [1, 2],
12833         func = _[methodName],
12834         object = { 'a': 1, 'b': 2 };
12835
12836     QUnit.test('should iterate over own properties of objects', function(assert) {
12837       assert.expect(1);
12838
12839       function Foo() { this.a = 'a'; }
12840       Foo.prototype.b = 'b';
12841
12842       var actual = func(new Foo, function(value, key) { return key; });
12843       assert.deepEqual(actual, { 'a': 'a' });
12844     });
12845
12846     QUnit.test('should accept a falsey `object` argument', function(assert) {
12847       assert.expect(1);
12848
12849       var expected = lodashStable.map(falsey, alwaysEmptyObject);
12850
12851       var actual = lodashStable.map(falsey, function(object, index) {
12852         try {
12853           return index ? func(object) : func();
12854         } catch (e) {}
12855       });
12856
12857       assert.deepEqual(actual, expected);
12858     });
12859
12860     QUnit.test('should return a wrapped value when chaining', function(assert) {
12861       assert.expect(1);
12862
12863       if (!isNpm) {
12864         assert.ok(_(object)[methodName](noop) instanceof _);
12865       }
12866       else {
12867         skipAssert(assert);
12868       }
12869     });
12870   });
12871
12872   /*--------------------------------------------------------------------------*/
12873
12874   QUnit.module('lodash.matches');
12875
12876   (function() {
12877     QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
12878       assert.expect(6);
12879
12880       var object = { 'a': 1, 'b': 2, 'c': 3 },
12881           matches = _.matches({ 'a': 1 });
12882
12883       assert.strictEqual(matches.length, 1);
12884       assert.strictEqual(matches(object), true);
12885
12886       matches = _.matches({ 'b': 1 });
12887       assert.strictEqual(matches(object), false);
12888
12889       matches = _.matches({ 'a': 1, 'c': 3 });
12890       assert.strictEqual(matches(object), true);
12891
12892       matches = _.matches({ 'c': 3, 'd': 4 });
12893       assert.strictEqual(matches(object), false);
12894
12895       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
12896       matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
12897
12898       assert.strictEqual(matches(object), true);
12899     });
12900
12901     QUnit.test('should match inherited `object` properties', function(assert) {
12902       assert.expect(1);
12903
12904       function Foo() { this.a = 1; }
12905       Foo.prototype.b = 2;
12906
12907       var object = { 'a': new Foo },
12908           matches = _.matches({ 'a': { 'b': 2 } });
12909
12910       assert.strictEqual(matches(object), true);
12911     });
12912
12913     QUnit.test('should not match by inherited `source` properties', function(assert) {
12914       assert.expect(1);
12915
12916       function Foo() { this.a = 1; }
12917       Foo.prototype.b = 2;
12918
12919       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
12920           source = new Foo,
12921           actual = lodashStable.map(objects, _.matches(source)),
12922           expected = lodashStable.map(objects, alwaysTrue);
12923
12924       assert.deepEqual(actual, expected);
12925     });
12926
12927     QUnit.test('should compare a variety of `source` property values', function(assert) {
12928       assert.expect(2);
12929
12930       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
12931           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
12932           matches = _.matches(object1);
12933
12934       assert.strictEqual(matches(object1), true);
12935       assert.strictEqual(matches(object2), false);
12936     });
12937
12938     QUnit.test('should match `-0` as `0`', function(assert) {
12939       assert.expect(2);
12940
12941       var object1 = { 'a': -0 },
12942           object2 = { 'a': 0 },
12943           matches = _.matches(object1);
12944
12945       assert.strictEqual(matches(object2), true);
12946
12947       matches = _.matches(object2);
12948       assert.strictEqual(matches(object1), true);
12949     });
12950
12951     QUnit.test('should compare functions by reference', function(assert) {
12952       assert.expect(3);
12953
12954       var object1 = { 'a': lodashStable.noop },
12955           object2 = { 'a': noop },
12956           object3 = { 'a': {} },
12957           matches = _.matches(object1);
12958
12959       assert.strictEqual(matches(object1), true);
12960       assert.strictEqual(matches(object2), false);
12961       assert.strictEqual(matches(object3), false);
12962     });
12963
12964     QUnit.test('should work with a function for `object`', function(assert) {
12965       assert.expect(1);
12966
12967       function Foo() {}
12968       Foo.a = { 'b': 1, 'c': 2 };
12969
12970       var matches = _.matches({ 'a': { 'b': 1 } });
12971       assert.strictEqual(matches(Foo), true);
12972     });
12973
12974     QUnit.test('should work with a function for `source`', function(assert) {
12975       assert.expect(1);
12976
12977       function Foo() {}
12978       Foo.a = 1;
12979       Foo.b = function() {};
12980       Foo.c = 3;
12981
12982       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
12983           actual = lodashStable.map(objects, _.matches(Foo));
12984
12985       assert.deepEqual(actual, [false, true]);
12986     });
12987
12988     QUnit.test('should work with a non-plain `object`', function(assert) {
12989       assert.expect(1);
12990
12991       function Foo(object) { lodashStable.assign(this, object); }
12992
12993       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
12994           matches = _.matches({ 'a': { 'b': 1 } });
12995
12996       assert.strictEqual(matches(object), true);
12997     });
12998
12999     QUnit.test('should partial match arrays', function(assert) {
13000       assert.expect(3);
13001
13002       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13003           actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
13004
13005       assert.deepEqual(actual, [objects[1]]);
13006
13007       actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
13008       assert.deepEqual(actual, []);
13009
13010       actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
13011       assert.deepEqual(actual, []);
13012     });
13013
13014     QUnit.test('should partial match arrays of objects', function(assert) {
13015       assert.expect(1);
13016
13017       var objects = [
13018         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
13019         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
13020       ];
13021
13022       var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
13023       assert.deepEqual(actual, [objects[0]]);
13024     });
13025
13026     QUnit.test('should partial match maps', function(assert) {
13027       assert.expect(3);
13028
13029       if (Map) {
13030         var objects = [{ 'a': new Map }, { 'a': new Map }];
13031         objects[0].a.set('a', 1);
13032         objects[1].a.set('a', 1);
13033         objects[1].a.set('b', 2);
13034
13035         var map = new Map;
13036         map.set('b', 2);
13037         var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13038
13039         assert.deepEqual(actual, [objects[1]]);
13040
13041         map['delete']('b');
13042         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13043
13044         assert.deepEqual(actual, objects);
13045
13046         map.set('c', 3);
13047         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13048
13049         assert.deepEqual(actual, []);
13050       }
13051       else {
13052         skipAssert(assert, 3);
13053       }
13054     });
13055
13056     QUnit.test('should partial match sets', function(assert) {
13057       assert.expect(3);
13058
13059       if (Set) {
13060         var objects = [{ 'a': new Set }, { 'a': new Set }];
13061         objects[0].a.add(1);
13062         objects[1].a.add(1);
13063         objects[1].a.add(2);
13064
13065         var set = new Set;
13066         set.add(2);
13067         var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13068
13069         assert.deepEqual(actual, [objects[1]]);
13070
13071         set['delete'](2);
13072         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13073
13074         assert.deepEqual(actual, objects);
13075
13076         set.add(3);
13077         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13078
13079         assert.deepEqual(actual, []);
13080       }
13081       else {
13082         skipAssert(assert, 3);
13083       }
13084     });
13085
13086     QUnit.test('should match `undefined` values', function(assert) {
13087       assert.expect(3);
13088
13089       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
13090           actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
13091           expected = [false, false, true];
13092
13093       assert.deepEqual(actual, expected);
13094
13095       actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
13096
13097       assert.deepEqual(actual, expected);
13098
13099       objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
13100       actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
13101
13102       assert.deepEqual(actual, expected);
13103     });
13104
13105     QUnit.test('should match `undefined` values on primitives', function(assert) {
13106       assert.expect(3);
13107
13108       numberProto.a = 1;
13109       numberProto.b = undefined;
13110
13111       try {
13112         var matches = _.matches({ 'b': undefined });
13113         assert.strictEqual(matches(1), true);
13114       } catch (e) {
13115         assert.ok(false, e.message);
13116       }
13117       try {
13118         matches = _.matches({ 'a': 1, 'b': undefined });
13119         assert.strictEqual(matches(1), true);
13120       } catch (e) {
13121         assert.ok(false, e.message);
13122       }
13123       numberProto.a = { 'b': 1, 'c': undefined };
13124       try {
13125         matches = _.matches({ 'a': { 'c': undefined } });
13126         assert.strictEqual(matches(1), true);
13127       } catch (e) {
13128         assert.ok(false, e.message);
13129       }
13130       delete numberProto.a;
13131       delete numberProto.b;
13132     });
13133
13134     QUnit.test('should return `false` when `object` is nullish', function(assert) {
13135       assert.expect(1);
13136
13137       var values = [, null, undefined],
13138           expected = lodashStable.map(values, alwaysFalse),
13139           matches = _.matches({ 'a': 1 });
13140
13141       var actual = lodashStable.map(values, function(value, index) {
13142         try {
13143           return index ? matches(value) : matches();
13144         } catch (e) {}
13145       });
13146
13147       assert.deepEqual(actual, expected);
13148     });
13149
13150     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
13151       assert.expect(1);
13152
13153       var values = [, null, undefined],
13154           expected = lodashStable.map(values, alwaysTrue),
13155           matches = _.matches({});
13156
13157       var actual = lodashStable.map(values, function(value, index) {
13158         try {
13159           return index ? matches(value) : matches();
13160         } catch (e) {}
13161       });
13162
13163       assert.deepEqual(actual, expected);
13164     });
13165
13166     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
13167       assert.expect(1);
13168
13169       var object = { 'a': 1 },
13170           expected = lodashStable.map(empties, alwaysTrue);
13171
13172       var actual = lodashStable.map(empties, function(value) {
13173         var matches = _.matches(value);
13174         return matches(object);
13175       });
13176
13177       assert.deepEqual(actual, expected);
13178     });
13179
13180     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
13181       assert.expect(1);
13182
13183       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
13184           actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
13185
13186       assert.deepEqual(actual, objects);
13187     });
13188
13189     QUnit.test('should not change behavior if `source` is modified', function(assert) {
13190       assert.expect(9);
13191
13192       var sources = [
13193         { 'a': { 'b': 2, 'c': 3 } },
13194         { 'a': 1, 'b': 2 },
13195         { 'a': 1 }
13196       ];
13197
13198       lodashStable.each(sources, function(source, index) {
13199         var object = lodashStable.cloneDeep(source),
13200             matches = _.matches(source);
13201
13202         assert.strictEqual(matches(object), true);
13203
13204         if (index) {
13205           source.a = 2;
13206           source.b = 1;
13207           source.c = 3;
13208         } else {
13209           source.a.b = 1;
13210           source.a.c = 2;
13211           source.a.d = 3;
13212         }
13213         assert.strictEqual(matches(object), true);
13214         assert.strictEqual(matches(source), false);
13215       });
13216     });
13217   }());
13218
13219   /*--------------------------------------------------------------------------*/
13220
13221   QUnit.module('lodash.matchesProperty');
13222
13223   (function() {
13224     QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
13225       assert.expect(6);
13226
13227       var object = { 'a': 1, 'b': 2, 'c': 3 },
13228           matches = _.matchesProperty('a', 1);
13229
13230       assert.strictEqual(matches.length, 1);
13231       assert.strictEqual(matches(object), true);
13232
13233       matches = _.matchesProperty('b', 3);
13234       assert.strictEqual(matches(object), false);
13235
13236       matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
13237       assert.strictEqual(matches({ 'a': object }), true);
13238
13239       matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
13240       assert.strictEqual(matches(object), false);
13241
13242       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13243       matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
13244
13245       assert.strictEqual(matches(object), true);
13246     });
13247
13248     QUnit.test('should support deep paths', function(assert) {
13249       assert.expect(2);
13250
13251       var object = { 'a': { 'b': { 'c': 3 } } };
13252
13253       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
13254         var matches = _.matchesProperty(path, 3);
13255         assert.strictEqual(matches(object), true);
13256       });
13257     });
13258
13259     QUnit.test('should coerce key to a string', function(assert) {
13260       assert.expect(1);
13261
13262       function fn() {}
13263       fn.toString = lodashStable.constant('fn');
13264
13265       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
13266           values = [null, undefined, fn, {}];
13267
13268       var expected = lodashStable.transform(values, function(result) {
13269         result.push(true, true);
13270       });
13271
13272       var actual = lodashStable.transform(objects, function(result, object, index) {
13273         var key = values[index];
13274         lodashStable.each([key, [key]], function(path) {
13275           var matches = _.matchesProperty(path, object[key]);
13276           result.push(matches(object));
13277         });
13278       });
13279
13280       assert.deepEqual(actual, expected);
13281     });
13282
13283     QUnit.test('should match a key over a path', function(assert) {
13284       assert.expect(2);
13285
13286       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
13287
13288       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
13289         var matches = _.matchesProperty(path, 3);
13290         assert.strictEqual(matches(object), true);
13291       });
13292     });
13293
13294     QUnit.test('should work with non-string `path` arguments', function(assert) {
13295       assert.expect(2);
13296
13297       var array = [1, 2, 3];
13298
13299       lodashStable.each([1, [1]], function(path) {
13300         var matches = _.matchesProperty(path, 2);
13301         assert.strictEqual(matches(array), true);
13302       });
13303     });
13304
13305     QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
13306       assert.expect(4);
13307
13308       var object = {};
13309
13310       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
13311         var matches = _.matchesProperty(path, 1);
13312         assert.strictEqual(matches(object), false);
13313       });
13314     });
13315
13316     QUnit.test('should return `false` with deep paths when `object` is nullish', function(assert) {
13317       assert.expect(2);
13318
13319       var values = [, null, undefined],
13320           expected = lodashStable.map(values, alwaysFalse);
13321
13322       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
13323         var matches = _.matchesProperty(path, 1);
13324
13325         var actual = lodashStable.map(values, function(value, index) {
13326           try {
13327             return index ? matches(value) : matches();
13328           } catch (e) {}
13329         });
13330
13331         assert.deepEqual(actual, expected);
13332       });
13333     });
13334
13335     QUnit.test('should match inherited `srcValue` properties', function(assert) {
13336       assert.expect(2);
13337
13338       function Foo() {}
13339       Foo.prototype.b = 2;
13340
13341       var object = { 'a': new Foo };
13342
13343       lodashStable.each(['a', ['a']], function(path) {
13344         var matches = _.matchesProperty(path, { 'b': 2 });
13345         assert.strictEqual(matches(object), true);
13346       });
13347     });
13348
13349     QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
13350       assert.expect(2);
13351
13352       function Foo() { this.a = 1; }
13353       Foo.prototype.b = 2;
13354
13355       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
13356           expected = lodashStable.map(objects, alwaysTrue);
13357
13358       lodashStable.each(['a', ['a']], function(path) {
13359         assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
13360       });
13361     });
13362
13363     QUnit.test('should compare a variety of values', function(assert) {
13364       assert.expect(2);
13365
13366       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13367           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13368           matches = _.matchesProperty('a', object1);
13369
13370       assert.strictEqual(matches({ 'a': object1 }), true);
13371       assert.strictEqual(matches({ 'a': object2 }), false);
13372     });
13373
13374     QUnit.test('should match `-0` as `0`', function(assert) {
13375       assert.expect(2);
13376
13377       var matches = _.matchesProperty('a', -0);
13378       assert.strictEqual(matches({ 'a': 0 }), true);
13379
13380       matches = _.matchesProperty('a', 0);
13381       assert.strictEqual(matches({ 'a': -0 }), true);
13382     });
13383
13384     QUnit.test('should compare functions by reference', function(assert) {
13385       assert.expect(3);
13386
13387       var object1 = { 'a': lodashStable.noop },
13388           object2 = { 'a': noop },
13389           object3 = { 'a': {} },
13390           matches = _.matchesProperty('a', object1);
13391
13392       assert.strictEqual(matches({ 'a': object1 }), true);
13393       assert.strictEqual(matches({ 'a': object2 }), false);
13394       assert.strictEqual(matches({ 'a': object3 }), false);
13395     });
13396
13397     QUnit.test('should work with a function for `srcValue`', function(assert) {
13398       assert.expect(1);
13399
13400       function Foo() {}
13401       Foo.a = 1;
13402       Foo.b = function() {};
13403       Foo.c = 3;
13404
13405       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
13406           actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
13407
13408       assert.deepEqual(actual, [false, true]);
13409     });
13410
13411     QUnit.test('should work with a non-plain `srcValue`', function(assert) {
13412       assert.expect(1);
13413
13414       function Foo(object) { lodashStable.assign(this, object); }
13415
13416       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
13417           matches = _.matchesProperty('a', { 'b': 1 });
13418
13419       assert.strictEqual(matches(object), true);
13420     });
13421
13422     QUnit.test('should partial match arrays', function(assert) {
13423       assert.expect(3);
13424
13425       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13426           actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
13427
13428       assert.deepEqual(actual, [objects[1]]);
13429
13430       actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
13431       assert.deepEqual(actual, []);
13432
13433       actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
13434       assert.deepEqual(actual, []);
13435     });
13436
13437     QUnit.test('should partial match arrays of objects', function(assert) {
13438       assert.expect(1);
13439
13440       var objects = [
13441         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
13442         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
13443       ];
13444
13445       var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
13446       assert.deepEqual(actual, [objects[0]]);
13447     });
13448     QUnit.test('should partial match maps', function(assert) {
13449       assert.expect(3);
13450
13451       if (Map) {
13452         var objects = [{ 'a': new Map }, { 'a': new Map }];
13453         objects[0].a.set('a', 1);
13454         objects[1].a.set('a', 1);
13455         objects[1].a.set('b', 2);
13456
13457         var map = new Map;
13458         map.set('b', 2);
13459         var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
13460
13461         assert.deepEqual(actual, [objects[1]]);
13462
13463         map['delete']('b');
13464         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
13465
13466         assert.deepEqual(actual, objects);
13467
13468         map.set('c', 3);
13469         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
13470
13471         assert.deepEqual(actual, []);
13472       }
13473       else {
13474         skipAssert(assert, 3);
13475       }
13476     });
13477
13478     QUnit.test('should partial match sets', function(assert) {
13479       assert.expect(3);
13480
13481       if (Set) {
13482         var objects = [{ 'a': new Set }, { 'a': new Set }];
13483         objects[0].a.add(1);
13484         objects[1].a.add(1);
13485         objects[1].a.add(2);
13486
13487         var set = new Set;
13488         set.add(2);
13489         var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
13490
13491         assert.deepEqual(actual, [objects[1]]);
13492
13493         set['delete'](2);
13494         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
13495
13496         assert.deepEqual(actual, objects);
13497
13498         set.add(3);
13499         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
13500
13501         assert.deepEqual(actual, []);
13502       }
13503       else {
13504         skipAssert(assert, 3);
13505       }
13506     });
13507
13508     QUnit.test('should match `undefined` values', function(assert) {
13509       assert.expect(2);
13510
13511       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
13512           actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
13513           expected = [false, false, true];
13514
13515       assert.deepEqual(actual, expected);
13516
13517       objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
13518       actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
13519
13520       assert.deepEqual(actual, expected);
13521     });
13522
13523     QUnit.test('should match `undefined` values on primitives', function(assert) {
13524       assert.expect(2);
13525
13526       numberProto.a = 1;
13527       numberProto.b = undefined;
13528
13529       try {
13530         var matches = _.matchesProperty('b', undefined);
13531         assert.strictEqual(matches(1), true);
13532       } catch (e) {
13533         assert.ok(false, e.message);
13534       }
13535       numberProto.a = { 'b': 1, 'c': undefined };
13536       try {
13537         matches = _.matchesProperty('a', { 'c': undefined });
13538         assert.strictEqual(matches(1), true);
13539       } catch (e) {
13540         assert.ok(false, e.message);
13541       }
13542       delete numberProto.a;
13543       delete numberProto.b;
13544     });
13545
13546     QUnit.test('should return `false` when `object` is nullish', function(assert) {
13547       assert.expect(2);
13548
13549       var values = [, null, undefined],
13550           expected = lodashStable.map(values, alwaysFalse);
13551
13552       lodashStable.each(['constructor', ['constructor']], function(path) {
13553         var matches = _.matchesProperty(path, 1);
13554
13555         var actual = lodashStable.map(values, function(value, index) {
13556           try {
13557             return index ? matches(value) : matches();
13558           } catch (e) {}
13559         });
13560
13561         assert.deepEqual(actual, expected);
13562       });
13563     });
13564
13565     QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
13566       assert.expect(1);
13567
13568       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
13569           matches = _.matchesProperty('a', { 'a': [], 'b': {} });
13570
13571       var actual = lodashStable.filter(objects, function(object) {
13572         return matches({ 'a': object });
13573       });
13574
13575       assert.deepEqual(actual, objects);
13576     });
13577
13578     QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
13579       assert.expect(9);
13580
13581       lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
13582         var object = lodashStable.cloneDeep(source),
13583             matches = _.matchesProperty('a', source);
13584
13585         assert.strictEqual(matches({ 'a': object }), true);
13586
13587         if (index) {
13588           source.a = 2;
13589           source.b = 1;
13590           source.c = 3;
13591         } else {
13592           source.a.b = 1;
13593           source.a.c = 2;
13594           source.a.d = 3;
13595         }
13596         assert.strictEqual(matches({ 'a': object }), true);
13597         assert.strictEqual(matches({ 'a': source }), false);
13598       });
13599     });
13600   }());
13601
13602   /*--------------------------------------------------------------------------*/
13603
13604   QUnit.module('lodash.max');
13605
13606   (function() {
13607     QUnit.test('should return the largest value from a collection', function(assert) {
13608       assert.expect(1);
13609
13610       assert.strictEqual(_.max([1, 2, 3]), 3);
13611     });
13612
13613     QUnit.test('should return `undefined` for empty collections', function(assert) {
13614       assert.expect(1);
13615
13616       var values = falsey.concat([[]]),
13617           expected = lodashStable.map(values, alwaysUndefined);
13618
13619       var actual = lodashStable.map(values, function(value, index) {
13620         try {
13621           return index ? _.max(value) : _.max();
13622         } catch (e) {}
13623       });
13624
13625       assert.deepEqual(actual, expected);
13626     });
13627
13628     QUnit.test('should work with non-numeric collection values', function(assert) {
13629       assert.expect(1);
13630
13631       assert.strictEqual(_.max(['a', 'b']), 'b');
13632     });
13633   }());
13634
13635   /*--------------------------------------------------------------------------*/
13636
13637   QUnit.module('lodash.mean');
13638
13639   (function() {
13640     QUnit.test('should return the mean of an array of numbers', function(assert) {
13641       assert.expect(1);
13642
13643       var array = [4, 2, 8, 6];
13644       assert.strictEqual(_.mean(array), 5);
13645     });
13646
13647     QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
13648       assert.expect(1);
13649
13650       var expected = lodashStable.map(empties, alwaysNaN),
13651           actual = lodashStable.map(empties, _.mean);
13652
13653       assert.deepEqual(actual, expected);
13654     });
13655   }());
13656
13657   /*--------------------------------------------------------------------------*/
13658
13659   QUnit.module('lodash.memoize');
13660
13661   (function() {
13662     QUnit.test('should memoize results based on the first argument given', function(assert) {
13663       assert.expect(2);
13664
13665       var memoized = _.memoize(function(a, b, c) {
13666         return a + b + c;
13667       });
13668
13669       assert.strictEqual(memoized(1, 2, 3), 6);
13670       assert.strictEqual(memoized(1, 3, 5), 6);
13671     });
13672
13673     QUnit.test('should support a `resolver` argument', function(assert) {
13674       assert.expect(2);
13675
13676       var fn = function(a, b, c) { return a + b + c; },
13677           memoized = _.memoize(fn, fn);
13678
13679       assert.strictEqual(memoized(1, 2, 3), 6);
13680       assert.strictEqual(memoized(1, 3, 5), 9);
13681     });
13682
13683     QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
13684       assert.expect(2);
13685
13686       var fn = function(a, b, c) { return a + this.b + this.c; },
13687           memoized = _.memoize(fn, fn);
13688
13689       var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
13690       assert.strictEqual(object.memoized(1), 6);
13691
13692       object.b = 3;
13693       object.c = 5;
13694       assert.strictEqual(object.memoized(1), 9);
13695     });
13696
13697     QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
13698       assert.expect(1);
13699
13700       assert.raises(function() { _.memoize(noop, true); }, TypeError);
13701     });
13702
13703     QUnit.test('should not error if `resolver` is falsey', function(assert) {
13704       assert.expect(1);
13705
13706       var expected = lodashStable.map(falsey, alwaysTrue);
13707
13708       var actual = lodashStable.map(falsey, function(resolver, index) {
13709         try {
13710           return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
13711         } catch (e) {}
13712       });
13713
13714       assert.deepEqual(actual, expected);
13715     });
13716
13717     QUnit.test('should check cache for own properties', function(assert) {
13718       assert.expect(1);
13719
13720       var props = [
13721         'constructor',
13722         'hasOwnProperty',
13723         'isPrototypeOf',
13724         'propertyIsEnumerable',
13725         'toLocaleString',
13726         'toString',
13727         'valueOf'
13728       ];
13729
13730       var memoized = _.memoize(identity);
13731
13732       var actual = lodashStable.map(props, function(value) {
13733         return memoized(value);
13734       });
13735
13736       assert.deepEqual(actual, props);
13737     });
13738
13739     QUnit.test('should cache the `__proto__` key', function(assert) {
13740       assert.expect(8);
13741
13742       var array = [],
13743           key = '__proto__';
13744
13745       lodashStable.times(2, function(index) {
13746         var count = 0,
13747             resolver = index && identity;
13748
13749         var memoized = _.memoize(function() {
13750           count++;
13751           return array;
13752         }, resolver);
13753
13754         var cache = memoized.cache;
13755
13756         memoized(key);
13757         memoized(key);
13758
13759         assert.strictEqual(count, 1);
13760         assert.strictEqual(cache.get(key), array);
13761         assert.notOk(cache.__data__ instanceof Array);
13762         assert.strictEqual(cache['delete'](key), true);
13763       });
13764     });
13765
13766     QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
13767       assert.expect(4);
13768
13769       var oldCache = _.memoize.Cache;
13770
13771       function Cache() {
13772         this.__data__ = [];
13773       }
13774
13775       Cache.prototype = {
13776         'get': function(key) {
13777           var entry = _.find(this.__data__, function(entry) {
13778             return key === entry.key;
13779           });
13780           return entry && entry.value;
13781         },
13782         'has': function(key) {
13783           return _.some(this.__data__, function(entry) {
13784             return key === entry.key;
13785           });
13786         },
13787         'set': function(key, value) {
13788           this.__data__.push({ 'key': key, 'value': value });
13789           return this;
13790         }
13791       };
13792
13793       _.memoize.Cache = Cache;
13794
13795       var memoized = _.memoize(function(object) {
13796         return 'value:' + object.id;
13797       });
13798
13799       var cache = memoized.cache,
13800           key1 = { 'id': 'a' },
13801           key2 = { 'id': 'b' };
13802
13803       assert.strictEqual(memoized(key1), 'value:a');
13804       assert.strictEqual(cache.has(key1), true);
13805
13806       assert.strictEqual(memoized(key2), 'value:b');
13807       assert.strictEqual(cache.has(key2), true);
13808
13809       _.memoize.Cache = oldCache;
13810     });
13811
13812     QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
13813       assert.expect(2);
13814
13815       var oldCache = _.memoize.Cache;
13816
13817       function Cache() {
13818         this.__data__ = [];
13819       }
13820
13821       Cache.prototype = {
13822         'get': function(key) {
13823           return _.find(this.__data__, function(entry) {
13824             return key === entry.key;
13825           }).value;
13826         },
13827         'has': function(key) {
13828           return _.some(this.__data__, function(entry) {
13829             return key === entry.key;
13830           });
13831         },
13832         'set': function(key, value) {
13833           var result = new Cache;
13834           result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
13835           return result;
13836         }
13837       };
13838
13839       _.memoize.Cache = Cache;
13840
13841       var memoized = _.memoize(function(object) {
13842         return object.id;
13843       });
13844
13845       var key1 = { 'id': 'a' },
13846           key2 = { 'id': 'b' };
13847
13848       memoized(key1);
13849       memoized(key2);
13850
13851       var cache = memoized.cache;
13852       assert.strictEqual(cache.has(key1), true);
13853       assert.strictEqual(cache.has(key2), true);
13854
13855       _.memoize.Cache = oldCache;
13856     });
13857
13858     QUnit.test('should implement a `Map` interface on the cache object', function(assert) {
13859       assert.expect(164);
13860
13861       var keys = [true, false, 1, -Infinity, NaN, {}, null, 'a', symbol || {} , undefined];
13862
13863       var pairs = lodashStable.map(keys, function(key, index) {
13864         var lastIndex = keys.length - 1;
13865         return [key, keys[lastIndex - index]];
13866       });
13867
13868       lodashStable.times(2, function(index) {
13869         var memoize = (index ? (lodashBizarro || {}) : _).memoize,
13870             Cache = memoize ? memoize.Cache : undefined,
13871             cache = Cache ? new Cache(pairs) : undefined;
13872
13873         lodashStable.each(keys, function(key, index) {
13874           if (cache) {
13875             var value = pairs[index][1];
13876
13877             assert.deepEqual(cache.get(key), value);
13878             assert.strictEqual(cache.has(key), true);
13879             assert.strictEqual(cache['delete'](key), true);
13880             assert.strictEqual(cache.has(key), false);
13881             assert.strictEqual(cache.get(key), undefined);
13882             assert.strictEqual(cache['delete'](key), false);
13883             assert.strictEqual(cache.set(key, value), cache);
13884             assert.strictEqual(cache.has(key), true);
13885           }
13886           else {
13887             skipAssert(assert, 8);
13888           }
13889         });
13890
13891         if (cache) {
13892           assert.strictEqual(cache.clear(), undefined);
13893           assert.ok(lodashStable.every(keys, function(key) {
13894             return !cache.has(key);
13895           }));
13896         }
13897         else {
13898           skipAssert(assert, 2);
13899         }
13900       });
13901     });
13902   }());
13903
13904   /*--------------------------------------------------------------------------*/
13905
13906   QUnit.module('lodash.merge');
13907
13908   (function() {
13909     var args = arguments;
13910
13911     QUnit.test('should merge `source` into `object`', function(assert) {
13912       assert.expect(1);
13913
13914       var names = {
13915         'characters': [
13916           { 'name': 'barney' },
13917           { 'name': 'fred' }
13918         ]
13919       };
13920
13921       var ages = {
13922         'characters': [
13923           { 'age': 36 },
13924           { 'age': 40 }
13925         ]
13926       };
13927
13928       var heights = {
13929         'characters': [
13930           { 'height': '5\'4"' },
13931           { 'height': '5\'5"' }
13932         ]
13933       };
13934
13935       var expected = {
13936         'characters': [
13937           { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
13938           { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
13939         ]
13940       };
13941
13942       assert.deepEqual(_.merge(names, ages, heights), expected);
13943     });
13944
13945     QUnit.test('should merge sources containing circular references', function(assert) {
13946       assert.expect(1);
13947
13948       var object = {
13949         'foo': { 'a': 1 },
13950         'bar': { 'a': 2 }
13951       };
13952
13953       var source = {
13954         'foo': { 'b': { 'c': { 'd': {} } } },
13955         'bar': {}
13956       };
13957
13958       source.foo.b.c.d = source;
13959       source.bar.b = source.foo.b;
13960
13961       var actual = _.merge(object, source);
13962       assert.ok(actual.bar.b === actual.foo.b && actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
13963     });
13964
13965     QUnit.test('should work with four arguments', function(assert) {
13966       assert.expect(1);
13967
13968       var expected = { 'a': 4 },
13969           actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
13970
13971       assert.deepEqual(actual, expected);
13972     });
13973
13974     QUnit.test('should merge onto function `object` values', function(assert) {
13975       assert.expect(2);
13976
13977       function Foo() {}
13978
13979       var source = { 'a': 1 },
13980           actual = _.merge(Foo, source);
13981
13982       assert.strictEqual(actual, Foo);
13983       assert.strictEqual(Foo.a, 1);
13984     });
13985
13986     QUnit.test('should not merge onto nested function values', function(assert) {
13987       assert.expect(3);
13988
13989       var source1 = { 'a': function() {} },
13990           source2 = { 'a': { 'b': 1 } },
13991           actual = _.merge({}, source1, source2),
13992           expected = { 'a': { 'b': 1 } };
13993
13994       assert.deepEqual(actual, expected);
13995
13996       source1 = { 'a': function() {} };
13997       source2 = { 'a': { 'b': 1 } };
13998
13999       expected = { 'a': function() {} };
14000       expected.a.b = 1;
14001
14002       actual = _.merge(source1, source2);
14003       assert.strictEqual(typeof actual.a, 'function');
14004       assert.strictEqual(actual.a.b, 1);
14005     });
14006
14007     QUnit.test('should merge onto non-plain `object` values', function(assert) {
14008       assert.expect(2);
14009
14010       function Foo() {}
14011
14012       var object = new Foo,
14013           source = { 'a': 1 },
14014           actual = _.merge(object, source);
14015
14016       assert.strictEqual(actual, object);
14017       assert.strictEqual(object.a, 1);
14018     });
14019
14020     QUnit.test('should pass thru primitive `object` values', function(assert) {
14021       assert.expect(1);
14022
14023       var values = [true, 1, '1'];
14024
14025       var actual = lodashStable.map(values, function(value) {
14026         return _.merge(value, { 'a': 1 });
14027       });
14028
14029       assert.deepEqual(actual, values);
14030     });
14031
14032     QUnit.test('should treat sparse array sources as dense', function(assert) {
14033       assert.expect(2);
14034
14035       var array = Array(3);
14036       array[0] = 1;
14037       array[2] = 3;
14038
14039       var actual = _.merge([], array),
14040           expected = array.slice();
14041
14042       expected[1] = undefined;
14043
14044       assert.ok('1' in actual);
14045       assert.deepEqual(actual, expected);
14046     });
14047
14048     QUnit.test('should merge `arguments` objects', function(assert) {
14049       assert.expect(7);
14050
14051       var object1 = { 'value': args },
14052           object2 = { 'value': { '3': 4 } },
14053           expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
14054           actual = _.merge(object1, object2);
14055
14056       assert.notOk('3' in args);
14057       assert.notOk(_.isArguments(actual.value));
14058       assert.deepEqual(actual.value, expected);
14059       object1.value = args;
14060
14061       actual = _.merge(object2, object1);
14062       assert.notOk(_.isArguments(actual.value));
14063       assert.deepEqual(actual.value, expected);
14064
14065       expected = { '0': 1, '1': 2, '2': 3 };
14066
14067       actual = _.merge({}, object1);
14068       assert.notOk(_.isArguments(actual.value));
14069       assert.deepEqual(actual.value, expected);
14070     });
14071
14072     QUnit.test('should merge typed arrays', function(assert) {
14073       assert.expect(4);
14074
14075       var array1 = [0],
14076           array2 = [0, 0],
14077           array3 = [0, 0, 0, 0],
14078           array4 = lodashStable.range(0, 8, 0);
14079
14080       var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
14081           buffer = ArrayBuffer && new ArrayBuffer(8);
14082
14083       // juggle for `Float64Array` shim
14084       if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
14085         arrays[1] = array4;
14086       }
14087       var expected = lodashStable.map(typedArrays, function(type, index) {
14088         var array = arrays[index].slice();
14089         array[0] = 1;
14090         return root[type] ? { 'value': array } : false;
14091       });
14092
14093       var actual = lodashStable.map(typedArrays, function(type) {
14094         var Ctor = root[type];
14095         return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
14096       });
14097
14098       assert.ok(lodashStable.isArray(actual));
14099       assert.deepEqual(actual, expected);
14100
14101       expected = lodashStable.map(typedArrays, function(type, index) {
14102         var array = arrays[index].slice();
14103         array.push(1);
14104         return root[type] ? { 'value': array } : false;
14105       });
14106
14107       actual = lodashStable.map(typedArrays, function(type, index) {
14108         var Ctor = root[type],
14109             array = lodashStable.range(arrays[index].length);
14110
14111         array.push(1);
14112         return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
14113       });
14114
14115       assert.ok(lodashStable.isArray(actual));
14116       assert.deepEqual(actual, expected);
14117     });
14118
14119     QUnit.test('should assign `null` values', function(assert) {
14120       assert.expect(1);
14121
14122       var actual = _.merge({ 'a': 1 }, { 'a': null });
14123       assert.strictEqual(actual.a, null);
14124     });
14125
14126     QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
14127       assert.expect(1);
14128
14129       function Foo() {}
14130
14131       var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
14132           expected = lodashStable.map(values, alwaysTrue);
14133
14134       var actual = lodashStable.map(values, function(value) {
14135         var object = _.merge({}, { 'value': value });
14136         return object.value === value;
14137       });
14138
14139       assert.deepEqual(actual, expected);
14140     });
14141
14142     QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) {
14143       assert.expect(1);
14144
14145       var typedArray = Uint8Array
14146         ? new Uint8Array(new ArrayBuffer(2))
14147         : { 'buffer': [0, 0] };
14148
14149       var props = ['0', 'a', 'buffer'],
14150           values = [[{ 'a': 1 }], { 'a': [1] }, typedArray],
14151           expected = lodashStable.map(values, alwaysTrue);
14152
14153       var actual = lodashStable.map(values, function(value, index) {
14154         var key = props[index],
14155             object = _.merge({}, { 'value': value }),
14156             newValue = object.value;
14157
14158         return (
14159           newValue !== value &&
14160           newValue[key] !== value[key] &&
14161           lodashStable.isEqual(newValue, value)
14162         );
14163       });
14164
14165       assert.deepEqual(actual, expected);
14166     });
14167
14168     QUnit.test('should not augment source objects', function(assert) {
14169       assert.expect(6);
14170
14171       var source1 = { 'a': [{ 'a': 1 }] },
14172           source2 = { 'a': [{ 'b': 2 }] },
14173           actual = _.merge({}, source1, source2);
14174
14175       assert.deepEqual(source1.a, [{ 'a': 1 }]);
14176       assert.deepEqual(source2.a, [{ 'b': 2 }]);
14177       assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
14178
14179       var source1 = { 'a': [[1, 2, 3]] },
14180           source2 = { 'a': [[3, 4]] },
14181           actual = _.merge({}, source1, source2);
14182
14183       assert.deepEqual(source1.a, [[1, 2, 3]]);
14184       assert.deepEqual(source2.a, [[3, 4]]);
14185       assert.deepEqual(actual.a, [[3, 4, 3]]);
14186     });
14187
14188     QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
14189       assert.expect(4);
14190
14191       function Foo(object) {
14192         lodashStable.assign(this, object);
14193       }
14194
14195       var object = { 'a': 1 },
14196           actual = _.merge(new Foo, object);
14197
14198       assert.ok(actual instanceof Foo);
14199       assert.deepEqual(actual, new Foo(object));
14200
14201       actual = _.merge([new Foo], [object]);
14202       assert.ok(actual[0] instanceof Foo);
14203       assert.deepEqual(actual, [new Foo(object)]);
14204     });
14205
14206     QUnit.test('should not assign `undefined` values', function(assert) {
14207       assert.expect(1);
14208
14209       var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
14210       assert.deepEqual(actual, { 'a': 1 });
14211     });
14212
14213     QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
14214       assert.expect(2);
14215
14216       var array = Array(3);
14217       array[0] = 1;
14218       array[2] = 3;
14219
14220       var actual = _.merge([4, 5, 6], array),
14221           expected = [1, 5, 3];
14222
14223       assert.deepEqual(actual, expected);
14224
14225       array = [1, , 3];
14226       array[1] = undefined;
14227
14228       actual = _.merge([4, 5, 6], array);
14229       assert.deepEqual(actual, expected);
14230     });
14231
14232     QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
14233       assert.expect(1);
14234
14235       if (defineProperty) {
14236         var object = {},
14237             pass = true;
14238
14239         defineProperty(object, 'a', {
14240           'enumerable': true,
14241           'configurable': true,
14242           'get': function() { pass = false; },
14243           'set': function() { pass = false; }
14244         });
14245
14246         _.merge(object, object);
14247         assert.ok(pass);
14248       }
14249       else {
14250         skipAssert(assert);
14251       }
14252     });
14253
14254     QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
14255       assert.expect(2);
14256
14257       var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
14258           actual = _.merge(object, { 'a': ['x'] });
14259
14260       assert.deepEqual(actual, { 'a': ['x', 'y'] });
14261
14262       actual = _.merge({ 'a': {} }, { 'a': [] });
14263       assert.deepEqual(actual, { 'a': [] });
14264     });
14265
14266     QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
14267       assert.expect(1);
14268
14269       var object = { 'a': 'abcde' },
14270           actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
14271
14272       assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
14273     });
14274
14275     QUnit.test('should not error on DOM elements', function(assert) {
14276       assert.expect(1);
14277
14278       var object1 = { 'el': document && document.createElement('div') },
14279           object2 = { 'el': document && document.createElement('div') },
14280           pairs = [[{}, object1], [object1, object2]],
14281           expected = lodashStable.map(pairs, alwaysTrue);
14282
14283       var actual = lodashStable.map(pairs, function(pair) {
14284         try {
14285           return _.merge(pair[0], pair[1]).el === pair[1].el;
14286         } catch (e) {}
14287       });
14288
14289       assert.deepEqual(actual, expected);
14290     });
14291   }(1, 2, 3));
14292
14293   /*--------------------------------------------------------------------------*/
14294
14295   QUnit.module('lodash.mergeWith');
14296
14297   (function() {
14298     QUnit.test('should handle merging if `customizer` returns `undefined`', function(assert) {
14299       assert.expect(2);
14300
14301       var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
14302       assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
14303
14304       actual = _.mergeWith([], [undefined], identity);
14305       assert.deepEqual(actual, [undefined]);
14306     });
14307
14308     QUnit.test('should defer to `customizer` when it returns a value other than `undefined`', function(assert) {
14309       assert.expect(1);
14310
14311       var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
14312         return lodashStable.isArray(a) ? a.concat(b) : undefined;
14313       });
14314
14315       assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
14316     });
14317
14318     QUnit.test('should overwrite primitives with source object clones', function(assert) {
14319       assert.expect(1);
14320
14321       var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
14322         return lodashStable.isArray(a) ? a.concat(b) : undefined;
14323       });
14324
14325       assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
14326     });
14327   }());
14328
14329   /*--------------------------------------------------------------------------*/
14330
14331   QUnit.module('lodash.method');
14332
14333   (function() {
14334     QUnit.test('should create a function that calls a method of a given object', function(assert) {
14335       assert.expect(4);
14336
14337       var object = { 'a': alwaysOne };
14338
14339       lodashStable.each(['a', ['a']], function(path) {
14340         var method = _.method(path);
14341         assert.strictEqual(method.length, 1);
14342         assert.strictEqual(method(object), 1);
14343       });
14344     });
14345
14346     QUnit.test('should work with deep property values', function(assert) {
14347       assert.expect(2);
14348
14349       var object = { 'a': { 'b': { 'c': alwaysThree } } };
14350
14351       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
14352         var method = _.method(path);
14353         assert.strictEqual(method(object), 3);
14354       });
14355     });
14356
14357     QUnit.test('should work with non-string `path` arguments', function(assert) {
14358       assert.expect(2);
14359
14360       var array = lodashStable.times(3, _.constant);
14361
14362       lodashStable.each([1, [1]], function(path) {
14363         var method = _.method(path);
14364         assert.strictEqual(method(array), 1);
14365       });
14366     });
14367
14368     QUnit.test('should coerce key to a string', function(assert) {
14369       assert.expect(1);
14370
14371       function fn() {}
14372       fn.toString = lodashStable.constant('fn');
14373
14374       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
14375           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
14376           values = [null, undefined, fn, {}];
14377
14378       var actual = lodashStable.transform(objects, function(result, object, index) {
14379         var key = values[index];
14380         lodashStable.each([key, [key]], function(path) {
14381           var method = _.method(key);
14382           result.push(method(object));
14383         });
14384       });
14385
14386       assert.deepEqual(actual, expected);
14387     });
14388
14389     QUnit.test('should work with inherited property values', function(assert) {
14390       assert.expect(2);
14391
14392       function Foo() {}
14393       Foo.prototype.a = alwaysOne;
14394
14395       lodashStable.each(['a', ['a']], function(path) {
14396         var method = _.method(path);
14397         assert.strictEqual(method(new Foo), 1);
14398       });
14399     });
14400
14401     QUnit.test('should use a key over a path', function(assert) {
14402       assert.expect(2);
14403
14404       var object = { 'a.b.c': alwaysThree, 'a': { 'b': { 'c': alwaysFour } } };
14405
14406       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
14407         var method = _.method(path);
14408         assert.strictEqual(method(object), 3);
14409       });
14410     });
14411
14412     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
14413       assert.expect(2);
14414
14415       var values = [, null, undefined],
14416           expected = lodashStable.map(values, alwaysUndefined);
14417
14418       lodashStable.each(['constructor', ['constructor']], function(path) {
14419         var method = _.method(path);
14420
14421         var actual = lodashStable.map(values, function(value, index) {
14422           return index ? method(value) : method();
14423         });
14424
14425         assert.deepEqual(actual, expected);
14426       });
14427     });
14428
14429     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
14430       assert.expect(2);
14431
14432       var values = [, null, undefined],
14433           expected = lodashStable.map(values, alwaysUndefined);
14434
14435       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
14436         var method = _.method(path);
14437
14438         var actual = lodashStable.map(values, function(value, index) {
14439           return index ? method(value) : method();
14440         });
14441
14442         assert.deepEqual(actual, expected);
14443       });
14444     });
14445
14446     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
14447       assert.expect(4);
14448
14449       var object = {};
14450
14451       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
14452         var method = _.method(path);
14453         assert.strictEqual(method(object), undefined);
14454       });
14455     });
14456
14457     QUnit.test('should apply partial arguments to function', function(assert) {
14458       assert.expect(2);
14459
14460       var object = {
14461         'fn': function() {
14462           return slice.call(arguments);
14463         }
14464       };
14465
14466       lodashStable.each(['fn', ['fn']], function(path) {
14467         var method = _.method(path, 1, 2, 3);
14468         assert.deepEqual(method(object), [1, 2, 3]);
14469       });
14470     });
14471
14472     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
14473       assert.expect(2);
14474
14475       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
14476
14477       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14478         var method = _.method(path);
14479         assert.strictEqual(method(object), 1);
14480       });
14481     });
14482   }());
14483
14484   /*--------------------------------------------------------------------------*/
14485
14486   QUnit.module('lodash.methodOf');
14487
14488   (function() {
14489     QUnit.test('should create a function that calls a method of a given key', function(assert) {
14490       assert.expect(4);
14491
14492       var object = { 'a': alwaysOne };
14493
14494       lodashStable.each(['a', ['a']], function(path) {
14495         var methodOf = _.methodOf(object);
14496         assert.strictEqual(methodOf.length, 1);
14497         assert.strictEqual(methodOf(path), 1);
14498       });
14499     });
14500
14501     QUnit.test('should work with deep property values', function(assert) {
14502       assert.expect(2);
14503
14504       var object = { 'a': { 'b': { 'c': alwaysThree } } };
14505
14506       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
14507         var methodOf = _.methodOf(object);
14508         assert.strictEqual(methodOf(path), 3);
14509       });
14510     });
14511
14512     QUnit.test('should work with non-string `path` arguments', function(assert) {
14513       assert.expect(2);
14514
14515       var array = lodashStable.times(3, _.constant);
14516
14517       lodashStable.each([1, [1]], function(path) {
14518         var methodOf = _.methodOf(array);
14519         assert.strictEqual(methodOf(path), 1);
14520       });
14521     });
14522
14523     QUnit.test('should coerce key to a string', function(assert) {
14524       assert.expect(1);
14525
14526       function fn() {}
14527       fn.toString = lodashStable.constant('fn');
14528
14529       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
14530           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
14531           values = [null, undefined, fn, {}];
14532
14533       var actual = lodashStable.transform(objects, function(result, object, index) {
14534         var key = values[index];
14535         lodashStable.each([key, [key]], function(path) {
14536           var methodOf = _.methodOf(object);
14537           result.push(methodOf(key));
14538         });
14539       });
14540
14541       assert.deepEqual(actual, expected);
14542     });
14543
14544     QUnit.test('should work with inherited property values', function(assert) {
14545       assert.expect(2);
14546
14547       function Foo() {}
14548       Foo.prototype.a = alwaysOne;
14549
14550       lodashStable.each(['a', ['a']], function(path) {
14551         var methodOf = _.methodOf(new Foo);
14552         assert.strictEqual(methodOf(path), 1);
14553       });
14554     });
14555
14556     QUnit.test('should use a key over a path', function(assert) {
14557       assert.expect(2);
14558
14559       var object = { 'a.b.c': alwaysThree, 'a': { 'b': { 'c': alwaysFour } } };
14560
14561       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
14562         var methodOf = _.methodOf(object);
14563         assert.strictEqual(methodOf(path), 3);
14564       });
14565     });
14566
14567     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
14568       assert.expect(2);
14569
14570       var values = [, null, undefined],
14571           expected = lodashStable.map(values, alwaysUndefined);
14572
14573       lodashStable.each(['constructor', ['constructor']], function(path) {
14574         var actual = lodashStable.map(values, function(value, index) {
14575           var methodOf = index ? _.methodOf() : _.methodOf(value);
14576           return methodOf(path);
14577         });
14578
14579         assert.deepEqual(actual, expected);
14580       });
14581     });
14582
14583     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
14584       assert.expect(2);
14585
14586       var values = [, null, undefined],
14587           expected = lodashStable.map(values, alwaysUndefined);
14588
14589       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
14590         var actual = lodashStable.map(values, function(value, index) {
14591           var methodOf = index ? _.methodOf() : _.methodOf(value);
14592           return methodOf(path);
14593         });
14594
14595         assert.deepEqual(actual, expected);
14596       });
14597     });
14598
14599     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
14600       assert.expect(4);
14601
14602       var object = {},
14603           methodOf = _.methodOf(object);
14604
14605       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
14606         assert.strictEqual(methodOf(path), undefined);
14607       });
14608     });
14609
14610     QUnit.test('should apply partial arguments to function', function(assert) {
14611       assert.expect(2);
14612
14613       var object = {
14614         'fn': function() {
14615           return slice.call(arguments);
14616         }
14617       };
14618
14619       var methodOf = _.methodOf(object, 1, 2, 3);
14620
14621       lodashStable.each(['fn', ['fn']], function(path) {
14622         assert.deepEqual(methodOf(path), [1, 2, 3]);
14623       });
14624     });
14625
14626     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
14627       assert.expect(2);
14628
14629       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
14630           methodOf = _.methodOf(object);
14631
14632       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14633         assert.strictEqual(methodOf(path), 1);
14634       });
14635     });
14636   }());
14637
14638   /*--------------------------------------------------------------------------*/
14639
14640   QUnit.module('lodash.min');
14641
14642   (function() {
14643     QUnit.test('should return the smallest value from a collection', function(assert) {
14644       assert.expect(1);
14645
14646       assert.strictEqual(_.min([1, 2, 3]), 1);
14647     });
14648
14649     QUnit.test('should return `undefined` for empty collections', function(assert) {
14650       assert.expect(1);
14651
14652       var values = falsey.concat([[]]),
14653           expected = lodashStable.map(values, alwaysUndefined);
14654
14655       var actual = lodashStable.map(values, function(value, index) {
14656         try {
14657           return index ? _.min(value) : _.min();
14658         } catch (e) {}
14659       });
14660
14661       assert.deepEqual(actual, expected);
14662     });
14663
14664     QUnit.test('should work with non-numeric collection values', function(assert) {
14665       assert.expect(1);
14666
14667       assert.strictEqual(_.min(['a', 'b']), 'a');
14668     });
14669   }());
14670
14671   /*--------------------------------------------------------------------------*/
14672
14673   QUnit.module('extremum methods');
14674
14675   lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
14676     var array = [1, 2, 3],
14677         func = _[methodName],
14678         isMax = /^max/.test(methodName);
14679
14680     QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
14681       assert.expect(1);
14682
14683       var curr = new Date,
14684           past = new Date(0);
14685
14686       assert.strictEqual(func([curr, past]), isMax ? curr : past);
14687     });
14688
14689     QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
14690       assert.expect(1);
14691
14692       var array = lodashStable.range(0, 5e5);
14693       assert.strictEqual(func(array), isMax ? 499999 : 0);
14694     });
14695
14696     QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
14697       assert.expect(1);
14698
14699       if (!isNpm) {
14700         var actual = _([40])[methodName]();
14701         assert.strictEqual(actual, 40);
14702       }
14703       else {
14704         skipAssert(assert);
14705       }
14706     });
14707   });
14708
14709   lodashStable.each(['maxBy', 'minBy'], function(methodName) {
14710     var array = [1, 2, 3],
14711         func = _[methodName],
14712         isMax = methodName == 'maxBy';
14713
14714     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
14715       assert.expect(1);
14716
14717       var actual = func(array, function(n) {
14718         return -n;
14719       });
14720
14721       assert.strictEqual(actual, isMax ? 1 : 3);
14722     });
14723
14724     QUnit.test('should work with "_.property" shorthands', function(assert) {
14725       assert.expect(2);
14726
14727       var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
14728           actual = func(objects, 'a');
14729
14730       assert.deepEqual(actual, objects[isMax ? 1 : 2]);
14731
14732       var arrays = [[2], [3], [1]];
14733       actual = func(arrays, 0);
14734
14735       assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
14736     });
14737
14738     QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
14739       assert.expect(1);
14740
14741       var value = isMax ? -Infinity : Infinity,
14742           object = { 'a': value };
14743
14744       var actual = func([object, { 'a': value }], function(object) {
14745         return object.a;
14746       });
14747
14748       assert.strictEqual(actual, object);
14749     });
14750   });
14751
14752   /*--------------------------------------------------------------------------*/
14753
14754   QUnit.module('lodash.mixin');
14755
14756   (function() {
14757     function Wrapper(value) {
14758       if (!(this instanceof Wrapper)) {
14759         return new Wrapper(value);
14760       }
14761       if (_.has(value, '__wrapped__')) {
14762         var actions = slice.call(value.__actions__),
14763             chain = value.__chain__;
14764
14765         value = value.__wrapped__;
14766       }
14767       this.__wrapped__ = value;
14768       this.__actions__ = actions || [];
14769       this.__chain__ = chain || false;
14770     }
14771
14772     Wrapper.prototype.value = function() {
14773       return getUnwrappedValue(this);
14774     };
14775
14776     var array = ['a'],
14777         source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
14778
14779     QUnit.test('should mixin `source` methods into lodash', function(assert) {
14780       assert.expect(4);
14781
14782       if (!isNpm) {
14783         _.mixin(source);
14784
14785         assert.strictEqual(_.a(array), 'a');
14786         assert.strictEqual(_(array).a().value(), 'a');
14787
14788         delete _.a;
14789         delete _.prototype.a;
14790
14791         assert.notOk('b' in _);
14792         assert.notOk('b' in _.prototype);
14793
14794         delete _.b;
14795         delete _.prototype.b;
14796       }
14797       else {
14798         skipAssert(assert, 4);
14799       }
14800     });
14801
14802     QUnit.test('should mixin chaining methods by reference', function(assert) {
14803       assert.expect(2);
14804
14805       if (!isNpm) {
14806         _.mixin(source);
14807         _.a = alwaysB;
14808
14809         assert.strictEqual(_.a(array), 'b');
14810         assert.strictEqual(_(array).a().value(), 'a');
14811
14812         delete _.a;
14813         delete _.prototype.a;
14814       }
14815       else {
14816         skipAssert(assert, 2);
14817       }
14818     });
14819
14820     QUnit.test('should use a default `object` of `this`', function(assert) {
14821       assert.expect(3);
14822
14823       var object = lodashStable.create(_);
14824       object.mixin(source);
14825
14826       assert.strictEqual(object.a(array), 'a');
14827
14828       assert.notOk('a' in _);
14829       assert.notOk('a' in _.prototype);
14830
14831       delete Wrapper.a;
14832       delete Wrapper.prototype.a;
14833       delete Wrapper.b;
14834       delete Wrapper.prototype.b;
14835     });
14836
14837     QUnit.test('should accept an `object` argument', function(assert) {
14838       assert.expect(1);
14839
14840       var object = {};
14841       _.mixin(object, source);
14842       assert.strictEqual(object.a(array), 'a');
14843     });
14844
14845     QUnit.test('should return `object`', function(assert) {
14846       assert.expect(2);
14847
14848       var object = {};
14849       assert.strictEqual(_.mixin(object, source), object);
14850       assert.strictEqual(_.mixin(), _);
14851     });
14852
14853     QUnit.test('should work with a function for `object`', function(assert) {
14854       assert.expect(2);
14855
14856       _.mixin(Wrapper, source);
14857
14858       var wrapped = Wrapper(array),
14859           actual = wrapped.a();
14860
14861       assert.strictEqual(actual.value(), 'a');
14862       assert.ok(actual instanceof Wrapper);
14863
14864       delete Wrapper.a;
14865       delete Wrapper.prototype.a;
14866       delete Wrapper.b;
14867       delete Wrapper.prototype.b;
14868     });
14869
14870     QUnit.test('should not assign inherited `source` methods', function(assert) {
14871       assert.expect(1);
14872
14873       function Foo() {}
14874       Foo.prototype.a = noop;
14875
14876       var object = {};
14877       assert.strictEqual(_.mixin(object, new Foo), object);
14878     });
14879
14880     QUnit.test('should accept an `options` argument', function(assert) {
14881       assert.expect(8);
14882
14883       function message(func, chain) {
14884         return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
14885       }
14886
14887       lodashStable.each([_, Wrapper], function(func) {
14888         lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
14889           if (!isNpm) {
14890             if (func === _) {
14891               _.mixin(source, options);
14892             } else {
14893               _.mixin(func, source, options);
14894             }
14895             var wrapped = func(array),
14896                 actual = wrapped.a();
14897
14898             if (options.chain) {
14899               assert.strictEqual(actual.value(), 'a', message(func, true));
14900               assert.ok(actual instanceof func, message(func, true));
14901             } else {
14902               assert.strictEqual(actual, 'a', message(func, false));
14903               assert.notOk(actual instanceof func, message(func, false));
14904             }
14905             delete func.a;
14906             delete func.prototype.a;
14907             delete func.b;
14908             delete func.prototype.b;
14909           }
14910           else {
14911             skipAssert(assert, 2);
14912           }
14913         });
14914       });
14915     });
14916
14917     QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
14918       assert.expect(1);
14919
14920       _.mixin({ 'a': noop }, {});
14921       assert.notOk('a' in _);
14922       delete _.a;
14923     });
14924
14925     QUnit.test('should not error for non-object `options` values', function(assert) {
14926       assert.expect(2);
14927
14928       var pass = true;
14929
14930       try {
14931         _.mixin({}, source, 1);
14932       } catch (e) {
14933         pass = false;
14934       }
14935       assert.ok(pass);
14936
14937       pass = true;
14938
14939       try {
14940         _.mixin(source, 1);
14941       } catch (e) {
14942         pass = false;
14943       }
14944       delete _.a;
14945       delete _.prototype.a;
14946       delete _.b;
14947       delete _.prototype.b;
14948
14949       assert.ok(pass);
14950     });
14951
14952     QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
14953       assert.expect(2);
14954
14955       lodashStable.each([_, Wrapper], function(func) {
14956         if (!isNpm) {
14957           if (func === _) {
14958             var wrapped = _(source),
14959                 actual = wrapped.mixin();
14960
14961             assert.strictEqual(actual.value(), _);
14962           }
14963           else {
14964             wrapped = _(func);
14965             actual = wrapped.mixin(source);
14966             assert.notStrictEqual(actual, wrapped);
14967           }
14968           delete func.a;
14969           delete func.prototype.a;
14970           delete func.b;
14971           delete func.prototype.b;
14972         }
14973         else {
14974           skipAssert(assert);
14975         }
14976       });
14977     });
14978
14979     QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
14980       assert.expect(1);
14981
14982       if (!isNpm) {
14983         _.mixin({ 'a': _.countBy, 'b': _.filter });
14984
14985         var array = lodashStable.range(LARGE_ARRAY_SIZE),
14986             actual = _(array).a().map(square).b(isEven).take().value();
14987
14988         assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
14989
14990         delete _.a;
14991         delete _.prototype.a;
14992         delete _.b;
14993         delete _.prototype.b;
14994       }
14995       else {
14996         skipAssert(assert);
14997       }
14998     });
14999   }());
15000
15001   /*--------------------------------------------------------------------------*/
15002
15003   QUnit.module('lodash.orderBy');
15004
15005   (function() {
15006     var objects = [
15007       { 'a': 'x', 'b': 3 },
15008       { 'a': 'y', 'b': 4 },
15009       { 'a': 'x', 'b': 1 },
15010       { 'a': 'y', 'b': 2 }
15011     ];
15012
15013     QUnit.test('should sort by a single property by a specified order', function(assert) {
15014       assert.expect(1);
15015
15016       var actual = _.orderBy(objects, 'a', 'desc');
15017       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15018     });
15019
15020     QUnit.test('should sort by multiple properties by specified orders', function(assert) {
15021       assert.expect(1);
15022
15023       var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
15024       assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
15025     });
15026
15027     QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
15028       assert.expect(2);
15029
15030       var expected = [objects[2], objects[0], objects[3], objects[1]],
15031           actual = _.orderBy(objects, ['a', 'b']);
15032
15033       assert.deepEqual(actual, expected);
15034
15035       expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
15036
15037       actual = lodashStable.map(falsey, function(order, index) {
15038         return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
15039       });
15040
15041       assert.deepEqual(actual, expected);
15042     });
15043
15044     QUnit.test('should work with `orders` specified as string objects', function(assert) {
15045       assert.expect(1);
15046
15047       var actual = _.orderBy(objects, ['a'], [Object('desc')]);
15048       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15049     });
15050   }());
15051
15052   /*--------------------------------------------------------------------------*/
15053
15054   QUnit.module('lodash.overArgs');
15055
15056   (function() {
15057     function fn() {
15058       return slice.call(arguments);
15059     }
15060
15061     QUnit.test('should transform each argument', function(assert) {
15062       assert.expect(1);
15063
15064       var over = _.overArgs(fn, doubled, square);
15065       assert.deepEqual(over(5, 10), [10, 100]);
15066     });
15067
15068     QUnit.test('should flatten `transforms`', function(assert) {
15069       assert.expect(1);
15070
15071       var over = _.overArgs(fn, [doubled, square], String);
15072       assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
15073     });
15074
15075     QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
15076       assert.expect(1);
15077
15078       var over = _.overArgs(fn, doubled, square);
15079       assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
15080     });
15081
15082     QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
15083       assert.expect(1);
15084
15085       var over = _.overArgs(fn);
15086       assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
15087     });
15088
15089     QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
15090       assert.expect(1);
15091
15092       var over = _.overArgs(fn, doubled, identity);
15093       assert.deepEqual(over(5), [10]);
15094     });
15095
15096     QUnit.test('should provide the correct argument to each transform', function(assert) {
15097       assert.expect(1);
15098
15099       var argsList = [],
15100           transform = function() { argsList.push(slice.call(arguments)); },
15101           over = _.overArgs(noop, transform, transform, transform);
15102
15103       over('a', 'b');
15104       assert.deepEqual(argsList, [['a'], ['b']]);
15105     });
15106
15107     QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
15108       assert.expect(1);
15109
15110       var over = _.overArgs(function(x) {
15111         return this[x];
15112       }, function(x) {
15113         return this === x;
15114       });
15115
15116       var object = { 'over': over, 'true': 1 };
15117       assert.strictEqual(object.over(object), 1);
15118     });
15119   }());
15120
15121   /*--------------------------------------------------------------------------*/
15122
15123   QUnit.module('lodash.negate');
15124
15125   (function() {
15126     QUnit.test('should create a function that negates the result of `func`', function(assert) {
15127       assert.expect(2);
15128
15129       var negate = _.negate(isEven);
15130
15131       assert.strictEqual(negate(1), true);
15132       assert.strictEqual(negate(2), false);
15133     });
15134   }());
15135
15136   /*--------------------------------------------------------------------------*/
15137
15138   QUnit.module('lodash.noop');
15139
15140   (function() {
15141     QUnit.test('should return `undefined`', function(assert) {
15142       assert.expect(1);
15143
15144       var values = empties.concat(true, new Date, _, 1, /x/, 'a'),
15145           expected = lodashStable.map(values, alwaysUndefined);
15146
15147       var actual = lodashStable.map(values, function(value, index) {
15148         return index ? _.noop(value) : _.noop();
15149       });
15150
15151       assert.deepEqual(actual, expected);
15152     });
15153   }());
15154
15155   /*--------------------------------------------------------------------------*/
15156
15157   QUnit.module('lodash.noConflict');
15158
15159   (function() {
15160     QUnit.test('should return the `lodash` function', function(assert) {
15161       assert.expect(2);
15162
15163       if (!isModularize) {
15164         assert.strictEqual(_.noConflict(), oldDash);
15165         assert.notStrictEqual(root._, oldDash);
15166         root._ = oldDash;
15167       }
15168       else {
15169         skipAssert(assert, 2);
15170       }
15171     });
15172
15173     QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
15174       assert.expect(2);
15175
15176       if (!isModularize) {
15177         var object = root._ = {};
15178         assert.strictEqual(_.noConflict(), oldDash);
15179         assert.strictEqual(root._, object);
15180         root._ = oldDash;
15181       }
15182       else {
15183         skipAssert(assert, 2);
15184       }
15185     });
15186
15187     QUnit.test('should work with a `root` of `this`', function(assert) {
15188       assert.expect(2);
15189
15190       if (!isModularize && !coverage && (!document && realm.object)) {
15191         var fs = require('fs'),
15192             vm = require('vm'),
15193             expected = {},
15194             context = vm.createContext({ '_': expected, 'console': console }),
15195             source = fs.readFileSync(filePath, 'utf8');
15196
15197         vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
15198
15199         assert.strictEqual(context._, expected);
15200         assert.ok(context.lodash);
15201       }
15202       else {
15203         skipAssert(assert, 2);
15204       }
15205     });
15206   }());
15207
15208   /*--------------------------------------------------------------------------*/
15209
15210   QUnit.module('lodash.now');
15211
15212   (function() {
15213     QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
15214       assert.expect(2);
15215
15216       var done = assert.async();
15217
15218       var stamp = +new Date,
15219           actual = _.now();
15220
15221       assert.ok(actual >= stamp);
15222
15223       setTimeout(function() {
15224         assert.ok(_.now() > actual);
15225         done();
15226       }, 32);
15227     });
15228   }());
15229
15230   /*--------------------------------------------------------------------------*/
15231
15232   QUnit.module('lodash.nthArg');
15233
15234   (function() {
15235     QUnit.test('should create a function that returns its nth argument', function(assert) {
15236       assert.expect(1);
15237
15238       var expected = ['a', 'b', 'c'];
15239
15240       var actual = lodashStable.times(expected.length, function(n) {
15241         var func = _.nthArg(n);
15242         return func.apply(undefined, expected);
15243       });
15244
15245       assert.deepEqual(actual, expected);
15246     });
15247
15248     QUnit.test('should coerce `n` to an integer', function(assert) {
15249       assert.expect(2);
15250
15251       var values = falsey,
15252           expected = lodashStable.map(values, alwaysA);
15253
15254       var actual = lodashStable.map(values, function(n) {
15255         var func = n ? _.nthArg(n) : _.nthArg();
15256         return func('a', 'b', 'c');
15257       });
15258
15259       assert.deepEqual(actual, expected);
15260
15261       values = ['1', 1.6];
15262       expected = lodashStable.map(values, alwaysB);
15263
15264       actual = lodashStable.map(values, function(n) {
15265         var func = _.nthArg(n);
15266         return func('a', 'b', 'c');
15267       });
15268
15269       assert.deepEqual(actual, expected);
15270     });
15271   }());
15272
15273   /*--------------------------------------------------------------------------*/
15274
15275   QUnit.module('lodash.omit');
15276
15277   (function() {
15278     var args = arguments,
15279         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
15280
15281     QUnit.test('should flatten `props`', function(assert) {
15282       assert.expect(2);
15283
15284       assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
15285       assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
15286     });
15287
15288     QUnit.test('should work with a primitive `object` argument', function(assert) {
15289       assert.expect(1);
15290
15291       stringProto.a = 1;
15292       stringProto.b = 2;
15293
15294       assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
15295
15296       delete stringProto.a;
15297       delete stringProto.b;
15298     });
15299
15300     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
15301       assert.expect(2);
15302
15303       objectProto.a = 1;
15304       lodashStable.each([null, undefined], function(value) {
15305         assert.deepEqual(_.omit(value, 'valueOf'), {});
15306       });
15307       delete objectProto.a;
15308     });
15309
15310     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
15311       assert.expect(1);
15312
15313       assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
15314     });
15315
15316     QUnit.test('should coerce property names to strings', function(assert) {
15317       assert.expect(1);
15318
15319       assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
15320     });
15321   }('a', 'c'));
15322
15323   /*--------------------------------------------------------------------------*/
15324
15325   QUnit.module('lodash.omitBy');
15326
15327   (function() {
15328     QUnit.test('should work with a predicate argument', function(assert) {
15329       assert.expect(1);
15330
15331       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
15332
15333       var actual = _.omitBy(object, function(n) {
15334         return n != 2 && n != 4;
15335       });
15336
15337       assert.deepEqual(actual, { 'b': 2, 'd': 4 });
15338     });
15339   }());
15340
15341   /*--------------------------------------------------------------------------*/
15342
15343   QUnit.module('omit methods');
15344
15345   lodashStable.each(['omit', 'omitBy'], function(methodName) {
15346     var expected = { 'b': 2, 'd': 4 },
15347         func = _[methodName],
15348         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
15349         prop = function(object, props) { return props; };
15350
15351     if (methodName == 'omitBy') {
15352       prop = function(object, props) {
15353         props = typeof props == 'string' ? [props] : props;
15354         return function(value) {
15355           return _.some(props, function(key) { return object[key] === value; });
15356         };
15357       };
15358     }
15359     QUnit.test('`_.' + methodName + '` should create an object with omitted properties', function(assert) {
15360       assert.expect(2);
15361
15362       assert.deepEqual(func(object, prop(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
15363       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
15364     });
15365
15366     QUnit.test('`_.' + methodName + '` should iterate over inherited properties', function(assert) {
15367       assert.expect(1);
15368
15369       function Foo() {}
15370       Foo.prototype = object;
15371
15372       var foo = new Foo;
15373       assert.deepEqual(func(foo, prop(object, ['a', 'c'])), expected);
15374     });
15375
15376     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
15377       assert.expect(1);
15378
15379       var array = [1, 2, 3];
15380       assert.deepEqual(func(array, prop(array, ['0', '2'])), { '1': 2 });
15381     });
15382   });
15383
15384   /*--------------------------------------------------------------------------*/
15385
15386   QUnit.module('lodash.once');
15387
15388   (function() {
15389     QUnit.test('should invoke `func` once', function(assert) {
15390       assert.expect(2);
15391
15392       var count = 0,
15393           once = _.once(function() { return ++count; });
15394
15395       once();
15396       assert.strictEqual(once(), 1);
15397       assert.strictEqual(count, 1);
15398     });
15399
15400     QUnit.test('should ignore recursive calls', function(assert) {
15401       assert.expect(2);
15402
15403       var count = 0;
15404
15405       var once = _.once(function() {
15406         once();
15407         return ++count;
15408       });
15409
15410       assert.strictEqual(once(), 1);
15411       assert.strictEqual(count, 1);
15412     });
15413
15414     QUnit.test('should not throw more than once', function(assert) {
15415       assert.expect(2);
15416
15417       var pass = true;
15418
15419       var once = _.once(function() {
15420         throw new Error;
15421       });
15422
15423       assert.raises(once);
15424
15425       try {
15426         once();
15427       } catch (e) {
15428         pass = false;
15429       }
15430       assert.ok(pass);
15431     });
15432   }());
15433
15434   /*--------------------------------------------------------------------------*/
15435
15436   QUnit.module('lodash.over');
15437
15438   (function() {
15439     QUnit.test('should create a function that invokes `iteratees`', function(assert) {
15440       assert.expect(1);
15441
15442       var over = _.over(Math.max, Math.min);
15443       assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
15444     });
15445
15446     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
15447       assert.expect(1);
15448
15449       var over = _.over(undefined, null);
15450       assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
15451     });
15452
15453     QUnit.test('should work with "_.property" shorthands', function(assert) {
15454       assert.expect(1);
15455
15456       var object = { 'a': 1, 'b': 2 },
15457           over = _.over('b', 'a');
15458
15459       assert.deepEqual(over(object), [2, 1]);
15460     });
15461
15462     QUnit.test('should work with "_.matches" shorthands', function(assert) {
15463       assert.expect(1);
15464
15465       var object = { 'a': 1, 'b': 2 },
15466           over = _.over({ 'c': 3 }, { 'a': 1 });
15467
15468       assert.deepEqual(over(object), [false, true]);
15469     });
15470
15471     QUnit.test('should provide arguments to predicates', function(assert) {
15472       assert.expect(1);
15473
15474       var over = _.over(function() {
15475         return slice.call(arguments);
15476       });
15477
15478       assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
15479     });
15480
15481     QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
15482       assert.expect(1);
15483
15484       var over = _.over(function() { return this.b; }, function() { return this.a; }),
15485           object = { 'over': over, 'a': 1, 'b': 2 };
15486
15487       assert.deepEqual(object.over(), [2, 1]);
15488     });
15489   }());
15490
15491   /*--------------------------------------------------------------------------*/
15492
15493   QUnit.module('lodash.overEvery');
15494
15495   (function() {
15496     QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
15497       assert.expect(1);
15498
15499       var over = _.overEvery(alwaysTrue, alwaysOne, alwaysA);
15500       assert.strictEqual(over(), true);
15501     });
15502
15503     QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
15504       assert.expect(2);
15505
15506       var count = 0,
15507           countFalse = function() { count++; return false; },
15508           countTrue = function() { count++; return true; },
15509           over = _.overEvery(countTrue, countFalse, countTrue);
15510
15511       assert.strictEqual(over(), false);
15512       assert.strictEqual(count, 2);
15513     });
15514
15515     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
15516       assert.expect(2);
15517
15518       var over = _.overEvery(undefined, null);
15519       assert.strictEqual(over(true), true);
15520       assert.strictEqual(over(false), false);
15521     });
15522
15523     QUnit.test('should work with "_.property" shorthands', function(assert) {
15524       assert.expect(2);
15525
15526       var object = { 'a': 1, 'b': 2 },
15527           over = _.overEvery('a', 'c');
15528
15529       assert.strictEqual(over(object), false);
15530
15531       over = _.overEvery('b', 'a');
15532       assert.strictEqual(over(object), true);
15533     });
15534
15535     QUnit.test('should work with "_.matches" shorthands', function(assert) {
15536       assert.expect(2);
15537
15538       var object = { 'a': 1, 'b': 2 },
15539           over = _.overEvery({ 'b': 2 }, { 'a': 1 });
15540
15541       assert.strictEqual(over(object), true);
15542
15543       over = _.overEvery({ 'a': 1 }, { 'c': 3 });
15544       assert.strictEqual(over(object), false);
15545     });
15546
15547     QUnit.test('should flatten `predicates`', function(assert) {
15548       assert.expect(1);
15549
15550       var over = _.overEvery(alwaysTrue, [alwaysFalse]);
15551       assert.strictEqual(over(), false);
15552     });
15553
15554     QUnit.test('should provide arguments to predicates', function(assert) {
15555       assert.expect(1);
15556
15557       var args;
15558
15559       var over = _.overEvery(function() {
15560         args = slice.call(arguments);
15561       });
15562
15563       over('a', 'b', 'c');
15564       assert.deepEqual(args, ['a', 'b', 'c']);
15565     });
15566
15567     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
15568       assert.expect(2);
15569
15570       var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
15571           object = { 'over': over, 'a': 1, 'b': 2 };
15572
15573       assert.strictEqual(object.over(), true);
15574
15575       object.a = 0;
15576       assert.strictEqual(object.over(), false);
15577     });
15578   }());
15579
15580   /*--------------------------------------------------------------------------*/
15581
15582   QUnit.module('lodash.overSome');
15583
15584   (function() {
15585     QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
15586       assert.expect(2);
15587
15588       var over = _.overSome(alwaysFalse, alwaysOne, alwaysEmptyString);
15589       assert.strictEqual(over(), true);
15590
15591       over = _.overSome(alwaysNull, alwaysA, alwaysZero);
15592       assert.strictEqual(over(), true);
15593     });
15594
15595     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
15596       assert.expect(2);
15597
15598       var count = 0,
15599           countFalse = function() { count++; return false; },
15600           countTrue = function() { count++; return true; },
15601           over = _.overSome(countFalse, countTrue, countFalse);
15602
15603       assert.strictEqual(over(), true);
15604       assert.strictEqual(count, 2);
15605     });
15606
15607     QUnit.test('should return `false` if all predicates return falsey', function(assert) {
15608       assert.expect(2);
15609
15610       var over = _.overSome(alwaysFalse, alwaysFalse, alwaysFalse);
15611       assert.strictEqual(over(), false);
15612
15613       over = _.overSome(alwaysNull, alwaysZero, alwaysEmptyString);
15614       assert.strictEqual(over(), false);
15615     });
15616
15617     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
15618       assert.expect(2);
15619
15620       var over = _.overSome(undefined, null);
15621       assert.strictEqual(over(true), true);
15622       assert.strictEqual(over(false), false);
15623     });
15624
15625     QUnit.test('should work with "_.property" shorthands', function(assert) {
15626       assert.expect(2);
15627
15628       var object = { 'a': 1, 'b': 2 },
15629           over = _.overSome('c', 'a');
15630
15631       assert.strictEqual(over(object), true);
15632
15633       over = _.overSome('d', 'c');
15634       assert.strictEqual(over(object), false);
15635     });
15636
15637     QUnit.test('should work with "_.matches" shorthands', function(assert) {
15638       assert.expect(2);
15639
15640       var object = { 'a': 1, 'b': 2 },
15641           over = _.overSome({ 'c': 3 }, { 'a': 1 });
15642
15643       assert.strictEqual(over(object), true);
15644
15645       over = _.overSome({ 'b': 1 }, { 'a': 2 });
15646       assert.strictEqual(over(object), false);
15647     });
15648
15649     QUnit.test('should flatten `predicates`', function(assert) {
15650       assert.expect(1);
15651
15652       var over = _.overSome(alwaysFalse, [alwaysTrue]);
15653       assert.strictEqual(over(), true);
15654     });
15655
15656     QUnit.test('should provide arguments to predicates', function(assert) {
15657       assert.expect(1);
15658
15659       var args;
15660
15661       var over = _.overSome(function() {
15662         args = slice.call(arguments);
15663       });
15664
15665       over('a', 'b', 'c');
15666       assert.deepEqual(args, ['a', 'b', 'c']);
15667     });
15668
15669     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
15670       assert.expect(2);
15671
15672       var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
15673           object = { 'over': over, 'a': 1, 'b': 2 };
15674
15675       assert.strictEqual(object.over(), true);
15676
15677       object.a = object.b = 0;
15678       assert.strictEqual(object.over(), false);
15679     });
15680   }());
15681
15682   /*--------------------------------------------------------------------------*/
15683
15684   QUnit.module('lodash.pad');
15685
15686   (function() {
15687     QUnit.test('should pad a string to a given length', function(assert) {
15688       assert.expect(1);
15689
15690       assert.strictEqual(_.pad('abc', 9), '   abc   ');
15691     });
15692
15693     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
15694       assert.expect(2);
15695
15696       assert.strictEqual(_.pad('abc', 8), '  abc   ');
15697       assert.strictEqual(_.pad('abc', 8, '_-'), '_-abc_-_');
15698     });
15699
15700     QUnit.test('should coerce `string` to a string', function(assert) {
15701       assert.expect(2);
15702
15703       assert.strictEqual(_.pad(Object('abc'), 4), 'abc ');
15704       assert.strictEqual(_.pad({ 'toString': lodashStable.constant('abc') }, 5), ' abc ');
15705     });
15706   }());
15707
15708   /*--------------------------------------------------------------------------*/
15709
15710   QUnit.module('lodash.padEnd');
15711
15712   (function() {
15713     QUnit.test('should pad a string to a given length', function(assert) {
15714       assert.expect(1);
15715
15716       assert.strictEqual(_.padEnd('abc', 6), 'abc   ');
15717     });
15718
15719     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
15720       assert.expect(1);
15721
15722       assert.strictEqual(_.padEnd('abc', 6, '_-'), 'abc_-_');
15723     });
15724
15725     QUnit.test('should coerce `string` to a string', function(assert) {
15726       assert.expect(2);
15727
15728       assert.strictEqual(_.padEnd(Object('abc'), 4), 'abc ');
15729       assert.strictEqual(_.padEnd({ 'toString': lodashStable.constant('abc') }, 5), 'abc  ');
15730     });
15731   }());
15732
15733   /*--------------------------------------------------------------------------*/
15734
15735   QUnit.module('lodash.padStart');
15736
15737   (function() {
15738     QUnit.test('should pad a string to a given length', function(assert) {
15739       assert.expect(1);
15740
15741       assert.strictEqual(_.padStart('abc', 6), '   abc');
15742     });
15743
15744     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
15745       assert.expect(1);
15746
15747       assert.strictEqual(_.padStart('abc', 6, '_-'), '_-_abc');
15748     });
15749
15750     QUnit.test('should coerce `string` to a string', function(assert) {
15751       assert.expect(2);
15752
15753       assert.strictEqual(_.padStart(Object('abc'), 4), ' abc');
15754       assert.strictEqual(_.padStart({ 'toString': lodashStable.constant('abc') }, 5), '  abc');
15755     });
15756   }());
15757
15758   /*--------------------------------------------------------------------------*/
15759
15760   QUnit.module('pad methods');
15761
15762   lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
15763     var func = _[methodName],
15764         isPad = methodName == 'pad',
15765         isStart = methodName == 'padStart';
15766
15767     QUnit.test('`_.' + methodName + '` should not pad is string is >= `length`', function(assert) {
15768       assert.expect(2);
15769
15770       assert.strictEqual(func('abc', 2), 'abc');
15771       assert.strictEqual(func('abc', 3), 'abc');
15772     });
15773
15774     QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
15775       assert.expect(2);
15776
15777       lodashStable.each([0, -2], function(length) {
15778         assert.strictEqual(func('abc', length), 'abc');
15779       });
15780     });
15781
15782     QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
15783       assert.expect(2);
15784
15785       lodashStable.each(['', '4'], function(length) {
15786         var actual = length ? (isStart ? ' abc' : 'abc ') : 'abc';
15787         assert.strictEqual(func('abc', length), actual);
15788       });
15789     });
15790
15791     QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
15792       assert.expect(6);
15793
15794       lodashStable.each([undefined, '_-'], function(chars) {
15795         var expected = chars ? (isPad ? '__' : chars) : '  ';
15796         assert.strictEqual(func(null, 2, chars), expected);
15797         assert.strictEqual(func(undefined, 2, chars), expected);
15798         assert.strictEqual(func('', 2, chars), expected);
15799       });
15800     });
15801
15802     QUnit.test('`_.' + methodName + '` should work with nullish or empty string values for `chars`', function(assert) {
15803       assert.expect(3);
15804
15805       assert.notStrictEqual(func('abc', 6, null), 'abc');
15806       assert.notStrictEqual(func('abc', 6, undefined), 'abc');
15807       assert.strictEqual(func('abc', 6, ''), 'abc');
15808     });
15809   });
15810
15811   /*--------------------------------------------------------------------------*/
15812
15813   QUnit.module('lodash.parseInt');
15814
15815   (function() {
15816     QUnit.test('should accept a `radix` argument', function(assert) {
15817       assert.expect(1);
15818
15819       var expected = lodashStable.range(2, 37);
15820
15821       var actual = lodashStable.map(expected, function(radix) {
15822         return _.parseInt('10', radix);
15823       });
15824
15825       assert.deepEqual(actual, expected);
15826     });
15827
15828     QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
15829       assert.expect(4);
15830
15831       assert.strictEqual(_.parseInt('10'), 10);
15832       assert.strictEqual(_.parseInt('10', 0), 10);
15833       assert.strictEqual(_.parseInt('10', 10), 10);
15834       assert.strictEqual(_.parseInt('10', undefined), 10);
15835     });
15836
15837     QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
15838       assert.expect(8);
15839
15840       lodashStable.each(['0x20', '0X20'], function(string) {
15841         assert.strictEqual(_.parseInt(string), 32);
15842         assert.strictEqual(_.parseInt(string, 0), 32);
15843         assert.strictEqual(_.parseInt(string, 16), 32);
15844         assert.strictEqual(_.parseInt(string, undefined), 32);
15845       });
15846     });
15847
15848     QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
15849       assert.expect(2);
15850
15851       assert.strictEqual(_.parseInt('08'), 8);
15852       assert.strictEqual(_.parseInt('08', 10), 8);
15853     });
15854
15855     QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
15856       assert.expect(2);
15857
15858       var expected = [8, 8, 10, 10, 32, 32, 32, 32];
15859
15860       lodashStable.times(2, function(index) {
15861         var actual = [],
15862             func = (index ? (lodashBizarro || {}) : _).parseInt;
15863
15864         if (func) {
15865           lodashStable.times(2, function(otherIndex) {
15866             var string = otherIndex ? '10' : '08';
15867             actual.push(
15868               func(whitespace + string, 10),
15869               func(whitespace + string)
15870             );
15871           });
15872
15873           lodashStable.each(['0x20', '0X20'], function(string) {
15874             actual.push(
15875               func(whitespace + string),
15876               func(whitespace + string, 16)
15877             );
15878           });
15879
15880           assert.deepEqual(actual, expected);
15881         }
15882         else {
15883           skipAssert(assert);
15884         }
15885       });
15886     });
15887
15888     QUnit.test('should coerce `radix` to a number', function(assert) {
15889       assert.expect(2);
15890
15891       var object = { 'valueOf': alwaysZero };
15892       assert.strictEqual(_.parseInt('08', object), 8);
15893       assert.strictEqual(_.parseInt('0x20', object), 32);
15894     });
15895
15896     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
15897       assert.expect(2);
15898
15899       var strings = lodashStable.map(['6', '08', '10'], Object),
15900           actual = lodashStable.map(strings, _.parseInt);
15901
15902       assert.deepEqual(actual, [6, 8, 10]);
15903
15904       actual = lodashStable.map('123', _.parseInt);
15905       assert.deepEqual(actual, [1, 2, 3]);
15906     });
15907   }());
15908
15909   /*--------------------------------------------------------------------------*/
15910
15911   QUnit.module('partial methods');
15912
15913   lodashStable.each(['partial', 'partialRight'], function(methodName) {
15914     var func = _[methodName],
15915         isPartial = methodName == 'partial',
15916         ph = func.placeholder;
15917
15918     QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
15919       assert.expect(1);
15920
15921       var par = func(identity, 'a');
15922       assert.strictEqual(par(), 'a');
15923     });
15924
15925     QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
15926       assert.expect(1);
15927
15928       var fn = function(a, b) { return [a, b]; },
15929           par = func(fn, 'a'),
15930           expected = isPartial ? ['a', 'b'] : ['b', 'a'];
15931
15932       assert.deepEqual(par('b'), expected);
15933     });
15934
15935     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
15936       assert.expect(1);
15937
15938       var fn = function() { return arguments.length; },
15939           par = func(fn);
15940
15941       assert.strictEqual(par(), 0);
15942     });
15943
15944     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
15945       assert.expect(1);
15946
15947       var par = func(identity);
15948       assert.strictEqual(par('a'), 'a');
15949     });
15950
15951     QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
15952       assert.expect(4);
15953
15954       var fn = function() { return slice.call(arguments); },
15955           par = func(fn, ph, 'b', ph);
15956
15957       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
15958       assert.deepEqual(par('a'), ['a', 'b', undefined]);
15959       assert.deepEqual(par(), [undefined, 'b', undefined]);
15960
15961       if (isPartial) {
15962         assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
15963       } else {
15964         par = func(fn, ph, 'c', ph);
15965         assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
15966       }
15967     });
15968
15969     QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
15970       assert.expect(1);
15971
15972       if (!isModularize) {
15973         var _ph = _.placeholder = {},
15974             fn = function() { return slice.call(arguments); },
15975             par = func(fn, _ph, 'b', ph),
15976             expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
15977
15978         assert.deepEqual(par('a', 'c'), expected);
15979         delete _.placeholder;
15980       }
15981       else {
15982         skipAssert(assert);
15983       }
15984     });
15985
15986     QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
15987       assert.expect(1);
15988
15989       var fn = function(a, b, c) {},
15990           par = func(fn, 'a');
15991
15992       assert.strictEqual(par.length, 0);
15993     });
15994
15995     QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
15996       assert.expect(2);
15997
15998       function Foo(value) {
15999         return value && object;
16000       }
16001
16002       var object = {},
16003           par = func(Foo);
16004
16005       assert.ok(new par instanceof Foo);
16006       assert.strictEqual(new par(true), object);
16007     });
16008
16009     QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
16010       assert.expect(3);
16011
16012       function greet(greeting, name) {
16013         return greeting + ' ' + name;
16014       }
16015
16016       var par1 = func(greet, 'hi'),
16017           par2 = func(par1, 'barney'),
16018           par3 = func(par1, 'pebbles');
16019
16020       assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
16021       assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
16022       assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
16023     });
16024
16025     QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
16026       assert.expect(2);
16027
16028       var fn = function(a, b, c) { return a + b + c; },
16029           curried = _.curry(func(fn, 1), 2);
16030
16031       assert.strictEqual(curried(2, 3), 6);
16032       assert.strictEqual(curried(2)(3), 6);
16033     });
16034
16035     QUnit.test('should work with placeholders and curried functions', function(assert) {
16036       assert.expect(1);
16037
16038       var fn = function() { return slice.call(arguments); },
16039           curried = _.curry(fn),
16040           par = func(curried, ph, 'b', ph, 'd');
16041
16042       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
16043     });
16044   });
16045
16046   /*--------------------------------------------------------------------------*/
16047
16048   QUnit.module('lodash.partialRight');
16049
16050   (function() {
16051     QUnit.test('should work as a deep `_.defaults`', function(assert) {
16052       assert.expect(1);
16053
16054       var object = { 'a': { 'b': 1 } },
16055           source = { 'a': { 'b': 2, 'c': 3 } },
16056           expected = { 'a': { 'b': 1, 'c': 3 } };
16057
16058       var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
16059         return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
16060       });
16061
16062       assert.deepEqual(defaultsDeep(object, source), expected);
16063     });
16064   }());
16065
16066   /*--------------------------------------------------------------------------*/
16067
16068   QUnit.module('methods using `createWrapper`');
16069
16070   (function() {
16071     function fn() {
16072       return slice.call(arguments);
16073     }
16074
16075     var ph1 = _.bind.placeholder,
16076         ph2 = _.bindKey.placeholder,
16077         ph3 = _.partial.placeholder,
16078         ph4 = _.partialRight.placeholder;
16079
16080     QUnit.test('should work with combinations of partial functions', function(assert) {
16081       assert.expect(1);
16082
16083       var a = _.partial(fn),
16084           b = _.partialRight(a, 3),
16085           c = _.partial(b, 1);
16086
16087       assert.deepEqual(c(2), [1, 2, 3]);
16088     });
16089
16090     QUnit.test('should work with combinations of bound and partial functions', function(assert) {
16091       assert.expect(3);
16092
16093       var fn = function() {
16094         var result = [this.a];
16095         push.apply(result, arguments);
16096         return result;
16097       };
16098
16099       var expected = [1, 2, 3, 4],
16100           object = { 'a': 1, 'fn': fn };
16101
16102       var a = _.bindKey(object, 'fn'),
16103           b = _.partialRight(a, 4),
16104           c = _.partial(b, 2);
16105
16106       assert.deepEqual(c(3), expected);
16107
16108       a = _.bind(fn, object);
16109       b = _.partialRight(a, 4);
16110       c = _.partial(b, 2);
16111
16112       assert.deepEqual(c(3), expected);
16113
16114       a = _.partial(fn, 2);
16115       b = _.bind(a, object);
16116       c = _.partialRight(b, 4);
16117
16118       assert.deepEqual(c(3), expected);
16119     });
16120
16121     QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
16122       assert.expect(2);
16123
16124       function Foo(a, b, c) {
16125         return b === 0 && object;
16126       }
16127
16128       var combo = _.partial(_.partialRight(Foo, 3), 1),
16129           object = {};
16130
16131       assert.ok(new combo(2) instanceof Foo);
16132       assert.strictEqual(new combo(0), object);
16133     });
16134
16135     QUnit.test('should work with combinations of functions with placeholders', function(assert) {
16136       assert.expect(3);
16137
16138       var expected = [1, 2, 3, 4, 5, 6],
16139           object = { 'fn': fn };
16140
16141       var a = _.bindKey(object, 'fn', ph2, 2),
16142           b = _.partialRight(a, ph4, 6),
16143           c = _.partial(b, 1, ph3, 4);
16144
16145       assert.deepEqual(c(3, 5), expected);
16146
16147       a = _.bind(fn, object, ph1, 2);
16148       b = _.partialRight(a, ph4, 6);
16149       c = _.partial(b, 1, ph3, 4);
16150
16151       assert.deepEqual(c(3, 5), expected);
16152
16153       a = _.partial(fn, ph3, 2);
16154       b = _.bind(a, object, 1, ph1, 4);
16155       c = _.partialRight(b, ph4, 6);
16156
16157       assert.deepEqual(c(3, 5), expected);
16158     });
16159
16160     QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
16161       assert.expect(3);
16162
16163       var expected = [1, 2, 3, 4],
16164           object = { 'fn': fn };
16165
16166       var a = _.bindKey(object, 'fn', ph2, 2),
16167           b = _.partialRight(a, ph4, 4),
16168           c = _.partial(b, ph3, 3);
16169
16170       assert.deepEqual(c(1), expected);
16171
16172       a = _.bind(fn, object, ph1, 2);
16173       b = _.partialRight(a, ph4, 4);
16174       c = _.partial(b, ph3, 3);
16175
16176       assert.deepEqual(c(1), expected);
16177
16178       a = _.partial(fn, ph3, 2);
16179       b = _.bind(a, object, ph1, 3);
16180       c = _.partialRight(b, ph4, 4);
16181
16182       assert.deepEqual(c(1), expected);
16183     });
16184
16185     QUnit.test('should work with recursively bound functions', function(assert) {
16186       assert.expect(1);
16187
16188       var fn = function() {
16189         return this.a;
16190       };
16191
16192       var a = _.bind(fn, { 'a': 1 }),
16193           b = _.bind(a,  { 'a': 2 }),
16194           c = _.bind(b,  { 'a': 3 });
16195
16196       assert.strictEqual(c(), 1);
16197     });
16198
16199     QUnit.test('should work when hot', function(assert) {
16200       assert.expect(12);
16201
16202       lodashStable.times(2, function(index) {
16203         var fn = function() {
16204           var result = [this];
16205           push.apply(result, arguments);
16206           return result;
16207         };
16208
16209         var object = {},
16210             bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
16211             expected = [object, 1, 2, 3];
16212
16213         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
16214           var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
16215           return index ? bound2(3) : bound2(1, 2, 3);
16216         }));
16217
16218         assert.deepEqual(actual, expected);
16219
16220         actual = _.last(lodashStable.times(HOT_COUNT, function() {
16221           var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
16222               bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
16223
16224           return index ? bound2(3) : bound2(1, 2, 3);
16225         }));
16226
16227         assert.deepEqual(actual, expected);
16228       });
16229
16230       lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
16231         var fn = function(a, b, c) { return [a, b, c]; },
16232             curried = _[methodName](fn),
16233             expected = index ? [3, 2, 1] :  [1, 2, 3];
16234
16235         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
16236           return curried(1)(2)(3);
16237         }));
16238
16239         assert.deepEqual(actual, expected);
16240
16241         actual = _.last(lodashStable.times(HOT_COUNT, function() {
16242           var curried = _[methodName](fn);
16243           return curried(1)(2)(3);
16244         }));
16245
16246         assert.deepEqual(actual, expected);
16247       });
16248
16249       lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
16250         var func = _[methodName],
16251             fn = function() { return slice.call(arguments); },
16252             par1 = func(fn, 1),
16253             expected = index ? [3, 2, 1] : [1, 2, 3];
16254
16255         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
16256           var par2 = func(par1, 2);
16257           return par2(3);
16258         }));
16259
16260         assert.deepEqual(actual, expected);
16261
16262         actual = _.last(lodashStable.times(HOT_COUNT, function() {
16263           var par1 = func(fn, 1),
16264               par2 = func(par1, 2);
16265
16266           return par2(3);
16267         }));
16268
16269         assert.deepEqual(actual, expected);
16270       });
16271     });
16272   }());
16273
16274   /*--------------------------------------------------------------------------*/
16275
16276   QUnit.module('lodash.partition');
16277
16278   (function() {
16279     var array = [1, 0, 1];
16280
16281     QUnit.test('should split elements into two groups by `predicate`', function(assert) {
16282       assert.expect(3);
16283
16284       assert.deepEqual(_.partition([], identity), [[], []]);
16285       assert.deepEqual(_.partition(array, alwaysTrue), [array, []]);
16286       assert.deepEqual(_.partition(array, alwaysFalse), [[], array]);
16287     });
16288
16289     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
16290       assert.expect(1);
16291
16292       var values = [, null, undefined],
16293           expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
16294
16295       var actual = lodashStable.map(values, function(value, index) {
16296         return index ? _.partition(array, value) : _.partition(array);
16297       });
16298
16299       assert.deepEqual(actual, expected);
16300     });
16301
16302     QUnit.test('should work with "_.property" shorthands', function(assert) {
16303       assert.expect(1);
16304
16305       var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
16306           actual = _.partition(objects, 'a');
16307
16308       assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
16309     });
16310
16311     QUnit.test('should work with a number for `predicate`', function(assert) {
16312       assert.expect(2);
16313
16314       var array = [
16315         [1, 0],
16316         [0, 1],
16317         [1, 0]
16318       ];
16319
16320       assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
16321       assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
16322     });
16323
16324     QUnit.test('should work with an object for `collection`', function(assert) {
16325       assert.expect(1);
16326
16327       var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
16328       assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
16329     });
16330   }());
16331
16332   /*--------------------------------------------------------------------------*/
16333
16334   QUnit.module('lodash.pick');
16335
16336   (function() {
16337     var args = arguments,
16338         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16339
16340     QUnit.test('should flatten `props`', function(assert) {
16341       assert.expect(2);
16342
16343       assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
16344       assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
16345     });
16346
16347     QUnit.test('should work with a primitive `object` argument', function(assert) {
16348       assert.expect(1);
16349
16350       assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
16351     });
16352
16353     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16354       assert.expect(2);
16355
16356       lodashStable.each([null, undefined], function(value) {
16357         assert.deepEqual(_.pick(value, 'valueOf'), {});
16358       });
16359     });
16360
16361     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
16362       assert.expect(1);
16363
16364       assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
16365     });
16366
16367     QUnit.test('should coerce property names to strings', function(assert) {
16368       assert.expect(1);
16369
16370       assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
16371     });
16372   }('a', 'c'));
16373
16374   /*--------------------------------------------------------------------------*/
16375
16376   QUnit.module('lodash.pickBy');
16377
16378   (function() {
16379     QUnit.test('should work with a predicate argument', function(assert) {
16380       assert.expect(1);
16381
16382       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16383
16384       var actual = _.pickBy(object, function(n) {
16385         return n == 1 || n == 3;
16386       });
16387
16388       assert.deepEqual(actual, { 'a': 1, 'c': 3 });
16389     });
16390   }());
16391
16392   /*--------------------------------------------------------------------------*/
16393
16394   QUnit.module('pick methods');
16395
16396   lodashStable.each(['pick', 'pickBy'], function(methodName) {
16397     var expected = { 'a': 1, 'c': 3 },
16398         func = _[methodName],
16399         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16400         prop = function(object, props) { return props; };
16401
16402     if (methodName == 'pickBy') {
16403       prop = function(object, props) {
16404         props = typeof props == 'string' ? [props] : props;
16405         return function(value) {
16406           return _.some(props, function(key) { return object[key] === value; });
16407         };
16408       };
16409     }
16410     QUnit.test('`_.' + methodName + '` should create an object of picked properties', function(assert) {
16411       assert.expect(2);
16412
16413       assert.deepEqual(func(object, prop(object, 'a')), { 'a': 1 });
16414       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
16415     });
16416
16417     QUnit.test('`_.' + methodName + '` should iterate over inherited properties', function(assert) {
16418       assert.expect(1);
16419
16420       function Foo() {}
16421       Foo.prototype = object;
16422
16423       var foo = new Foo;
16424       assert.deepEqual(func(foo, prop(foo, ['a', 'c'])), expected);
16425     });
16426
16427     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
16428       assert.expect(1);
16429
16430       var array = [1, 2, 3];
16431       assert.deepEqual(func(array, prop(array, '1')), { '1': 2 });
16432     });
16433   });
16434
16435   /*--------------------------------------------------------------------------*/
16436
16437   QUnit.module('lodash.property');
16438
16439   (function() {
16440     QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
16441       assert.expect(4);
16442
16443       var object = { 'a': 1 };
16444
16445       lodashStable.each(['a', ['a']], function(path) {
16446         var prop = _.property(path);
16447         assert.strictEqual(prop.length, 1);
16448         assert.strictEqual(prop(object), 1);
16449       });
16450     });
16451
16452     QUnit.test('should pluck deep property values', function(assert) {
16453       assert.expect(2);
16454
16455       var object = { 'a': { 'b': { 'c': 3 } } };
16456
16457       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
16458         var prop = _.property(path);
16459         assert.strictEqual(prop(object), 3);
16460       });
16461     });
16462
16463     QUnit.test('should work with non-string `path` arguments', function(assert) {
16464       assert.expect(2);
16465
16466       var array = [1, 2, 3];
16467
16468       lodashStable.each([1, [1]], function(path) {
16469         var prop = _.property(path);
16470         assert.strictEqual(prop(array), 2);
16471       });
16472     });
16473
16474     QUnit.test('should coerce key to a string', function(assert) {
16475       assert.expect(1);
16476
16477       function fn() {}
16478       fn.toString = lodashStable.constant('fn');
16479
16480       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
16481           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
16482           values = [null, undefined, fn, {}];
16483
16484       var actual = lodashStable.transform(objects, function(result, object, index) {
16485         var key = values[index];
16486         lodashStable.each([key, [key]], function(path) {
16487           var prop = _.property(key);
16488           result.push(prop(object));
16489         });
16490       });
16491
16492       assert.deepEqual(actual, expected);
16493     });
16494
16495     QUnit.test('should pluck inherited property values', function(assert) {
16496       assert.expect(2);
16497
16498       function Foo() {}
16499       Foo.prototype.a = 1;
16500
16501       lodashStable.each(['a', ['a']], function(path) {
16502         var prop = _.property(path);
16503         assert.strictEqual(prop(new Foo), 1);
16504       });
16505     });
16506
16507     QUnit.test('should pluck a key over a path', function(assert) {
16508       assert.expect(2);
16509
16510       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
16511
16512       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
16513         var prop = _.property(path);
16514         assert.strictEqual(prop(object), 3);
16515       });
16516     });
16517
16518     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
16519       assert.expect(2);
16520
16521       var values = [, null, undefined],
16522           expected = lodashStable.map(values, alwaysUndefined);
16523
16524       lodashStable.each(['constructor', ['constructor']], function(path) {
16525         var prop = _.property(path);
16526
16527         var actual = lodashStable.map(values, function(value, index) {
16528           return index ? prop(value) : prop();
16529         });
16530
16531         assert.deepEqual(actual, expected);
16532       });
16533     });
16534
16535     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
16536       assert.expect(2);
16537
16538       var values = [, null, undefined],
16539           expected = lodashStable.map(values, alwaysUndefined);
16540
16541       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
16542         var prop = _.property(path);
16543
16544         var actual = lodashStable.map(values, function(value, index) {
16545           return index ? prop(value) : prop();
16546         });
16547
16548         assert.deepEqual(actual, expected);
16549       });
16550     });
16551
16552     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
16553       assert.expect(4);
16554
16555       var object = {};
16556
16557       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
16558         var prop = _.property(path);
16559         assert.strictEqual(prop(object), undefined);
16560       });
16561     });
16562   }());
16563
16564   /*--------------------------------------------------------------------------*/
16565
16566   QUnit.module('lodash.propertyOf');
16567
16568   (function() {
16569     QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
16570       assert.expect(3);
16571
16572       var object = { 'a': 1 },
16573           propOf = _.propertyOf(object);
16574
16575       assert.strictEqual(propOf.length, 1);
16576       lodashStable.each(['a', ['a']], function(path) {
16577         assert.strictEqual(propOf(path), 1);
16578       });
16579     });
16580
16581     QUnit.test('should pluck deep property values', function(assert) {
16582       assert.expect(2);
16583
16584       var object = { 'a': { 'b': { 'c': 3 } } },
16585           propOf = _.propertyOf(object);
16586
16587       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
16588         assert.strictEqual(propOf(path), 3);
16589       });
16590     });
16591
16592     QUnit.test('should work with non-string `path` arguments', function(assert) {
16593       assert.expect(2);
16594
16595       var array = [1, 2, 3],
16596           propOf = _.propertyOf(array);
16597
16598       lodashStable.each([1, [1]], function(path) {
16599         assert.strictEqual(propOf(path), 2);
16600       });
16601     });
16602
16603     QUnit.test('should coerce key to a string', function(assert) {
16604       assert.expect(1);
16605
16606       function fn() {}
16607       fn.toString = lodashStable.constant('fn');
16608
16609       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
16610           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
16611           values = [null, undefined, fn, {}];
16612
16613       var actual = lodashStable.transform(objects, function(result, object, index) {
16614         var key = values[index];
16615         lodashStable.each([key, [key]], function(path) {
16616           var propOf = _.propertyOf(object);
16617           result.push(propOf(key));
16618         });
16619       });
16620
16621       assert.deepEqual(actual, expected);
16622     });
16623
16624     QUnit.test('should pluck inherited property values', function(assert) {
16625       assert.expect(2);
16626
16627       function Foo() { this.a = 1; }
16628       Foo.prototype.b = 2;
16629
16630       var propOf = _.propertyOf(new Foo);
16631
16632       lodashStable.each(['b', ['b']], function(path) {
16633         assert.strictEqual(propOf(path), 2);
16634       });
16635     });
16636
16637     QUnit.test('should pluck a key over a path', function(assert) {
16638       assert.expect(2);
16639
16640       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } },
16641           propOf = _.propertyOf(object);
16642
16643       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
16644         assert.strictEqual(propOf(path), 3);
16645       });
16646     });
16647
16648     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
16649       assert.expect(2);
16650
16651       var values = [, null, undefined],
16652           expected = lodashStable.map(values, alwaysUndefined);
16653
16654       lodashStable.each(['constructor', ['constructor']], function(path) {
16655         var actual = lodashStable.map(values, function(value, index) {
16656           var propOf = index ? _.propertyOf(value) : _.propertyOf();
16657           return propOf(path);
16658         });
16659
16660         assert.deepEqual(actual, expected);
16661       });
16662     });
16663
16664     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
16665       assert.expect(2);
16666
16667       var values = [, null, undefined],
16668           expected = lodashStable.map(values, alwaysUndefined);
16669
16670       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
16671         var actual = lodashStable.map(values, function(value, index) {
16672           var propOf = index ? _.propertyOf(value) : _.propertyOf();
16673           return propOf(path);
16674         });
16675
16676         assert.deepEqual(actual, expected);
16677       });
16678     });
16679
16680     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
16681       assert.expect(4);
16682
16683       var propOf = _.propertyOf({});
16684
16685       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
16686         assert.strictEqual(propOf(path), undefined);
16687       });
16688     });
16689   }());
16690
16691   /*--------------------------------------------------------------------------*/
16692
16693   QUnit.module('pull methods');
16694
16695   lodashStable.each(['pull', 'pullAll'], function(methodName) {
16696     var func = _[methodName],
16697         isPull = methodName == 'pull';
16698
16699     function pull(array, values) {
16700       return isPull
16701         ? func.apply(undefined, [array].concat(values))
16702         : func(array, values);
16703     }
16704
16705     QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
16706       assert.expect(2);
16707
16708       var array = [1, 2, 3],
16709           actual = pull(array, [1, 3]);
16710
16711       assert.deepEqual(array, [2]);
16712       assert.ok(actual === array);
16713     });
16714
16715     QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
16716       assert.expect(2);
16717
16718       var array = [1, 2, 3, 4];
16719       delete array[1];
16720       delete array[3];
16721
16722       pull(array, [1]);
16723       assert.notOk('0' in array);
16724       assert.notOk('2' in array);
16725     });
16726
16727     QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
16728       assert.expect(1);
16729
16730       var array = [1, 2, 3];
16731       delete array[1];
16732
16733       pull(array, [undefined]);
16734       assert.deepEqual(array, [1, 3]);
16735     });
16736
16737     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
16738       assert.expect(1);
16739
16740       var array = [1, NaN, 3, NaN];
16741
16742       pull(array, [NaN]);
16743       assert.deepEqual(array, [1, 3]);
16744     });
16745   });
16746
16747   /*--------------------------------------------------------------------------*/
16748
16749   QUnit.module('lodash.pullAllBy');
16750
16751   (function() {
16752     QUnit.test('should accept an `iteratee` argument', function(assert) {
16753       assert.expect(1);
16754
16755       var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
16756
16757       var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
16758         return object.x;
16759       });
16760
16761       assert.deepEqual(actual, [{ 'x': 2 }]);
16762     });
16763
16764     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
16765       assert.expect(1);
16766
16767       var args,
16768           array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
16769
16770       _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
16771         args || (args = slice.call(arguments));
16772       });
16773
16774       assert.deepEqual(args, [{ 'x': 1 }]);
16775     });
16776   }());
16777
16778   /*--------------------------------------------------------------------------*/
16779
16780   QUnit.module('lodash.pullAt');
16781
16782   (function() {
16783     QUnit.test('should modify the array and return removed elements', function(assert) {
16784       assert.expect(2);
16785
16786       var array = [1, 2, 3],
16787           actual = _.pullAt(array, [0, 1]);
16788
16789       assert.deepEqual(array, [3]);
16790       assert.deepEqual(actual, [1, 2]);
16791     });
16792
16793     QUnit.test('should work with unsorted indexes', function(assert) {
16794       assert.expect(2);
16795
16796       var array = [1, 2, 3, 4],
16797           actual = _.pullAt(array, [1, 3, 0]);
16798
16799       assert.deepEqual(array, [3]);
16800       assert.deepEqual(actual, [2, 4, 1]);
16801     });
16802
16803     QUnit.test('should work with repeated indexes', function(assert) {
16804       assert.expect(2);
16805
16806       var array = [1, 2, 3, 4],
16807           actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
16808
16809       assert.deepEqual(array, [4]);
16810       assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
16811     });
16812
16813     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
16814       assert.expect(2);
16815
16816       var array = ['a', 'b', 'c'],
16817           actual = _.pullAt(array, [2, 4, 0]);
16818
16819       assert.deepEqual(array, ['b']);
16820       assert.deepEqual(actual, ['c', undefined, 'a']);
16821     });
16822
16823     QUnit.test('should flatten `indexes`', function(assert) {
16824       assert.expect(4);
16825
16826       var array = ['a', 'b', 'c'];
16827       assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
16828       assert.deepEqual(array, ['b']);
16829
16830       array = ['a', 'b', 'c', 'd'];
16831       assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
16832       assert.deepEqual(array, ['b']);
16833     });
16834
16835     QUnit.test('should return an empty array when no indexes are given', function(assert) {
16836       assert.expect(4);
16837
16838       var array = ['a', 'b', 'c'],
16839           actual = _.pullAt(array);
16840
16841       assert.deepEqual(array, ['a', 'b', 'c']);
16842       assert.deepEqual(actual, []);
16843
16844       actual = _.pullAt(array, [], []);
16845
16846       assert.deepEqual(array, ['a', 'b', 'c']);
16847       assert.deepEqual(actual, []);
16848     });
16849
16850     QUnit.test('should work with non-index paths', function(assert) {
16851       assert.expect(2);
16852
16853       var values = lodashStable.reject(empties, function(value) {
16854         return (value === 0) || lodashStable.isArray(value);
16855       }).concat(-1, 1.1);
16856
16857       var array = lodashStable.transform(values, function(result, value) {
16858         result[value] = 1;
16859       }, []);
16860
16861       var expected = lodashStable.map(values, alwaysOne),
16862           actual = _.pullAt(array, values);
16863
16864       assert.deepEqual(actual, expected);
16865
16866       expected = lodashStable.map(values, alwaysUndefined),
16867       actual = _.at(array, values);
16868
16869       assert.deepEqual(actual, expected);
16870     });
16871
16872     QUnit.test('should work with deep paths', function(assert) {
16873       assert.expect(3);
16874
16875       var array = [];
16876       array.a = { 'b': { 'c': 3 } };
16877
16878       var actual = _.pullAt(array, 'a.b.c');
16879
16880       assert.deepEqual(actual, [3]);
16881       assert.deepEqual(array.a, { 'b': {} });
16882
16883       try {
16884         actual = _.pullAt(array, 'a.b.c.d.e');
16885       } catch (e) {}
16886
16887       assert.deepEqual(actual, [undefined]);
16888     });
16889
16890     QUnit.test('should work with a falsey `array` argument when keys are given', function(assert) {
16891       assert.expect(1);
16892
16893       var values = falsey.slice(),
16894           expected = lodashStable.map(values, lodashStable.constant(Array(4)));
16895
16896       var actual = lodashStable.map(values, function(array) {
16897         try {
16898           return _.pullAt(array, 0, 1, 'pop', 'push');
16899         } catch (e) {}
16900       });
16901
16902       assert.deepEqual(actual, expected);
16903     });
16904   }());
16905
16906   /*--------------------------------------------------------------------------*/
16907
16908   QUnit.module('lodash.random');
16909
16910   (function() {
16911     var array = Array(1000);
16912
16913     QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
16914       assert.expect(1);
16915
16916       var actual = lodashStable.map(array, function() {
16917         return _.random();
16918       });
16919
16920       assert.deepEqual(_.uniq(actual).sort(), [0, 1]);
16921     });
16922
16923     QUnit.test('should support a `min` and `max` argument', function(assert) {
16924       assert.expect(1);
16925
16926       var min = 5,
16927           max = 10;
16928
16929       assert.ok(_.some(array, function() {
16930         var result = _.random(min, max);
16931         return result >= min && result <= max;
16932       }));
16933     });
16934
16935     QUnit.test('should support not providing a `max` argument', function(assert) {
16936       assert.expect(1);
16937
16938       var min = 0,
16939           max = 5;
16940
16941       assert.ok(_.some(array, function() {
16942         var result = _.random(max);
16943         return result >= min && result <= max;
16944       }));
16945     });
16946
16947     QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
16948       assert.expect(1);
16949
16950       var min = 4,
16951           max = 2,
16952           expected = [2, 3, 4];
16953
16954       var actual = lodashStable.uniq(lodashStable.map(array, function() {
16955         return _.random(min, max);
16956       })).sort();
16957
16958       assert.deepEqual(actual, expected);
16959     });
16960
16961     QUnit.test('should support large integer values', function(assert) {
16962       assert.expect(2);
16963
16964       var min = Math.pow(2, 31),
16965           max = Math.pow(2, 62);
16966
16967       assert.ok(lodashStable.every(array, function() {
16968         var result = _.random(min, max);
16969         return result >= min && result <= max;
16970       }));
16971
16972       assert.ok(_.some(array, function() {
16973         return _.random(MAX_INTEGER) > 0;
16974       }));
16975     });
16976
16977     QUnit.test('should coerce arguments to finite numbers', function(assert) {
16978       assert.expect(2);
16979
16980       assert.strictEqual(_.random('1', '1'), 1);
16981       assert.strictEqual(_.random(NaN, NaN), 0);
16982     });
16983
16984     QUnit.test('should support floats', function(assert) {
16985       assert.expect(2);
16986
16987       var min = 1.5,
16988           max = 1.6,
16989           actual = _.random(min, max);
16990
16991       assert.ok(actual % 1);
16992       assert.ok(actual >= min && actual <= max);
16993     });
16994
16995     QUnit.test('should support providing a `floating` argument', function(assert) {
16996       assert.expect(3);
16997
16998       var actual = _.random(true);
16999       assert.ok(actual % 1 && actual >= 0 && actual <= 1);
17000
17001       actual = _.random(2, true);
17002       assert.ok(actual % 1 && actual >= 0 && actual <= 2);
17003
17004       actual = _.random(2, 4, true);
17005       assert.ok(actual % 1 && actual >= 2 && actual <= 4);
17006     });
17007
17008     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17009       assert.expect(1);
17010
17011       var array = [1, 2, 3],
17012           expected = lodashStable.map(array, alwaysTrue),
17013           randoms = lodashStable.map(array, _.random);
17014
17015       var actual = lodashStable.map(randoms, function(result, index) {
17016         return result >= 0 && result <= array[index] && (result % 1) == 0;
17017       });
17018
17019       assert.deepEqual(actual, expected);
17020     });
17021   }());
17022
17023   /*--------------------------------------------------------------------------*/
17024
17025   QUnit.module('range methods');
17026
17027   lodashStable.each(['range', 'rangeRight'], function(methodName) {
17028     var func = _[methodName],
17029         isRange = methodName == 'range';
17030
17031     function resolve(range) {
17032       return isRange ? range : range.reverse();
17033     }
17034
17035     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
17036       assert.expect(2);
17037
17038       assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
17039       assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
17040     });
17041
17042     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
17043       assert.expect(2);
17044
17045       assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
17046       assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
17047     });
17048
17049     QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
17050       assert.expect(3);
17051
17052       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
17053       assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
17054       assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
17055     });
17056
17057     QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
17058       assert.expect(1);
17059
17060       assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
17061     });
17062
17063     QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
17064       assert.expect(1);
17065
17066       assert.deepEqual(func(1, 5, 20), [1]);
17067     });
17068
17069     QUnit.test('`_.' + methodName + '` should work with a negative `step` argument', function(assert) {
17070       assert.expect(2);
17071
17072       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
17073       assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
17074     });
17075
17076     QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
17077       assert.expect(1);
17078
17079       var actual = func(-0, 1);
17080       assert.strictEqual(1 / actual[0], -Infinity);
17081     });
17082
17083     QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
17084       assert.expect(13);
17085
17086       lodashStable.each(falsey, function(value, index) {
17087         if (index) {
17088           assert.deepEqual(func(value), []);
17089           assert.deepEqual(func(value, 1), [0]);
17090         } else {
17091           assert.deepEqual(func(), []);
17092         }
17093       });
17094     });
17095
17096     QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
17097       assert.expect(1);
17098
17099       var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
17100       assert.deepEqual(actual, [[0], [0], [0], [], []]);
17101     });
17102
17103     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
17104       assert.expect(2);
17105
17106       var array = [1, 2, 3],
17107           object = { 'a': 1, 'b': 2, 'c': 3 },
17108           expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
17109
17110       lodashStable.each([array, object], function(collection) {
17111         var actual = lodashStable.map(collection, func);
17112         assert.deepEqual(actual, expected);
17113       });
17114     });
17115   });
17116
17117   /*--------------------------------------------------------------------------*/
17118
17119   QUnit.module('lodash.rearg');
17120
17121   (function() {
17122     function fn() {
17123       return slice.call(arguments);
17124     }
17125
17126     QUnit.test('should reorder arguments provided to `func`', function(assert) {
17127       assert.expect(1);
17128
17129       var rearged = _.rearg(fn, [2, 0, 1]);
17130       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
17131     });
17132
17133     QUnit.test('should work with repeated indexes', function(assert) {
17134       assert.expect(1);
17135
17136       var rearged = _.rearg(fn, [1, 1, 1]);
17137       assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
17138     });
17139
17140     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
17141       assert.expect(1);
17142
17143       var rearged = _.rearg(fn, [1, 4]);
17144       assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
17145     });
17146
17147     QUnit.test('should use `undefined` for non-index values', function(assert) {
17148       assert.expect(1);
17149
17150       var values = lodashStable.reject(empties, function(value) {
17151         return (value === 0) || lodashStable.isArray(value);
17152       }).concat(-1, 1.1);
17153
17154       var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
17155
17156       var actual = lodashStable.map(values, function(value) {
17157         var rearged = _.rearg(fn, [value]);
17158         return rearged('a', 'b', 'c');
17159       });
17160
17161       assert.deepEqual(actual, expected);
17162     });
17163
17164     QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
17165       assert.expect(2);
17166
17167       var rearged = _.rearg(fn);
17168       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
17169
17170       rearged = _.rearg(fn, [], []);
17171       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
17172     });
17173
17174     QUnit.test('should accept multiple index arguments', function(assert) {
17175       assert.expect(1);
17176
17177       var rearged = _.rearg(fn, 2, 0, 1);
17178       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
17179     });
17180
17181     QUnit.test('should accept multiple arrays of indexes', function(assert) {
17182       assert.expect(1);
17183
17184       var rearged = _.rearg(fn, [2], [0, 1]);
17185       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
17186     });
17187
17188     QUnit.test('should work with fewer indexes than arguments', function(assert) {
17189       assert.expect(1);
17190
17191       var rearged = _.rearg(fn, [1, 0]);
17192       assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
17193     });
17194
17195     QUnit.test('should work on functions that have been rearged', function(assert) {
17196       assert.expect(1);
17197
17198       var rearged1 = _.rearg(fn, 2, 1, 0),
17199           rearged2 = _.rearg(rearged1, 1, 0, 2);
17200
17201       assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
17202     });
17203   }());
17204
17205   /*--------------------------------------------------------------------------*/
17206
17207   QUnit.module('lodash.reduce');
17208
17209   (function() {
17210     var array = [1, 2, 3];
17211
17212     QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
17213       assert.expect(1);
17214
17215       assert.strictEqual(_.reduce(array), 1);
17216     });
17217
17218     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
17219       assert.expect(2);
17220
17221       var args;
17222
17223       _.reduce(array, function() {
17224         args || (args = slice.call(arguments));
17225       }, 0);
17226
17227       assert.deepEqual(args, [0, 1, 0, array]);
17228
17229       args = undefined;
17230       _.reduce(array, function() {
17231         args || (args = slice.call(arguments));
17232       });
17233
17234       assert.deepEqual(args, [1, 2, 1, array]);
17235     });
17236
17237     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
17238       assert.expect(2);
17239
17240       var args,
17241           object = { 'a': 1, 'b': 2 },
17242           firstKey = _.head(_.keys(object));
17243
17244       var expected = firstKey == 'a'
17245         ? [0, 1, 'a', object]
17246         : [0, 2, 'b', object];
17247
17248       _.reduce(object, function() {
17249         args || (args = slice.call(arguments));
17250       }, 0);
17251
17252       assert.deepEqual(args, expected);
17253
17254       args = undefined;
17255       expected = firstKey == 'a'
17256         ? [1, 2, 'b', object]
17257         : [2, 1, 'a', object];
17258
17259       _.reduce(object, function() {
17260         args || (args = slice.call(arguments));
17261       });
17262
17263       assert.deepEqual(args, expected);
17264     });
17265   }());
17266
17267   /*--------------------------------------------------------------------------*/
17268
17269   QUnit.module('lodash.reduceRight');
17270
17271   (function() {
17272     var array = [1, 2, 3];
17273
17274     QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
17275       assert.expect(1);
17276
17277       assert.strictEqual(_.reduceRight(array), 3);
17278     });
17279
17280     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
17281       assert.expect(2);
17282
17283       var args;
17284
17285       _.reduceRight(array, function() {
17286         args || (args = slice.call(arguments));
17287       }, 0);
17288
17289       assert.deepEqual(args, [0, 3, 2, array]);
17290
17291       args = undefined;
17292       _.reduceRight(array, function() {
17293         args || (args = slice.call(arguments));
17294       });
17295
17296       assert.deepEqual(args, [3, 2, 1, array]);
17297     });
17298
17299     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
17300       assert.expect(2);
17301
17302       var args,
17303           object = { 'a': 1, 'b': 2 },
17304           isFIFO = lodashStable.keys(object)[0] == 'a';
17305
17306       var expected = isFIFO
17307         ? [0, 2, 'b', object]
17308         : [0, 1, 'a', object];
17309
17310       _.reduceRight(object, function() {
17311         args || (args = slice.call(arguments));
17312       }, 0);
17313
17314       assert.deepEqual(args, expected);
17315
17316       args = undefined;
17317       expected = isFIFO
17318         ? [2, 1, 'a', object]
17319         : [1, 2, 'b', object];
17320
17321       _.reduceRight(object, function() {
17322         args || (args = slice.call(arguments));
17323       });
17324
17325       assert.deepEqual(args, expected);
17326     });
17327   }());
17328
17329   /*--------------------------------------------------------------------------*/
17330
17331   QUnit.module('reduce methods');
17332
17333   lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
17334     var func = _[methodName],
17335         array = [1, 2, 3],
17336         isReduce = methodName == 'reduce';
17337
17338     QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
17339       assert.expect(1);
17340
17341       var actual = func(['a', 'b', 'c'], function(accumulator, value) {
17342         return accumulator + value;
17343       }, '');
17344
17345       assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
17346     });
17347
17348     QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
17349       assert.expect(1);
17350
17351       var actual = [],
17352           expected = lodashStable.map(empties, alwaysUndefined);
17353
17354       lodashStable.each(empties, function(value) {
17355         try {
17356           actual.push(func(value, noop));
17357         } catch (e) {}
17358       });
17359
17360       assert.deepEqual(actual, expected);
17361     });
17362
17363     QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
17364       assert.expect(1);
17365
17366       var expected = lodashStable.map(empties, lodashStable.constant('x'));
17367
17368       var actual = lodashStable.map(empties, function(value) {
17369         try {
17370           return func(value, noop, 'x');
17371         } catch (e) {}
17372       });
17373
17374       assert.deepEqual(actual, expected);
17375     });
17376
17377     QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
17378       assert.expect(1);
17379
17380       var actual = func([], noop, undefined);
17381       assert.strictEqual(actual, undefined);
17382     });
17383
17384     QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
17385       assert.expect(2);
17386
17387       var array = [],
17388           object = { '0': 1, 'length': 0 };
17389
17390       if ('__proto__' in array) {
17391         array.__proto__ = object;
17392         assert.strictEqual(func(array, noop), undefined);
17393       }
17394       else {
17395         skipAssert(assert);
17396       }
17397       assert.strictEqual(func(object, noop), undefined);
17398     });
17399
17400     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
17401       assert.expect(1);
17402
17403       if (!isNpm) {
17404         assert.strictEqual(_(array)[methodName](add), 6);
17405       }
17406       else {
17407         skipAssert(assert);
17408       }
17409     });
17410
17411     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
17412       assert.expect(1);
17413
17414       if (!isNpm) {
17415         assert.ok(_(array).chain()[methodName](add) instanceof _);
17416       }
17417       else {
17418         skipAssert(assert);
17419       }
17420     });
17421   });
17422
17423   /*--------------------------------------------------------------------------*/
17424
17425   QUnit.module('lodash.reject');
17426
17427   (function() {
17428     var array = [1, 2, 3];
17429
17430     QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
17431       assert.expect(1);
17432
17433       assert.deepEqual(_.reject(array, isEven), [1, 3]);
17434     });
17435   }());
17436
17437   /*--------------------------------------------------------------------------*/
17438
17439   QUnit.module('filter methods');
17440
17441   lodashStable.each(['filter', 'reject'], function(methodName) {
17442     var array = [1, 2, 3, 4],
17443         func = _[methodName],
17444         isFilter = methodName == 'filter',
17445         objects = [{ 'a': 0 }, { 'a': 1 }];
17446
17447     QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
17448       assert.expect(1);
17449
17450       var actual = func([0], function(value, index, array) {
17451         array[index] = 1;
17452         return isFilter;
17453       });
17454
17455       assert.deepEqual(actual, [0]);
17456     });
17457
17458     QUnit.test('`_.' + methodName + '` should work with "_.property" shorthands', function(assert) {
17459       assert.expect(1);
17460
17461       assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
17462     });
17463
17464     QUnit.test('`_.' + methodName + '` should work with "_.matches" shorthands', function(assert) {
17465       assert.expect(1);
17466
17467       assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
17468     });
17469
17470     QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
17471       assert.expect(2);
17472
17473       if (!isNpm) {
17474         var wrapped = _(array);
17475
17476         var actual = wrapped[methodName](function(n) {
17477           return n < 3;
17478         });
17479
17480         assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
17481
17482         actual = wrapped[methodName](function(n) {
17483           return n > 2;
17484         });
17485
17486         assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
17487       }
17488       else {
17489         skipAssert(assert, 2);
17490       }
17491     });
17492
17493     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
17494       assert.expect(2);
17495
17496       if (!isNpm) {
17497         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
17498             predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
17499             actual = _(array).slice(1).map(square)[methodName](predicate).value();
17500
17501         assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
17502
17503         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
17504           return ['key' + index, index];
17505         }));
17506
17507         actual = _(object).mapValues(square)[methodName](predicate).value();
17508         assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
17509       }
17510       else {
17511         skipAssert(assert, 2);
17512       }
17513     });
17514
17515     QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
17516       assert.expect(5);
17517
17518       if (!isNpm) {
17519         var args,
17520             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
17521             expected = [1, 0, lodashStable.map(array.slice(1), square)];
17522
17523         _(array).slice(1)[methodName](function(value, index, array) {
17524           args || (args = slice.call(arguments));
17525         }).value();
17526
17527         assert.deepEqual(args, [1, 0, array.slice(1)]);
17528
17529         args = undefined;
17530         _(array).slice(1).map(square)[methodName](function(value, index, array) {
17531           args || (args = slice.call(arguments));
17532         }).value();
17533
17534         assert.deepEqual(args, expected);
17535
17536         args = undefined;
17537         _(array).slice(1).map(square)[methodName](function(value, index) {
17538           args || (args = slice.call(arguments));
17539         }).value();
17540
17541         assert.deepEqual(args, expected);
17542
17543         args = undefined;
17544         _(array).slice(1).map(square)[methodName](function(value) {
17545           args || (args = slice.call(arguments));
17546         }).value();
17547
17548         assert.deepEqual(args, [1]);
17549
17550         args = undefined;
17551         _(array).slice(1).map(square)[methodName](function() {
17552           args || (args = slice.call(arguments));
17553         }).value();
17554
17555         assert.deepEqual(args, expected);
17556       }
17557       else {
17558         skipAssert(assert, 5);
17559       }
17560     });
17561   });
17562
17563   /*--------------------------------------------------------------------------*/
17564
17565   QUnit.module('lodash.remove');
17566
17567   (function() {
17568     QUnit.test('should modify the array and return removed elements', function(assert) {
17569       assert.expect(2);
17570
17571       var array = [1, 2, 3, 4];
17572
17573       var actual = _.remove(array, function(n) {
17574         return n % 2 == 0;
17575       });
17576
17577       assert.deepEqual(array, [1, 3]);
17578       assert.deepEqual(actual, [2, 4]);
17579     });
17580
17581     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
17582       assert.expect(1);
17583
17584       var argsList = [],
17585           array = [1, 2, 3],
17586           clone = array.slice();
17587
17588       _.remove(array, function(n, index) {
17589         var args = slice.call(arguments);
17590         args[2] = args[2].slice();
17591         argsList.push(args);
17592         return isEven(index);
17593       });
17594
17595       assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
17596     });
17597
17598     QUnit.test('should work with "_.matches" shorthands', function(assert) {
17599       assert.expect(1);
17600
17601       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
17602       _.remove(objects, { 'a': 1 });
17603       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
17604     });
17605
17606     QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
17607       assert.expect(1);
17608
17609       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
17610       _.remove(objects, ['a', 1]);
17611       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
17612     });
17613
17614     QUnit.test('should work with "_.property" shorthands', function(assert) {
17615       assert.expect(1);
17616
17617       var objects = [{ 'a': 0 }, { 'a': 1 }];
17618       _.remove(objects, 'a');
17619       assert.deepEqual(objects, [{ 'a': 0 }]);
17620     });
17621
17622     QUnit.test('should preserve holes in arrays', function(assert) {
17623       assert.expect(2);
17624
17625       var array = [1, 2, 3, 4];
17626       delete array[1];
17627       delete array[3];
17628
17629       _.remove(array, function(n) {
17630         return n === 1;
17631       });
17632
17633       assert.notOk('0' in array);
17634       assert.notOk('2' in array);
17635     });
17636
17637     QUnit.test('should treat holes as `undefined`', function(assert) {
17638       assert.expect(1);
17639
17640       var array = [1, 2, 3];
17641       delete array[1];
17642
17643       _.remove(array, function(n) {
17644         return n == null;
17645       });
17646
17647       assert.deepEqual(array, [1, 3]);
17648     });
17649
17650     QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
17651       assert.expect(1);
17652
17653       var array = [1, 2, 3];
17654
17655       _.remove(array, function(n, index) {
17656         return isEven(index);
17657       });
17658
17659       assert.deepEqual(array, [2]);
17660     });
17661   }());
17662
17663   /*--------------------------------------------------------------------------*/
17664
17665   QUnit.module('lodash.repeat');
17666
17667   (function() {
17668     QUnit.test('should repeat a string `n` times', function(assert) {
17669       assert.expect(2);
17670
17671       assert.strictEqual(_.repeat('*', 3), '***');
17672       assert.strictEqual(_.repeat('abc', 2), 'abcabc');
17673     });
17674
17675     QUnit.test('should return an empty string for negative `n` or `n` of `0`', function(assert) {
17676       assert.expect(2);
17677
17678       assert.strictEqual(_.repeat('abc', 0), '');
17679       assert.strictEqual(_.repeat('abc', -2), '');
17680     });
17681
17682     QUnit.test('should coerce `n` to an integer', function(assert) {
17683       assert.expect(4);
17684
17685       assert.strictEqual(_.repeat('abc'), '');
17686       assert.strictEqual(_.repeat('abc', '2'), 'abcabc');
17687       assert.strictEqual(_.repeat('abc', 2.6), 'abcabc');
17688       assert.strictEqual(_.repeat('*', { 'valueOf': alwaysThree }), '***');
17689     });
17690
17691     QUnit.test('should coerce `string` to a string', function(assert) {
17692       assert.expect(2);
17693
17694       assert.strictEqual(_.repeat(Object('abc'), 2), 'abcabc');
17695       assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
17696     });
17697   }());
17698
17699   /*--------------------------------------------------------------------------*/
17700
17701   QUnit.module('lodash.replace');
17702
17703   (function() {
17704     QUnit.test('should replace the matched pattern', function(assert) {
17705       assert.expect(2);
17706
17707       var string = 'abcde';
17708       assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
17709       assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
17710     });
17711   }());
17712
17713   /*--------------------------------------------------------------------------*/
17714
17715   QUnit.module('lodash.result');
17716
17717   (function() {
17718     var object = {
17719       'a': 1,
17720       'b': function() { return this.a; }
17721     };
17722
17723     QUnit.test('should invoke function values', function(assert) {
17724       assert.expect(1);
17725
17726       assert.strictEqual(_.result(object, 'b'), 1);
17727     });
17728
17729     QUnit.test('should invoke default function values', function(assert) {
17730       assert.expect(1);
17731
17732       var actual = _.result(object, 'c', object.b);
17733       assert.strictEqual(actual, 1);
17734     });
17735
17736     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
17737       assert.expect(2);
17738
17739       var value = { 'a': object };
17740
17741       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17742         assert.strictEqual(_.result(value, path), 1);
17743       });
17744     });
17745   }());
17746
17747   /*--------------------------------------------------------------------------*/
17748
17749   QUnit.module('lodash.get and lodash.result');
17750
17751   lodashStable.each(['get', 'result'], function(methodName) {
17752     var func = _[methodName];
17753
17754     QUnit.test('`_.' + methodName + '` should get property values', function(assert) {
17755       assert.expect(2);
17756
17757       var object = { 'a': 1 };
17758
17759       lodashStable.each(['a', ['a']], function(path) {
17760         assert.strictEqual(func(object, path), 1);
17761       });
17762     });
17763
17764     QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
17765       assert.expect(2);
17766
17767       var object = { 'a': { 'b': { 'c': 3 } } };
17768
17769       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
17770         assert.strictEqual(func(object, path), 3);
17771       });
17772     });
17773
17774     QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
17775       assert.expect(2);
17776
17777       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
17778
17779       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
17780         assert.strictEqual(func(object, path), 3);
17781       });
17782     });
17783
17784     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
17785       assert.expect(1);
17786
17787       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
17788       assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
17789     });
17790
17791     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
17792       assert.expect(1);
17793
17794       var object = { 'a': 1 };
17795       assert.strictEqual(func(object, 'a[]'), 1);
17796     });
17797
17798     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
17799       assert.expect(4);
17800
17801       lodashStable.each([['', ''], [[], ['']]], function(pair) {
17802         assert.strictEqual(func({}, pair[0]), undefined);
17803         assert.strictEqual(func({ '': 3 }, pair[1]), 3);
17804       });
17805     });
17806
17807     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
17808       assert.expect(2);
17809
17810       var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
17811
17812       var paths = [
17813         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
17814         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
17815       ];
17816
17817       lodashStable.each(paths, function(path) {
17818         assert.strictEqual(func(object, path), 8);
17819       });
17820     });
17821
17822     QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
17823       assert.expect(4);
17824
17825       lodashStable.each(['constructor', ['constructor']], function(path) {
17826         assert.strictEqual(func(null, path), undefined);
17827         assert.strictEqual(func(undefined, path), undefined);
17828       });
17829     });
17830
17831     QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
17832       assert.expect(2);
17833
17834       var values = [null, undefined],
17835           expected = lodashStable.map(values, alwaysUndefined),
17836           paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
17837
17838       lodashStable.each(paths, function(path) {
17839         var actual = lodashStable.map(values, function(value) {
17840           return func(value, path);
17841         });
17842
17843         assert.deepEqual(actual, expected);
17844       });
17845     });
17846
17847     QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
17848       assert.expect(2);
17849
17850       var object = { 'a': [, null] };
17851
17852       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
17853         assert.strictEqual(func(object, path), undefined);
17854       });
17855     });
17856
17857     QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
17858       assert.expect(2);
17859
17860       var object = { 'a': { 'b': null } };
17861
17862       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17863         assert.strictEqual(func(object, path), null);
17864       });
17865     });
17866
17867     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
17868       assert.expect(4);
17869
17870       var object = { 'a': '' },
17871           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
17872
17873       lodashStable.each(paths, function(path) {
17874         numberProto.a = 1;
17875
17876         var actual = func(0, path);
17877         assert.strictEqual(actual, 1);
17878
17879         delete numberProto.a;
17880       });
17881
17882       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
17883         stringProto.replace.b = 1;
17884
17885         var actual = func(object, path);
17886         assert.strictEqual(actual, 1);
17887
17888         delete stringProto.replace.b;
17889       });
17890     });
17891
17892     QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
17893       assert.expect(1);
17894
17895       var object = { 'a': {} },
17896           values = empties.concat(true, new Date, 1, /x/, 'a');
17897
17898       var expected = lodashStable.transform(values, function(result, value) {
17899         result.push(value, value, value, value);
17900       });
17901
17902       var actual = lodashStable.transform(values, function(result, value) {
17903         lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
17904           result.push(
17905             func(object, path, value),
17906             func(null, path, value)
17907           );
17908         });
17909       });
17910
17911       assert.deepEqual(actual, expected);
17912     });
17913   });
17914
17915   /*--------------------------------------------------------------------------*/
17916
17917   QUnit.module('lodash.rest');
17918
17919   (function() {
17920     function fn(a, b, c) {
17921       return slice.call(arguments);
17922     }
17923
17924     QUnit.test('should apply a rest parameter to `func`', function(assert) {
17925       assert.expect(1);
17926
17927       var rest = _.rest(fn);
17928       assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
17929     });
17930
17931     QUnit.test('should work with `start`', function(assert) {
17932       assert.expect(1);
17933
17934       var rest = _.rest(fn, 1);
17935       assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
17936     });
17937
17938     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
17939       assert.expect(1);
17940
17941       var values = [-1, NaN, 'a'],
17942           expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
17943
17944       var actual = lodashStable.map(values, function(value) {
17945         var rest = _.rest(fn, value);
17946         return rest(1, 2, 3, 4);
17947       });
17948
17949       assert.deepEqual(actual, expected);
17950     });
17951
17952     QUnit.test('should coerce `start` to an integer', function(assert) {
17953       assert.expect(1);
17954
17955       var rest = _.rest(fn, 1.6);
17956       assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
17957     });
17958
17959     QUnit.test('should use an empty array when `start` is not reached', function(assert) {
17960       assert.expect(1);
17961
17962       var rest = _.rest(fn);
17963       assert.deepEqual(rest(1), [1, undefined, []]);
17964     });
17965
17966     QUnit.test('should work on functions with more than three parameters', function(assert) {
17967       assert.expect(1);
17968
17969       var rest = _.rest(function(a, b, c, d) {
17970         return slice.call(arguments);
17971       });
17972
17973       assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
17974     });
17975   }());
17976
17977   /*--------------------------------------------------------------------------*/
17978
17979   QUnit.module('lodash.reverse');
17980
17981   (function() {
17982     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
17983         smallArray = [0, 1, 2, null];
17984
17985     QUnit.test('should reverse `array`', function(assert) {
17986       assert.expect(2);
17987
17988       var array = [1, 2, 3],
17989           actual = _.reverse(array);
17990
17991       assert.deepEqual(array, [3, 2, 1]);
17992       assert.strictEqual(actual, array);
17993     });
17994
17995     QUnit.test('should return the wrapped reversed `array`', function(assert) {
17996       assert.expect(6);
17997
17998       if (!isNpm) {
17999         lodashStable.times(2, function(index) {
18000           var array = (index ? largeArray : smallArray).slice(),
18001               clone = array.slice(),
18002               wrapped = _(array).reverse(),
18003               actual = wrapped.value();
18004
18005           assert.ok(wrapped instanceof _);
18006           assert.strictEqual(actual, array);
18007           assert.deepEqual(actual, clone.slice().reverse());
18008         });
18009       }
18010       else {
18011         skipAssert(assert, 6);
18012       }
18013     });
18014
18015     QUnit.test('should work in a lazy sequence', function(assert) {
18016       assert.expect(4);
18017
18018       if (!isNpm) {
18019         lodashStable.times(2, function(index) {
18020           var array = (index ? largeArray : smallArray).slice(),
18021               expected = array.slice(),
18022               actual = _(array).slice(1).reverse().value();
18023
18024           assert.deepEqual(actual, expected.slice(1).reverse());
18025           assert.deepEqual(array, expected);
18026         });
18027       }
18028       else {
18029         skipAssert(assert, 4);
18030       }
18031     });
18032
18033     QUnit.test('should be lazy when in a lazy sequence', function(assert) {
18034       assert.expect(3);
18035
18036       if (!isNpm) {
18037         var spy = {
18038           'toString': function() {
18039             throw new Error('spy was revealed');
18040           }
18041         };
18042
18043         var array = largeArray.concat(spy),
18044             expected = array.slice();
18045
18046         try {
18047           var wrapped = _(array).slice(1).map(String).reverse(),
18048               actual = wrapped.last();
18049         } catch (e) {}
18050
18051         assert.ok(wrapped instanceof _);
18052         assert.strictEqual(actual, '1');
18053         assert.deepEqual(array, expected);
18054       }
18055       else {
18056         skipAssert(assert, 3);
18057       }
18058     });
18059
18060     QUnit.test('should work in a hybrid sequence', function(assert) {
18061       assert.expect(8);
18062
18063       if (!isNpm) {
18064         lodashStable.times(2, function(index) {
18065           var clone = (index ? largeArray : smallArray).slice();
18066
18067           lodashStable.each(['map', 'filter'], function(methodName) {
18068             var array = clone.slice(),
18069                 expected = clone.slice(1, -1).reverse(),
18070                 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
18071
18072             assert.deepEqual(actual, expected);
18073
18074             array = clone.slice();
18075             actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
18076
18077             assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
18078           });
18079         });
18080       }
18081       else {
18082         skipAssert(assert, 8);
18083       }
18084     });
18085
18086     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
18087       assert.expect(6);
18088
18089       if (!isNpm) {
18090         lodashStable.times(2, function(index) {
18091           var array = (index ? largeArray : smallArray).slice(),
18092               expected = array.slice().reverse(),
18093               wrapped = _(array).chain().reverse().head();
18094
18095           assert.ok(wrapped instanceof _);
18096           assert.strictEqual(wrapped.value(), _.head(expected));
18097           assert.deepEqual(array, expected);
18098         });
18099       }
18100       else {
18101         skipAssert(assert, 6);
18102       }
18103     });
18104   }());
18105
18106   /*--------------------------------------------------------------------------*/
18107
18108   QUnit.module('round methods');
18109
18110   lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
18111     var func = _[methodName],
18112         isCeil = methodName == 'ceil',
18113         isFloor = methodName == 'floor';
18114
18115     QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
18116       assert.expect(1);
18117
18118       var actual = func(4.006);
18119       assert.strictEqual(actual, isCeil ? 5 : 4);
18120     });
18121
18122     QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
18123       assert.expect(1);
18124
18125       var actual = func(4.006, 0);
18126       assert.strictEqual(actual, isCeil ? 5 : 4);
18127     });
18128
18129     QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
18130       assert.expect(2);
18131
18132       var actual = func(4.016, 2);
18133       assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
18134
18135       actual = func(4.1, 2);
18136       assert.strictEqual(actual, 4.1);
18137     });
18138
18139     QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
18140       assert.expect(1);
18141
18142       var actual = func(4160, -2);
18143       assert.strictEqual(actual, isFloor ? 4100 : 4200);
18144     });
18145
18146     QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
18147       assert.expect(3);
18148
18149       var actual = func(4.006, NaN);
18150       assert.strictEqual(actual, isCeil ? 5 : 4);
18151
18152       var expected = isFloor ? 4.01 : 4.02;
18153
18154       actual = func(4.016, 2.6);
18155       assert.strictEqual(actual, expected);
18156
18157       actual = func(4.016, '+2');
18158       assert.strictEqual(actual, expected);
18159     });
18160
18161     QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
18162       assert.expect(3);
18163
18164       var actual = func(5e1, 2);
18165       assert.deepEqual(actual, 50);
18166
18167       actual = func('5e', 1);
18168       assert.deepEqual(actual, NaN);
18169
18170       actual = func('5e1e1', 1);
18171       assert.deepEqual(actual, NaN);
18172     });
18173
18174     QUnit.test('`_.' + methodName + '` should preserve sign of `0`', function(assert) {
18175       assert.expect(1);
18176
18177       var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
18178           expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
18179
18180       var actual = lodashStable.map(values, function(args) {
18181         return 1 / func.apply(undefined, args);
18182       });
18183
18184       assert.deepEqual(actual, expected);
18185     });
18186   });
18187
18188   /*--------------------------------------------------------------------------*/
18189
18190   QUnit.module('lodash.runInContext');
18191
18192   (function() {
18193     QUnit.test('should not require a fully populated `context` object', function(assert) {
18194       assert.expect(1);
18195
18196       if (!isModularize) {
18197         var lodash = _.runInContext({
18198           'setTimeout': function(callback) {
18199             callback();
18200           }
18201         });
18202
18203         var pass = false;
18204         lodash.delay(function() { pass = true; }, 32);
18205         assert.ok(pass);
18206       }
18207       else {
18208         skipAssert(assert);
18209       }
18210     });
18211
18212     QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
18213       assert.expect(3);
18214
18215       if (!isModularize) {
18216         lodashStable.times(2, _.uniqueId);
18217
18218         var oldId = Number(_.uniqueId()),
18219             lodash = _.runInContext();
18220
18221         assert.ok(_.uniqueId() > oldId);
18222
18223         var id = lodash.uniqueId();
18224         assert.strictEqual(id, '1');
18225         assert.ok(id < oldId);
18226       }
18227       else {
18228         skipAssert(assert, 3);
18229       }
18230     });
18231   }());
18232
18233   /*--------------------------------------------------------------------------*/
18234
18235   QUnit.module('lodash.sample');
18236
18237   (function() {
18238     var array = [1, 2, 3];
18239
18240     QUnit.test('should return a random element', function(assert) {
18241       assert.expect(1);
18242
18243       var actual = _.sample(array);
18244       assert.ok(lodashStable.includes(array, actual));
18245     });
18246
18247     QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
18248       assert.expect(1);
18249
18250       var expected = lodashStable.map(empties, alwaysUndefined);
18251
18252       var actual = lodashStable.transform(empties, function(result, value) {
18253         try {
18254           result.push(_.sample(value));
18255         } catch (e) {}
18256       });
18257
18258       assert.deepEqual(actual, expected);
18259     });
18260
18261     QUnit.test('should sample an object', function(assert) {
18262       assert.expect(1);
18263
18264       var object = { 'a': 1, 'b': 2, 'c': 3 },
18265           actual = _.sample(object);
18266
18267       assert.ok(lodashStable.includes(array, actual));
18268     });
18269   }());
18270
18271   /*--------------------------------------------------------------------------*/
18272
18273   QUnit.module('lodash.sampleSize');
18274
18275   (function() {
18276     var array = [1, 2, 3];
18277
18278     QUnit.test('should return an array of random elements', function(assert) {
18279       assert.expect(2);
18280
18281       var actual = _.sampleSize(array, 2);
18282       assert.strictEqual(actual.length, 2);
18283       assert.deepEqual(lodashStable.difference(actual, array), []);
18284     });
18285
18286     QUnit.test('should contain elements of the collection', function(assert) {
18287       assert.expect(1);
18288
18289       var actual = _.sampleSize(array, array.length);
18290       assert.deepEqual(actual.sort(), array);
18291     });
18292
18293     QUnit.test('should treat falsey `n` values as `0`', function(assert) {
18294       assert.expect(1);
18295
18296       var expected = lodashStable.map(falsey, alwaysEmptyArray);
18297
18298       var actual = lodashStable.map(falsey, function(n, index) {
18299         return index ? _.sampleSize([1], n) : _.sampleSize([1]);
18300       });
18301
18302       assert.deepEqual(actual, expected);
18303     });
18304
18305     QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
18306       assert.expect(3);
18307
18308       lodashStable.each([0, -1, -Infinity], function(n) {
18309         assert.deepEqual(_.sampleSize(array, n), []);
18310       });
18311     });
18312
18313     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
18314       assert.expect(4);
18315
18316       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
18317         assert.deepEqual(_.sampleSize(array, n).sort(), array);
18318       });
18319     });
18320
18321     QUnit.test('should coerce `n` to an integer', function(assert) {
18322       assert.expect(1);
18323
18324       var actual = _.sampleSize(array, 1.6);
18325       assert.strictEqual(actual.length, 1);
18326     });
18327
18328     QUnit.test('should return an empty array for empty collections', function(assert) {
18329       assert.expect(1);
18330
18331       var expected = lodashStable.map(empties, alwaysEmptyArray);
18332
18333       var actual = lodashStable.transform(empties, function(result, value) {
18334         try {
18335           result.push(_.sampleSize(value, 1));
18336         } catch (e) {}
18337       });
18338
18339       assert.deepEqual(actual, expected);
18340     });
18341
18342     QUnit.test('should sample an object', function(assert) {
18343       assert.expect(2);
18344
18345       var object = { 'a': 1, 'b': 2, 'c': 3 },
18346           actual = _.sampleSize(object, 2);
18347
18348       assert.strictEqual(actual.length, 2);
18349       assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
18350     });
18351   }());
18352
18353   /*--------------------------------------------------------------------------*/
18354
18355   QUnit.module('lodash.setWith');
18356
18357   (function() {
18358     QUnit.test('should work with a `customizer` callback', function(assert) {
18359       assert.expect(1);
18360
18361       var actual = _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, function(value) {
18362         if (!lodashStable.isObject(value)) {
18363           return {};
18364         }
18365       });
18366
18367       assert.deepEqual(actual, { '0': { '1': { '2': 3 }, 'length': 2 } });
18368     });
18369
18370     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
18371       assert.expect(1);
18372
18373       var actual = _.setWith({}, 'a[0].b.c', 4, alwaysUndefined);
18374       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
18375     });
18376   }());
18377
18378   /*--------------------------------------------------------------------------*/
18379
18380   QUnit.module('set methods');
18381
18382   lodashStable.each(['set', 'setWith'], function(methodName) {
18383     var func = _[methodName];
18384
18385     QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
18386       assert.expect(4);
18387
18388       var object = { 'a': 1 };
18389
18390       lodashStable.each(['a', ['a']], function(path) {
18391         var actual = func(object, path, 2);
18392
18393         assert.strictEqual(actual, object);
18394         assert.strictEqual(object.a, 2);
18395
18396         object.a = 1;
18397       });
18398     });
18399
18400     QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
18401       assert.expect(4);
18402
18403       var object = { 'a': { 'b': { 'c': 3 } } };
18404
18405       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
18406         var actual = func(object, path, 4);
18407
18408         assert.strictEqual(actual, object);
18409         assert.strictEqual(object.a.b.c, 4);
18410
18411         object.a.b.c = 3;
18412       });
18413     });
18414
18415     QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
18416       assert.expect(4);
18417
18418       var object = { 'a.b.c': 3 };
18419
18420       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
18421         var actual = func(object, path, 4);
18422
18423         assert.strictEqual(actual, object);
18424         assert.deepEqual(object, { 'a.b.c': 4 });
18425
18426         object['a.b.c'] = 3;
18427       });
18428     });
18429
18430     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
18431       assert.expect(1);
18432
18433       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 3 } } };
18434       func(object, ['a', 'b', 'c'], 4);
18435       assert.strictEqual(object.a.b.c, 4);
18436     });
18437
18438     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
18439       assert.expect(1);
18440
18441       var object = {};
18442       func(object, 'a[]', 1);
18443       assert.deepEqual(object, { 'a': 1 });
18444     });
18445
18446     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
18447       assert.expect(4);
18448
18449       lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
18450         var object = {};
18451
18452         func(object, pair[0], 1);
18453         assert.deepEqual(object, index ? {} : { '': 1 });
18454
18455         func(object, pair[1], 2);
18456         assert.deepEqual(object, { '': 2 });
18457       });
18458     });
18459
18460     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
18461       assert.expect(2);
18462
18463       var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
18464
18465       var paths = [
18466         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
18467         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
18468       ];
18469
18470       lodashStable.each(paths, function(path) {
18471         func(object, path, 10);
18472         assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, 10);
18473         object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = 8;
18474       });
18475     });
18476
18477     QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
18478       assert.expect(6);
18479
18480       var object = {};
18481
18482       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
18483         var actual = func(object, path, 4);
18484
18485         assert.strictEqual(actual, object);
18486         assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': 4 } }] });
18487         assert.notOk('0' in object.a);
18488
18489         delete object.a;
18490       });
18491     });
18492
18493     QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
18494       assert.expect(1);
18495
18496       var values = [null, undefined],
18497           expected = [[null, null], [undefined, undefined]];
18498
18499       var actual = lodashStable.map(values, function(value) {
18500         try {
18501           return [func(value, 'a.b', 1), func(value, ['a', 'b'], 1)];
18502         } catch (e) {
18503           return e.message;
18504         }
18505       });
18506
18507       assert.deepEqual(actual, expected);
18508     });
18509
18510     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
18511       assert.expect(4);
18512
18513       var object = { 'a': '' },
18514           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
18515
18516       lodashStable.each(paths, function(path) {
18517         func(0, path, 1);
18518         assert.strictEqual(0..a, 1);
18519         delete numberProto.a;
18520       });
18521
18522       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
18523         func(object, path, 1);
18524         assert.strictEqual(stringProto.replace.b, 1);
18525         delete stringProto.replace.b;
18526       });
18527     });
18528
18529     QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
18530       'use strict';
18531
18532       assert.expect(2);
18533
18534       numberProto.a = 0;
18535
18536       lodashStable.each(['a', 'a.a.a'], function(path) {
18537         try {
18538           func(0, path, 1);
18539           assert.strictEqual(0..a, 0);
18540         } catch (e) {
18541           assert.ok(false, e.message);
18542         }
18543         numberProto.a = 0;
18544       });
18545
18546       delete numberProto.a;
18547     });
18548
18549     QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
18550       assert.expect(1);
18551
18552       var object = {};
18553
18554       func(object, ['1a', '2b', '3c'], 1);
18555       assert.deepEqual(object, { '1a': { '2b': { '3c': 1 } } });
18556     });
18557
18558     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
18559       assert.expect(4);
18560
18561       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
18562         if (defineProperty) {
18563           var object = {},
18564               pass = true;
18565
18566           defineProperty(object, 'a', {
18567             'enumerable': true,
18568             'configurable': true,
18569             'get': lodashStable.constant(value),
18570             'set': function() { pass = false; }
18571           });
18572
18573           func(object, 'a', value);
18574           assert.ok(pass);
18575         }
18576         else {
18577           skipAssert(assert);
18578         }
18579       });
18580     });
18581   });
18582
18583   /*--------------------------------------------------------------------------*/
18584
18585   QUnit.module('lodash.shuffle');
18586
18587   (function() {
18588     var array = [1, 2, 3],
18589         object = { 'a': 1, 'b': 2, 'c': 3 };
18590
18591     QUnit.test('should return a new array', function(assert) {
18592       assert.expect(1);
18593
18594       assert.notStrictEqual(_.shuffle(array), array);
18595     });
18596
18597     QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
18598       assert.expect(2);
18599
18600       assert.deepEqual(_.shuffle(array).sort(), array);
18601       assert.deepEqual(_.shuffle(object).sort(), array);
18602     });
18603
18604     QUnit.test('should shuffle small collections', function(assert) {
18605       assert.expect(1);
18606
18607       var actual = lodashStable.times(1000, function(assert) {
18608         return _.shuffle([1, 2]);
18609       });
18610
18611       assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
18612     });
18613
18614     QUnit.test('should treat number values for `collection` as empty', function(assert) {
18615       assert.expect(1);
18616
18617       assert.deepEqual(_.shuffle(1), []);
18618     });
18619   }());
18620
18621   /*--------------------------------------------------------------------------*/
18622
18623   QUnit.module('lodash.size');
18624
18625   (function() {
18626     var args = arguments,
18627         array = [1, 2, 3];
18628
18629     QUnit.test('should return the number of own enumerable properties of an object', function(assert) {
18630       assert.expect(1);
18631
18632       assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
18633     });
18634
18635     QUnit.test('should return the length of an array', function(assert) {
18636       assert.expect(1);
18637
18638       assert.strictEqual(_.size(array), 3);
18639     });
18640
18641     QUnit.test('should accept a falsey `object` argument', function(assert) {
18642       assert.expect(1);
18643
18644       var expected = lodashStable.map(falsey, alwaysZero);
18645
18646       var actual = lodashStable.map(falsey, function(object, index) {
18647         try {
18648           return index ? _.size(object) : _.size();
18649         } catch (e) {}
18650       });
18651
18652       assert.deepEqual(actual, expected);
18653     });
18654
18655     QUnit.test('should work with `arguments` objects', function(assert) {
18656       assert.expect(1);
18657
18658       assert.strictEqual(_.size(args), 3);
18659     });
18660
18661     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
18662       assert.expect(1);
18663
18664       function Foo(elements) { push.apply(this, elements); }
18665       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
18666
18667       assert.strictEqual(_.size(new Foo(array)), 3);
18668     });
18669
18670     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
18671       assert.expect(1);
18672
18673       assert.strictEqual(_.size({ 'length': -1 }), 1);
18674     });
18675
18676     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
18677       assert.expect(1);
18678
18679       assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
18680     });
18681
18682     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
18683       assert.expect(1);
18684
18685       assert.strictEqual(_.size({ 'length': '0' }), 1);
18686     });
18687   }(1, 2, 3));
18688
18689   /*--------------------------------------------------------------------------*/
18690
18691   QUnit.module('lodash.slice');
18692
18693   (function() {
18694     var array = [1, 2, 3];
18695
18696     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
18697       assert.expect(2);
18698
18699       var actual = _.slice(array);
18700       assert.deepEqual(actual, array);
18701       assert.notStrictEqual(actual, array);
18702     });
18703
18704     QUnit.test('should work with a positive `start`', function(assert) {
18705       assert.expect(2);
18706
18707       assert.deepEqual(_.slice(array, 1), [2, 3]);
18708       assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
18709     });
18710
18711     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
18712       assert.expect(4);
18713
18714       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
18715         assert.deepEqual(_.slice(array, start), []);
18716       });
18717     });
18718
18719     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
18720       assert.expect(1);
18721
18722       var expected = lodashStable.map(falsey, lodashStable.constant(array));
18723
18724       var actual = lodashStable.map(falsey, function(start) {
18725         return _.slice(array, start);
18726       });
18727
18728       assert.deepEqual(actual, expected);
18729     });
18730
18731     QUnit.test('should work with a negative `start`', function(assert) {
18732       assert.expect(1);
18733
18734       assert.deepEqual(_.slice(array, -1), [3]);
18735     });
18736
18737     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
18738       assert.expect(3);
18739
18740       lodashStable.each([-3, -4, -Infinity], function(start) {
18741         assert.deepEqual(_.slice(array, start), array);
18742       });
18743     });
18744
18745     QUnit.test('should work with `start` >= `end`', function(assert) {
18746       assert.expect(2);
18747
18748       lodashStable.each([2, 3], function(start) {
18749         assert.deepEqual(_.slice(array, start, 2), []);
18750       });
18751     });
18752
18753     QUnit.test('should work with a positive `end`', function(assert) {
18754       assert.expect(1);
18755
18756       assert.deepEqual(_.slice(array, 0, 1), [1]);
18757     });
18758
18759     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
18760       assert.expect(4);
18761
18762       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
18763         assert.deepEqual(_.slice(array, 0, end), array);
18764       });
18765     });
18766
18767     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
18768       assert.expect(1);
18769
18770       var expected = lodashStable.map(falsey, function(value) {
18771         return value === undefined ? array : [];
18772       });
18773
18774       var actual = lodashStable.map(falsey, function(end) {
18775         return _.slice(array, 0, end);
18776       });
18777
18778       assert.deepEqual(actual, expected);
18779     });
18780
18781     QUnit.test('should work with a negative `end`', function(assert) {
18782       assert.expect(1);
18783
18784       assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
18785     });
18786
18787     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
18788       assert.expect(3);
18789
18790       lodashStable.each([-3, -4, -Infinity], function(end) {
18791         assert.deepEqual(_.slice(array, 0, end), []);
18792       });
18793     });
18794
18795     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
18796       assert.expect(1);
18797
18798       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
18799
18800       var actual = lodashStable.map(positions, function(pos) {
18801         return _.slice.apply(_, [array].concat(pos));
18802       });
18803
18804       assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
18805     });
18806
18807     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18808       assert.expect(2);
18809
18810       var array = [[1], [2, 3]],
18811           actual = lodashStable.map(array, _.slice);
18812
18813       assert.deepEqual(actual, array);
18814       assert.notStrictEqual(actual, array);
18815     });
18816
18817     QUnit.test('should work in a lazy sequence', function(assert) {
18818       assert.expect(38);
18819
18820       if (!isNpm) {
18821         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
18822             length = array.length,
18823             wrapped = _(array);
18824
18825         lodashStable.each(['map', 'filter'], function(methodName) {
18826           assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
18827           assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
18828           assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
18829           assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
18830
18831           assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
18832           assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
18833           assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
18834           assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
18835
18836           assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
18837           assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
18838           assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
18839
18840           assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
18841           assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
18842
18843           assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
18844           assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
18845           assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
18846           assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
18847           assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
18848           assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
18849         });
18850       }
18851       else {
18852         skipAssert(assert, 38);
18853       }
18854     });
18855   }());
18856
18857   /*--------------------------------------------------------------------------*/
18858
18859   QUnit.module('lodash.some');
18860
18861   (function() {
18862     QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
18863       assert.expect(2);
18864
18865       assert.strictEqual(_.some([false, 1, ''], identity), true);
18866       assert.strictEqual(_.some([null, 'a', 0], identity), true);
18867     });
18868
18869     QUnit.test('should return `false` for empty collections', function(assert) {
18870       assert.expect(1);
18871
18872       var expected = lodashStable.map(empties, alwaysFalse);
18873
18874       var actual = lodashStable.map(empties, function(value) {
18875         try {
18876           return _.some(value, identity);
18877         } catch (e) {}
18878       });
18879
18880       assert.deepEqual(actual, expected);
18881     });
18882
18883     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
18884       assert.expect(2);
18885
18886       var count = 0;
18887
18888       assert.strictEqual(_.some([null, true, null], function(value) {
18889         count++;
18890         return value;
18891       }), true);
18892
18893       assert.strictEqual(count, 2);
18894     });
18895
18896     QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
18897       assert.expect(2);
18898
18899       assert.strictEqual(_.some([false, false, false], identity), false);
18900       assert.strictEqual(_.some([null, 0, ''], identity), false);
18901     });
18902
18903     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
18904       assert.expect(2);
18905
18906       var values = [, null, undefined],
18907           expected = lodashStable.map(values, alwaysFalse);
18908
18909       var actual = lodashStable.map(values, function(value, index) {
18910         var array = [0, 0];
18911         return index ? _.some(array, value) : _.some(array);
18912       });
18913
18914       assert.deepEqual(actual, expected);
18915
18916       expected = lodashStable.map(values, alwaysTrue);
18917       actual = lodashStable.map(values, function(value, index) {
18918         var array = [0, 1];
18919         return index ? _.some(array, value) : _.some(array);
18920       });
18921
18922       assert.deepEqual(actual, expected);
18923     });
18924
18925     QUnit.test('should work with "_.property" shorthands', function(assert) {
18926       assert.expect(2);
18927
18928       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
18929       assert.strictEqual(_.some(objects, 'a'), false);
18930       assert.strictEqual(_.some(objects, 'b'), true);
18931     });
18932
18933     QUnit.test('should work with "_.matches" shorthands', function(assert) {
18934       assert.expect(2);
18935
18936       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
18937       assert.strictEqual(_.some(objects, { 'a': 0 }), true);
18938       assert.strictEqual(_.some(objects, { 'b': 2 }), false);
18939     });
18940
18941     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18942       assert.expect(1);
18943
18944       var actual = lodashStable.map([[1]], _.some);
18945       assert.deepEqual(actual, [true]);
18946     });
18947   }());
18948
18949   /*--------------------------------------------------------------------------*/
18950
18951   QUnit.module('lodash.sortBy');
18952
18953   (function() {
18954     var objects = [
18955       { 'a': 'x', 'b': 3 },
18956       { 'a': 'y', 'b': 4 },
18957       { 'a': 'x', 'b': 1 },
18958       { 'a': 'y', 'b': 2 }
18959     ];
18960
18961     QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
18962       assert.expect(1);
18963
18964       var actual = lodashStable.map(_.sortBy(objects, function(object) {
18965         return object.b;
18966       }), 'b');
18967
18968       assert.deepEqual(actual, [1, 2, 3, 4]);
18969     });
18970
18971     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
18972       assert.expect(1);
18973
18974       var array = [3, 2, 1],
18975           values = [, null, undefined],
18976           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
18977
18978       var actual = lodashStable.map(values, function(value, index) {
18979         return index ? _.sortBy(array, value) : _.sortBy(array);
18980       });
18981
18982       assert.deepEqual(actual, expected);
18983     });
18984
18985     QUnit.test('should work with "_.property" shorthands', function(assert) {
18986       assert.expect(1);
18987
18988       var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
18989       assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
18990     });
18991
18992     QUnit.test('should work with an object for `collection`', function(assert) {
18993       assert.expect(1);
18994
18995       var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
18996       assert.deepEqual(actual, [3, 1, 2]);
18997     });
18998
18999     QUnit.test('should move `null`, `undefined`, and `NaN` values to the end', function(assert) {
19000       assert.expect(2);
19001
19002       var array = [NaN, undefined, null, 4, null, 1, undefined, 3, NaN, 2];
19003       assert.deepEqual(_.sortBy(array), [1, 2, 3, 4, null, null, undefined, undefined, NaN, NaN]);
19004
19005       array = [NaN, undefined, null, 'd', null, 'a', undefined, 'c', NaN, 'b'];
19006       assert.deepEqual(_.sortBy(array), ['a', 'b', 'c', 'd', null, null, undefined, undefined, NaN, NaN]);
19007     });
19008
19009     QUnit.test('should treat number values for `collection` as empty', function(assert) {
19010       assert.expect(1);
19011
19012       assert.deepEqual(_.sortBy(1), []);
19013     });
19014
19015     QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
19016       assert.expect(1);
19017
19018       var actual = _.sortBy(objects, function(object) {
19019         var result = [object.a, object.b];
19020         result.toString = function() { return String(this[0]); };
19021         return result;
19022       });
19023
19024       assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
19025     });
19026
19027     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19028       assert.expect(1);
19029
19030       var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
19031       assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
19032     });
19033   }());
19034
19035   /*--------------------------------------------------------------------------*/
19036
19037   QUnit.module('sortBy methods');
19038
19039   lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
19040     var func = _[methodName];
19041
19042     function Pair(a, b, c) {
19043       this.a = a;
19044       this.b = b;
19045       this.c = c;
19046     }
19047
19048     var objects = [
19049       { 'a': 'x', 'b': 3 },
19050       { 'a': 'y', 'b': 4 },
19051       { 'a': 'x', 'b': 1 },
19052       { 'a': 'y', 'b': 2 }
19053     ];
19054
19055     var stableArray = [
19056       new Pair(1, 1, 1), new Pair(1, 2, 1),
19057       new Pair(1, 1, 1), new Pair(1, 2, 1),
19058       new Pair(1, 3, 1), new Pair(1, 4, 1),
19059       new Pair(1, 5, 1), new Pair(1, 6, 1),
19060       new Pair(2, 1, 2), new Pair(2, 2, 2),
19061       new Pair(2, 3, 2), new Pair(2, 4, 2),
19062       new Pair(2, 5, 2), new Pair(2, 6, 2),
19063       new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
19064       new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
19065       new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
19066     ];
19067
19068     var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
19069
19070     QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
19071       assert.expect(1);
19072
19073       var actual = func(objects, ['a', 'b']);
19074       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
19075     });
19076
19077     QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
19078       assert.expect(1);
19079
19080       var actual = func(objects, ['a', function(object) { return object.b; }]);
19081       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
19082     });
19083
19084     QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
19085       assert.expect(2);
19086
19087       lodashStable.each([stableArray, stableObject], function(value, index) {
19088         var actual = func(value, ['a', 'c']);
19089         assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
19090       });
19091     });
19092
19093     QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
19094       assert.expect(1);
19095
19096       try {
19097         var actual = func(objects.concat(null, undefined), ['a', 'b']);
19098       } catch (e) {}
19099
19100       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
19101     });
19102
19103     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
19104       assert.expect(3);
19105
19106       var objects = [
19107         { 'a': 'x', '0': 3 },
19108         { 'a': 'y', '0': 4 },
19109         { 'a': 'x', '0': 1 },
19110         { 'a': 'y', '0': 2 }
19111       ];
19112
19113       var funcs = [func, lodashStable.partialRight(func, 'bogus')];
19114
19115       lodashStable.each(['a', 0, [0]], function(props, index) {
19116         var expected = lodashStable.map(funcs, lodashStable.constant(
19117           index
19118             ? [objects[2], objects[3], objects[0], objects[1]]
19119             : [objects[0], objects[2], objects[1], objects[3]]
19120         ));
19121
19122         var actual = lodashStable.map(funcs, function(func) {
19123           return lodashStable.reduce([props], func, objects);
19124         });
19125
19126         assert.deepEqual(actual, expected);
19127       });
19128     });
19129   });
19130
19131   /*--------------------------------------------------------------------------*/
19132
19133   QUnit.module('sortedIndex methods');
19134
19135   lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
19136     var func = _[methodName],
19137         isSortedIndex = methodName == 'sortedIndex';
19138
19139     QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
19140       assert.expect(1);
19141
19142       var array = [30, 50],
19143           values = [30, 40, 50],
19144           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
19145
19146       var actual = lodashStable.map(values, function(value) {
19147         return func(array, value);
19148       });
19149
19150       assert.deepEqual(actual, expected);
19151     });
19152
19153     QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
19154       assert.expect(1);
19155
19156       var array = ['a', 'c'],
19157           values = ['a', 'b', 'c'],
19158           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
19159
19160       var actual = lodashStable.map(values, function(value) {
19161         return func(array, value);
19162       });
19163
19164       assert.deepEqual(actual, expected);
19165     });
19166
19167     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
19168       assert.expect(1);
19169
19170       var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
19171
19172       var actual = lodashStable.map(falsey, function(array) {
19173         return [func(array, 1), func(array, undefined), func(array, NaN)];
19174       });
19175
19176       assert.deepEqual(actual, expected);
19177     });
19178
19179     QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
19180       assert.expect(10);
19181
19182       var expected = [1, '2', {}, null, undefined, NaN, NaN];
19183
19184       lodashStable.each([
19185         [NaN, null, 1, '2', {}, NaN, undefined],
19186         ['2', null, 1, NaN, {}, NaN, undefined]
19187       ], function(array) {
19188         assert.deepEqual(_.sortBy(array), expected);
19189         assert.strictEqual(func(expected, 3), 2);
19190         assert.strictEqual(func(expected, null), isSortedIndex ? 3 : 4);
19191         assert.strictEqual(func(expected, undefined), isSortedIndex ? 4 : 5);
19192         assert.strictEqual(func(expected, NaN), isSortedIndex ? 5 : 7);
19193       });
19194     });
19195   });
19196
19197   /*--------------------------------------------------------------------------*/
19198
19199   QUnit.module('sortedIndexBy methods');
19200
19201   lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
19202     var func = _[methodName],
19203         isSortedIndexBy = methodName == 'sortedIndexBy';
19204
19205     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
19206       assert.expect(1);
19207
19208       var args;
19209
19210       func([30, 50], 40, function(assert) {
19211         args || (args = slice.call(arguments));
19212       });
19213
19214       assert.deepEqual(args, [40]);
19215     });
19216
19217     QUnit.test('`_.' + methodName + '` should work with "_.property" shorthands', function(assert) {
19218       assert.expect(1);
19219
19220       var objects = [{ 'x': 30 }, { 'x': 50 }],
19221           actual = func(objects, { 'x': 40 }, 'x');
19222
19223       assert.strictEqual(actual, 1);
19224     });
19225
19226     QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
19227       assert.expect(12);
19228
19229       lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
19230         var array = [],
19231             values = [MAX_ARRAY_LENGTH, NaN, undefined];
19232
19233         array.length = length;
19234
19235         lodashStable.each(values, function(value) {
19236           var steps = 0;
19237
19238           var actual = func(array, value, function(value) {
19239             steps++;
19240             return value;
19241           });
19242
19243           var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
19244             ? 0
19245             : Math.min(length, MAX_ARRAY_INDEX);
19246
19247           // Avoid false fails in older Firefox.
19248           if (array.length == length) {
19249             assert.ok(steps == 32 || steps == 33);
19250             assert.strictEqual(actual, expected);
19251           }
19252           else {
19253             skipAssert(assert, 2);
19254           }
19255         });
19256       });
19257     });
19258   });
19259
19260   /*--------------------------------------------------------------------------*/
19261
19262   QUnit.module('sortedIndexOf methods');
19263
19264   lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
19265     var func = _[methodName],
19266         isSortedIndexOf = methodName == 'sortedIndexOf';
19267
19268     QUnit.test('should perform a binary search', function(assert) {
19269       assert.expect(1);
19270
19271       var sorted = [4, 4, 5, 5, 6, 6];
19272       assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
19273     });
19274   });
19275
19276   /*--------------------------------------------------------------------------*/
19277
19278   QUnit.module('lodash.sortedUniq');
19279
19280   (function() {
19281     QUnit.test('should return unique values of a sorted array', function(assert) {
19282       assert.expect(3);
19283
19284       var expected = [1, 2, 3];
19285
19286       lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
19287         assert.deepEqual(_.sortedUniq(array), expected);
19288       });
19289     });
19290   }());
19291
19292   /*--------------------------------------------------------------------------*/
19293
19294   QUnit.module('lodash.split');
19295
19296   (function() {
19297     QUnit.test('should support string split', function(assert) {
19298       assert.expect(3);
19299
19300       var string = 'abcde';
19301       assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
19302       assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
19303       assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
19304     });
19305
19306     QUnit.test('should allow mixed string and array prototype methods', function(assert) {
19307       assert.expect(1);
19308
19309       if (!isNpm) {
19310         var wrapped = _('abc');
19311         assert.strictEqual(wrapped.split('b').join(','), 'a,c');
19312       }
19313       else {
19314         skipAssert(assert);
19315       }
19316     });
19317   }());
19318
19319   /*--------------------------------------------------------------------------*/
19320
19321   QUnit.module('lodash.spread');
19322
19323   (function() {
19324     function fn(a, b, c) {
19325       return slice.call(arguments);
19326     }
19327
19328     QUnit.test('should spread arguments to `func`', function(assert) {
19329       assert.expect(1);
19330
19331       var spread = _.spread(fn);
19332       assert.deepEqual(spread([4, 2]), [4, 2]);
19333     });
19334
19335     QUnit.test('should accept a falsey `array` argument', function(assert) {
19336       assert.expect(1);
19337
19338       var spread = _.spread(alwaysTrue),
19339           expected = lodashStable.map(falsey, alwaysTrue);
19340
19341       var actual = lodashStable.map(falsey, function(array, index) {
19342         try {
19343           return index ? spread(array) : spread();
19344         } catch (e) {}
19345       });
19346
19347       assert.deepEqual(actual, expected);
19348     });
19349
19350     QUnit.test('should provide the correct `func` arguments', function(assert) {
19351       assert.expect(1);
19352
19353       var args;
19354
19355       var spread = _.spread(function() {
19356         args = slice.call(arguments);
19357       });
19358
19359       spread([4, 2], 'ignored');
19360       assert.deepEqual(args, [4, 2]);
19361     });
19362
19363     QUnit.test('should work with `start`', function(assert) {
19364       assert.expect(1);
19365
19366       var spread = _.spread(fn, 1);
19367       assert.deepEqual(spread(1, [2, 3, 4]), [1, 2, 3, 4]);
19368     });
19369
19370     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
19371       assert.expect(1);
19372
19373       var values = [-1, NaN, 'a'],
19374           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
19375
19376       var actual = lodashStable.map(values, function(value) {
19377         var spread = _.spread(fn, value);
19378         return spread([1, 2, 3, 4]);
19379       });
19380
19381       assert.deepEqual(actual, expected);
19382     });
19383
19384     QUnit.test('should coerce `start` to an integer', function(assert) {
19385       assert.expect(1);
19386
19387       var spread = _.spread(fn, 1.6);
19388       assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
19389     });
19390   }());
19391
19392   /*--------------------------------------------------------------------------*/
19393
19394   QUnit.module('lodash.startsWith');
19395
19396   (function() {
19397     var string = 'abc';
19398
19399     QUnit.test('should return `true` if a string starts with `target`', function(assert) {
19400       assert.expect(1);
19401
19402       assert.strictEqual(_.startsWith(string, 'a'), true);
19403     });
19404
19405     QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
19406       assert.expect(1);
19407
19408       assert.strictEqual(_.startsWith(string, 'b'), false);
19409     });
19410
19411     QUnit.test('should work with a `position` argument', function(assert) {
19412       assert.expect(1);
19413
19414       assert.strictEqual(_.startsWith(string, 'b', 1), true);
19415     });
19416
19417     QUnit.test('should work with `position` >= `string.length`', function(assert) {
19418       assert.expect(4);
19419
19420       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
19421         assert.strictEqual(_.startsWith(string, 'a', position), false);
19422       });
19423     });
19424
19425     QUnit.test('should treat falsey `position` values as `0`', function(assert) {
19426       assert.expect(1);
19427
19428       var expected = lodashStable.map(falsey, alwaysTrue);
19429
19430       var actual = lodashStable.map(falsey, function(position) {
19431         return _.startsWith(string, 'a', position);
19432       });
19433
19434       assert.deepEqual(actual, expected);
19435     });
19436
19437     QUnit.test('should treat a negative `position` as `0`', function(assert) {
19438       assert.expect(6);
19439
19440       lodashStable.each([-1, -3, -Infinity], function(position) {
19441         assert.strictEqual(_.startsWith(string, 'a', position), true);
19442         assert.strictEqual(_.startsWith(string, 'b', position), false);
19443       });
19444     });
19445
19446     QUnit.test('should coerce `position` to an integer', function(assert) {
19447       assert.expect(1);
19448
19449       assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
19450     });
19451
19452     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
19453       assert.expect(1);
19454
19455       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
19456         return _.startsWith(string, '', position, true);
19457       }));
19458     });
19459   }());
19460
19461   /*--------------------------------------------------------------------------*/
19462
19463   QUnit.module('lodash.startsWith and lodash.endsWith');
19464
19465   lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
19466     var func = _[methodName],
19467         isStartsWith = methodName == 'startsWith';
19468
19469     var string = 'abc',
19470         chr = isStartsWith ? 'a' : 'c';
19471
19472     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
19473       assert.expect(2);
19474
19475       assert.strictEqual(func(Object(string), chr), true);
19476       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
19477     });
19478
19479     QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
19480       assert.expect(2);
19481
19482       assert.strictEqual(func(string, Object(chr)), true);
19483       assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
19484     });
19485
19486     QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
19487       assert.expect(2);
19488
19489       var position = isStartsWith ? 1 : 2;
19490       assert.strictEqual(func(string, 'b', Object(position)), true);
19491       assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
19492     });
19493   });
19494
19495   /*--------------------------------------------------------------------------*/
19496
19497   QUnit.module('lodash.subtract');
19498
19499   (function() {
19500     QUnit.test('should subtract two numbers', function(assert) {
19501       assert.expect(3);
19502
19503       assert.strictEqual(_.subtract(6, 4), 2);
19504       assert.strictEqual(_.subtract(-6, 4), -10);
19505       assert.strictEqual(_.subtract(-6, -4), -2);
19506     });
19507
19508     QUnit.test('should return `0` when no arguments are given', function(assert) {
19509       assert.expect(1);
19510
19511       assert.strictEqual(_.subtract(), 0);
19512     });
19513
19514     QUnit.test('should coerce arguments only numbers', function(assert) {
19515       assert.expect(2);
19516
19517       assert.strictEqual(_.subtract('6', '4'), 2);
19518       assert.deepEqual(_.subtract('x', 'y'), NaN);
19519     });
19520
19521     QUnit.test('should work with only a `minuend` or `subtrahend`', function(assert) {
19522       assert.expect(3);
19523
19524       assert.strictEqual(_.subtract(6), 6);
19525       assert.strictEqual(_.subtract(6, undefined), 6);
19526       assert.strictEqual(_.subtract(undefined, 4), 4);
19527     });
19528
19529     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
19530       assert.expect(1);
19531
19532       if (!isNpm) {
19533         assert.strictEqual(_(1).subtract(2), -1);
19534       }
19535       else {
19536         skipAssert(assert);
19537       }
19538     });
19539
19540     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
19541       assert.expect(1);
19542
19543       if (!isNpm) {
19544         assert.ok(_(1).chain().subtract(2) instanceof _);
19545       }
19546       else {
19547         skipAssert(assert);
19548       }
19549     });
19550   }());
19551
19552   /*--------------------------------------------------------------------------*/
19553
19554   QUnit.module('lodash.sum');
19555
19556   (function() {
19557     var array = [6, 4, 2];
19558
19559     QUnit.test('should return the sum of an array of numbers', function(assert) {
19560       assert.expect(1);
19561
19562       assert.strictEqual(_.sum(array), 12);
19563     });
19564
19565     QUnit.test('should return `0` when passing empty `array` values', function(assert) {
19566       assert.expect(1);
19567
19568       var expected = lodashStable.map(empties, alwaysZero),
19569           actual = lodashStable.map(empties, _.sum);
19570
19571       assert.deepEqual(actual, expected);
19572     });
19573
19574     QUnit.test('should skip `undefined` values', function(assert) {
19575       assert.expect(1);
19576
19577       assert.strictEqual(_.sum([1, undefined]), 1);
19578     });
19579
19580     QUnit.test('should not skip `NaN` values', function(assert) {
19581       assert.expect(1);
19582
19583       assert.deepEqual(_.sum([1, NaN]), NaN);
19584     });
19585
19586     QUnit.test('should not coerce values to numbers', function(assert) {
19587       assert.expect(1);
19588
19589       assert.strictEqual(_.sum(['1', '2']), '12');
19590     });
19591   }());
19592
19593   /*--------------------------------------------------------------------------*/
19594
19595   QUnit.module('lodash.sumBy');
19596
19597   (function() {
19598     var array = [6, 4, 2],
19599         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
19600
19601     QUnit.test('should work with an `iteratee` argument', function(assert) {
19602       assert.expect(1);
19603
19604       var actual = _.sumBy(objects, function(object) {
19605         return object.a;
19606       });
19607
19608       assert.deepEqual(actual, 6);
19609     });
19610
19611     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
19612       assert.expect(1);
19613
19614       var args;
19615
19616       _.sumBy(array, function() {
19617         args || (args = slice.call(arguments));
19618       });
19619
19620       assert.deepEqual(args, [6]);
19621     });
19622
19623     QUnit.test('should work with "_.property" shorthands', function(assert) {
19624       assert.expect(2);
19625
19626       var arrays = [[2], [3], [1]];
19627       assert.strictEqual(_.sumBy(arrays, 0), 6);
19628       assert.strictEqual(_.sumBy(objects, 'a'), 6);
19629     });
19630   }());
19631
19632   /*--------------------------------------------------------------------------*/
19633
19634   QUnit.module('lodash.tail');
19635
19636   (function() {
19637     var array = [1, 2, 3];
19638
19639     QUnit.test('should accept a falsey `array` argument', function(assert) {
19640       assert.expect(1);
19641
19642       var expected = lodashStable.map(falsey, alwaysEmptyArray);
19643
19644       var actual = lodashStable.map(falsey, function(array, index) {
19645         try {
19646           return index ? _.tail(array) : _.tail();
19647         } catch (e) {}
19648       });
19649
19650       assert.deepEqual(actual, expected);
19651     });
19652
19653     QUnit.test('should exclude the first element', function(assert) {
19654       assert.expect(1);
19655
19656       assert.deepEqual(_.tail(array), [2, 3]);
19657     });
19658
19659     QUnit.test('should return an empty when querying empty arrays', function(assert) {
19660       assert.expect(1);
19661
19662       assert.deepEqual(_.tail([]), []);
19663     });
19664
19665     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19666       assert.expect(1);
19667
19668       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
19669           actual = lodashStable.map(array, _.tail);
19670
19671       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
19672     });
19673
19674     QUnit.test('should work in a lazy sequence', function(assert) {
19675       assert.expect(4);
19676
19677       if (!isNpm) {
19678         var array = lodashStable.range(LARGE_ARRAY_SIZE),
19679             values = [];
19680
19681         var actual = _(array).tail().filter(function(value) {
19682           values.push(value);
19683           return false;
19684         })
19685         .value();
19686
19687         assert.deepEqual(actual, []);
19688         assert.deepEqual(values, array.slice(1));
19689
19690         values = [];
19691
19692         actual = _(array).filter(function(value) {
19693           values.push(value);
19694           return isEven(value);
19695         })
19696         .tail()
19697         .value();
19698
19699         assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
19700         assert.deepEqual(values, array);
19701       }
19702       else {
19703         skipAssert(assert, 4);
19704       }
19705     });
19706
19707     QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
19708       assert.expect(4);
19709
19710       if (!isNpm) {
19711         var array = lodashStable.range(LARGE_ARRAY_SIZE),
19712             iteratee = function() { pass = false; },
19713             pass = true,
19714             actual = _(array).slice(0, 1).tail().map(iteratee).value();
19715
19716         assert.ok(pass);
19717         assert.deepEqual(actual, []);
19718
19719         pass = true;
19720         actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
19721
19722         assert.ok(pass);
19723         assert.deepEqual(actual, []);
19724       }
19725       else {
19726         skipAssert(assert, 4);
19727       }
19728     });
19729   }());
19730
19731   /*--------------------------------------------------------------------------*/
19732
19733   QUnit.module('lodash.take');
19734
19735   (function() {
19736     var array = [1, 2, 3];
19737
19738     QUnit.test('should take the first two elements', function(assert) {
19739       assert.expect(1);
19740
19741       assert.deepEqual(_.take(array, 2), [1, 2]);
19742     });
19743
19744     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
19745       assert.expect(1);
19746
19747       var expected = lodashStable.map(falsey, function(value) {
19748         return value === undefined ? [1] : [];
19749       });
19750
19751       var actual = lodashStable.map(falsey, function(n) {
19752         return _.take(array, n);
19753       });
19754
19755       assert.deepEqual(actual, expected);
19756     });
19757
19758     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
19759       assert.expect(3);
19760
19761       lodashStable.each([0, -1, -Infinity], function(n) {
19762         assert.deepEqual(_.take(array, n), []);
19763       });
19764     });
19765
19766     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
19767       assert.expect(4);
19768
19769       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19770         assert.deepEqual(_.take(array, n), array);
19771       });
19772     });
19773
19774     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19775       assert.expect(1);
19776
19777       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
19778           actual = lodashStable.map(array, _.take);
19779
19780       assert.deepEqual(actual, [[1], [4], [7]]);
19781     });
19782
19783     QUnit.test('should work in a lazy sequence', function(assert) {
19784       assert.expect(6);
19785
19786       if (!isNpm) {
19787         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
19788             predicate = function(value) { values.push(value); return isEven(value); },
19789             values = [],
19790             actual = _(array).take(2).take().value();
19791
19792         assert.deepEqual(actual, _.take(_.take(array, 2)));
19793
19794         actual = _(array).filter(predicate).take(2).take().value();
19795         assert.deepEqual(values, [1, 2]);
19796         assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
19797
19798         actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
19799         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
19800
19801         values = [];
19802
19803         actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
19804         assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
19805         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
19806       }
19807       else {
19808         skipAssert(assert, 6);
19809       }
19810     });
19811   }());
19812
19813   /*--------------------------------------------------------------------------*/
19814
19815   QUnit.module('lodash.takeRight');
19816
19817   (function() {
19818     var array = [1, 2, 3];
19819
19820     QUnit.test('should take the last two elements', function(assert) {
19821       assert.expect(1);
19822
19823       assert.deepEqual(_.takeRight(array, 2), [2, 3]);
19824     });
19825
19826     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
19827       assert.expect(1);
19828
19829       var expected = lodashStable.map(falsey, function(value) {
19830         return value === undefined ? [3] : [];
19831       });
19832
19833       var actual = lodashStable.map(falsey, function(n) {
19834         return _.takeRight(array, n);
19835       });
19836
19837       assert.deepEqual(actual, expected);
19838     });
19839
19840     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
19841       assert.expect(3);
19842
19843       lodashStable.each([0, -1, -Infinity], function(n) {
19844         assert.deepEqual(_.takeRight(array, n), []);
19845       });
19846     });
19847
19848     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
19849       assert.expect(4);
19850
19851       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19852         assert.deepEqual(_.takeRight(array, n), array);
19853       });
19854     });
19855
19856     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19857       assert.expect(1);
19858
19859       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
19860           actual = lodashStable.map(array, _.takeRight);
19861
19862       assert.deepEqual(actual, [[3], [6], [9]]);
19863     });
19864
19865     QUnit.test('should work in a lazy sequence', function(assert) {
19866       assert.expect(6);
19867
19868       if (!isNpm) {
19869         var array = lodashStable.range(LARGE_ARRAY_SIZE),
19870             predicate = function(value) { values.push(value); return isEven(value); },
19871             values = [],
19872             actual = _(array).takeRight(2).takeRight().value();
19873
19874         assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
19875
19876         actual = _(array).filter(predicate).takeRight(2).takeRight().value();
19877         assert.deepEqual(values, array);
19878         assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
19879
19880         actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
19881         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
19882
19883         values = [];
19884
19885         actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
19886         assert.deepEqual(values, array);
19887         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
19888       }
19889       else {
19890         skipAssert(assert, 6);
19891       }
19892     });
19893   }());
19894
19895   /*--------------------------------------------------------------------------*/
19896
19897   QUnit.module('lodash.takeRightWhile');
19898
19899   (function() {
19900     var array = [1, 2, 3, 4];
19901
19902     var objects = [
19903       { 'a': 0, 'b': 0 },
19904       { 'a': 1, 'b': 1 },
19905       { 'a': 2, 'b': 2 }
19906     ];
19907
19908     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
19909       assert.expect(1);
19910
19911       var actual = _.takeRightWhile(array, function(n) {
19912         return n > 2;
19913       });
19914
19915       assert.deepEqual(actual, [3, 4]);
19916     });
19917
19918     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
19919       assert.expect(1);
19920
19921       var args;
19922
19923       _.takeRightWhile(array, function() {
19924         args = slice.call(arguments);
19925       });
19926
19927       assert.deepEqual(args, [4, 3, array]);
19928     });
19929
19930     QUnit.test('should work with "_.matches" shorthands', function(assert) {
19931       assert.expect(1);
19932
19933       assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
19934     });
19935
19936     QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
19937       assert.expect(1);
19938
19939       assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
19940     });
19941
19942     QUnit.test('should work with "_.property" shorthands', function(assert) {
19943       assert.expect(1);
19944
19945       assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
19946     });
19947
19948     QUnit.test('should work in a lazy sequence', function(assert) {
19949       assert.expect(3);
19950
19951       if (!isNpm) {
19952         var array = lodashStable.range(LARGE_ARRAY_SIZE),
19953             predicate = function(n) { return n > 2; },
19954             expected = _.takeRightWhile(array, predicate),
19955             wrapped = _(array).takeRightWhile(predicate);
19956
19957         assert.deepEqual(wrapped.value(), expected);
19958         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
19959         assert.strictEqual(wrapped.last(), _.last(expected));
19960       }
19961       else {
19962         skipAssert(assert, 3);
19963       }
19964     });
19965
19966     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
19967       assert.expect(5);
19968
19969       if (!isNpm) {
19970         var args,
19971             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19972             expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
19973
19974         _(array).slice(1).takeRightWhile(function(value, index, array) {
19975           args = slice.call(arguments);
19976         }).value();
19977
19978         assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
19979
19980         _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
19981           args = slice.call(arguments);
19982         }).value();
19983
19984         assert.deepEqual(args, expected);
19985
19986         _(array).slice(1).map(square).takeRightWhile(function(value, index) {
19987           args = slice.call(arguments);
19988         }).value();
19989
19990         assert.deepEqual(args, expected);
19991
19992         _(array).slice(1).map(square).takeRightWhile(function(index) {
19993           args = slice.call(arguments);
19994         }).value();
19995
19996         assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
19997
19998         _(array).slice(1).map(square).takeRightWhile(function() {
19999           args = slice.call(arguments);
20000         }).value();
20001
20002         assert.deepEqual(args, expected);
20003       }
20004       else {
20005         skipAssert(assert, 5);
20006       }
20007     });
20008   }());
20009
20010   /*--------------------------------------------------------------------------*/
20011
20012   QUnit.module('lodash.takeWhile');
20013
20014   (function() {
20015     var array = [1, 2, 3, 4];
20016
20017     var objects = [
20018       { 'a': 2, 'b': 2 },
20019       { 'a': 1, 'b': 1 },
20020       { 'a': 0, 'b': 0 }
20021     ];
20022
20023     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
20024       assert.expect(1);
20025
20026       var actual = _.takeWhile(array, function(n) {
20027         return n < 3;
20028       });
20029
20030       assert.deepEqual(actual, [1, 2]);
20031     });
20032
20033     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
20034       assert.expect(1);
20035
20036       var args;
20037
20038       _.takeWhile(array, function() {
20039         args = slice.call(arguments);
20040       });
20041
20042       assert.deepEqual(args, [1, 0, array]);
20043     });
20044
20045     QUnit.test('should work with "_.matches" shorthands', function(assert) {
20046       assert.expect(1);
20047
20048       assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
20049     });
20050
20051     QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
20052       assert.expect(1);
20053
20054       assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
20055     });
20056     QUnit.test('should work with "_.property" shorthands', function(assert) {
20057       assert.expect(1);
20058
20059       assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
20060     });
20061
20062     QUnit.test('should work in a lazy sequence', function(assert) {
20063       assert.expect(3);
20064
20065       if (!isNpm) {
20066         var array = lodashStable.range(LARGE_ARRAY_SIZE),
20067             predicate = function(n) { return n < 3; },
20068             expected = _.takeWhile(array, predicate),
20069             wrapped = _(array).takeWhile(predicate);
20070
20071         assert.deepEqual(wrapped.value(), expected);
20072         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
20073         assert.strictEqual(wrapped.last(), _.last(expected));
20074       }
20075       else {
20076         skipAssert(assert, 3);
20077       }
20078     });
20079
20080     QUnit.test('should work in a lazy sequence with `take`', function(assert) {
20081       assert.expect(1);
20082
20083       if (!isNpm) {
20084         var array = lodashStable.range(LARGE_ARRAY_SIZE);
20085
20086         var actual = _(array)
20087           .takeWhile(function(n) { return n < 4; })
20088           .take(2)
20089           .takeWhile(function(n) { return n == 0; })
20090           .value();
20091
20092         assert.deepEqual(actual, [0]);
20093       }
20094       else {
20095         skipAssert(assert);
20096       }
20097     });
20098
20099     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
20100       assert.expect(5);
20101
20102       if (!isNpm) {
20103         var args,
20104             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
20105             expected = [1, 0, lodashStable.map(array.slice(1), square)];
20106
20107         _(array).slice(1).takeWhile(function(value, index, array) {
20108           args = slice.call(arguments);
20109         }).value();
20110
20111         assert.deepEqual(args, [1, 0, array.slice(1)]);
20112
20113         _(array).slice(1).map(square).takeWhile(function(value, index, array) {
20114           args = slice.call(arguments);
20115         }).value();
20116
20117         assert.deepEqual(args, expected);
20118
20119         _(array).slice(1).map(square).takeWhile(function(value, index) {
20120           args = slice.call(arguments);
20121         }).value();
20122
20123         assert.deepEqual(args, expected);
20124
20125         _(array).slice(1).map(square).takeWhile(function(value) {
20126           args = slice.call(arguments);
20127         }).value();
20128
20129         assert.deepEqual(args, [1]);
20130
20131         _(array).slice(1).map(square).takeWhile(function() {
20132           args = slice.call(arguments);
20133         }).value();
20134
20135         assert.deepEqual(args, expected);
20136       }
20137       else {
20138         skipAssert(assert, 5);
20139       }
20140     });
20141   }());
20142
20143   /*--------------------------------------------------------------------------*/
20144
20145   QUnit.module('lodash.tap');
20146
20147   (function() {
20148     QUnit.test('should intercept and return the given value', function(assert) {
20149       assert.expect(2);
20150
20151       if (!isNpm) {
20152         var intercepted,
20153             array = [1, 2, 3];
20154
20155         var actual = _.tap(array, function(value) {
20156           intercepted = value;
20157         });
20158
20159         assert.strictEqual(actual, array);
20160         assert.strictEqual(intercepted, array);
20161       }
20162       else {
20163         skipAssert(assert, 2);
20164       }
20165     });
20166
20167     QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
20168       assert.expect(2);
20169
20170       if (!isNpm) {
20171         var intercepted,
20172             array = [1, 2, 3];
20173
20174         var wrapped = _(array).tap(function(value) {
20175           intercepted = value;
20176           value.pop();
20177         });
20178
20179         assert.ok(wrapped instanceof _);
20180
20181         wrapped.value();
20182         assert.strictEqual(intercepted, array);
20183       }
20184       else {
20185         skipAssert(assert, 2);
20186       }
20187     });
20188   }());
20189
20190   /*--------------------------------------------------------------------------*/
20191
20192   QUnit.module('lodash.template');
20193
20194   (function() {
20195     QUnit.test('should escape values in "escape" delimiters', function(assert) {
20196       assert.expect(1);
20197
20198       var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
20199           expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
20200           data = { 'value': '&<>"\'`\/' };
20201
20202       var actual = lodashStable.map(strings, function(string) {
20203         return _.template(string)(data);
20204       });
20205
20206       assert.deepEqual(actual, expected);
20207     });
20208
20209     QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
20210       assert.expect(1);
20211
20212       var compiled = _.template('<%= typeof __e %>');
20213       assert.strictEqual(compiled({}), 'undefined');
20214     });
20215
20216     QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
20217       assert.expect(1);
20218
20219       var compiled = _.template(
20220         '<ul><%\
20221         for (var key in collection) {\
20222           %><li><%= collection[key] %></li><%\
20223         } %></ul>'
20224       );
20225
20226       var data = { 'collection': { 'a': 'A', 'b': 'B' } },
20227           actual = compiled(data);
20228
20229       assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
20230     });
20231
20232     QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
20233       assert.expect(1);
20234
20235       var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
20236           data = { 'value': true };
20237
20238       assert.strictEqual(compiled(data), 'yap');
20239     });
20240
20241     QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
20242       assert.expect(1);
20243
20244       var compiled = _.template('<% var b = a; %><%= b.value %>'),
20245           data = { 'a': { 'value': 1 } };
20246
20247       assert.strictEqual(compiled(data), '1');
20248     });
20249
20250     QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
20251       assert.expect(1);
20252
20253       var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
20254           expected = lodashStable.map(strings, lodashStable.constant('ABC')),
20255           data = { 'a': 'A' };
20256
20257       var actual = lodashStable.map(strings, function(string) {
20258         return _.template(string)(data);
20259       });
20260
20261       assert.deepEqual(actual, expected);
20262     });
20263
20264     QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
20265       assert.expect(1);
20266
20267       var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
20268           data = { 'a': true };
20269
20270       assert.strictEqual(compiled(data), 'a="A"');
20271     });
20272
20273     QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
20274       assert.expect(1);
20275
20276       var compiled = _.template('<%= value ? value : "b" %>'),
20277           data = { 'value': 'a' };
20278
20279       assert.strictEqual(compiled(data), 'a');
20280     });
20281
20282     QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
20283       assert.expect(1);
20284
20285       var compiled = _.template('<%= typeof Math.abs %>');
20286
20287       try {
20288         var actual = compiled();
20289       } catch (e) {}
20290
20291       assert.strictEqual(actual, 'function');
20292     });
20293
20294     QUnit.test('should support complex "interpolate" delimiters', function(assert) {
20295       assert.expect(22);
20296
20297       lodashStable.forOwn({
20298         '<%= a + b %>': '3',
20299         '<%= b - a %>': '1',
20300         '<%= a = b %>': '2',
20301         '<%= !a %>': 'false',
20302         '<%= ~a %>': '-2',
20303         '<%= a * b %>': '2',
20304         '<%= a / b %>': '0.5',
20305         '<%= a % b %>': '1',
20306         '<%= a >> b %>': '0',
20307         '<%= a << b %>': '4',
20308         '<%= a & b %>': '0',
20309         '<%= a ^ b %>': '3',
20310         '<%= a | b %>': '3',
20311         '<%= {}.toString.call(0) %>': numberTag,
20312         '<%= a.toFixed(2) %>': '1.00',
20313         '<%= obj["a"] %>': '1',
20314         '<%= delete a %>': 'true',
20315         '<%= "a" in obj %>': 'true',
20316         '<%= obj instanceof Object %>': 'true',
20317         '<%= new Boolean %>': 'false',
20318         '<%= typeof a %>': 'number',
20319         '<%= void a %>': ''
20320       },
20321       function(value, key) {
20322         var compiled = _.template(key),
20323             data = { 'a': 1, 'b': 2 };
20324
20325         assert.strictEqual(compiled(data), value, key);
20326       });
20327     });
20328
20329     QUnit.test('should support ES6 template delimiters', function(assert) {
20330       assert.expect(2);
20331
20332       var data = { 'value': 2 };
20333       assert.strictEqual(_.template('1${value}3')(data), '123');
20334       assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
20335     });
20336
20337     QUnit.test('should support the "imports" option', function(assert) {
20338       assert.expect(1);
20339
20340       var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
20341       assert.strictEqual(compiled({}), '1');
20342     });
20343
20344     QUnit.test('should support the "variable" options', function(assert) {
20345       assert.expect(1);
20346
20347       var compiled = _.template(
20348         '<% _.each( data.a, function( value ) { %>' +
20349             '<%= value.valueOf() %>' +
20350         '<% }) %>', { 'variable': 'data' }
20351       );
20352
20353       var data = { 'a': [1, 2, 3] };
20354
20355       try {
20356         assert.strictEqual(compiled(data), '123');
20357       } catch (e) {
20358         assert.ok(false, e.message);
20359       }
20360     });
20361
20362     QUnit.test('should support custom delimiters', function(assert) {
20363       assert.expect(2);
20364
20365       lodashStable.times(2, function(index) {
20366         var settingsClone = lodashStable.clone(_.templateSettings);
20367
20368         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
20369           'escape': /\{\{-([\s\S]+?)\}\}/g,
20370           'evaluate': /\{\{([\s\S]+?)\}\}/g,
20371           'interpolate': /\{\{=([\s\S]+?)\}\}/g
20372         });
20373
20374         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
20375             compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
20376             data = { 'collection': ['a & A', 'b & B'] };
20377
20378         assert.strictEqual(compiled(data), expected);
20379         lodashStable.assign(_.templateSettings, settingsClone);
20380       });
20381     });
20382
20383     QUnit.test('should support custom delimiters containing special characters', function(assert) {
20384       assert.expect(2);
20385
20386       lodashStable.times(2, function(index) {
20387         var settingsClone = lodashStable.clone(_.templateSettings);
20388
20389         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
20390           'escape': /<\?-([\s\S]+?)\?>/g,
20391           'evaluate': /<\?([\s\S]+?)\?>/g,
20392           'interpolate': /<\?=([\s\S]+?)\?>/g
20393         });
20394
20395         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
20396             compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
20397             data = { 'collection': ['a & A', 'b & B'] };
20398
20399         assert.strictEqual(compiled(data), expected);
20400         lodashStable.assign(_.templateSettings, settingsClone);
20401       });
20402     });
20403
20404     QUnit.test('should use a `with` statement by default', function(assert) {
20405       assert.expect(1);
20406
20407       var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
20408           actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
20409
20410       assert.strictEqual(actual, '1b012');
20411     });
20412
20413     QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
20414       assert.expect(1);
20415
20416       var lodash = _.templateSettings.imports._,
20417           settingsClone = lodashStable.clone(lodash.templateSettings);
20418
20419       lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
20420         'interpolate': /\{\{=([\s\S]+?)\}\}/g
20421       });
20422
20423       var compiled = _.template('{{= a }}');
20424       assert.strictEqual(compiled({ 'a': 1 }), '1');
20425
20426       if (settingsClone) {
20427         lodashStable.assign(lodash.templateSettings, settingsClone);
20428       } else {
20429         delete lodash.templateSettings;
20430       }
20431     });
20432
20433     QUnit.test('should fallback to `_.templateSettings`', function(assert) {
20434       assert.expect(1);
20435
20436       var lodash = _.templateSettings.imports._,
20437           delimiter = _.templateSettings.interpolate;
20438
20439       _.templateSettings.imports._ = { 'escape': lodashStable.escape };
20440       _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
20441
20442       var compiled = _.template('{{= a }}');
20443       assert.strictEqual(compiled({ 'a': 1 }), '1');
20444
20445       _.templateSettings.imports._ = lodash;
20446       _.templateSettings.interpolate = delimiter;
20447     });
20448
20449     QUnit.test('should ignore `null` delimiters', function(assert) {
20450       assert.expect(3);
20451
20452       var delimiter = {
20453         'escape': /\{\{-([\s\S]+?)\}\}/g,
20454         'evaluate': /\{\{([\s\S]+?)\}\}/g,
20455         'interpolate': /\{\{=([\s\S]+?)\}\}/g
20456       };
20457
20458       lodashStable.forOwn({
20459         'escape': '{{- a }}',
20460         'evaluate': '{{ print(a) }}',
20461         'interpolate': '{{= a }}'
20462       },
20463       function(value, key) {
20464         var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
20465         settings[key] = delimiter[key];
20466
20467         var expected = '1 <%- a %> <% print(a) %> <%= a %>',
20468             compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
20469             data = { 'a': 1 };
20470
20471         assert.strictEqual(compiled(data), expected);
20472       });
20473     });
20474
20475     QUnit.test('should work without delimiters', function(assert) {
20476       assert.expect(1);
20477
20478       var expected = 'abc';
20479       assert.strictEqual(_.template(expected)({}), expected);
20480     });
20481
20482     QUnit.test('should work with `this` references', function(assert) {
20483       assert.expect(2);
20484
20485       var compiled = _.template('a<%= this.String("b") %>c');
20486       assert.strictEqual(compiled(), 'abc');
20487
20488       var object = { 'b': 'B' };
20489       object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
20490       assert.strictEqual(object.compiled(), 'ABC');
20491     });
20492
20493     QUnit.test('should work with backslashes', function(assert) {
20494       assert.expect(1);
20495
20496       var compiled = _.template('<%= a %> \\b'),
20497           data = { 'a': 'A' };
20498
20499       assert.strictEqual(compiled(data), 'A \\b');
20500     });
20501
20502     QUnit.test('should work with escaped characters in string literals', function(assert) {
20503       assert.expect(2);
20504
20505       var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
20506       assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
20507
20508       var data = { 'a': 'A' };
20509       compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
20510       assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
20511     });
20512
20513     QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
20514       assert.expect(1);
20515
20516       var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
20517       assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
20518     });
20519
20520     QUnit.test('should work with statements containing quotes', function(assert) {
20521       assert.expect(1);
20522
20523       var compiled = _.template("<%\
20524         if (a == 'A' || a == \"a\") {\
20525           %>'a',\"A\"<%\
20526         } %>"
20527       );
20528
20529       var data = { 'a': 'A' };
20530       assert.strictEqual(compiled(data), "'a',\"A\"");
20531     });
20532
20533     QUnit.test('should work with templates containing newlines and comments', function(assert) {
20534       assert.expect(1);
20535
20536       var compiled = _.template('<%\n\
20537         // A code comment.\n\
20538         if (value) { value += 3; }\n\
20539         %><p><%= value %></p>'
20540       );
20541
20542       assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
20543     });
20544
20545     QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
20546       assert.expect(1);
20547
20548       var compiled = _.template(''),
20549           pass = true;
20550
20551       /*@cc_on @*/
20552       try {
20553         compiled();
20554       } catch (e) {
20555         pass = false;
20556       }
20557       assert.ok(pass);
20558     });
20559
20560     QUnit.test('should tokenize delimiters', function(assert) {
20561       assert.expect(1);
20562
20563       var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
20564           data = { 'type': 1 };
20565
20566       assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
20567     });
20568
20569     QUnit.test('should evaluate delimiters once', function(assert) {
20570       assert.expect(1);
20571
20572       var actual = [],
20573           compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
20574           data = { 'func': function(value) { actual.push(value); } };
20575
20576       compiled(data);
20577       assert.deepEqual(actual, ['a', 'b', 'c']);
20578     });
20579
20580     QUnit.test('should match delimiters before escaping text', function(assert) {
20581       assert.expect(1);
20582
20583       var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
20584       assert.strictEqual(compiled(), '<<\n a \n>>');
20585     });
20586
20587     QUnit.test('should resolve nullish values to an empty string', function(assert) {
20588       assert.expect(3);
20589
20590       var compiled = _.template('<%= a %><%- a %>'),
20591           data = { 'a': null };
20592
20593       assert.strictEqual(compiled(data), '');
20594
20595       data = { 'a': undefined };
20596       assert.strictEqual(compiled(data), '');
20597
20598       data = { 'a': {} };
20599       compiled = _.template('<%= a.b %><%- a.b %>');
20600       assert.strictEqual(compiled(data), '');
20601     });
20602
20603     QUnit.test('should return an empty string for empty values', function(assert) {
20604       assert.expect(1);
20605
20606       var values = [, null, undefined, ''],
20607           expected = lodashStable.map(values, alwaysEmptyString),
20608           data = { 'a': 1 };
20609
20610       var actual = lodashStable.map(values, function(value, index) {
20611         var compiled = index ? _.template(value) : _.template();
20612         return compiled(data);
20613       });
20614
20615       assert.deepEqual(actual, expected);
20616     });
20617
20618     QUnit.test('should parse delimiters without newlines', function(assert) {
20619       assert.expect(1);
20620
20621       var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
20622           compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
20623           data = { 'value': true };
20624
20625       assert.strictEqual(compiled(data), expected);
20626     });
20627
20628     QUnit.test('should support recursive calls', function(assert) {
20629       assert.expect(1);
20630
20631       var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
20632           data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
20633
20634       assert.strictEqual(compiled(data), 'AB');
20635     });
20636
20637     QUnit.test('should coerce `text` argument to a string', function(assert) {
20638       assert.expect(1);
20639
20640       var object = { 'toString': lodashStable.constant('<%= a %>') },
20641           data = { 'a': 1 };
20642
20643       assert.strictEqual(_.template(object)(data), '1');
20644     });
20645
20646     QUnit.test('should not modify the `options` object', function(assert) {
20647       assert.expect(1);
20648
20649       var options = {};
20650       _.template('', options);
20651       assert.deepEqual(options, {});
20652     });
20653
20654     QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
20655       assert.expect(2);
20656
20657       var data = { 'a': 1 };
20658
20659       assert.notOk('a' in _.templateSettings);
20660       _.template('', {}, data);
20661       assert.notOk('a' in _.templateSettings);
20662
20663       delete _.templateSettings.a;
20664     });
20665
20666     QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
20667       assert.expect(2);
20668
20669       var pass = true;
20670
20671       try {
20672         _.template('')(1);
20673       } catch (e) {
20674         pass = false;
20675       }
20676       assert.ok(pass, '`data` value');
20677
20678       pass = true;
20679
20680       try {
20681         _.template('', 1)(1);
20682       } catch (e) {
20683         pass = false;
20684       }
20685       assert.ok(pass, '`options` value');
20686     });
20687
20688     QUnit.test('should expose the source on compiled templates', function(assert) {
20689       assert.expect(1);
20690
20691       var compiled = _.template('x'),
20692           values = [String(compiled), compiled.source],
20693           expected = lodashStable.map(values, alwaysTrue);
20694
20695       var actual = lodashStable.map(values, function(value) {
20696         return lodashStable.includes(value, '__p');
20697       });
20698
20699       assert.deepEqual(actual, expected);
20700     });
20701
20702     QUnit.test('should expose the source on SyntaxErrors', function(assert) {
20703       assert.expect(1);
20704
20705       try {
20706         _.template('<% if x %>');
20707       } catch (e) {
20708         var source = e.source;
20709       }
20710       assert.ok(lodashStable.includes(source, '__p'));
20711     });
20712
20713     QUnit.test('should not include sourceURLs in the source', function(assert) {
20714       assert.expect(1);
20715
20716       var options = { 'sourceURL': '/a/b/c' },
20717           compiled = _.template('x', options),
20718           values = [compiled.source, undefined];
20719
20720       try {
20721         _.template('<% if x %>', options);
20722       } catch (e) {
20723         values[1] = e.source;
20724       }
20725       var expected = lodashStable.map(values, alwaysFalse);
20726
20727       var actual = lodashStable.map(values, function(value) {
20728         return lodashStable.includes(value, 'sourceURL');
20729       });
20730
20731       assert.deepEqual(actual, expected);
20732     });
20733
20734     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20735       assert.expect(1);
20736
20737       var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
20738           compiles = lodashStable.map(array, _.template),
20739           data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
20740
20741       var actual = lodashStable.map(compiles, function(compiled) {
20742         return compiled(data);
20743       });
20744
20745       assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
20746     });
20747   }());
20748
20749   /*--------------------------------------------------------------------------*/
20750
20751   QUnit.module('lodash.truncate');
20752
20753   (function() {
20754     var string = 'hi-diddly-ho there, neighborino';
20755
20756     QUnit.test('should use a default `length` of `30`', function(assert) {
20757       assert.expect(1);
20758
20759       assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
20760     });
20761
20762     QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
20763       assert.expect(2);
20764
20765       assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
20766       assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
20767     });
20768
20769     QUnit.test('should truncate string the given length', function(assert) {
20770       assert.expect(1);
20771
20772       assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
20773     });
20774
20775     QUnit.test('should support a `omission` option', function(assert) {
20776       assert.expect(1);
20777
20778       assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
20779     });
20780
20781     QUnit.test('should support a `length` option', function(assert) {
20782       assert.expect(1);
20783
20784       assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
20785     });
20786
20787     QUnit.test('should support a `separator` option', function(assert) {
20788       assert.expect(3);
20789
20790       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
20791       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
20792       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
20793     });
20794
20795     QUnit.test('should treat negative `length` as `0`', function(assert) {
20796       assert.expect(2);
20797
20798       lodashStable.each([0, -2], function(length) {
20799         assert.strictEqual(_.truncate(string, { 'length': length }), '...');
20800       });
20801     });
20802
20803     QUnit.test('should coerce `length` to an integer', function(assert) {
20804       assert.expect(4);
20805
20806       lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
20807         var actual = index > 1 ? 'h...' : '...';
20808         assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
20809       });
20810     });
20811
20812     QUnit.test('should coerce `string` to a string', function(assert) {
20813       assert.expect(2);
20814
20815       assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
20816       assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
20817     });
20818
20819     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20820       assert.expect(1);
20821
20822       var actual = lodashStable.map([string, string, string], _.truncate),
20823           truncated = 'hi-diddly-ho there, neighbo...';
20824
20825       assert.deepEqual(actual, [truncated, truncated, truncated]);
20826     });
20827   }());
20828
20829   /*--------------------------------------------------------------------------*/
20830
20831   QUnit.module('lodash.throttle');
20832
20833   (function() {
20834     QUnit.test('should throttle a function', function(assert) {
20835       assert.expect(2);
20836
20837       var done = assert.async();
20838
20839       var callCount = 0,
20840           throttled = _.throttle(function() { callCount++; }, 32);
20841
20842       throttled();
20843       throttled();
20844       throttled();
20845
20846       var lastCount = callCount;
20847       assert.ok(callCount > 0);
20848
20849       setTimeout(function() {
20850         assert.ok(callCount > lastCount);
20851         done();
20852       }, 64);
20853     });
20854
20855     QUnit.test('subsequent calls should return the result of the first call', function(assert) {
20856       assert.expect(5);
20857
20858       var done = assert.async();
20859
20860       var throttled = _.throttle(identity, 32),
20861           result = [throttled('a'), throttled('b')];
20862
20863       assert.deepEqual(result, ['a', 'a']);
20864
20865       setTimeout(function() {
20866         var result = [throttled('x'), throttled('y')];
20867         assert.notEqual(result[0], 'a');
20868         assert.notStrictEqual(result[0], undefined);
20869
20870         assert.notEqual(result[1], 'y');
20871         assert.notStrictEqual(result[1], undefined);
20872         done();
20873       }, 64);
20874     });
20875
20876     QUnit.test('should clear timeout when `func` is called', function(assert) {
20877       assert.expect(1);
20878
20879       var done = assert.async();
20880
20881       if (!isModularize) {
20882         var callCount = 0,
20883             dateCount = 0;
20884
20885         var getTime = function() {
20886           return ++dateCount == 5
20887             ? Infinity
20888             : +new Date;
20889         };
20890
20891         var lodash = _.runInContext(lodashStable.assign({}, root, {
20892           'Date': lodashStable.assign(function() {
20893             return { 'getTime': getTime };
20894           }, {
20895             'now': Date.now
20896           })
20897         }));
20898
20899         var throttled = lodash.throttle(function() {
20900           callCount++;
20901         }, 32);
20902
20903         throttled();
20904         throttled();
20905         throttled();
20906
20907         setTimeout(function() {
20908           assert.strictEqual(callCount, 2);
20909           done();
20910         }, 64);
20911       }
20912       else {
20913         skipAssert(assert);
20914         done();
20915       }
20916     });
20917
20918     QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
20919       assert.expect(2);
20920
20921       var done = assert.async();
20922
20923       var callCount = 0,
20924           throttled = _.throttle(function() { callCount++; }, 32);
20925
20926       throttled();
20927       assert.strictEqual(callCount, 1);
20928
20929       setTimeout(function() {
20930         assert.strictEqual(callCount, 1);
20931         done();
20932       }, 64);
20933     });
20934
20935     lodashStable.times(2, function(index) {
20936       QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
20937         assert.expect(1);
20938
20939         var done = assert.async();
20940
20941         var callCount = 0,
20942             limit = (argv || isPhantom) ? 1000 : 320,
20943             options = index ? { 'leading': false } : {};
20944
20945         var throttled = _.throttle(function() {
20946           callCount++;
20947         }, 32, options);
20948
20949         var start = +new Date;
20950         while ((new Date - start) < limit) {
20951           throttled();
20952         }
20953         var actual = callCount > 1;
20954
20955         setTimeout(function() {
20956           assert.ok(actual);
20957           done();
20958         }, 1);
20959       });
20960     });
20961
20962     QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
20963       assert.expect(2);
20964
20965       var done = assert.async();
20966
20967       var callCount = 0;
20968
20969       var throttled = _.throttle(function() {
20970         callCount++;
20971       }, 128, { 'leading': false });
20972
20973       throttled();
20974
20975       setTimeout(function() {
20976         assert.strictEqual(callCount, 1);
20977         throttled();
20978       }, 192);
20979
20980       setTimeout(function() {
20981         assert.strictEqual(callCount, 2);
20982         done();
20983       }, 288);
20984     });
20985
20986     QUnit.test('should apply default options', function(assert) {
20987       assert.expect(3);
20988
20989       var done = assert.async();
20990
20991       var callCount = 0;
20992
20993       var throttled = _.throttle(function(value) {
20994         callCount++;
20995         return value;
20996       }, 32, {});
20997
20998       assert.strictEqual(throttled('a'), 'a');
20999       assert.strictEqual(throttled('b'), 'a');
21000
21001       setTimeout(function() {
21002         assert.strictEqual(callCount, 2);
21003         done();
21004       }, 128);
21005     });
21006
21007     QUnit.test('should support a `leading` option', function(assert) {
21008       assert.expect(2);
21009
21010       var withLeading = _.throttle(identity, 32, { 'leading': true });
21011       assert.strictEqual(withLeading('a'), 'a');
21012
21013       var withoutLeading = _.throttle(identity, 32, { 'leading': false });
21014       assert.strictEqual(withoutLeading('a'), undefined);
21015     });
21016
21017     QUnit.test('should support a `trailing` option', function(assert) {
21018       assert.expect(6);
21019
21020       var done = assert.async();
21021
21022       var withCount = 0,
21023           withoutCount = 0;
21024
21025       var withTrailing = _.throttle(function(value) {
21026         withCount++;
21027         return value;
21028       }, 64, { 'trailing': true });
21029
21030       var withoutTrailing = _.throttle(function(value) {
21031         withoutCount++;
21032         return value;
21033       }, 64, { 'trailing': false });
21034
21035       assert.strictEqual(withTrailing('a'), 'a');
21036       assert.strictEqual(withTrailing('b'), 'a');
21037
21038       assert.strictEqual(withoutTrailing('a'), 'a');
21039       assert.strictEqual(withoutTrailing('b'), 'a');
21040
21041       setTimeout(function() {
21042         assert.strictEqual(withCount, 2);
21043         assert.strictEqual(withoutCount, 1);
21044         done();
21045       }, 256);
21046     });
21047
21048     QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
21049       assert.expect(1);
21050
21051       var done = assert.async();
21052
21053       var callCount = 0;
21054
21055       var throttled = _.throttle(function() {
21056         callCount++;
21057       }, 64, { 'trailing': false });
21058
21059       throttled();
21060       throttled();
21061
21062       setTimeout(function() {
21063         throttled();
21064         throttled();
21065       }, 96);
21066
21067       setTimeout(function() {
21068         assert.ok(callCount > 1);
21069         done();
21070       }, 192);
21071     });
21072   }());
21073
21074   /*--------------------------------------------------------------------------*/
21075
21076   QUnit.module('lodash.debounce and lodash.throttle');
21077
21078   lodashStable.each(['debounce', 'throttle'], function(methodName) {
21079     var func = _[methodName],
21080         isDebounce = methodName == 'debounce';
21081
21082     QUnit.test('_.' + methodName + ' should not error for non-object `options` values', function(assert) {
21083       assert.expect(1);
21084
21085       var pass = true;
21086
21087       try {
21088         func(noop, 32, 1);
21089       } catch (e) {
21090         pass = false;
21091       }
21092       assert.ok(pass);
21093     });
21094
21095     QUnit.test('_.' + methodName + ' should use a default `wait` of `0`', function(assert) {
21096       assert.expect(1);
21097
21098       var done = assert.async();
21099
21100       var callCount = 0;
21101
21102       var funced = func(function() {
21103         callCount++;
21104       });
21105
21106       funced();
21107
21108       setTimeout(function() {
21109         funced();
21110         assert.strictEqual(callCount, isDebounce ? 1 : 2);
21111         done();
21112       }, 32);
21113     });
21114
21115     QUnit.test('_.' + methodName + ' should invoke `func` with the correct `this` binding', function(assert) {
21116       assert.expect(1);
21117
21118       var done = assert.async();
21119
21120       var object = {
21121         'funced': func(function() { actual.push(this); }, 32)
21122       };
21123
21124       var actual = [],
21125           expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
21126
21127       object.funced();
21128       if (!isDebounce) {
21129         object.funced();
21130       }
21131       setTimeout(function() {
21132         assert.deepEqual(actual, expected);
21133         done();
21134       }, 64);
21135     });
21136
21137     QUnit.test('_.' + methodName + ' supports recursive calls', function(assert) {
21138       assert.expect(2);
21139
21140       var done = assert.async();
21141
21142       var actual = [],
21143           args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
21144           expected = args.slice(),
21145           queue = args.slice();
21146
21147       var funced = func(function() {
21148         var current = [this];
21149         push.apply(current, arguments);
21150         actual.push(current);
21151
21152         var next = queue.shift();
21153         if (next) {
21154           funced.call(next[0], next[1]);
21155         }
21156       }, 32);
21157
21158       var next = queue.shift();
21159       funced.call(next[0], next[1]);
21160       assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
21161
21162       setTimeout(function() {
21163         assert.deepEqual(actual, expected.slice(0, actual.length));
21164         done();
21165       }, 256);
21166     });
21167
21168     QUnit.test('_.' + methodName + ' should work if the system time is set backwards', function(assert) {
21169       assert.expect(1);
21170
21171       var done = assert.async();
21172
21173       if (!isModularize) {
21174         var callCount = 0,
21175             dateCount = 0;
21176
21177         var getTime = function() {
21178           return ++dateCount === 4
21179             ? +new Date(2012, 3, 23, 23, 27, 18)
21180             : +new Date;
21181         };
21182
21183         var lodash = _.runInContext(lodashStable.assign({}, root, {
21184           'Date': lodashStable.assign(function() {
21185             return { 'getTime': getTime, 'valueOf': getTime };
21186           }, {
21187             'now': Date.now
21188           })
21189         }));
21190
21191         var funced = lodash[methodName](function() {
21192           callCount++;
21193         }, 32);
21194
21195         funced();
21196
21197         setTimeout(function() {
21198           funced();
21199           assert.strictEqual(callCount, isDebounce ? 1 : 2);
21200           done();
21201         }, 64);
21202       }
21203       else {
21204         skipAssert(assert);
21205         done();
21206       }
21207     });
21208
21209     QUnit.test('_.' + methodName + ' should support cancelling delayed calls', function(assert) {
21210       assert.expect(1);
21211
21212       var done = assert.async();
21213
21214       var callCount = 0;
21215
21216       var funced = func(function() {
21217         callCount++;
21218       }, 32, { 'leading': false });
21219
21220       funced();
21221       funced.cancel();
21222
21223       setTimeout(function() {
21224         assert.strictEqual(callCount, 0);
21225         done();
21226       }, 64);
21227     });
21228
21229     QUnit.test('_.' + methodName + ' should reset `lastCalled` after cancelling', function(assert) {
21230       assert.expect(3);
21231
21232       var done = assert.async();
21233
21234       var callCount = 0;
21235
21236       var funced = func(function() {
21237         return ++callCount;
21238       }, 32, { 'leading': true });
21239
21240       assert.strictEqual(funced(), 1);
21241       funced.cancel();
21242       assert.strictEqual(funced(), 2);
21243
21244       setTimeout(function() {
21245         assert.strictEqual(callCount, 2);
21246         done();
21247       }, 64);
21248     });
21249
21250     QUnit.test('_.' + methodName + ' should support flushing delayed calls', function(assert) {
21251       assert.expect(2);
21252
21253       var done = assert.async();
21254
21255       var callCount = 0;
21256
21257       var funced = func(function() {
21258         return ++callCount;
21259       }, 32, { 'leading': false });
21260
21261       funced();
21262       var actual = funced.flush();
21263
21264       setTimeout(function() {
21265         assert.strictEqual(actual, 1);
21266         assert.strictEqual(callCount, 1);
21267         done();
21268       }, 64);
21269     });
21270   });
21271
21272   /*--------------------------------------------------------------------------*/
21273
21274   QUnit.module('lodash.times');
21275
21276   (function() {
21277     QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
21278       assert.expect(3);
21279
21280       lodashStable.each([-Infinity, NaN, Infinity], function(n) {
21281         assert.deepEqual(_.times(n), []);
21282       });
21283     });
21284
21285     QUnit.test('should coerce `n` to an integer', function(assert) {
21286       assert.expect(1);
21287
21288       var actual = _.times(2.6, _.indentify);
21289       assert.deepEqual(actual, [0, 1]);
21290     });
21291
21292     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
21293       assert.expect(1);
21294
21295       var args;
21296
21297       _.times(1, function(assert) {
21298         args || (args = slice.call(arguments));
21299       });
21300
21301       assert.deepEqual(args, [0]);
21302     });
21303
21304     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
21305       assert.expect(1);
21306
21307       var values = [, null, undefined],
21308           expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
21309
21310       var actual = lodashStable.map(values, function(value, index) {
21311         return index ? _.times(3, value) : _.times(3);
21312       });
21313
21314       assert.deepEqual(actual, expected);
21315     });
21316
21317     QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
21318       assert.expect(1);
21319
21320       assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
21321     });
21322
21323     QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
21324       assert.expect(1);
21325
21326       var values = falsey.concat(-1, -Infinity),
21327           expected = lodashStable.map(values, alwaysEmptyArray);
21328
21329       var actual = lodashStable.map(values, function(value, index) {
21330         return index ? _.times(value) : _.times();
21331       });
21332
21333       assert.deepEqual(actual, expected);
21334     });
21335
21336     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
21337       assert.expect(1);
21338
21339       if (!isNpm) {
21340         assert.deepEqual(_(3).times(), [0, 1, 2]);
21341       }
21342       else {
21343         skipAssert(assert);
21344       }
21345     });
21346
21347     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
21348       assert.expect(1);
21349
21350       if (!isNpm) {
21351         assert.ok(_(3).chain().times() instanceof _);
21352       }
21353       else {
21354         skipAssert(assert);
21355       }
21356     });
21357   }());
21358
21359   /*--------------------------------------------------------------------------*/
21360
21361   QUnit.module('lodash.toArray');
21362
21363   (function() {
21364     QUnit.test('should convert objects to arrays', function(assert) {
21365       assert.expect(1);
21366
21367       assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
21368     });
21369
21370     QUnit.test('should convert strings to arrays', function(assert) {
21371       assert.expect(3);
21372
21373       assert.deepEqual(_.toArray(''), []);
21374       assert.deepEqual(_.toArray('ab'), ['a', 'b']);
21375       assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
21376     });
21377
21378     QUnit.test('should convert iterables to arrays', function(assert) {
21379       assert.expect(1);
21380
21381       if (!isNpm && Symbol && Symbol.iterator) {
21382         var object = { '0': 'a', 'length': 1 };
21383         object[Symbol.iterator] = arrayProto[Symbol.iterator];
21384
21385         assert.deepEqual(_.toArray(object), ['a']);
21386       }
21387       else {
21388         skipAssert(assert);
21389       }
21390     });
21391
21392     QUnit.test('should work in a lazy sequence', function(assert) {
21393       assert.expect(2);
21394
21395       if (!isNpm) {
21396         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21397             actual = _(array).slice(1).map(String).toArray().value();
21398
21399         assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
21400
21401         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
21402           return ['key' + index, index];
21403         }));
21404
21405         actual = _(object).toArray().slice(1).map(String).value();
21406         assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
21407       }
21408       else {
21409         skipAssert(assert, 2);
21410       }
21411     });
21412   }());
21413
21414   /*--------------------------------------------------------------------------*/
21415
21416   QUnit.module('lodash.toLower');
21417
21418   (function() {
21419     QUnit.test('should convert whole string to lower case', function(assert) {
21420       assert.expect(3);
21421
21422       assert.deepEqual(_.toLower('--Foo-Bar'), '--foo-bar');
21423       assert.deepEqual(_.toLower('fooBar'), 'foobar');
21424       assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
21425     });
21426   }());
21427
21428   /*--------------------------------------------------------------------------*/
21429
21430   QUnit.module('lodash.toUpper');
21431
21432   (function() {
21433     QUnit.test('should convert whole string to upper case', function(assert) {
21434       assert.expect(3);
21435
21436       assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
21437       assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
21438       assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
21439     });
21440   }());
21441
21442   /*--------------------------------------------------------------------------*/
21443
21444   QUnit.module('lodash.slice and lodash.toArray');
21445
21446   lodashStable.each(['slice', 'toArray'], function(methodName) {
21447     var args = (function() { return arguments; }(1, 2, 3)),
21448         array = [1, 2, 3],
21449         func = _[methodName];
21450
21451     QUnit.test('should return a dense array', function(assert) {
21452       assert.expect(3);
21453
21454       var sparse = Array(3);
21455       sparse[1] = 2;
21456
21457       var actual = func(sparse);
21458
21459       assert.ok('0' in actual);
21460       assert.ok('2' in actual);
21461       assert.deepEqual(actual, sparse);
21462     });
21463
21464     QUnit.test('should treat array-like objects like arrays', function(assert) {
21465       assert.expect(2);
21466
21467       var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
21468       assert.deepEqual(func(object), ['a', 'b', 'c']);
21469       assert.deepEqual(func(args), array);
21470     });
21471
21472     QUnit.test('should return a shallow clone of arrays', function(assert) {
21473       assert.expect(2);
21474
21475       var actual = func(array);
21476       assert.deepEqual(actual, array);
21477       assert.notStrictEqual(actual, array);
21478     });
21479
21480     QUnit.test('should work with a node list for `collection`', function(assert) {
21481       assert.expect(1);
21482
21483       if (document) {
21484         try {
21485           var actual = func(document.getElementsByTagName('body'));
21486         } catch (e) {}
21487
21488         assert.deepEqual(actual, [body]);
21489       }
21490       else {
21491         skipAssert(assert);
21492       }
21493     });
21494   });
21495
21496   /*--------------------------------------------------------------------------*/
21497
21498   QUnit.module('toInteger methods');
21499
21500   lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
21501     var func = _[methodName],
21502         isSafe = methodName == 'toSafeInteger';
21503
21504     QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
21505       assert.expect(6);
21506
21507       assert.strictEqual(func(-5.6), -5);
21508       assert.strictEqual(func('5.6'), 5);
21509       assert.strictEqual(func(), 0);
21510       assert.strictEqual(func(NaN), 0);
21511
21512       var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
21513       assert.strictEqual(func(Infinity), expected);
21514       assert.strictEqual(func(-Infinity), -expected);
21515     });
21516
21517     QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
21518       assert.expect(1);
21519
21520       assert.strictEqual(1 / func(-0), -Infinity);
21521     });
21522   });
21523
21524   /*--------------------------------------------------------------------------*/
21525
21526   QUnit.module('lodash.toLength');
21527
21528   (function() {
21529     QUnit.test('should return a valid length', function(assert) {
21530       assert.expect(4);
21531
21532       assert.strictEqual(_.toLength(-1), 0);
21533       assert.strictEqual(_.toLength('1'), 1);
21534       assert.strictEqual(_.toLength(1.1), 1);
21535       assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
21536     });
21537
21538     QUnit.test('should return `value` if a valid length', function(assert) {
21539       assert.expect(3);
21540
21541       assert.strictEqual(_.toLength(0), 0);
21542       assert.strictEqual(_.toLength(3), 3);
21543       assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
21544     });
21545
21546     QUnit.test('should convert `-0` to `0`', function(assert) {
21547       assert.expect(1);
21548
21549       assert.strictEqual(1 / _.toLength(-0), Infinity);
21550     });
21551   }());
21552
21553   /*--------------------------------------------------------------------------*/
21554
21555   QUnit.module('lodash.toInteger and lodash.toNumber');
21556
21557   lodashStable.each(['toInteger', 'toNumber'], function(methodName) {
21558     var func = _[methodName],
21559         isInt = methodName == 'toInteger';
21560
21561     function negative(string) {
21562       return '-' + string;
21563     }
21564
21565     function pad(string) {
21566       return whitespace + string + whitespace;
21567     }
21568
21569     function positive(string) {
21570       return '+' + string;
21571     }
21572
21573     QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
21574       assert.expect(1);
21575
21576       var values = falsey.concat(whitespace);
21577
21578       var expected = lodashStable.map(values, function(value) {
21579         return (isInt || (value === whitespace)) ? 0 : Number(value);
21580       });
21581
21582       var actual = lodashStable.map(values, function(value, index) {
21583         return index ? func(value) : func();
21584       });
21585
21586       assert.deepEqual(actual, expected);
21587     });
21588
21589     QUnit.test('`_.' + methodName + '` should preserve sign of `0`', function(assert) {
21590       assert.expect(1);
21591
21592       var values = [0, '0', -0, '-0'],
21593           expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
21594
21595       var actual = lodashStable.map(values, function(value) {
21596         var result = func(value);
21597         return [result, 1 / result];
21598       });
21599
21600       assert.deepEqual(actual, expected);
21601     });
21602
21603     QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
21604       assert.expect(1);
21605
21606       var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
21607
21608       var expected = lodashStable.map(values, function(value) {
21609         if (isInt) {
21610           if (value == 1.2) {
21611             value = 1;
21612           }
21613           else if (value == Infinity) {
21614             value = MAX_INTEGER;
21615           }
21616           else if (value !== value) {
21617             value = 0;
21618           }
21619         }
21620         return [value, value, -value, -value];
21621       });
21622
21623       var actual = lodashStable.map(values, function(value) {
21624         return lodashStable.flattenDeep(
21625           lodashStable.times(2, function(index) {
21626             var other = index ? -value : value;
21627             return [
21628               func(other),
21629               func(Object(other))
21630             ];
21631           })
21632         );
21633       });
21634
21635       assert.deepEqual(actual, expected);
21636     });
21637
21638     QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
21639       assert.expect(1);
21640
21641       var transforms = [identity, pad, positive, negative];
21642
21643       var values = [
21644         '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
21645         '1e+308', '1e308', '1E+308', '1E308',
21646         '5e-324', '5E-324',
21647         'Infinity', 'NaN'
21648       ];
21649
21650       var expected = lodashStable.map(values, function(value) {
21651         var n = +value;
21652         if (isInt) {
21653           if (n == 1.234567890) {
21654             n = 1;
21655           }
21656           else if (n == Infinity) {
21657             n = MAX_INTEGER;
21658           }
21659           else if (n == Number.MIN_VALUE || n !== n) {
21660             n = 0;
21661           }
21662         }
21663         return [n, n, n, n, n, n, -n, -n];
21664       });
21665
21666       var actual = lodashStable.map(values, function(value) {
21667         return lodashStable.flattenDeep(
21668           lodashStable.map(transforms, function(mod) {
21669             return [
21670               func(mod(value)),
21671               func(Object(mod(value)))
21672             ];
21673           })
21674         );
21675       });
21676
21677       assert.deepEqual(actual, expected);
21678     });
21679
21680     QUnit.test('`_.' + methodName + '` should convert binary and octal strings to numbers', function(assert) {
21681       assert.expect(1);
21682
21683       var numbers = [42, 5349, 1715004],
21684           transforms = [identity, pad],
21685           values = ['0b101010', '0o12345', '0x1a2b3c'];
21686
21687       var expected = lodashStable.map(numbers, function(n) {
21688         return lodashStable.times(8, lodashStable.constant(n));
21689       });
21690
21691       var actual = lodashStable.map(values, function(value) {
21692         return lodashStable.flattenDeep(
21693           lodashStable.times(2, function(index) {
21694             var other = index ? value.toUpperCase() : value;
21695             return lodashStable.map(transforms, function(mod) {
21696               return [
21697                 func(mod(other)),
21698                 func(Object(mod(other)))
21699               ];
21700             });
21701           })
21702         );
21703       });
21704
21705       assert.deepEqual(actual, expected);
21706     });
21707
21708     QUnit.test('`_.' + methodName + '` should convert invalid binary and octal strings to `NaN`', function(assert) {
21709       assert.expect(1);
21710
21711       var transforms = [identity, pad, positive, negative],
21712           values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
21713
21714       var expected = lodashStable.map(values, function(n) {
21715         return lodashStable.times(16, lodashStable.constant(isInt ? 0 : NaN));
21716       });
21717
21718       var actual = lodashStable.map(values, function(value) {
21719         return lodashStable.flattenDeep(
21720           lodashStable.times(2, function(index) {
21721             var other = index ? value.toUpperCase() : value;
21722             return lodashStable.map(transforms, function(mod) {
21723               return [
21724                 func(mod(value)),
21725                 func(Object(mod(value)))
21726               ];
21727             });
21728           })
21729         );
21730       });
21731
21732       assert.deepEqual(actual, expected);
21733     });
21734
21735     QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
21736       assert.expect(1);
21737
21738       var values = [
21739         {},
21740         [],
21741         [1],
21742         [1, 2],
21743         { 'valueOf': '1.1' },
21744         { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
21745         { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
21746         { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
21747         { 'valueOf': lodashStable.constant('-0x1a2b3c') },
21748         { 'toString': lodashStable.constant('-0x1a2b3c') },
21749         { 'valueOf': lodashStable.constant('0o12345') },
21750         { 'toString': lodashStable.constant('0o12345') },
21751         { 'valueOf': lodashStable.constant('0b101010') },
21752         { 'toString': lodashStable.constant('0b101010') }
21753       ];
21754
21755       var expected = [
21756         NaN,   0,   1,   NaN,
21757         NaN,  2.2,  1.1, 1.1,
21758         NaN,  NaN,
21759         5349, 5349,
21760         42,   42
21761       ];
21762
21763       if (isInt) {
21764         expected = [
21765           0, 0, 1, 0,
21766           0, 2, 1, 1,
21767           0, 0,
21768           5349, 5349,
21769           42, 42
21770         ];
21771       }
21772       var actual = lodashStable.map(values, func);
21773
21774       assert.deepEqual(actual, expected);
21775     });
21776   });
21777
21778   /*--------------------------------------------------------------------------*/
21779
21780   QUnit.module('lodash.toPairs');
21781
21782   (function() {
21783     QUnit.test('should create a two dimensional array of key-value pairs', function(assert) {
21784       assert.expect(1);
21785
21786       var object = { 'a': 1, 'b': 2 };
21787       assert.deepEqual(_.toPairs(object), [['a', 1], ['b', 2]]);
21788     });
21789
21790     QUnit.test('should work with an object that has a `length` property', function(assert) {
21791       assert.expect(1);
21792
21793       var object = { '0': 'a', '1': 'b', 'length': 2 };
21794       assert.deepEqual(_.toPairs(object), [['0', 'a'], ['1', 'b'], ['length', 2]]);
21795     });
21796
21797     QUnit.test('should work with strings', function(assert) {
21798       assert.expect(2);
21799
21800       lodashStable.each(['xo', Object('xo')], function(string) {
21801         assert.deepEqual(_.toPairs(string), [['0', 'x'], ['1', 'o']]);
21802       });
21803     });
21804   }());
21805
21806   /*--------------------------------------------------------------------------*/
21807
21808   QUnit.module('lodash.toPath');
21809
21810   (function() {
21811     QUnit.test('should convert a string to a path', function(assert) {
21812       assert.expect(2);
21813
21814       assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
21815       assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
21816     });
21817
21818     QUnit.test('should coerce array elements to strings', function(assert) {
21819       assert.expect(4);
21820
21821       var array = ['a', 'b', 'c'];
21822
21823       lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
21824         var actual = _.toPath(value);
21825         assert.deepEqual(actual, array);
21826         assert.notStrictEqual(actual, array);
21827       });
21828     });
21829
21830     QUnit.test('should handle complex paths', function(assert) {
21831       assert.expect(1);
21832
21833       var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
21834       assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
21835     });
21836
21837     QUnit.test('should ignore consecutive brackets and dots', function(assert) {
21838       assert.expect(4);
21839
21840       var expected = ['a'];
21841       assert.deepEqual(_.toPath('a.'), expected);
21842       assert.deepEqual(_.toPath('a[]'), expected);
21843
21844       expected = ['a', 'b'];
21845       assert.deepEqual(_.toPath('a..b'), expected);
21846       assert.deepEqual(_.toPath('a[][]b'), expected);
21847     });
21848   }());
21849
21850   /*--------------------------------------------------------------------------*/
21851
21852   QUnit.module('lodash.toPlainObject');
21853
21854   (function() {
21855     var args = arguments;
21856
21857     QUnit.test('should flatten inherited properties', function(assert) {
21858       assert.expect(1);
21859
21860       function Foo() { this.b = 2; }
21861       Foo.prototype.c = 3;
21862
21863       var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
21864       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
21865     });
21866
21867     QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
21868       assert.expect(1);
21869
21870       var actual = _.toPlainObject(args),
21871           expected = { '0': 1, '1': 2, '2': 3 };
21872
21873       assert.deepEqual(actual, expected);
21874     });
21875
21876     QUnit.test('should convert arrays to plain objects', function(assert) {
21877       assert.expect(1);
21878
21879       var actual = _.toPlainObject(['a', 'b', 'c']),
21880           expected = { '0': 'a', '1': 'b', '2': 'c' };
21881
21882       assert.deepEqual(actual, expected);
21883     });
21884   }(1, 2, 3));
21885
21886   /*--------------------------------------------------------------------------*/
21887
21888   QUnit.module('lodash.toString');
21889
21890   (function() {
21891     QUnit.test('should treat nullish values as empty strings', function(assert) {
21892       assert.expect(1);
21893
21894       var values = [, null, undefined],
21895           expected = lodashStable.map(values, alwaysEmptyString);
21896
21897       var actual = lodashStable.map(values, function(value, index) {
21898         return index ? _.toString(value) : _.toString();
21899       });
21900
21901       assert.deepEqual(actual, expected);
21902     });
21903
21904     QUnit.test('should preserve sign of `0`', function(assert) {
21905       assert.expect(1);
21906
21907       var values = [0, Object(0), -0, Object(-0)],
21908           expected = ['0', '0', '-0', '-0'],
21909           actual = lodashStable.map(values, _.toString);
21910
21911       assert.deepEqual(actual, expected);
21912     });
21913
21914     QUnit.test('should not error on symbols', function(assert) {
21915       assert.expect(1);
21916
21917       if (Symbol) {
21918         try {
21919           assert.strictEqual(_.toString(symbol), 'Symbol(a)');
21920         } catch (e) {
21921           assert.ok(false, e.message);
21922         }
21923       }
21924       else {
21925         skipAssert(assert);
21926       }
21927     });
21928
21929     QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
21930       assert.expect(1);
21931
21932       if (!isNpm) {
21933         var wrapped = _([1, 2, 3]);
21934         assert.strictEqual(wrapped.toString(), '1,2,3');
21935       }
21936       else {
21937         skipAssert(assert);
21938       }
21939     });
21940   }());
21941
21942   /*--------------------------------------------------------------------------*/
21943
21944   QUnit.module('lodash.transform');
21945
21946   (function() {
21947     function Foo() {
21948       this.a = 1;
21949       this.b = 2;
21950       this.c = 3;
21951     }
21952
21953     QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
21954       assert.expect(4);
21955
21956       var accumulators = [, null, undefined],
21957           expected = lodashStable.map(accumulators, alwaysTrue),
21958           object = new Foo;
21959
21960       var iteratee = function(result, value, key) {
21961         result[key] = square(value);
21962       };
21963
21964       var mapper = function(accumulator, index) {
21965         return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
21966       };
21967
21968       var results = lodashStable.map(accumulators, mapper);
21969
21970       var actual = lodashStable.map(results, function(result) {
21971         return result instanceof Foo;
21972       });
21973
21974       assert.deepEqual(actual, expected);
21975
21976       expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
21977       actual = lodashStable.map(results, lodashStable.toPlainObject);
21978
21979       assert.deepEqual(actual, expected);
21980
21981       object = { 'a': 1, 'b': 2, 'c': 3 };
21982       actual = lodashStable.map(accumulators, mapper);
21983
21984       assert.deepEqual(actual, expected);
21985
21986       object = [1, 2, 3];
21987       expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
21988       actual = lodashStable.map(accumulators, mapper);
21989
21990       assert.deepEqual(actual, expected);
21991     });
21992
21993     QUnit.test('should create regular arrays from typed arrays', function(assert) {
21994       assert.expect(1);
21995
21996       var expected = lodashStable.map(typedArrays, alwaysTrue);
21997
21998       var actual = lodashStable.map(typedArrays, function(type) {
21999         var Ctor = root[type],
22000             array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
22001
22002         return lodashStable.isArray(_.transform(array, noop));
22003       });
22004
22005       assert.deepEqual(actual, expected);
22006     });
22007
22008     QUnit.test('should support an `accumulator` value', function(assert) {
22009       assert.expect(6);
22010
22011       var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
22012           expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
22013
22014       var actual = lodashStable.map(values, function(value) {
22015         return _.transform(value, function(result, value) {
22016           result.push(square(value));
22017         }, []);
22018       });
22019
22020       assert.deepEqual(actual, expected);
22021
22022       var object = { 'a': 1, 'b': 4, 'c': 9 },
22023       expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
22024
22025       actual = lodashStable.map(values, function(value) {
22026         return _.transform(value, function(result, value, key) {
22027           result[key] = square(value);
22028         }, {});
22029       });
22030
22031       assert.deepEqual(actual, expected);
22032
22033       lodashStable.each([[], {}], function(accumulator) {
22034         var actual = lodashStable.map(values, function(value) {
22035           return _.transform(value, noop, accumulator);
22036         });
22037
22038         assert.ok(lodashStable.every(actual, function(result) {
22039           return result === accumulator;
22040         }));
22041
22042         assert.strictEqual(_.transform(null, null, accumulator), accumulator);
22043       });
22044     });
22045
22046     QUnit.test('should treat sparse arrays as dense', function(assert) {
22047       assert.expect(1);
22048
22049       var actual = _.transform(Array(1), function(result, value, index) {
22050         result[index] = String(value);
22051       });
22052
22053       assert.deepEqual(actual, ['undefined']);
22054     });
22055
22056     QUnit.test('should work without an `iteratee` argument', function(assert) {
22057       assert.expect(1);
22058
22059       assert.ok(_.transform(new Foo) instanceof Foo);
22060     });
22061
22062     QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
22063       assert.expect(2);
22064
22065       var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
22066           values = [true, false, 0, 1, NaN, '', 'a'],
22067           expected = lodashStable.map(values, alwaysEmptyObject);
22068
22069       var results = lodashStable.map(values, function(value) {
22070         return _.transform(value);
22071       });
22072
22073       assert.deepEqual(results, expected);
22074
22075       expected = lodashStable.map(values, alwaysFalse);
22076
22077       var actual = lodashStable.map(results, function(value, index) {
22078         return value instanceof Ctors[index];
22079       });
22080
22081       assert.deepEqual(actual, expected);
22082     });
22083
22084     QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
22085       assert.expect(1);
22086
22087       Foo.prototype.constructor = null;
22088       assert.notOk(_.transform(new Foo) instanceof Foo);
22089       Foo.prototype.constructor = Foo;
22090     });
22091
22092     QUnit.test('should create an empty object when given a falsey `object` argument', function(assert) {
22093       assert.expect(1);
22094
22095       var expected = lodashStable.map(falsey, alwaysEmptyObject);
22096
22097       var actual = lodashStable.map(falsey, function(object, index) {
22098         return index ? _.transform(object) : _.transform();
22099       });
22100
22101       assert.deepEqual(actual, expected);
22102     });
22103
22104     lodashStable.each({
22105       'array': [1, 2, 3],
22106       'object': { 'a': 1, 'b': 2, 'c': 3 }
22107     },
22108     function(object, key) {
22109       QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
22110         assert.expect(2);
22111
22112         var args;
22113
22114         _.transform(object, function() {
22115           args || (args = slice.call(arguments));
22116         });
22117
22118         var first = args[0];
22119         if (key == 'array') {
22120           assert.ok(first !== object && lodashStable.isArray(first));
22121           assert.deepEqual(args, [first, 1, 0, object]);
22122         } else {
22123           assert.ok(first !== object && lodashStable.isPlainObject(first));
22124           assert.deepEqual(args, [first, 1, 'a', object]);
22125         }
22126       });
22127     });
22128
22129     QUnit.test('should create an object from the same realm as `object`', function(assert) {
22130       assert.expect(1);
22131
22132       var objects = lodashStable.filter(realm, function(value) {
22133         return lodashStable.isObject(value) && !lodashStable.isElement(value);
22134       });
22135
22136       var expected = lodashStable.map(objects, alwaysTrue);
22137
22138       var actual = lodashStable.map(objects, function(object) {
22139         var Ctor = object.constructor,
22140             result = _.transform(object);
22141
22142         if (result === object) {
22143           return false;
22144         }
22145         if (lodashStable.isTypedArray(object)) {
22146           return result instanceof Array;
22147         }
22148         return result instanceof Ctor || !(new Ctor instanceof Ctor);
22149       });
22150
22151       assert.deepEqual(actual, expected);
22152     });
22153   }());
22154
22155   /*--------------------------------------------------------------------------*/
22156
22157   QUnit.module('trim methods');
22158
22159   lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
22160     var func = _[methodName],
22161         parts = [];
22162
22163     if (index != 2) {
22164       parts.push('leading');
22165     }
22166     if (index != 1) {
22167       parts.push('trailing');
22168     }
22169     parts = parts.join(' and ');
22170
22171     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
22172       assert.expect(1);
22173
22174       var string = whitespace + 'a b c' + whitespace,
22175           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
22176
22177       assert.strictEqual(func(string), expected);
22178     });
22179
22180     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
22181       assert.expect(1);
22182
22183       var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
22184           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
22185
22186       assert.strictEqual(func(object), expected);
22187     });
22188
22189     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
22190       assert.expect(1);
22191
22192       var string = '-_-a-b-c-_-',
22193           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
22194
22195       assert.strictEqual(func(string, '_-'), expected);
22196     });
22197
22198     QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
22199       assert.expect(1);
22200
22201       var object = { 'toString': lodashStable.constant('_-') },
22202           string = '-_-a-b-c-_-',
22203           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
22204
22205       assert.strictEqual(func(string, object), expected);
22206     });
22207
22208     QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
22209       assert.expect(6);
22210
22211       lodashStable.each([null, '_-'], function(chars) {
22212         assert.strictEqual(func(null, chars), '');
22213         assert.strictEqual(func(undefined, chars), '');
22214         assert.strictEqual(func('', chars), '');
22215       });
22216     });
22217
22218     QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
22219       assert.expect(2);
22220
22221       var string = whitespace + 'a b c' + whitespace,
22222           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
22223
22224       assert.strictEqual(func(string, undefined), expected);
22225       assert.strictEqual(func(string, ''), string);
22226     });
22227
22228     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
22229       assert.expect(1);
22230
22231       var string = Object(whitespace + 'a b c' + whitespace),
22232           trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
22233           actual = lodashStable.map([string, string, string], func);
22234
22235       assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
22236     });
22237
22238     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
22239       assert.expect(1);
22240
22241       if (!isNpm) {
22242         var string = whitespace + 'a b c' + whitespace,
22243             expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
22244
22245         assert.strictEqual(_(string)[methodName](), expected);
22246       }
22247       else {
22248         skipAssert(assert);
22249       }
22250     });
22251
22252     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
22253       assert.expect(1);
22254
22255       if (!isNpm) {
22256         var string = whitespace + 'a b c' + whitespace;
22257         assert.ok(_(string).chain()[methodName]() instanceof _);
22258       }
22259       else {
22260         skipAssert(assert);
22261       }
22262     });
22263   });
22264
22265   /*--------------------------------------------------------------------------*/
22266
22267   QUnit.module('uncommon symbols');
22268
22269   (function() {
22270     var flag = '\ud83c\uddfa\ud83c\uddf8',
22271         heart = '\u2764' + emojiVar,
22272         hearts = '\ud83d\udc95',
22273         comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
22274         hashKeycap = '#' + emojiVar + '\u20e3',
22275         leafs = '\ud83c\udf42',
22276         noMic = '\ud83c\udf99\u20e0',
22277         raisedHand = '\u270B' + emojiVar,
22278         rocket = '\ud83d\ude80',
22279         thumbsUp = '\ud83d\udc4d';
22280
22281     QUnit.test('should account for astral symbols', function(assert) {
22282       assert.expect(26);
22283
22284       var allHearts = _.repeat(hearts, 10),
22285           chars = hearts + comboGlyph,
22286           string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
22287           trimChars = comboGlyph + hearts,
22288           trimString = trimChars + string + trimChars;
22289
22290       assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
22291       assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
22292       assert.strictEqual(_.capitalize(rocket), rocket);
22293
22294       assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
22295       assert.strictEqual(_.padStart(string, 16), '   ' + string);
22296       assert.strictEqual(_.padEnd(string, 16), string + '   ');
22297
22298       assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
22299       assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
22300       assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
22301
22302       assert.strictEqual(_.size(string), 13);
22303       assert.deepEqual(_.toArray(string), ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket]);
22304
22305       assert.strictEqual(_.trim(trimString, chars), string);
22306       assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
22307       assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
22308
22309       assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
22310       assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
22311
22312       assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
22313       assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
22314
22315       lodashStable.times(2, function(index) {
22316         var separator = index ? RegExp(hearts) : hearts,
22317             options = { 'length': 4, 'separator': separator },
22318             actual = _.truncate(string, options);
22319
22320         assert.strictEqual(actual, 'A...');
22321         assert.strictEqual(actual.length, 4);
22322
22323         actual = _.truncate(allHearts, options);
22324         assert.strictEqual(actual, hearts + '...');
22325         assert.strictEqual(actual.length, 5);
22326       });
22327     });
22328
22329     QUnit.test('should account for combining diacritical marks', function(assert) {
22330       assert.expect(1);
22331
22332       var values = lodashStable.map(comboMarks, function(mark) {
22333         return 'o' + mark;
22334       });
22335
22336       var expected = lodashStable.map(values, function(value) {
22337         return [1, [value], [value]];
22338       });
22339
22340       var actual = lodashStable.map(values, function(value) {
22341         return [_.size(value), _.toArray(value), _.words(value)];
22342       });
22343
22344       assert.deepEqual(actual, expected);
22345     });
22346
22347     QUnit.test('should account for fitzpatrick modifiers', function(assert) {
22348       assert.expect(1);
22349
22350       var values = lodashStable.map(fitzModifiers, function(modifier) {
22351         return thumbsUp + modifier;
22352       });
22353
22354       var expected = lodashStable.map(values, function(value) {
22355         return [1, [value], [value]];
22356       });
22357
22358       var actual = lodashStable.map(values, function(value) {
22359         return [_.size(value), _.toArray(value), _.words(value)];
22360       });
22361
22362       assert.deepEqual(actual, expected);
22363     });
22364
22365     QUnit.test('should account for regional symbols', function(assert) {
22366       assert.expect(6);
22367
22368       var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
22369           regionals = pair.join(' ');
22370
22371       assert.strictEqual(_.size(flag), 1);
22372       assert.strictEqual(_.size(regionals), 3);
22373
22374       assert.deepEqual(_.toArray(flag), [flag]);
22375       assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
22376
22377       assert.deepEqual(_.words(flag), [flag]);
22378       assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
22379     });
22380
22381     QUnit.test('should account for variation selectors', function(assert) {
22382       assert.expect(3);
22383
22384       assert.strictEqual(_.size(heart), 1);
22385       assert.deepEqual(_.toArray(heart), [heart]);
22386       assert.deepEqual(_.words(heart), [heart]);
22387     });
22388
22389     QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
22390       assert.expect(1);
22391
22392       var values = lodashStable.map(fitzModifiers, function(modifier) {
22393         return raisedHand + modifier;
22394       });
22395
22396       var expected = lodashStable.map(values, function(value) {
22397         return [1, [value], [value]];
22398       });
22399
22400       var actual = lodashStable.map(values, function(value) {
22401         return [_.size(value), _.toArray(value), _.words(value)];
22402       });
22403
22404       assert.deepEqual(actual, expected);
22405     });
22406
22407     QUnit.test('should match lone surrogates', function(assert) {
22408       assert.expect(3);
22409
22410       var pair = hearts.split(''),
22411           surrogates = pair[0] + ' ' + pair[1];
22412
22413       assert.strictEqual(_.size(surrogates), 3);
22414       assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
22415       assert.deepEqual(_.words(surrogates), []);
22416     });
22417
22418     QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
22419       assert.expect(1);
22420
22421       var string = fitzModifiers[0] + fitzModifiers[0];
22422       assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
22423     });
22424   }());
22425
22426   /*--------------------------------------------------------------------------*/
22427
22428   QUnit.module('lodash.unescape');
22429
22430   (function() {
22431     var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
22432         unescaped = '&<>"\'\/';
22433
22434     escaped += escaped;
22435     unescaped += unescaped;
22436
22437     QUnit.test('should unescape entities in order', function(assert) {
22438       assert.expect(1);
22439
22440       assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
22441     });
22442
22443     QUnit.test('should unescape the proper entities', function(assert) {
22444       assert.expect(1);
22445
22446       assert.strictEqual(_.unescape(escaped), unescaped);
22447     });
22448
22449     QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
22450       assert.expect(1);
22451
22452       assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
22453     });
22454
22455     QUnit.test('should handle strings with nothing to unescape', function(assert) {
22456       assert.expect(1);
22457
22458       assert.strictEqual(_.unescape('abc'), 'abc');
22459     });
22460
22461     QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
22462       assert.expect(1);
22463
22464       assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
22465     });
22466   }());
22467
22468   /*--------------------------------------------------------------------------*/
22469
22470   QUnit.module('lodash.upperCase');
22471
22472   (function() {
22473     QUnit.test('should uppercase as space-separated words', function(assert) {
22474       assert.expect(3);
22475
22476       assert.strictEqual(_.upperCase('--foo-bar'), 'FOO BAR');
22477       assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
22478       assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
22479     });
22480   }());
22481
22482   /*--------------------------------------------------------------------------*/
22483
22484   QUnit.module('lodash.upperFirst');
22485
22486   (function() {
22487     QUnit.test('should uppercase only the first character', function(assert) {
22488       assert.expect(3);
22489
22490       assert.strictEqual(_.upperFirst('fred'), 'Fred');
22491       assert.strictEqual(_.upperFirst('Fred'), 'Fred');
22492       assert.strictEqual(_.upperFirst('FRED'), 'FRED');
22493     });
22494   }());
22495
22496   /*--------------------------------------------------------------------------*/
22497
22498   QUnit.module('lodash.unary');
22499
22500   (function() {
22501     function fn() {
22502       return slice.call(arguments);
22503     }
22504
22505     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
22506       assert.expect(1);
22507
22508       var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
22509       assert.deepEqual(actual, [6, 8, 10]);
22510     });
22511
22512     QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
22513       assert.expect(1);
22514
22515       var capped = _.unary(fn);
22516       assert.deepEqual(capped(), []);
22517     });
22518   }());
22519
22520   /*--------------------------------------------------------------------------*/
22521
22522   QUnit.module('union methods');
22523
22524   lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
22525     var args = (function() { return arguments; }(1, 2, 3)),
22526         func = _[methodName];
22527
22528     QUnit.test('`_.' + methodName + '` should return the union of the given arrays', function(assert) {
22529       assert.expect(1);
22530
22531       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
22532       assert.deepEqual(actual, [1, 3, 2, 5, 4]);
22533     });
22534
22535     QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
22536       assert.expect(1);
22537
22538       var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
22539       assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
22540     });
22541
22542     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
22543       assert.expect(3);
22544
22545       var array = [0];
22546       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
22547       assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
22548       assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
22549     });
22550   });
22551
22552   /*--------------------------------------------------------------------------*/
22553
22554   QUnit.module('lodash.unionBy');
22555
22556   (function() {
22557     QUnit.test('should accept an `iteratee` argument', function(assert) {
22558       assert.expect(2);
22559
22560       var actual = _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
22561       assert.deepEqual(actual, [2.1, 1.2, 4.3]);
22562
22563       actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
22564       assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
22565     });
22566
22567     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
22568       assert.expect(1);
22569
22570       var args;
22571
22572       _.unionBy([2.1, 1.2], [4.3, 2.4], function() {
22573         args || (args = slice.call(arguments));
22574       });
22575
22576       assert.deepEqual(args, [2.1]);
22577     });
22578   }());
22579
22580   /*--------------------------------------------------------------------------*/
22581
22582   QUnit.module('lodash.unionWith');
22583
22584   (function() {
22585     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
22586
22587     QUnit.test('should work with a `comparator` argument', function(assert) {
22588       assert.expect(1);
22589
22590       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
22591           actual = _.unionWith(objects, others, lodashStable.isEqual);
22592
22593       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]);
22594     });
22595   }());
22596
22597   /*--------------------------------------------------------------------------*/
22598
22599   QUnit.module('lodash.uniq');
22600
22601   (function() {
22602     QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
22603       assert.expect(1);
22604
22605       var array = [[2, 1, 2], [1, 2, 1]],
22606           actual = lodashStable.map(array, lodashStable.uniq);
22607
22608       assert.deepEqual(actual, [[2, 1], [1, 2]]);
22609     });
22610   }());
22611
22612   /*--------------------------------------------------------------------------*/
22613
22614   QUnit.module('uniq methods');
22615
22616   lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
22617     var func = _[methodName],
22618         isSorted = /^sorted/.test(methodName),
22619         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
22620
22621     if (isSorted) {
22622       objects = _.sortBy(objects, 'a');
22623     }
22624     else {
22625       QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
22626         assert.expect(1);
22627
22628         var array = [2, 3, 1, 2, 3, 1];
22629         assert.deepEqual(func(array), [2, 3, 1]);
22630       });
22631     }
22632     QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
22633       assert.expect(1);
22634
22635       var array = [1, 1, 2, 2, 3];
22636       assert.deepEqual(func(array), [1, 2, 3]);
22637     });
22638
22639     QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
22640       assert.expect(1);
22641
22642       assert.deepEqual(func(objects), objects);
22643     });
22644
22645     QUnit.test('`_.' + methodName + '` should not treat `NaN` as unique', function(assert) {
22646       assert.expect(1);
22647
22648       assert.deepEqual(func([1, 3, NaN, NaN]), [1, 3, NaN]);
22649     });
22650
22651     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
22652       assert.expect(1);
22653
22654       var largeArray = [],
22655           expected = [0, {}, 'a'],
22656           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
22657
22658       lodashStable.each(expected, function(value) {
22659         lodashStable.times(count, function() {
22660           largeArray.push(value);
22661         });
22662       });
22663
22664       assert.deepEqual(func(largeArray), expected);
22665     });
22666
22667     QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
22668       assert.expect(1);
22669
22670       var largeArray = [],
22671           expected = [false, true, null, undefined, NaN],
22672           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
22673
22674       lodashStable.each(expected, function(value) {
22675         lodashStable.times(count, function() {
22676           largeArray.push(value);
22677         });
22678       });
22679
22680       assert.deepEqual(func(largeArray), expected);
22681     });
22682
22683     QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
22684       assert.expect(1);
22685
22686       if (Symbol) {
22687         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
22688         assert.deepEqual(func(largeArray), largeArray);
22689       }
22690       else {
22691         skipAssert(assert);
22692       }
22693     });
22694
22695     QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
22696       assert.expect(1);
22697
22698       // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
22699       if (Symbol) {
22700         var expected = [
22701           Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
22702           Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
22703           Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
22704         ];
22705
22706         var largeArray = [],
22707             count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
22708
22709         expected = lodashStable.map(expected, function(symbol) {
22710           return symbol || {};
22711         });
22712
22713         lodashStable.each(expected, function(value) {
22714           lodashStable.times(count, function() {
22715             largeArray.push(value);
22716           });
22717         });
22718
22719         assert.deepEqual(func(largeArray), expected);
22720       }
22721       else {
22722         skipAssert(assert);
22723       }
22724     });
22725
22726     QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
22727       assert.expect(1);
22728
22729       var largeArray = [],
22730           expected = ['2', 2, Object('2'), Object(2)],
22731           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
22732
22733       lodashStable.each(expected, function(value) {
22734         lodashStable.times(count, function() {
22735           largeArray.push(value);
22736         });
22737       });
22738
22739       assert.deepEqual(func(largeArray), expected);
22740     });
22741   });
22742
22743   /*--------------------------------------------------------------------------*/
22744
22745   QUnit.module('uniqBy methods');
22746
22747   lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
22748     var func = _[methodName],
22749         isSorted = methodName == 'sortedUniqBy',
22750         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
22751
22752     if (isSorted) {
22753       objects = _.sortBy(objects, 'a');
22754     }
22755     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
22756       assert.expect(1);
22757
22758       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
22759
22760       var actual = func(objects, function(object) {
22761         return object.a;
22762       });
22763
22764       assert.deepEqual(actual, expected);
22765     });
22766
22767     QUnit.test('should work with large arrays', function(assert) {
22768       assert.expect(2);
22769
22770       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
22771         return [1, 2];
22772       });
22773
22774       var actual = func(largeArray, String);
22775
22776       assert.deepEqual(actual, [[1, 2]]);
22777       assert.strictEqual(actual[0], largeArray[0]);
22778     });
22779
22780     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
22781       assert.expect(1);
22782
22783       var args;
22784
22785       func(objects, function() {
22786         args || (args = slice.call(arguments));
22787       });
22788
22789       assert.deepEqual(args, [objects[0]]);
22790     });
22791
22792     QUnit.test('`_.' + methodName + '` should work with "_.property" shorthands', function(assert) {
22793       assert.expect(2);
22794
22795       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
22796           actual = func(objects, 'a');
22797
22798       assert.deepEqual(actual, expected);
22799
22800       var arrays = [[2], [3], [1], [2], [3], [1]];
22801       if (isSorted) {
22802         arrays = lodashStable.sortBy(arrays, 0);
22803       }
22804       expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
22805       actual = func(arrays, 0);
22806
22807       assert.deepEqual(actual, expected);
22808     });
22809
22810     lodashStable.each({
22811       'an array': [0, 'a'],
22812       'an object': { '0': 'a' },
22813       'a number': 0,
22814       'a string': '0'
22815     },
22816     function(iteratee, key) {
22817       QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
22818         assert.expect(1);
22819
22820         var actual = func([['a'], ['a'], ['b']], iteratee);
22821         assert.deepEqual(actual, [['a'], ['b']]);
22822       });
22823     });
22824   });
22825
22826   /*--------------------------------------------------------------------------*/
22827
22828   QUnit.module('lodash.uniqWith');
22829
22830   (function() {
22831     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
22832
22833     QUnit.test('should work with a `comparator` argument', function(assert) {
22834       assert.expect(1);
22835
22836       var actual = _.uniqWith(objects, lodashStable.isEqual);
22837       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]);
22838     });
22839   }());
22840
22841   /*--------------------------------------------------------------------------*/
22842
22843   QUnit.module('lodash.uniqueId');
22844
22845   (function() {
22846     QUnit.test('should generate unique ids', function(assert) {
22847       assert.expect(1);
22848
22849       var actual = lodashStable.times(1000, function(assert) {
22850         return _.uniqueId();
22851       });
22852
22853       assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
22854     });
22855
22856     QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
22857       assert.expect(1);
22858
22859       assert.strictEqual(typeof _.uniqueId(), 'string');
22860     });
22861
22862     QUnit.test('should coerce the prefix argument to a string', function(assert) {
22863       assert.expect(1);
22864
22865       var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
22866       assert.ok(/3\d+,2\d+,1\d+/.test(actual));
22867     });
22868   }());
22869
22870   /*--------------------------------------------------------------------------*/
22871
22872   QUnit.module('lodash.unset');
22873
22874   (function() {
22875     QUnit.test('should unset property values', function(assert) {
22876       assert.expect(4);
22877
22878       lodashStable.each(['a', ['a']], function(path) {
22879         var object = { 'a': 1, 'c': 2 };
22880         assert.strictEqual(_.unset(object, path), true);
22881         assert.deepEqual(object, { 'c': 2 });
22882       });
22883     });
22884
22885     QUnit.test('should unset deep property values', function(assert) {
22886       assert.expect(4);
22887
22888       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
22889         var object = { 'a': { 'b': { 'c': null } } };
22890         assert.strictEqual(_.unset(object, path), true);
22891         assert.deepEqual(object, { 'a': { 'b': {} } });
22892       });
22893     });
22894
22895     QUnit.test('should handle complex paths', function(assert) {
22896       assert.expect(4);
22897
22898       var paths = [
22899         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
22900         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
22901       ];
22902
22903       lodashStable.each(paths, function(path) {
22904         var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
22905         assert.strictEqual(_.unset(object, path), true);
22906         assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
22907       });
22908     });
22909
22910     QUnit.test('should return `true` for nonexistent paths', function(assert) {
22911       assert.expect(5);
22912
22913       var object = { 'a': { 'b': { 'c': null } } };
22914
22915       lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
22916         assert.strictEqual(_.unset(object, path), true);
22917       });
22918
22919       assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
22920     });
22921
22922     QUnit.test('should not error when `object` is nullish', function(assert) {
22923       assert.expect(1);
22924
22925       var values = [null, undefined],
22926           expected = [[true, true], [true, true]];
22927
22928       var actual = lodashStable.map(values, function(value) {
22929         try {
22930           return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
22931         } catch (e) {
22932           return e.message;
22933         }
22934       });
22935
22936       assert.deepEqual(actual, expected);
22937     });
22938
22939     QUnit.test('should follow `path` over non-plain objects', function(assert) {
22940       assert.expect(8);
22941
22942       var object = { 'a': '' },
22943           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
22944
22945       lodashStable.each(paths, function(path) {
22946         numberProto.a = 1;
22947
22948         var actual = _.unset(0, path);
22949         assert.strictEqual(actual, true);
22950         assert.notOk('a' in numberProto);
22951
22952         delete numberProto.a;
22953       });
22954
22955       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
22956         stringProto.replace.b = 1;
22957
22958         var actual = _.unset(object, path);
22959         assert.strictEqual(actual, true);
22960         assert.notOk('a' in stringProto.replace);
22961
22962         delete stringProto.replace.b;
22963       });
22964     });
22965
22966     QUnit.test('should return `false` for non-configurable properties', function(assert) {
22967       assert.expect(1);
22968
22969       var object = {};
22970
22971       if (!isStrict && defineProperty) {
22972         defineProperty(object, 'a', {
22973           'configurable': false,
22974           'enumerable': true,
22975           'writable': true,
22976           'value': 1,
22977         });
22978         assert.strictEqual(_.unset(object, 'a'), false);
22979       }
22980       else {
22981         skipAssert(assert);
22982       }
22983     });
22984   }());
22985
22986   /*--------------------------------------------------------------------------*/
22987
22988   QUnit.module('lodash.unzipWith');
22989
22990   (function() {
22991     QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
22992       assert.expect(1);
22993
22994       var array = [[1, 4], [2, 5], [3, 6]];
22995
22996       var actual = _.unzipWith(array, function(a, b, c) {
22997         return a + b + c;
22998       });
22999
23000       assert.deepEqual(actual, [6, 15]);
23001     });
23002
23003     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23004       assert.expect(1);
23005
23006       var args;
23007
23008       _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
23009         args || (args = slice.call(arguments));
23010       });
23011
23012       assert.deepEqual(args, [1, 2]);
23013     });
23014
23015     QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
23016       assert.expect(1);
23017
23018       var array = [[1, 3], [2, 4]],
23019           values = [, null, undefined],
23020           expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
23021
23022       var actual = lodashStable.map(values, function(value, index) {
23023         return index ? _.unzipWith(array, value) : _.unzipWith(array);
23024       });
23025
23026       assert.deepEqual(actual, expected);
23027     });
23028   }());
23029
23030   /*--------------------------------------------------------------------------*/
23031
23032   QUnit.module('values methods');
23033
23034   lodashStable.each(['values', 'valuesIn'], function(methodName) {
23035     var args = (function() { return arguments; }(1, 2, 3)),
23036         func = _[methodName],
23037         isValues = methodName == 'values';
23038
23039     QUnit.test('`_.' + methodName + '` should get the values of an object', function(assert) {
23040       assert.expect(1);
23041
23042       var object = { 'a': 1, 'b': 2 };
23043       assert.deepEqual(func(object), [1, 2]);
23044     });
23045
23046     QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
23047       assert.expect(1);
23048
23049       var object = { '0': 'a', '1': 'b', 'length': 2 };
23050       assert.deepEqual(func(object), ['a', 'b', 2]);
23051     });
23052
23053     QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + ' include inherited property values', function(assert) {
23054       assert.expect(1);
23055
23056       function Foo() { this.a = 1; }
23057       Foo.prototype.b = 2;
23058
23059       var expected = isValues ? [1] : [1, 2];
23060       assert.deepEqual(func(new Foo).sort(), expected);
23061     });
23062   });
23063
23064   /*--------------------------------------------------------------------------*/
23065
23066   QUnit.module('lodash.without');
23067
23068   (function() {
23069     QUnit.test('should use strict equality to determine the values to reject', function(assert) {
23070       assert.expect(2);
23071
23072       var object1 = { 'a': 1 },
23073           object2 = { 'b': 2 },
23074           array = [object1, object2];
23075
23076       assert.deepEqual(_.without(array, { 'a': 1 }), array);
23077       assert.deepEqual(_.without(array, object1), [object2]);
23078     });
23079
23080     QUnit.test('should remove all occurrences of each value from an array', function(assert) {
23081       assert.expect(1);
23082
23083       var array = [1, 2, 3, 1, 2, 3];
23084       assert.deepEqual(_.without(array, 1, 2), [3, 3]);
23085     });
23086   }(1, 2, 3));
23087
23088   /*--------------------------------------------------------------------------*/
23089
23090   QUnit.module('lodash.words');
23091
23092   (function() {
23093     QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
23094       assert.expect(1);
23095
23096       var expected = lodashStable.map(burredLetters, function(letter) {
23097         return [letter];
23098       });
23099
23100       var actual = lodashStable.map(burredLetters, function(letter) {
23101         return _.words(letter);
23102       });
23103
23104       assert.deepEqual(actual, expected);
23105     });
23106
23107     QUnit.test('should not treat mathematical operators as words', function(assert) {
23108       assert.expect(1);
23109
23110       var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
23111           expected = lodashStable.map(operators, alwaysEmptyArray),
23112           actual = lodashStable.map(operators, _.words);
23113
23114       assert.deepEqual(actual, expected);
23115     });
23116
23117     QUnit.test('should support a `pattern` argument', function(assert) {
23118       assert.expect(2);
23119
23120       assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
23121       assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
23122     });
23123
23124     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
23125       assert.expect(1);
23126
23127       var strings = lodashStable.map(['a', 'b', 'c'], Object),
23128           actual = lodashStable.map(strings, _.words);
23129
23130       assert.deepEqual(actual, [['a'], ['b'], ['c']]);
23131     });
23132
23133     QUnit.test('should work with compound words', function(assert) {
23134       assert.expect(9);
23135
23136       assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
23137       assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
23138       assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
23139       assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
23140       assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
23141       assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
23142       assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
23143       assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
23144       assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
23145     });
23146
23147     QUnit.test('should work with compound words containing diacritical marks', function(assert) {
23148       assert.expect(3);
23149
23150       assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
23151       assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
23152       assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
23153     });
23154   }());
23155
23156   /*--------------------------------------------------------------------------*/
23157
23158   QUnit.module('lodash.wrap');
23159
23160   (function() {
23161     QUnit.test('should create a wrapped function', function(assert) {
23162       assert.expect(1);
23163
23164       var p = _.wrap(_.escape, function(func, text) {
23165         return '<p>' + func(text) + '</p>';
23166       });
23167
23168       assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
23169     });
23170
23171     QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
23172       assert.expect(1);
23173
23174       var args;
23175
23176       var wrapped = _.wrap(noop, function() {
23177         args || (args = slice.call(arguments));
23178       });
23179
23180       wrapped(1, 2, 3);
23181       assert.deepEqual(args, [noop, 1, 2, 3]);
23182     });
23183
23184     QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
23185       assert.expect(1);
23186
23187       var values = [, null, undefined],
23188           expected = lodashStable.map(values, alwaysA);
23189
23190       var actual = lodashStable.map(values, function(value, index) {
23191         var wrapped = index ? _.wrap('a', value) : _.wrap('a');
23192         return wrapped('b', 'c');
23193       });
23194
23195       assert.deepEqual(actual, expected);
23196     });
23197
23198     QUnit.test('should not set a `this` binding', function(assert) {
23199       assert.expect(1);
23200
23201       var p = _.wrap(_.escape, function(func) {
23202         return '<p>' + func(this.text) + '</p>';
23203       });
23204
23205       var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
23206       assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
23207     });
23208   }());
23209
23210   /*--------------------------------------------------------------------------*/
23211
23212   QUnit.module('xor methods');
23213
23214   lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
23215     var args = (function() { return arguments; }(1, 2, 3)),
23216         func = _[methodName];
23217
23218     QUnit.test('`_.' + methodName + '` should return the symmetric difference of the given arrays', function(assert) {
23219       assert.expect(1);
23220
23221       var actual = func([1, 2, 5], [2, 3, 5], [3, 4, 5]);
23222       assert.deepEqual(actual, [1, 4, 5]);
23223     });
23224
23225     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
23226       assert.expect(2);
23227
23228       var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
23229       assert.deepEqual(actual, [1, 4, 5]);
23230
23231       actual = func([1, 1]);
23232       assert.deepEqual(actual, [1]);
23233     });
23234
23235     QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
23236       assert.expect(1);
23237
23238       var array = [1];
23239       assert.notStrictEqual(func(array), array);
23240     });
23241
23242     QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
23243       assert.expect(1);
23244
23245       var array = [0];
23246       assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
23247     });
23248
23249     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
23250       assert.expect(3);
23251
23252       var array = [1, 2];
23253       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
23254       assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
23255       assert.deepEqual(func(array, null, args, null), [3]);
23256     });
23257
23258     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
23259       assert.expect(1);
23260
23261       if (!isNpm) {
23262         var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
23263         assert.ok(wrapped instanceof _);
23264       }
23265       else {
23266         skipAssert(assert);
23267       }
23268     });
23269
23270     QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
23271       assert.expect(1);
23272
23273       if (!isNpm) {
23274         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
23275             wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
23276
23277         var actual = lodashStable.map(['head', 'last'], function(methodName) {
23278           return wrapped[methodName]();
23279         });
23280
23281         assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
23282       }
23283       else {
23284         skipAssert(assert);
23285       }
23286     });
23287   });
23288
23289   /*--------------------------------------------------------------------------*/
23290
23291   QUnit.module('lodash.xorBy');
23292
23293   (function() {
23294     QUnit.test('should accept an `iteratee` argument', function(assert) {
23295       assert.expect(2);
23296
23297       var actual = _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
23298       assert.deepEqual(actual, [1.2, 4.3]);
23299
23300       actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
23301       assert.deepEqual(actual, [{ 'x': 2 }]);
23302     });
23303
23304     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23305       assert.expect(1);
23306
23307       var args;
23308
23309       _.xorBy([2.1, 1.2], [4.3, 2.4], function() {
23310         args || (args = slice.call(arguments));
23311       });
23312
23313       assert.deepEqual(args, [4.3]);
23314     });
23315   }());
23316
23317   /*--------------------------------------------------------------------------*/
23318
23319   QUnit.module('lodash.xorWith');
23320
23321   (function() {
23322     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
23323
23324     QUnit.test('should work with a `comparator` argument', function(assert) {
23325       assert.expect(1);
23326
23327       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
23328           actual = _.xorWith(objects, others, lodashStable.isEqual);
23329
23330       assert.deepEqual(actual, [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]);
23331     });
23332   }());
23333
23334   /*--------------------------------------------------------------------------*/
23335
23336   QUnit.module('zipObject methods');
23337
23338   lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
23339     var func = _[methodName],
23340         array = [['barney', 36], ['fred', 40]],
23341         object = { 'barney': 36, 'fred': 40 },
23342         isDeep = methodName == 'zipObjectDeep';
23343
23344     QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
23345       assert.expect(1);
23346
23347       var actual = func(['barney', 'fred'], [36, 40]);
23348       assert.deepEqual(actual, object);
23349     });
23350
23351     QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
23352       assert.expect(1);
23353
23354       assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
23355     });
23356
23357     QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
23358       assert.expect(1);
23359
23360       assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
23361     });
23362
23363     QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
23364       assert.expect(2);
23365
23366       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
23367         var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
23368         assert.deepEqual(func([path], [1]), expected);
23369       });
23370     });
23371
23372     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
23373       assert.expect(1);
23374
23375       if (!isNpm) {
23376         var values = lodashStable.range(LARGE_ARRAY_SIZE),
23377             props = lodashStable.map(values, function(value) { return 'key' + value; }),
23378             actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
23379
23380         assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
23381       }
23382       else {
23383         skipAssert(assert);
23384       }
23385     });
23386   });
23387
23388   /*--------------------------------------------------------------------------*/
23389
23390   QUnit.module('lodash.zipWith');
23391
23392   (function() {
23393     QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
23394       assert.expect(2);
23395
23396       var array1 = [1, 2, 3],
23397           array2 = [4, 5, 6],
23398           array3 = [7, 8, 9];
23399
23400       var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
23401         return a + b + c;
23402       });
23403
23404       assert.deepEqual(actual, [12, 15, 18]);
23405
23406       var actual = _.zipWith(array1, [], function(a, b) {
23407         return a + (b || 0);
23408       });
23409
23410       assert.deepEqual(actual, [1, 2, 3]);
23411     });
23412
23413     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23414       assert.expect(1);
23415
23416       var args;
23417
23418       _.zipWith([1, 2], [3, 4], [5, 6], function() {
23419         args || (args = slice.call(arguments));
23420       });
23421
23422       assert.deepEqual(args, [1, 3, 5]);
23423     });
23424
23425     QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
23426       assert.expect(1);
23427
23428       var array1 = [1, 2],
23429           array2 = [3, 4],
23430           values = [, null, undefined],
23431           expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
23432
23433       var actual = lodashStable.map(values, function(value, index) {
23434         return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
23435       });
23436
23437       assert.deepEqual(actual, expected);
23438     });
23439   }());
23440
23441   /*--------------------------------------------------------------------------*/
23442
23443   QUnit.module('lodash.unzip and lodash.zip');
23444
23445   lodashStable.each(['unzip', 'zip'], function(methodName, index) {
23446     var func = _[methodName];
23447     func = lodashStable.bind(index ? func.apply : func.call, func, null);
23448
23449     var object = {
23450       'an empty array': [
23451         [],
23452         []
23453       ],
23454       '0-tuples': [
23455         [[], []],
23456         []
23457       ],
23458       '2-tuples': [
23459         [['barney', 'fred'], [36, 40]],
23460         [['barney', 36], ['fred', 40]]
23461       ],
23462       '3-tuples': [
23463         [['barney', 'fred'], [36, 40], [true, false]],
23464         [['barney', 36, true], ['fred', 40, false]]
23465       ]
23466     };
23467
23468     lodashStable.forOwn(object, function(pair, key) {
23469       QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
23470         assert.expect(2);
23471
23472         var actual = func(pair[0]);
23473         assert.deepEqual(actual, pair[1]);
23474         assert.deepEqual(func(actual), actual.length ? pair[0] : []);
23475       });
23476     });
23477
23478     QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
23479       assert.expect(4);
23480
23481       var pair = [
23482         [['barney', 36], ['fred', 40, false]],
23483         [['barney', 'fred'], [36, 40], [undefined, false]]
23484       ];
23485
23486       var actual = func(pair[0]);
23487       assert.ok('0' in actual[2]);
23488       assert.deepEqual(actual, pair[1]);
23489
23490       actual = func(actual);
23491       assert.ok('2' in actual[0]);
23492       assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
23493     });
23494
23495     QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
23496       assert.expect(1);
23497
23498       var expected = lodashStable.map(falsey, alwaysEmptyArray);
23499
23500       var actual = lodashStable.map(falsey, function(value) {
23501         return func([value, value, value]);
23502       });
23503
23504       assert.deepEqual(actual, expected);
23505     });
23506
23507     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
23508       assert.expect(1);
23509
23510       var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
23511       assert.deepEqual(func(array), [[1, 3], [2, 4]]);
23512     });
23513
23514     QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
23515       assert.expect(1);
23516
23517       var expected = [['barney', 'fred'], [36, 40]];
23518       assert.deepEqual(func(func(func(func(expected)))), expected);
23519     });
23520   });
23521
23522   /*--------------------------------------------------------------------------*/
23523
23524   QUnit.module('lodash(...).commit');
23525
23526   (function() {
23527     QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
23528       assert.expect(4);
23529
23530       if (!isNpm) {
23531         var array = [1],
23532             wrapped = _(array).push(2).push(3);
23533
23534         assert.deepEqual(array, [1]);
23535
23536         var otherWrapper = wrapped.commit();
23537         assert.ok(otherWrapper instanceof _);
23538         assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
23539         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
23540       }
23541       else {
23542         skipAssert(assert, 4);
23543       }
23544     });
23545
23546     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
23547       assert.expect(2);
23548
23549       if (!isNpm) {
23550         var wrapped = _([1]).chain().commit().head();
23551         assert.ok(wrapped instanceof _);
23552         assert.strictEqual(wrapped.value(), 1);
23553       }
23554       else {
23555         skipAssert(assert, 2);
23556       }
23557     });
23558   }());
23559
23560   /*--------------------------------------------------------------------------*/
23561
23562   QUnit.module('lodash(...).next');
23563
23564   lodashStable.each([true, false], function(implict) {
23565     function chain(value) {
23566       return implict ? _(value) : _.chain(value);
23567     }
23568
23569     var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
23570
23571     QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
23572       assert.expect(3);
23573
23574       if (!isNpm) {
23575         var wrapped = chain([1, 2]);
23576
23577         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
23578         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
23579         assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
23580       }
23581       else {
23582         skipAssert(assert, 3);
23583       }
23584     });
23585
23586     QUnit.test('should act as an iterable ' + chainType, function(assert) {
23587       assert.expect(2);
23588
23589       if (!isNpm && Symbol && Symbol.iterator) {
23590         var array = [1, 2],
23591             wrapped = chain(array);
23592
23593         assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
23594         assert.deepEqual(_.toArray(wrapped), array);
23595       }
23596       else {
23597         skipAssert(assert, 2);
23598       }
23599     });
23600
23601     QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
23602       assert.expect(3);
23603
23604       if (!isNpm && Array.from) {
23605         var hearts = '\ud83d\udc95',
23606             values = [[1], { 'a': 1 }, hearts];
23607
23608         lodashStable.each(values, function(value) {
23609           var wrapped = chain(value);
23610           assert.deepEqual(Array.from(wrapped), _.toArray(value));
23611         });
23612       }
23613       else {
23614         skipAssert(assert, 3);
23615       }
23616     });
23617
23618     QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
23619       assert.expect(4);
23620
23621       if (!isNpm && Symbol && Symbol.iterator) {
23622         var array = [1, 2],
23623             wrapped = chain(array);
23624
23625         assert.deepEqual(_.toArray(wrapped), array);
23626         assert.deepEqual(_.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
23627
23628         var other = wrapped.filter();
23629         assert.deepEqual(_.toArray(other), array, 'reset for new chain segments');
23630         assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted');
23631       }
23632       else {
23633         skipAssert(assert, 4);
23634       }
23635     });
23636
23637     QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
23638       assert.expect(3);
23639
23640       if (!isNpm && Symbol && Symbol.iterator) {
23641         var array = lodashStable.range(LARGE_ARRAY_SIZE),
23642             predicate = function(value) { values.push(value); return isEven(value); },
23643             values = [],
23644             wrapped = chain(array);
23645
23646         assert.deepEqual(_.toArray(wrapped), array);
23647
23648         wrapped = wrapped.filter(predicate);
23649         assert.deepEqual(_.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
23650         assert.deepEqual(values, array, 'memoizes iterator values');
23651       }
23652       else {
23653         skipAssert(assert, 3);
23654       }
23655     });
23656   });
23657
23658   /*--------------------------------------------------------------------------*/
23659
23660   QUnit.module('lodash(...).plant');
23661
23662   (function() {
23663     QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
23664       assert.expect(2);
23665
23666       if (!isNpm) {
23667         var array1 = [5, null, 3, null, 1],
23668             array2 = [10, null, 8, null, 6],
23669             wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
23670             wrapped2 = wrapped1.plant(array2);
23671
23672         assert.deepEqual(wrapped2.value(), [36, 64]);
23673         assert.deepEqual(wrapped1.value(), [1, 9]);
23674       }
23675       else {
23676         skipAssert(assert, 2);
23677       }
23678     });
23679
23680     QUnit.test('should clone `chainAll` settings', function(assert) {
23681       assert.expect(1);
23682
23683       if (!isNpm) {
23684         var array1 = [2, 4],
23685             array2 = [6, 8],
23686             wrapped1 = _(array1).chain().map(square),
23687             wrapped2 = wrapped1.plant(array2);
23688
23689         assert.deepEqual(wrapped2.head().value(), 36);
23690       }
23691       else {
23692         skipAssert(assert);
23693       }
23694     });
23695
23696     QUnit.test('should reset iterator data on cloned sequences', function(assert) {
23697       assert.expect(3);
23698
23699       if (!isNpm && Symbol && Symbol.iterator) {
23700         var array1 = [2, 4],
23701             array2 = [6, 8],
23702             wrapped1 = _(array1).map(square);
23703
23704         assert.deepEqual(_.toArray(wrapped1), [4, 16]);
23705         assert.deepEqual(_.toArray(wrapped1), []);
23706
23707         var wrapped2 = wrapped1.plant(array2);
23708         assert.deepEqual(_.toArray(wrapped2), [36, 64]);
23709       }
23710       else {
23711         skipAssert(assert, 3);
23712       }
23713     });
23714   }());
23715
23716   /*--------------------------------------------------------------------------*/
23717
23718   QUnit.module('lodash(...).pop');
23719
23720   (function() {
23721     QUnit.test('should remove elements from the end of `array`', function(assert) {
23722       assert.expect(5);
23723
23724       if (!isNpm) {
23725         var array = [1, 2],
23726             wrapped = _(array);
23727
23728         assert.strictEqual(wrapped.pop(), 2);
23729         assert.deepEqual(wrapped.value(), [1]);
23730         assert.strictEqual(wrapped.pop(), 1);
23731
23732         var actual = wrapped.value();
23733         assert.deepEqual(actual, []);
23734         assert.strictEqual(actual, array);
23735       }
23736       else {
23737         skipAssert(assert, 5);
23738       }
23739     });
23740   }());
23741
23742   /*--------------------------------------------------------------------------*/
23743
23744   QUnit.module('lodash(...).push');
23745
23746   (function() {
23747     QUnit.test('should append elements to `array`', function(assert) {
23748       assert.expect(2);
23749
23750       if (!isNpm) {
23751         var array = [1],
23752             wrapped = _(array).push(2, 3),
23753             actual = wrapped.value();
23754
23755         assert.strictEqual(actual, array);
23756         assert.deepEqual(actual, [1, 2, 3]);
23757       }
23758       else {
23759         skipAssert(assert, 2);
23760       }
23761     });
23762   }());
23763
23764   /*--------------------------------------------------------------------------*/
23765
23766   QUnit.module('lodash(...).shift');
23767
23768   (function() {
23769     QUnit.test('should remove elements from the front of `array`', function(assert) {
23770       assert.expect(5);
23771
23772       if (!isNpm) {
23773         var array = [1, 2],
23774             wrapped = _(array);
23775
23776         assert.strictEqual(wrapped.shift(), 1);
23777         assert.deepEqual(wrapped.value(), [2]);
23778         assert.strictEqual(wrapped.shift(), 2);
23779
23780         var actual = wrapped.value();
23781         assert.deepEqual(actual, []);
23782         assert.strictEqual(actual, array);
23783       }
23784       else {
23785         skipAssert(assert, 5);
23786       }
23787     });
23788   }());
23789
23790   /*--------------------------------------------------------------------------*/
23791
23792   QUnit.module('lodash(...).sort');
23793
23794   (function() {
23795     QUnit.test('should return the wrapped sorted `array`', function(assert) {
23796       assert.expect(2);
23797
23798       if (!isNpm) {
23799         var array = [3, 1, 2],
23800             wrapped = _(array).sort(),
23801             actual = wrapped.value();
23802
23803         assert.strictEqual(actual, array);
23804         assert.deepEqual(actual, [1, 2, 3]);
23805       }
23806       else {
23807         skipAssert(assert, 2);
23808       }
23809     });
23810   }());
23811
23812   /*--------------------------------------------------------------------------*/
23813
23814   QUnit.module('lodash(...).splice');
23815
23816   (function() {
23817     QUnit.test('should support removing and inserting elements', function(assert) {
23818       assert.expect(5);
23819
23820       if (!isNpm) {
23821         var array = [1, 2],
23822             wrapped = _(array);
23823
23824         assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
23825         assert.deepEqual(wrapped.value(), [1, 3]);
23826         assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
23827
23828         var actual = wrapped.value();
23829         assert.deepEqual(actual, []);
23830         assert.strictEqual(actual, array);
23831       }
23832       else {
23833         skipAssert(assert, 5);
23834       }
23835     });
23836   }());
23837
23838   /*--------------------------------------------------------------------------*/
23839
23840   QUnit.module('lodash(...).unshift');
23841
23842   (function() {
23843     QUnit.test('should prepend elements to `array`', function(assert) {
23844       assert.expect(2);
23845
23846       if (!isNpm) {
23847         var array = [3],
23848             wrapped = _(array).unshift(1, 2),
23849             actual = wrapped.value();
23850
23851         assert.strictEqual(actual, array);
23852         assert.deepEqual(actual, [1, 2, 3]);
23853       }
23854       else {
23855         skipAssert(assert, 2);
23856       }
23857     });
23858   }());
23859
23860   /*--------------------------------------------------------------------------*/
23861
23862   QUnit.module('lodash(...).value');
23863
23864   (function() {
23865     QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
23866       assert.expect(4);
23867
23868       if (!isNpm) {
23869         var array = [1],
23870             wrapped = _(array).push(2).push(3);
23871
23872         assert.deepEqual(array, [1]);
23873         assert.deepEqual(wrapped.value(), [1, 2, 3]);
23874         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
23875         assert.deepEqual(array, [1, 2, 3, 2, 3]);
23876       }
23877       else {
23878         skipAssert(assert, 4);
23879       }
23880     });
23881
23882     QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
23883       assert.expect(1);
23884
23885       if (!isNpm) {
23886         var wrapped = _(123);
23887         assert.strictEqual(Number(wrapped), 123);
23888       }
23889       else {
23890         skipAssert(assert);
23891       }
23892     });
23893
23894     QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
23895       assert.expect(1);
23896
23897       if (!isNpm && JSON) {
23898         var wrapped = _([1, 2, 3]);
23899         assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
23900       }
23901       else {
23902         skipAssert(assert);
23903       }
23904     });
23905
23906     QUnit.test('should be aliased', function(assert) {
23907       assert.expect(2);
23908
23909       if (!isNpm) {
23910         var expected = _.prototype.value;
23911         assert.strictEqual(_.prototype.toJSON, expected);
23912         assert.strictEqual(_.prototype.valueOf, expected);
23913       }
23914       else {
23915         skipAssert(assert, 2);
23916       }
23917     });
23918   }());
23919
23920   /*--------------------------------------------------------------------------*/
23921
23922   QUnit.module('lodash(...) methods that return the wrapped modified array');
23923
23924   (function() {
23925     var funcs = [
23926       'push',
23927       'reverse',
23928       'sort',
23929       'unshift'
23930     ];
23931
23932     lodashStable.each(funcs, function(methodName) {
23933       QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
23934         assert.expect(2);
23935
23936         if (!isNpm) {
23937           var array = [1, 2, 3],
23938               wrapped = _(array),
23939               actual = wrapped[methodName]();
23940
23941           assert.ok(actual instanceof _);
23942           assert.notStrictEqual(actual, wrapped);
23943         }
23944         else {
23945           skipAssert(assert, 2);
23946         }
23947       });
23948     });
23949   }());
23950
23951   /*--------------------------------------------------------------------------*/
23952
23953   QUnit.module('lodash(...) methods that return new wrapped values');
23954
23955   (function() {
23956     var funcs = [
23957       'castArray',
23958       'concat',
23959       'pull',
23960       'pullAll',
23961       'pullAt',
23962       'sampleSize',
23963       'shuffle',
23964       'slice',
23965       'splice',
23966       'split',
23967       'toArray',
23968       'words'
23969     ];
23970
23971     lodashStable.each(funcs, function(methodName) {
23972       QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
23973         assert.expect(2);
23974
23975         if (!isNpm) {
23976           var value = methodName == 'split' ? 'abc' : [1, 2, 3],
23977               wrapped = _(value),
23978               actual = wrapped[methodName]();
23979
23980           assert.ok(actual instanceof _);
23981           assert.notStrictEqual(actual, wrapped);
23982         }
23983         else {
23984           skipAssert(assert, 2);
23985         }
23986       });
23987     });
23988   }());
23989
23990   /*--------------------------------------------------------------------------*/
23991
23992   QUnit.module('lodash(...) methods that return unwrapped values');
23993
23994   (function() {
23995     var funcs = [
23996       'camelCase',
23997       'capitalize',
23998       'ceil',
23999       'clone',
24000       'deburr',
24001       'endsWith',
24002       'escape',
24003       'escapeRegExp',
24004       'every',
24005       'find',
24006       'floor',
24007       'has',
24008       'hasIn',
24009       'head',
24010       'includes',
24011       'isArguments',
24012       'isArray',
24013       'isArrayBuffer',
24014       'isArrayLike',
24015       'isBoolean',
24016       'isBuffer',
24017       'isDate',
24018       'isElement',
24019       'isEmpty',
24020       'isEqual',
24021       'isError',
24022       'isFinite',
24023       'isFunction',
24024       'isInteger',
24025       'isMap',
24026       'isNaN',
24027       'isNative',
24028       'isNil',
24029       'isNull',
24030       'isNumber',
24031       'isObject',
24032       'isObjectLike',
24033       'isPlainObject',
24034       'isRegExp',
24035       'isSafeInteger',
24036       'isSet',
24037       'isString',
24038       'isUndefined',
24039       'isWeakMap',
24040       'isWeakSet',
24041       'join',
24042       'kebabCase',
24043       'last',
24044       'lowerCase',
24045       'lowerFirst',
24046       'max',
24047       'maxBy',
24048       'min',
24049       'minBy',
24050       'pad',
24051       'padEnd',
24052       'padStart',
24053       'parseInt',
24054       'pop',
24055       'random',
24056       'reduce',
24057       'reduceRight',
24058       'repeat',
24059       'replace',
24060       'round',
24061       'sample',
24062       'shift',
24063       'size',
24064       'snakeCase',
24065       'some',
24066       'startCase',
24067       'startsWith',
24068       'sum',
24069       'toInteger',
24070       'toLower',
24071       'toNumber',
24072       'toSafeInteger',
24073       'toString',
24074       'toUpper',
24075       'trim',
24076       'trimEnd',
24077       'trimStart',
24078       'truncate',
24079       'unescape',
24080       'upperCase',
24081       'upperFirst'
24082     ];
24083
24084     lodashStable.each(funcs, function(methodName) {
24085       QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
24086         assert.expect(1);
24087
24088         if (!isNpm) {
24089           var array = [1, 2, 3],
24090               actual = _(array)[methodName]();
24091
24092           assert.notOk(actual instanceof _);
24093         }
24094         else {
24095           skipAssert(assert);
24096         }
24097       });
24098
24099       QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
24100         assert.expect(1);
24101
24102         if (!isNpm) {
24103           var array = [1, 2, 3],
24104               actual = _(array).chain()[methodName]();
24105
24106           assert.ok(actual instanceof _);
24107         }
24108         else {
24109           skipAssert(assert);
24110         }
24111       });
24112     });
24113   }());
24114
24115   /*--------------------------------------------------------------------------*/
24116
24117   QUnit.module('"Arrays" category methods');
24118
24119   (function() {
24120     var args = (function() { return arguments; }(1, null, [3], null, 5)),
24121         sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
24122         array = [1, 2, 3, 4, 5, 6];
24123
24124     QUnit.test('should work with `arguments` objects', function(assert) {
24125       assert.expect(30);
24126
24127       function message(methodName) {
24128         return '`_.' + methodName + '` should work with `arguments` objects';
24129       }
24130
24131       assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
24132       assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
24133
24134       assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
24135       assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
24136
24137       assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
24138       assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
24139       assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
24140       assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
24141       assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
24142       assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
24143       assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
24144       assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
24145       assert.deepEqual(_.head(args), 1, message('head'));
24146       assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
24147       assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
24148       assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
24149       assert.deepEqual(_.last(args), 5, message('last'));
24150       assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
24151       assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
24152       assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
24153       assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
24154       assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
24155       assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
24156       assert.deepEqual(_.take(args, 2), [1, null], message('take'));
24157       assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
24158       assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
24159       assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
24160       assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
24161       assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
24162       assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
24163     });
24164
24165     QUnit.test('should accept falsey primary arguments', function(assert) {
24166       assert.expect(4);
24167
24168       function message(methodName) {
24169         return '`_.' + methodName + '` should accept falsey primary arguments';
24170       }
24171
24172       assert.deepEqual(_.difference(null, array), [], message('difference'));
24173       assert.deepEqual(_.intersection(null, array), [], message('intersection'));
24174       assert.deepEqual(_.union(null, array), array, message('union'));
24175       assert.deepEqual(_.xor(null, array), array, message('xor'));
24176     });
24177
24178     QUnit.test('should accept falsey secondary arguments', function(assert) {
24179       assert.expect(3);
24180
24181       function message(methodName) {
24182         return '`_.' + methodName + '` should accept falsey secondary arguments';
24183       }
24184
24185       assert.deepEqual(_.difference(array, null), array, message('difference'));
24186       assert.deepEqual(_.intersection(array, null), [], message('intersection'));
24187       assert.deepEqual(_.union(array, null), array, message('union'));
24188     });
24189   }());
24190
24191   /*--------------------------------------------------------------------------*/
24192
24193   QUnit.module('"Strings" category methods');
24194
24195   (function() {
24196     var stringMethods = [
24197       'camelCase',
24198       'capitalize',
24199       'escape',
24200       'kebabCase',
24201       'lowerCase',
24202       'lowerFirst',
24203       'pad',
24204       'padEnd',
24205       'padStart',
24206       'repeat',
24207       'snakeCase',
24208       'toLower',
24209       'toUpper',
24210       'trim',
24211       'trimEnd',
24212       'trimStart',
24213       'truncate',
24214       'unescape',
24215       'upperCase',
24216       'upperFirst'
24217     ];
24218
24219     lodashStable.each(stringMethods, function(methodName) {
24220       var func = _[methodName];
24221
24222       QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
24223         assert.expect(1);
24224
24225         var values = [, null, undefined, ''],
24226             expected = lodashStable.map(values, alwaysEmptyString);
24227
24228         var actual = lodashStable.map(values, function(value, index) {
24229           return index ? func(value) : func();
24230         });
24231
24232         assert.deepEqual(actual, expected);
24233       });
24234     });
24235   }());
24236
24237   /*--------------------------------------------------------------------------*/
24238
24239   QUnit.module('lodash methods');
24240
24241   (function() {
24242     var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
24243       return lodashStable.startsWith(methodName, '_');
24244     });
24245
24246     var checkFuncs = [
24247       'after',
24248       'ary',
24249       'before',
24250       'bind',
24251       'curry',
24252       'curryRight',
24253       'debounce',
24254       'defer',
24255       'delay',
24256       'flip',
24257       'flow',
24258       'flowRight',
24259       'memoize',
24260       'negate',
24261       'once',
24262       'partial',
24263       'partialRight',
24264       'rearg',
24265       'rest',
24266       'spread',
24267       'throttle',
24268       'unary'
24269     ];
24270
24271     var noBinding = [
24272       'flip',
24273       'memoize',
24274       'negate',
24275       'once',
24276       'overArgs',
24277       'partial',
24278       'partialRight',
24279       'rearg',
24280       'rest',
24281       'spread'
24282     ];
24283
24284     var rejectFalsey = [
24285       'tap',
24286       'thru'
24287     ].concat(checkFuncs);
24288
24289     var returnArrays = [
24290       'at',
24291       'chunk',
24292       'compact',
24293       'difference',
24294       'drop',
24295       'filter',
24296       'flatten',
24297       'functions',
24298       'initial',
24299       'intersection',
24300       'invokeMap',
24301       'keys',
24302       'map',
24303       'orderBy',
24304       'pull',
24305       'pullAll',
24306       'pullAt',
24307       'range',
24308       'rangeRight',
24309       'reject',
24310       'remove',
24311       'sampleSize',
24312       'shuffle',
24313       'sortBy',
24314       'tail',
24315       'take',
24316       'times',
24317       'toArray',
24318       'toPairs',
24319       'union',
24320       'uniq',
24321       'values',
24322       'without',
24323       'xor',
24324       'zip'
24325     ];
24326
24327     var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
24328
24329     QUnit.test('should accept falsey arguments', function(assert) {
24330       assert.expect(297);
24331
24332       var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
24333
24334       lodashStable.each(acceptFalsey, function(methodName) {
24335         var expected = emptyArrays,
24336             func = _[methodName],
24337             pass = true;
24338
24339         var actual = lodashStable.map(falsey, function(value, index) {
24340           try {
24341             return index ? func(value) : func();
24342           } catch (e) {
24343             pass = false;
24344           }
24345         });
24346
24347         if (methodName == 'noConflict') {
24348           root._ = oldDash;
24349         }
24350         else if (methodName == 'pull' || methodName == 'pullAll') {
24351           expected = falsey;
24352         }
24353         if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
24354           assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
24355         }
24356         assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
24357       });
24358
24359       // Skip tests for missing methods of modularized builds.
24360       lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
24361         if (!_[methodName]) {
24362           skipAssert(assert);
24363         }
24364       });
24365     });
24366
24367     QUnit.test('should return an array', function(assert) {
24368       assert.expect(70);
24369
24370       var array = [1, 2, 3];
24371
24372       lodashStable.each(returnArrays, function(methodName) {
24373         var actual,
24374             func = _[methodName];
24375
24376         switch (methodName) {
24377           case 'invokeMap':
24378             actual = func(array, 'toFixed');
24379             break;
24380           case 'sample':
24381             actual = func(array, 1);
24382             break;
24383           default:
24384             actual = func(array);
24385         }
24386         assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
24387
24388         var isPull = methodName == 'pull' || methodName == 'pullAll';
24389         assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
24390       });
24391     });
24392
24393     QUnit.test('should throw an error for falsey arguments', function(assert) {
24394       assert.expect(24);
24395
24396       lodashStable.each(rejectFalsey, function(methodName) {
24397         var expected = lodashStable.map(falsey, alwaysTrue),
24398             func = _[methodName];
24399
24400         var actual = lodashStable.map(falsey, function(value, index) {
24401           var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
24402
24403           try {
24404             index ? func(value) : func();
24405           } catch (e) {
24406             pass = !pass && (e instanceof TypeError) &&
24407               (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
24408           }
24409           return pass;
24410         });
24411
24412         assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
24413       });
24414     });
24415
24416     QUnit.test('should not set a `this` binding', function(assert) {
24417       assert.expect(30);
24418
24419       lodashStable.each(noBinding, function(methodName) {
24420         var fn = function() { return this.a; },
24421             func = _[methodName],
24422             isNegate = methodName == 'negate',
24423             object = { 'a': 1 },
24424             expected = isNegate ? false : 1;
24425
24426         var wrapper = func(_.bind(fn, object));
24427         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
24428
24429         wrapper = _.bind(func(fn), object);
24430         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
24431
24432         object.wrapper = func(fn);
24433         assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
24434       });
24435     });
24436
24437     QUnit.test('should not contain minified method names (test production builds)', function(assert) {
24438       assert.expect(1);
24439
24440       var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
24441       assert.ok(lodashStable.every(_.functions(_), function(methodName) {
24442         return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
24443       }));
24444     });
24445   }());
24446
24447   /*--------------------------------------------------------------------------*/
24448
24449   QUnit.config.asyncRetries = 10;
24450   QUnit.config.hidepassed = true;
24451
24452   if (!document) {
24453     QUnit.config.noglobals = true;
24454     QUnit.load();
24455   }
24456 }.call(this));