Built motion from commit 7767ffc.|0.0.132
[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       funcProto = Function.prototype,
37       objectProto = Object.prototype,
38       numberProto = Number.prototype,
39       stringProto = String.prototype;
40
41   /** Method and object shortcuts. */
42   var phantom = root.phantom,
43       process = root.process,
44       amd = root.define && define.amd,
45       argv = process && process.argv,
46       defineProperty = Object.defineProperty,
47       document = !phantom && root.document,
48       body = root.document && root.document.body,
49       create = Object.create,
50       fnToString = funcProto.toString,
51       freeze = Object.freeze,
52       getSymbols = Object.getOwnPropertySymbols,
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       Promise = root.Promise,
65       Map = root.Map,
66       Set = root.Set,
67       Symbol = root.Symbol,
68       Uint8Array = root.Uint8Array,
69       WeakMap = root.WeakMap,
70       WeakSet = root.WeakSet;
71
72   var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
73       map = Map ? new Map : undefined,
74       promise = Promise ? Promise.resolve(1) : undefined,
75       set = Set ? new Set : undefined,
76       symbol = Symbol ? Symbol('a') : undefined,
77       weakMap = WeakMap ? new WeakMap : undefined,
78       weakSet = WeakSet ? new WeakSet : undefined;
79
80   /** Math helpers. */
81   var add = function(x, y) { return x + y; },
82       doubled = function(n) { return n * 2; },
83       isEven = function(n) { return n % 2 == 0; },
84       square = function(n) { return n * n; };
85
86   /** Constant functions. */
87   var alwaysA = function() { return 'a'; },
88       alwaysB = function() { return 'b'; },
89       alwaysC = function() { return 'c'; };
90
91   var alwaysTrue = function() { return true; },
92       alwaysFalse = function() { return false; };
93
94   var alwaysNaN = function() { return NaN; },
95       alwaysNull = function() { return null; };
96
97   var alwaysZero = function() { return 0; },
98       alwaysOne = function() { return 1; },
99       alwaysTwo = function() { return 2; },
100       alwaysThree = function() { return 3; },
101       alwaysFour = function() { return 4; };
102
103   var alwaysEmptyArray = function() { return []; },
104       alwaysEmptyObject = function() { return {}; },
105       alwaysEmptyString = function() { return ''; };
106
107   /** List of latin-1 supplementary letters to basic latin letters. */
108   var burredLetters = [
109     '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce',
110     '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
111     '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
112     '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
113   ];
114
115   /** List of combining diacritical marks. */
116   var comboMarks = [
117     '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
118     '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
119     '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
120     '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
121     '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
122     '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
123     '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
124     '\ufe20', '\ufe21', '\ufe22', '\ufe23'
125   ];
126
127   /** List of `burredLetters` translated to basic latin letters. */
128   var deburredLetters = [
129     'A',  'A', 'A', 'A', 'A', 'A', 'Ae', 'C',  'E', 'E', 'E', 'E', 'I', 'I', 'I',
130     'I',  'D', 'N', 'O', 'O', 'O', 'O',  'O',  'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
131     'ss', 'a', 'a', 'a', 'a', 'a', 'a',  'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i',  'i',
132     'i',  'd', 'n', 'o', 'o', 'o', 'o',  'o',  'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y'
133   ];
134
135   /** Used to provide falsey values to methods. */
136   var falsey = [, null, undefined, false, 0, NaN, ''];
137
138   /** Used to specify the emoji style glyph variant of characters. */
139   var emojiVar = '\ufe0f';
140
141   /** Used to provide empty values to methods. */
142   var empties = [[], {}].concat(falsey.slice(1));
143
144   /** Used to test error objects. */
145   var errors = [
146     new Error,
147     new EvalError,
148     new RangeError,
149     new ReferenceError,
150     new SyntaxError,
151     new TypeError,
152     new URIError
153   ];
154
155   /** List of fitzpatrick modifiers. */
156   var fitzModifiers = [
157     '\ud83c\udffb',
158     '\ud83c\udffc',
159     '\ud83c\udffd',
160     '\ud83c\udffe',
161     '\ud83c\udfff'
162   ];
163
164   /** Used to provide primitive values to methods. */
165   var primitives = [null, undefined, false, true, 1, NaN, 'a'];
166
167   /** Used to check whether methods support typed arrays. */
168   var typedArrays = [
169     'Float32Array',
170     'Float64Array',
171     'Int8Array',
172     'Int16Array',
173     'Int32Array',
174     'Uint8Array',
175     'Uint8ClampedArray',
176     'Uint16Array',
177     'Uint32Array'
178   ];
179
180   /** Used to check whether methods support array views. */
181   var arrayViews = typedArrays.concat('DataView');
182
183   /** The file path of the lodash file to test. */
184   var filePath = (function() {
185     var min = 2,
186         result = params || [];
187
188     if (phantom) {
189       min = 0;
190       result = params = phantom.args || require('system').args;
191     }
192     var last = result[result.length - 1];
193     result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
194
195     if (!amd) {
196       try {
197         result = require('fs').realpathSync(result);
198       } catch (e) {}
199
200       try {
201         result = require.resolve(result);
202       } catch (e) {}
203     }
204     return result;
205   }());
206
207   /** The `ui` object. */
208   var ui = root.ui || (root.ui = {
209     'buildPath': filePath,
210     'loaderPath': '',
211     'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath),
212     'isStrict': /\bes\b/.test(filePath),
213     'urlParams': {}
214   });
215
216   /** The basename of the lodash file to test. */
217   var basename = /[\w.-]+$/.exec(filePath)[0];
218
219   /** Used to indicate testing a modularized build. */
220   var isModularize = ui.isModularize;
221
222   /** Detect if testing `npm` modules. */
223   var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
224
225   /** Detect if running in PhantomJS. */
226   var isPhantom = phantom || (typeof callPhantom == 'function');
227
228   /** Detect if lodash is in strict mode. */
229   var isStrict = ui.isStrict;
230
231   /*--------------------------------------------------------------------------*/
232
233   // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
234   root.msWDfn = undefined;
235
236   // Exit early if going to run tests in a PhantomJS web page.
237   if (phantom && isModularize) {
238     var page = require('webpage').create();
239
240     page.onCallback = function(details) {
241       var coverage = details.coverage;
242       if (coverage) {
243         var fs = require('fs'),
244             cwd = fs.workingDirectory,
245             sep = fs.separator;
246
247         fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
248       }
249       phantom.exit(details.failed ? 1 : 0);
250     };
251
252     page.onConsoleMessage = function(message) {
253       console.log(message);
254     };
255
256     page.onInitialized = function() {
257       page.evaluate(function() {
258         document.addEventListener('DOMContentLoaded', function() {
259           QUnit.done(function(details) {
260             details.coverage = window.__coverage__;
261             callPhantom(details);
262           });
263         });
264       });
265     };
266
267     page.open(filePath, function(status) {
268       if (status != 'success') {
269         console.log('PhantomJS failed to load page: ' + filePath);
270         phantom.exit(1);
271       }
272     });
273
274     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
275     return;
276   }
277
278   /*--------------------------------------------------------------------------*/
279
280   /** Used to test Web Workers. */
281   var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
282     (document && document.origin != 'null') && root.Worker;
283
284   /** Used to test host objects in IE. */
285   try {
286     var xml = new ActiveXObject('Microsoft.XMLDOM');
287   } catch (e) {}
288
289   /** Poison the free variable `root` in Node.js */
290   try {
291     defineProperty(global.root, 'root', {
292       'configurable': false,
293       'enumerable': false,
294       'get': function() { throw new ReferenceError; }
295     });
296   } catch (e) {}
297
298   /** Use a single "load" function. */
299   var load = (!amd && typeof require == 'function')
300     ? require
301     : noop;
302
303   /** The unit testing framework. */
304   var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qunit.js'));
305
306   /** Load stable Lodash and QUnit Extras. */
307   var lodashStable = root.lodashStable;
308   if (!lodashStable) {
309     try {
310       lodashStable = load('../node_modules/lodash/lodash.js');
311     } catch (e) {
312       console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
313       return;
314     }
315     lodashStable = lodashStable.noConflict();
316   }
317   lodashStable = lodashStable.runInContext(root);
318
319   var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
320   if (QUnitExtras) {
321     QUnitExtras.runInContext(root);
322   }
323
324   /** The `lodash` function to test. */
325   var _ = root._ || (root._ = (
326     _ = load(filePath),
327     _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default']) || _,
328     (_.runInContext ? _.runInContext(root) : _)
329   ));
330
331   /** Used to detect instrumented istanbul code coverage runs. */
332   var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
333     return /^(?:\$\$cov_\d+\$\$)$/.test(key);
334   })];
335
336   /** Used to test generator functions. */
337   var generator = lodashStable.attempt(function() {
338     return Function('return function*(){}');
339   });
340
341   /** Used to restore the `_` reference. */
342   var oldDash = root._;
343
344   /**
345    * Used to check for problems removing whitespace. For a whitespace reference,
346    * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
347    */
348   var whitespace = lodashStable.filter([
349     // Basic whitespace characters.
350     ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
351
352     // Line terminators.
353     '\n', '\r', '\u2028', '\u2029',
354
355     // Unicode category "Zs" space separators.
356     '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
357     '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
358   ],
359   function(chr) { return /\s/.exec(chr); })
360   .join('');
361
362   /**
363    * Creates a custom error object.
364    *
365    * @private
366    * @constructor
367    * @param {string} message The error message.
368    */
369   function CustomError(message) {
370     this.name = 'CustomError';
371     this.message = message;
372   }
373
374   CustomError.prototype = lodashStable.create(Error.prototype, {
375     'constructor': CustomError
376   });
377
378   /**
379    * Removes all own enumerable string keyed properties from a given object.
380    *
381    * @private
382    * @param {Object} object The object to empty.
383    */
384   function emptyObject(object) {
385     lodashStable.forOwn(object, function(value, key, object) {
386       delete object[key];
387     });
388   }
389
390   /**
391    * Extracts the unwrapped value from its wrapper.
392    *
393    * @private
394    * @param {Object} wrapper The wrapper to unwrap.
395    * @returns {*} Returns the unwrapped value.
396    */
397   function getUnwrappedValue(wrapper) {
398     var index = -1,
399         actions = wrapper.__actions__,
400         length = actions.length,
401         result = wrapper.__wrapped__;
402
403     while (++index < length) {
404       var args = [result],
405           action = actions[index];
406
407       push.apply(args, action.args);
408       result = action.func.apply(action.thisArg, args);
409     }
410     return result;
411   }
412
413   /**
414    * Sets a non-enumerable property value on `object`.
415    *
416    * Note: This function is used to avoid a bug in older versions of V8 where
417    * overwriting non-enumerable built-ins makes them enumerable.
418    * See https://code.google.com/p/v8/issues/detail?id=1623
419    *
420    * @private
421    * @param {Object} object The object modify.
422    * @param {string} key The name of the property to set.
423    * @param {*} value The property value.
424    */
425   function setProperty(object, key, value) {
426     try {
427       defineProperty(object, key, {
428         'configurable': true,
429         'enumerable': false,
430         'writable': true,
431         'value': value
432       });
433     } catch (e) {
434       object[key] = value;
435     }
436     return object;
437   }
438
439   /**
440    * Skips a given number of tests with a passing result.
441    *
442    * @private
443    * @param {Object} assert The QUnit assert object.
444    * @param {number} [count=1] The number of tests to skip.
445    */
446   function skipAssert(assert, count) {
447     count || (count = 1);
448     while (count--) {
449       assert.ok(true, 'test skipped');
450     }
451   }
452
453   /*--------------------------------------------------------------------------*/
454
455   // Add bizarro values.
456   (function() {
457     if (document || (typeof require != 'function')) {
458       return;
459     }
460     var nativeString = fnToString.call(toString),
461         reToString = /toString/g;
462
463     function createToString(funcName) {
464       return lodashStable.constant(nativeString.replace(reToString, funcName));
465     }
466
467     // Allow bypassing native checks.
468     setProperty(funcProto, 'toString', function wrapper() {
469       setProperty(funcProto, 'toString', fnToString);
470       var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
471       setProperty(funcProto, 'toString', wrapper);
472       return result;
473     });
474
475     // Add prototype extensions.
476     funcProto._method = noop;
477
478     // Set bad shims.
479     setProperty(Object, 'create', (function() {
480       function object() {}
481       return function(prototype) {
482         if (lodashStable.isObject(prototype)) {
483           object.prototype = prototype;
484           var result = new object;
485           object.prototype = undefined;
486         }
487         return result || {};
488       };
489     }()));
490
491     setProperty(Object, 'getOwnPropertySymbols', undefined);
492
493     var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
494     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
495       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
496     });
497
498     if (Buffer) {
499       defineProperty(root, 'Buffer', {
500         'configurable': true,
501         'enumerable': true,
502         'get': function get() {
503           var caller = get.caller,
504               name = caller ? caller.name : '';
505
506           if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
507             return Buffer;
508           }
509         }
510       });
511     }
512     if (Map) {
513       setProperty(root, 'Map', (function() {
514         var count = 0;
515         return function() {
516           if (count++) {
517             return new Map;
518           }
519           setProperty(root, 'Map', Map);
520           return {};
521         };
522       }()));
523
524       setProperty(root.Map, 'toString', createToString('Map'));
525     }
526     setProperty(root, 'Promise', noop);
527     setProperty(root, 'Set', noop);
528     setProperty(root, 'Symbol', undefined);
529     setProperty(root, 'WeakMap', noop);
530
531     // Fake `WinRTError`.
532     setProperty(root, 'WinRTError', Error);
533
534     // Clear cache so lodash can be reloaded.
535     emptyObject(require.cache);
536
537     // Load lodash and expose it to the bad extensions/shims.
538     lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
539     root._ = oldDash;
540
541     // Restore built-in methods.
542     setProperty(Object, 'create', create);
543     setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
544     setProperty(root, 'Buffer', Buffer);
545
546     if (getSymbols) {
547       Object.getOwnPropertySymbols = getSymbols;
548     } else {
549       delete Object.getOwnPropertySymbols;
550     }
551     if (Map) {
552       setProperty(root, 'Map', Map);
553     } else {
554       delete root.Map;
555     }
556     if (Promise) {
557       setProperty(root, 'Promise', Promise);
558     } else {
559       delete root.Promise;
560     }
561     if (Set) {
562       setProperty(root, 'Set', Set);
563     } else {
564       delete root.Set;
565     }
566     if (Symbol) {
567       setProperty(root, 'Symbol', Symbol);
568     } else {
569       delete root.Symbol;
570     }
571     if (WeakMap) {
572       setProperty(root, 'WeakMap', WeakMap);
573     } else {
574       delete root.WeakMap;
575     }
576     delete root.WinRTError;
577     delete funcProto._method;
578   }());
579
580   // Add other realm values from the `vm` module.
581   lodashStable.attempt(function() {
582     lodashStable.assign(realm, require('vm').runInNewContext([
583       '(function() {',
584       '  var noop = function() {},',
585       '      root = this;',
586       '',
587       '  var object = {',
588       "    'ArrayBuffer': root.ArrayBuffer,",
589       "    'arguments': (function() { return arguments; }(1, 2, 3)),",
590       "    'array': [1],",
591       "    'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
592       "    'boolean': Object(false),",
593       "    'date': new Date,",
594       "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
595       "    'function': noop,",
596       "    'map': root.Map ? new root.Map : undefined,",
597       "    'nan': NaN,",
598       "    'null': null,",
599       "    'number': Object(0),",
600       "    'object': { 'a': 1 },",
601       "    'promise': root.Promise ? Promise.resolve(1) : undefined,",
602       "    'regexp': /x/,",
603       "    'set': root.Set ? new root.Set : undefined,",
604       "    'string': Object('a'),",
605       "    'symbol': root.Symbol ? root.Symbol() : undefined,",
606       "    'undefined': undefined,",
607       "    'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
608       "    'weakSet': root.WeakSet ? new root.WeakSet : undefined",
609       '  };',
610       '',
611       "  ['" + arrayViews.join("', '") + "'].forEach(function(type) {",
612       '    var Ctor = root[type]',
613       '    object[type] = Ctor;',
614       '    object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
615       '  });',
616       '',
617       '  return object;',
618       '}())'
619     ].join('\n')));
620   });
621
622   // Add other realm values from an iframe.
623   lodashStable.attempt(function() {
624     _._realm = realm;
625
626     var iframe = document.createElement('iframe');
627     iframe.frameBorder = iframe.height = iframe.width = 0;
628     body.appendChild(iframe);
629
630     var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
631     idoc.write([
632       '<script>',
633       'var _ = parent._;',
634       '',
635       '  var noop = function() {},',
636       '      root = this;',
637       '',
638       'var object = {',
639       "  'ArrayBuffer': root.ArrayBuffer,",
640       "  'arguments': (function() { return arguments; }(1, 2, 3)),",
641       "  'array': [1],",
642       "  'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
643       "  'boolean': Object(false),",
644       "  'date': new Date,",
645       "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
646       "  'function': noop,",
647       "  'map': root.Map ? new root.Map : undefined,",
648       "  'nan': NaN,",
649       "  'null': null,",
650       "  'number': Object(0),",
651       "  'object': { 'a': 1 },",
652       "  'promise': root.Promise ? Promise.resolve(1) : undefined,",
653       "  'regexp': /x/,",
654       "  'set': root.Set ? new root.Set : undefined,",
655       "  'string': Object('a'),",
656       "  'symbol': root.Symbol ? root.Symbol() : undefined,",
657       "  'undefined': undefined,",
658       "  'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
659       "  'weakSet': root.WeakSet ? new root.WeakSet : undefined",
660       '};',
661       '',
662       "_.each(['" + arrayViews.join("', '") + "'], function(type) {",
663       '  var Ctor = root[type];',
664       '  object[type] = Ctor;',
665       '  object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
666       '});',
667       '',
668       '_.assign(_._realm, object);',
669       '<\/script>'
670     ].join('\n'));
671
672     idoc.close();
673     delete _._realm;
674   });
675
676   // Add a web worker.
677   lodashStable.attempt(function() {
678     var worker = new Worker('./asset/worker.js?t=' + (+new Date));
679     worker.addEventListener('message', function(e) {
680       _._VERSION = e.data || '';
681     }, false);
682
683     worker.postMessage(ui.buildPath);
684   });
685
686   // Expose internal modules for better code coverage.
687   lodashStable.attempt(function() {
688     var path = require('path'),
689         basePath = path.dirname(filePath);
690
691     if (isModularize && !(amd || isNpm)) {
692       lodashStable.each([
693         '_baseEach',
694         '_isIndex',
695         '_isIterateeCall'
696       ], function(relPath) {
697         var func = require(path.join(basePath, relPath)),
698             funcName = path.basename(relPath);
699
700         _['_' + funcName] = func[funcName] || func['default'] || func;
701       });
702     }
703   });
704
705   /*--------------------------------------------------------------------------*/
706
707   if (params) {
708     console.log('Running lodash tests.');
709     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
710   }
711
712   QUnit.module(basename);
713
714   (function() {
715     QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
716       assert.expect(1);
717
718       if (amd) {
719         assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
720       }
721       else {
722         skipAssert(assert);
723       }
724     });
725
726     QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
727       assert.expect(1);
728
729       if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
730         assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
731       } else {
732         skipAssert(assert);
733       }
734     });
735
736     QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
737       assert.expect(1);
738
739       if (amd) {
740         assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
741       }
742       else {
743         skipAssert(assert);
744       }
745     });
746
747     QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
748       assert.expect(1);
749
750       var done = assert.async();
751
752       if (Worker) {
753         var limit = 30000 / QUnit.config.asyncRetries,
754             start = +new Date;
755
756         var attempt = function() {
757           var actual = _._VERSION;
758           if ((new Date - start) < limit && typeof actual != 'string') {
759             setTimeout(attempt, 16);
760             return;
761           }
762           assert.strictEqual(actual, _.VERSION);
763           done();
764         };
765
766         attempt();
767       }
768       else {
769         skipAssert(assert);
770         done();
771       }
772     });
773
774     QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
775       assert.expect(1);
776
777       if (lodashBizarro) {
778         assert.notOk('_method' in lodashBizarro);
779       }
780       else {
781         skipAssert(assert);
782       }
783     });
784
785     QUnit.test('should avoid non-native built-ins', function(assert) {
786       assert.expect(7);
787
788       function message(lodashMethod, nativeMethod) {
789         return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
790       }
791
792       function Foo() {
793         this.a = 1;
794       }
795       Foo.prototype.b = 2;
796
797       var object = { 'a': 1 },
798           otherObject = { 'b': 2 },
799           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
800
801       if (lodashBizarro) {
802         try {
803           var actual = lodashBizarro.keysIn(new Foo).sort();
804         } catch (e) {
805           actual = null;
806         }
807         var label = message('_.keysIn', 'Object#propertyIsEnumerable');
808         assert.deepEqual(actual, ['a', 'b'], label);
809
810         try {
811           var actual = lodashBizarro.isEmpty({});
812         } catch (e) {
813           actual = null;
814         }
815         var label = message('_.isEmpty', 'Object#propertyIsEnumerable');
816         assert.strictEqual(actual, true, label);
817
818         try {
819           actual = [
820             lodashBizarro.difference([object, otherObject], largeArray),
821             lodashBizarro.intersection(largeArray, [object]),
822             lodashBizarro.uniq(largeArray)
823           ];
824         } catch (e) {
825           actual = null;
826         }
827         label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
828         assert.deepEqual(actual, [[otherObject], [object], [object]], label);
829
830         try {
831           if (Symbol) {
832             object[symbol] = {};
833           }
834           actual = [
835             lodashBizarro.clone(object),
836             lodashBizarro.cloneDeep(object)
837           ];
838         } catch (e) {
839           actual = null;
840         }
841         label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
842         assert.deepEqual(actual, [object, object], label);
843
844         try {
845           var symObject = Object(symbol);
846
847           // Avoid symbol detection in Babel's `typeof` helper.
848           symObject.constructor = Object;
849
850           actual = [
851             Symbol ? lodashBizarro.clone(symObject) : { 'constructor': Object },
852             Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
853             Symbol ? lodashBizarro.toString(symObject) : ''
854           ];
855         } catch (e) {
856           actual = null;
857         }
858         label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
859         assert.deepEqual(actual, [{ 'constructor': Object }, false, ''], label);
860
861         try {
862           var map = new lodashBizarro.memoize.Cache;
863           actual = map.set('a', 1).get('a');
864         } catch (e) {
865           actual = null;
866         }
867         label = message('_.memoize.Cache', 'Map');
868         assert.deepEqual(actual, 1, label);
869
870         try {
871           map = new (Map || Object);
872           if (Symbol && Symbol.iterator) {
873             map[Symbol.iterator] = null;
874           }
875           actual = lodashBizarro.toArray(map);
876         } catch (e) {
877           actual = null;
878         }
879         label = message('_.toArray', 'Map');
880         assert.deepEqual(actual, [], label);
881       }
882       else {
883         skipAssert(assert, 7);
884       }
885     });
886   }());
887
888   /*--------------------------------------------------------------------------*/
889
890   QUnit.module('isIndex');
891
892   (function() {
893     var func = _._isIndex;
894
895     QUnit.test('should return `true` for indexes', function(assert) {
896       assert.expect(1);
897
898       if (func) {
899         var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
900             expected = lodashStable.map(values, alwaysTrue);
901
902         var actual = lodashStable.map(values, function(args) {
903           return func.apply(undefined, args);
904         });
905
906         assert.deepEqual(actual, expected);
907       }
908       else {
909         skipAssert(assert);
910       }
911     });
912
913     QUnit.test('should return `false` for non-indexes', function(assert) {
914       assert.expect(1);
915
916       if (func) {
917         var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
918             expected = lodashStable.map(values, alwaysFalse);
919
920         var actual = lodashStable.map(values, function(args) {
921           return func.apply(undefined, args);
922         });
923
924         assert.deepEqual(actual, expected);
925       }
926       else {
927         skipAssert(assert);
928       }
929     });
930   }());
931
932   /*--------------------------------------------------------------------------*/
933
934   QUnit.module('isIterateeCall');
935
936   (function() {
937     var array = [1],
938         func = _._isIterateeCall,
939         object =  { 'a': 1 };
940
941     QUnit.test('should return `true` for iteratee calls', function(assert) {
942       assert.expect(3);
943
944       function Foo() {}
945       Foo.prototype.a = 1;
946
947       if (func) {
948         assert.strictEqual(func(1, 0, array), true);
949         assert.strictEqual(func(1, 'a', object), true);
950         assert.strictEqual(func(1, 'a', new Foo), true);
951       }
952       else {
953         skipAssert(assert, 3);
954       }
955     });
956
957     QUnit.test('should return `false` for non-iteratee calls', function(assert) {
958       assert.expect(4);
959
960       if (func) {
961         assert.strictEqual(func(2, 0, array), false);
962         assert.strictEqual(func(1, 1.1, array), false);
963         assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
964         assert.strictEqual(func(1, 'b', object), false);
965       }
966       else {
967         skipAssert(assert, 4);
968       }
969     });
970
971     QUnit.test('should work with `NaN` values', function(assert) {
972       assert.expect(2);
973
974       if (func) {
975         assert.strictEqual(func(NaN, 0, [NaN]), true);
976         assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
977       }
978       else {
979         skipAssert(assert, 2);
980       }
981     });
982
983     QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
984       assert.expect(1);
985
986       if (func) {
987         try {
988           var actual = func(1, { 'toString': null }, [1]);
989         } catch (e) {
990           var message = e.message;
991         }
992         assert.strictEqual(actual, false, message || '');
993       }
994       else {
995         skipAssert(assert);
996       }
997     });
998   }());
999
1000   /*--------------------------------------------------------------------------*/
1001
1002   QUnit.module('lodash constructor');
1003
1004   (function() {
1005     var values = empties.concat(true, 1, 'a'),
1006         expected = lodashStable.map(values, alwaysTrue);
1007
1008     QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
1009       assert.expect(1);
1010
1011       if (!isNpm) {
1012         var actual = lodashStable.map(values, function(value) {
1013           return _(value) instanceof _;
1014         });
1015
1016         assert.deepEqual(actual, expected);
1017       }
1018       else {
1019         skipAssert(assert);
1020       }
1021     });
1022
1023     QUnit.test('should return the given `lodash` instances', function(assert) {
1024       assert.expect(1);
1025
1026       if (!isNpm) {
1027         var actual = lodashStable.map(values, function(value) {
1028           var wrapped = _(value);
1029           return _(wrapped) === wrapped;
1030         });
1031
1032         assert.deepEqual(actual, expected);
1033       }
1034       else {
1035         skipAssert(assert);
1036       }
1037     });
1038
1039     QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
1040       assert.expect(1);
1041
1042       if (!isNpm && lodashBizarro) {
1043         var actual = lodashStable.map(values, function(value) {
1044           var wrapped = _(lodashBizarro(value)),
1045               unwrapped = wrapped.value();
1046
1047           return wrapped instanceof _ &&
1048             ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
1049         });
1050
1051         assert.deepEqual(actual, expected);
1052       }
1053       else {
1054         skipAssert(assert);
1055       }
1056     });
1057   }());
1058
1059   /*--------------------------------------------------------------------------*/
1060
1061   QUnit.module('lodash.add');
1062
1063   (function() {
1064     QUnit.test('should add two numbers', function(assert) {
1065       assert.expect(3);
1066
1067       assert.strictEqual(_.add(6, 4), 10);
1068       assert.strictEqual(_.add(-6, 4), -2);
1069       assert.strictEqual(_.add(-6, -4), -10);
1070     });
1071
1072     QUnit.test('should not coerce arguments to numbers', function(assert) {
1073       assert.expect(2);
1074
1075       assert.strictEqual(_.add('6', '4'), '64');
1076       assert.strictEqual(_.add('x', 'y'), 'xy');
1077     });
1078   }());
1079
1080   /*--------------------------------------------------------------------------*/
1081
1082   QUnit.module('lodash.after');
1083
1084   (function() {
1085     function after(n, times) {
1086       var count = 0;
1087       lodashStable.times(times, _.after(n, function() { count++; }));
1088       return count;
1089     }
1090
1091     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1092       assert.expect(4);
1093
1094       assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1095       assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1096       assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1097       assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1098     });
1099
1100     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1101       assert.expect(1);
1102
1103       assert.strictEqual(after(NaN, 1), 1);
1104     });
1105
1106     QUnit.test('should not set a `this` binding', function(assert) {
1107       assert.expect(2);
1108
1109       var after = _.after(1, function(assert) { return ++this.count; }),
1110           object = { 'after': after, 'count': 0 };
1111
1112       object.after();
1113       assert.strictEqual(object.after(), 2);
1114       assert.strictEqual(object.count, 2);
1115     });
1116   }());
1117
1118   /*--------------------------------------------------------------------------*/
1119
1120   QUnit.module('lodash.ary');
1121
1122   (function() {
1123     function fn(a, b, c) {
1124       return slice.call(arguments);
1125     }
1126
1127     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1128       assert.expect(2);
1129
1130       var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1131       assert.deepEqual(actual, [6, 8, 10]);
1132
1133       var capped = _.ary(fn, 2);
1134       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1135     });
1136
1137     QUnit.test('should use `func.length` if `n` is not given', function(assert) {
1138       assert.expect(1);
1139
1140       var capped = _.ary(fn);
1141       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1142     });
1143
1144     QUnit.test('should treat a negative `n` as `0`', function(assert) {
1145       assert.expect(1);
1146
1147       var capped = _.ary(fn, -1);
1148
1149       try {
1150         var actual = capped('a');
1151       } catch (e) {}
1152
1153       assert.deepEqual(actual, []);
1154     });
1155
1156     QUnit.test('should coerce `n` to an integer', function(assert) {
1157       assert.expect(1);
1158
1159       var values = ['1', 1.6, 'xyz'],
1160           expected = [['a'], ['a'], []];
1161
1162       var actual = lodashStable.map(values, function(n) {
1163         var capped = _.ary(fn, n);
1164         return capped('a', 'b');
1165       });
1166
1167       assert.deepEqual(actual, expected);
1168     });
1169
1170     QUnit.test('should work when given less than the capped number of arguments', function(assert) {
1171       assert.expect(1);
1172
1173       var capped = _.ary(fn, 3);
1174       assert.deepEqual(capped('a'), ['a']);
1175     });
1176
1177     QUnit.test('should use the existing `ary` if smaller', function(assert) {
1178       assert.expect(1);
1179
1180       var capped = _.ary(_.ary(fn, 1), 2);
1181       assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1182     });
1183
1184     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1185       assert.expect(1);
1186
1187       var funcs = lodashStable.map([fn], _.ary),
1188           actual = funcs[0]('a', 'b', 'c');
1189
1190       assert.deepEqual(actual, ['a', 'b', 'c']);
1191     });
1192
1193     QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1194       assert.expect(2);
1195
1196       var array = ['a', 'b', 'c'],
1197           includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1198
1199       assert.strictEqual(includes('b')(array, 2), true);
1200
1201       if (!isNpm) {
1202         includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1203         assert.strictEqual(includes('b')(array, 2), true);
1204       }
1205       else {
1206         skipAssert(assert);
1207       }
1208     });
1209   }());
1210
1211   /*--------------------------------------------------------------------------*/
1212
1213   QUnit.module('lodash.assignIn');
1214
1215   (function() {
1216     QUnit.test('should be aliased', function(assert) {
1217       assert.expect(1);
1218
1219       assert.strictEqual(_.extend, _.assignIn);
1220     });
1221   }());
1222
1223   /*--------------------------------------------------------------------------*/
1224
1225   QUnit.module('lodash.assign and lodash.assignIn');
1226
1227   lodashStable.each(['assign', 'assignIn'], function(methodName) {
1228     var func = _[methodName];
1229
1230     QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1231       assert.expect(1);
1232
1233       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1234     });
1235
1236     QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1237       assert.expect(2);
1238
1239       var expected = { 'a': 1, 'b': 2, 'c': 3 };
1240       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1241       assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1242     });
1243
1244     QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1245       assert.expect(1);
1246
1247       var expected = { 'a': 3, 'b': 2, 'c': 1 };
1248       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1249     });
1250
1251     QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1252       assert.expect(1);
1253
1254       var expected = { 'a': null, 'b': undefined, 'c': null };
1255       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1256     });
1257
1258     QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1259       assert.expect(1);
1260
1261       var object = {};
1262
1263       var descriptor = {
1264         'configurable': true,
1265         'enumerable': true,
1266         'set': function() { throw new Error; }
1267       };
1268
1269       var source = {
1270         'a': 1,
1271         'b': undefined,
1272         'c': NaN,
1273         'd': undefined,
1274         'constructor': Object,
1275         'toString': lodashStable.constant('source')
1276       };
1277
1278       defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1279         'get': alwaysOne
1280       }));
1281
1282       defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1283         'get': noop
1284       }));
1285
1286       defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1287         'get': alwaysNaN
1288       }));
1289
1290       defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1291         'get': lodashStable.constant(Object)
1292       }));
1293
1294       try {
1295         var actual = func(object, source);
1296       } catch (e) {}
1297
1298       assert.deepEqual(actual, source);
1299     });
1300
1301     QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) {
1302       assert.expect(1);
1303
1304       var array = [1];
1305       array[2] = 3;
1306
1307       assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 });
1308     });
1309
1310     QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) {
1311       assert.expect(1);
1312
1313       function Foo() {}
1314       Foo.prototype.a = 1;
1315
1316       assert.deepEqual(func({}, Foo.prototype), { 'a': 1 });
1317     });
1318
1319     QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) {
1320       assert.expect(1);
1321
1322       assert.deepEqual(func({}, 'a'), { '0': 'a' });
1323     });
1324   });
1325
1326   /*--------------------------------------------------------------------------*/
1327
1328   QUnit.module('lodash.assignInWith');
1329
1330   (function() {
1331     QUnit.test('should be aliased', function(assert) {
1332       assert.expect(1);
1333
1334       assert.strictEqual(_.extendWith, _.assignInWith);
1335     });
1336   }());
1337
1338   /*--------------------------------------------------------------------------*/
1339
1340   QUnit.module('lodash.assignWith and lodash.assignInWith');
1341
1342   lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1343     var func = _[methodName];
1344
1345     QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1346       assert.expect(1);
1347
1348       var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1349         return a === undefined ? b : a;
1350       });
1351
1352       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1353     });
1354
1355     QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1356       assert.expect(1);
1357
1358       var expected = { 'a': undefined };
1359       assert.deepEqual(func({}, expected, noop), expected);
1360     });
1361   });
1362
1363   /*--------------------------------------------------------------------------*/
1364
1365   QUnit.module('lodash.at');
1366
1367   (function() {
1368     var args = arguments,
1369         array = ['a', 'b', 'c'],
1370         object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1371
1372     QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1373       assert.expect(1);
1374
1375       var actual = _.at(array, [0, 2]);
1376       assert.deepEqual(actual, ['a', 'c']);
1377     });
1378
1379     QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1380       assert.expect(1);
1381
1382       var actual = _.at(array, [2, 4, 0]);
1383       assert.deepEqual(actual, ['c', undefined, 'a']);
1384     });
1385
1386     QUnit.test('should work with non-index keys on array values', function(assert) {
1387       assert.expect(1);
1388
1389       var values = lodashStable.reject(empties, function(value) {
1390         return (value === 0) || lodashStable.isArray(value);
1391       }).concat(-1, 1.1);
1392
1393       var array = lodashStable.transform(values, function(result, value) {
1394         result[value] = 1;
1395       }, []);
1396
1397       var expected = lodashStable.map(values, alwaysOne),
1398           actual = _.at(array, values);
1399
1400       assert.deepEqual(actual, expected);
1401     });
1402
1403     QUnit.test('should return an empty array when no keys are given', function(assert) {
1404       assert.expect(2);
1405
1406       assert.deepEqual(_.at(array), []);
1407       assert.deepEqual(_.at(array, [], []), []);
1408     });
1409
1410     QUnit.test('should accept multiple key arguments', function(assert) {
1411       assert.expect(1);
1412
1413       var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1414       assert.deepEqual(actual, ['d', 'a', 'c']);
1415     });
1416
1417     QUnit.test('should work with a falsey `object` argument when keys are given', function(assert) {
1418       assert.expect(1);
1419
1420       var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1421
1422       var actual = lodashStable.map(falsey, function(object) {
1423         try {
1424           return _.at(object, 0, 1, 'pop', 'push');
1425         } catch (e) {}
1426       });
1427
1428       assert.deepEqual(actual, expected);
1429     });
1430
1431     QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1432       assert.expect(1);
1433
1434       var actual = _.at(args, [2, 0]);
1435       assert.deepEqual(actual, [3, 1]);
1436     });
1437
1438     QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1439       assert.expect(1);
1440
1441       var actual = _.at([1, 2, 3, 4, 5], args);
1442       assert.deepEqual(actual, [2, 3, 4]);
1443     });
1444
1445     QUnit.test('should work with an object for `object`', function(assert) {
1446       assert.expect(1);
1447
1448       var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1449       assert.deepEqual(actual, [3, 4]);
1450     });
1451
1452     QUnit.test('should pluck inherited property values', function(assert) {
1453       assert.expect(1);
1454
1455       function Foo() {
1456         this.a = 1;
1457       }
1458       Foo.prototype.b = 2;
1459
1460       var actual = _.at(new Foo, 'b');
1461       assert.deepEqual(actual, [2]);
1462     });
1463
1464     QUnit.test('should work in a lazy sequence', function(assert) {
1465       assert.expect(6);
1466
1467       if (!isNpm) {
1468         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1469             smallArray = array;
1470
1471         lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1472           lodashStable.times(2, function(index) {
1473             var array = index ? largeArray : smallArray,
1474                 wrapped = _(array).map(identity).at(paths);
1475
1476             assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1477           });
1478         });
1479       }
1480       else {
1481         skipAssert(assert, 6);
1482       }
1483     });
1484
1485     QUnit.test('should support shortcut fusion', function(assert) {
1486       assert.expect(8);
1487
1488       if (!isNpm) {
1489         var array = lodashStable.range(LARGE_ARRAY_SIZE),
1490             count = 0,
1491             iteratee = function(value) { count++; return square(value); },
1492             lastIndex = LARGE_ARRAY_SIZE - 1;
1493
1494         lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1495           count = 0;
1496           var actual = _(array).map(iteratee).at(n).value(),
1497               expected = index < 2 ? 1 : 0;
1498
1499           assert.strictEqual(count, expected);
1500
1501           expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1502           assert.deepEqual(actual, expected);
1503         });
1504       }
1505       else {
1506         skipAssert(assert, 8);
1507       }
1508     });
1509
1510     QUnit.test('work with an object for `object` when chaining', function(assert) {
1511       assert.expect(2);
1512
1513       if (!isNpm) {
1514         var paths = ['a[0].b.c', 'a[1]'],
1515             actual = _(object).map(identity).at(paths).value();
1516
1517         assert.deepEqual(actual, _.at(_.map(object, identity), paths));
1518
1519         var indexObject = { '0': 1 };
1520         actual = _(indexObject).at(0).value();
1521         assert.deepEqual(actual, _.at(indexObject, 0));
1522       }
1523       else {
1524         skipAssert(assert, 2);
1525       }
1526     });
1527   }(1, 2, 3));
1528
1529   /*--------------------------------------------------------------------------*/
1530
1531   QUnit.module('lodash.attempt');
1532
1533   (function() {
1534     QUnit.test('should return the result of `func`', function(assert) {
1535       assert.expect(1);
1536
1537       assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1538     });
1539
1540     QUnit.test('should provide additional arguments to `func`', function(assert) {
1541       assert.expect(1);
1542
1543       var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1544       assert.deepEqual(actual, [1, 2]);
1545     });
1546
1547     QUnit.test('should return the caught error', function(assert) {
1548       assert.expect(1);
1549
1550       var expected = lodashStable.map(errors, alwaysTrue);
1551
1552       var actual = lodashStable.map(errors, function(error) {
1553         return _.attempt(function() { throw error; }) === error;
1554       });
1555
1556       assert.deepEqual(actual, expected);
1557     });
1558
1559     QUnit.test('should coerce errors to error objects', function(assert) {
1560       assert.expect(1);
1561
1562       var actual = _.attempt(function() { throw 'x'; });
1563       assert.ok(lodashStable.isEqual(actual, Error('x')));
1564     });
1565
1566     QUnit.test('should preserve custom errors', function(assert) {
1567       assert.expect(1);
1568
1569       var actual = _.attempt(function() { throw new CustomError('x'); });
1570       assert.ok(actual instanceof CustomError);
1571     });
1572
1573     QUnit.test('should work with an error object from another realm', function(assert) {
1574       assert.expect(1);
1575
1576       if (realm.errors) {
1577         var expected = lodashStable.map(realm.errors, alwaysTrue);
1578
1579         var actual = lodashStable.map(realm.errors, function(error) {
1580           return _.attempt(function() { throw error; }) === error;
1581         });
1582
1583         assert.deepEqual(actual, expected);
1584       }
1585       else {
1586         skipAssert(assert);
1587       }
1588     });
1589
1590     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1591       assert.expect(1);
1592
1593       if (!isNpm) {
1594         assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1595       }
1596       else {
1597         skipAssert(assert);
1598       }
1599     });
1600
1601     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1602       assert.expect(1);
1603
1604       if (!isNpm) {
1605         assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1606       }
1607       else {
1608         skipAssert(assert);
1609       }
1610     });
1611   }());
1612
1613   /*--------------------------------------------------------------------------*/
1614
1615   QUnit.module('lodash.before');
1616
1617   (function() {
1618     function before(n, times) {
1619       var count = 0;
1620       lodashStable.times(times, _.before(n, function() { count++; }));
1621       return count;
1622     }
1623
1624     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1625       assert.expect(4);
1626
1627       assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1628       assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1629       assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1630       assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1631     });
1632
1633     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1634       assert.expect(1);
1635
1636       assert.strictEqual(before(NaN, 1), 0);
1637     });
1638
1639     QUnit.test('should not set a `this` binding', function(assert) {
1640       assert.expect(2);
1641
1642       var before = _.before(2, function(assert) { return ++this.count; }),
1643           object = { 'before': before, 'count': 0 };
1644
1645       object.before();
1646       assert.strictEqual(object.before(), 1);
1647       assert.strictEqual(object.count, 1);
1648     });
1649   }());
1650
1651   /*--------------------------------------------------------------------------*/
1652
1653   QUnit.module('lodash.bind');
1654
1655   (function() {
1656     function fn() {
1657       var result = [this];
1658       push.apply(result, arguments);
1659       return result;
1660     }
1661
1662     QUnit.test('should bind a function to an object', function(assert) {
1663       assert.expect(1);
1664
1665       var object = {},
1666           bound = _.bind(fn, object);
1667
1668       assert.deepEqual(bound('a'), [object, 'a']);
1669     });
1670
1671     QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
1672       assert.expect(1);
1673
1674       var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1675           expected = lodashStable.map(values, function(value) { return [value]; });
1676
1677       var actual = lodashStable.map(values, function(value) {
1678         try {
1679           var bound = _.bind(fn, value);
1680           return bound();
1681         } catch (e) {}
1682       });
1683
1684       assert.ok(lodashStable.every(actual, function(value, index) {
1685         return lodashStable.isEqual(value, expected[index]);
1686       }));
1687     });
1688
1689     QUnit.test('should bind a function to nullish values', function(assert) {
1690       assert.expect(6);
1691
1692       var bound = _.bind(fn, null),
1693           actual = bound('a');
1694
1695       assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1696       assert.strictEqual(actual[1], 'a');
1697
1698       lodashStable.times(2, function(index) {
1699         bound = index ? _.bind(fn, undefined) : _.bind(fn);
1700         actual = bound('b');
1701
1702         assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1703         assert.strictEqual(actual[1], 'b');
1704       });
1705     });
1706
1707     QUnit.test('should partially apply arguments ', function(assert) {
1708       assert.expect(4);
1709
1710       var object = {},
1711           bound = _.bind(fn, object, 'a');
1712
1713       assert.deepEqual(bound(), [object, 'a']);
1714
1715       bound = _.bind(fn, object, 'a');
1716       assert.deepEqual(bound('b'), [object, 'a', 'b']);
1717
1718       bound = _.bind(fn, object, 'a', 'b');
1719       assert.deepEqual(bound(), [object, 'a', 'b']);
1720       assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1721     });
1722
1723     QUnit.test('should support placeholders', function(assert) {
1724       assert.expect(4);
1725
1726       var object = {},
1727           ph = _.bind.placeholder,
1728           bound = _.bind(fn, object, ph, 'b', ph);
1729
1730       assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1731       assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1732       assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1733       assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1734     });
1735
1736     QUnit.test('should use `_.placeholder` when set', function(assert) {
1737       assert.expect(1);
1738
1739       if (!isModularize) {
1740         var _ph = _.placeholder = {},
1741             ph = _.bind.placeholder,
1742             object = {},
1743             bound = _.bind(fn, object, _ph, 'b', ph);
1744
1745         assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
1746         delete _.placeholder;
1747       }
1748       else {
1749         skipAssert(assert);
1750       }
1751     });
1752
1753     QUnit.test('should create a function with a `length` of `0`', function(assert) {
1754       assert.expect(2);
1755
1756       var fn = function(a, b, c) {},
1757           bound = _.bind(fn, {});
1758
1759       assert.strictEqual(bound.length, 0);
1760
1761       bound = _.bind(fn, {}, 1);
1762       assert.strictEqual(bound.length, 0);
1763     });
1764
1765     QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1766       assert.expect(3);
1767
1768       function Foo() {
1769         return this;
1770       }
1771
1772       var bound = _.bind(Foo, { 'a': 1 }),
1773           newBound = new bound;
1774
1775       assert.strictEqual(bound().a, 1);
1776       assert.strictEqual(newBound.a, undefined);
1777       assert.ok(newBound instanceof Foo);
1778     });
1779
1780     QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1781       assert.expect(1);
1782
1783       function Foo() {
1784         return this;
1785       }
1786
1787       function Bar() {}
1788
1789       var thisArg = { 'a': 1 },
1790           boundFoo = _.bind(Foo, thisArg),
1791           boundBar = _.bind(Bar, thisArg),
1792           count = 9,
1793           expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1794
1795       var actual = lodashStable.times(count, function(index) {
1796         try {
1797           switch (index) {
1798             case 0: return [new boundFoo().a, new boundBar().a];
1799             case 1: return [new boundFoo(1).a, new boundBar(1).a];
1800             case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1801             case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1802             case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1803             case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1804             case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1805             case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1806             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];
1807           }
1808         } catch (e) {}
1809       });
1810
1811       assert.deepEqual(actual, expected);
1812     });
1813
1814     QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1815       assert.expect(2);
1816
1817       function Foo(value) {
1818         return value && object;
1819       }
1820
1821       var bound = _.bind(Foo),
1822           object = {};
1823
1824       assert.ok(new bound instanceof Foo);
1825       assert.strictEqual(new bound(true), object);
1826     });
1827
1828     QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1829       assert.expect(1);
1830
1831       var object = {},
1832           bound = _.bind(fn, object, 'a');
1833
1834       assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1835     });
1836
1837     QUnit.test('should not rebind functions', function(assert) {
1838       assert.expect(3);
1839
1840       var object1 = {},
1841           object2 = {},
1842           object3 = {};
1843
1844       var bound1 = _.bind(fn, object1),
1845           bound2 = _.bind(bound1, object2, 'a'),
1846           bound3 = _.bind(bound1, object3, 'b');
1847
1848       assert.deepEqual(bound1(), [object1]);
1849       assert.deepEqual(bound2(), [object1, 'a']);
1850       assert.deepEqual(bound3(), [object1, 'b']);
1851     });
1852
1853     QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1854       assert.expect(2);
1855
1856       var Ctor = _.bind(Date, null),
1857           expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1858
1859       try {
1860         var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1861       } catch (e) {}
1862
1863       assert.deepEqual(actual, expected);
1864
1865       Ctor = _.bind(Date, null, 2012, 4, 23);
1866
1867       try {
1868         actual = new Ctor(0, 0, 0, 0);
1869       } catch (e) {}
1870
1871       assert.deepEqual(actual, expected);
1872     });
1873
1874     QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
1875       assert.expect(1);
1876
1877       var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
1878
1879       if (typeof createCtor == 'function') {
1880         var bound = _.bind(createCtor()),
1881             count = 8,
1882             expected = lodashStable.times(count, alwaysTrue);
1883
1884         var actual = lodashStable.times(count, function(index) {
1885           try {
1886             switch (index) {
1887               case 0: return !!(new bound);
1888               case 1: return !!(new bound(1));
1889               case 2: return !!(new bound(1, 2));
1890               case 3: return !!(new bound(1, 2, 3));
1891               case 4: return !!(new bound(1, 2, 3, 4));
1892               case 5: return !!(new bound(1, 2, 3, 4, 5));
1893               case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
1894               case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
1895             }
1896           } catch (e) {}
1897         });
1898
1899         assert.deepEqual(actual, expected);
1900       }
1901       else {
1902         skipAssert(assert);
1903       }
1904     });
1905
1906     QUnit.test('should return a wrapped value when chaining', function(assert) {
1907       assert.expect(2);
1908
1909       if (!isNpm) {
1910         var object = {},
1911             bound = _(fn).bind({}, 'a', 'b');
1912
1913         assert.ok(bound instanceof _);
1914
1915         var actual = bound.value()('c');
1916         assert.deepEqual(actual, [object, 'a', 'b', 'c']);
1917       }
1918       else {
1919         skipAssert(assert, 2);
1920       }
1921     });
1922   }());
1923
1924   /*--------------------------------------------------------------------------*/
1925
1926   QUnit.module('lodash.bindAll');
1927
1928   (function() {
1929     var args = arguments;
1930
1931     var source = {
1932       '_n0': -2,
1933       '_p0': -1,
1934       '_a': 1,
1935       '_b': 2,
1936       '_c': 3,
1937       '_d': 4,
1938       '-0': function() { return this._n0; },
1939       '0': function() { return this._p0; },
1940       'a': function() { return this._a; },
1941       'b': function() { return this._b; },
1942       'c': function() { return this._c; },
1943       'd': function() { return this._d; }
1944     };
1945
1946     QUnit.test('should accept individual method names', function(assert) {
1947       assert.expect(1);
1948
1949       var object = lodashStable.cloneDeep(source);
1950       _.bindAll(object, 'a', 'b');
1951
1952       var actual = lodashStable.map(['a', 'b', 'c'], function(key) {
1953         return object[key].call({});
1954       });
1955
1956       assert.deepEqual(actual, [1, 2, undefined]);
1957     });
1958
1959     QUnit.test('should accept arrays of method names', function(assert) {
1960       assert.expect(1);
1961
1962       var object = lodashStable.cloneDeep(source);
1963       _.bindAll(object, ['a', 'b'], ['c']);
1964
1965       var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) {
1966         return object[key].call({});
1967       });
1968
1969       assert.deepEqual(actual, [1, 2, 3, undefined]);
1970     });
1971
1972     QUnit.test('should preserve the sign of `0`', function(assert) {
1973       assert.expect(1);
1974
1975       var props = [-0, Object(-0), 0, Object(0)];
1976
1977       var actual = lodashStable.map(props, function(key) {
1978         var object = lodashStable.cloneDeep(source);
1979         _.bindAll(object, key);
1980         return object[lodashStable.toString(key)].call({});
1981       });
1982
1983       assert.deepEqual(actual, [-2, -2, -1, -1]);
1984     });
1985
1986     QUnit.test('should work with an array `object` argument', function(assert) {
1987       assert.expect(1);
1988
1989       var array = ['push', 'pop'];
1990       _.bindAll(array);
1991       assert.strictEqual(array.pop, arrayProto.pop);
1992     });
1993
1994     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
1995       assert.expect(1);
1996
1997       var object = lodashStable.cloneDeep(source);
1998       _.bindAll(object, args);
1999
2000       var actual = lodashStable.map(args, function(key) {
2001         return object[key].call({});
2002       });
2003
2004       assert.deepEqual(actual, [1]);
2005     });
2006   }('a'));
2007
2008   /*--------------------------------------------------------------------------*/
2009
2010   QUnit.module('lodash.bindKey');
2011
2012   (function() {
2013     QUnit.test('should work when the target function is overwritten', function(assert) {
2014       assert.expect(2);
2015
2016       var object = {
2017         'user': 'fred',
2018         'greet': function(greeting) {
2019           return this.user + ' says: ' + greeting;
2020         }
2021       };
2022
2023       var bound = _.bindKey(object, 'greet', 'hi');
2024       assert.strictEqual(bound(), 'fred says: hi');
2025
2026       object.greet = function(greeting) {
2027         return this.user + ' says: ' + greeting + '!';
2028       };
2029
2030       assert.strictEqual(bound(), 'fred says: hi!');
2031     });
2032
2033     QUnit.test('should support placeholders', function(assert) {
2034       assert.expect(4);
2035
2036       var object = {
2037         'fn': function() {
2038           return slice.call(arguments);
2039         }
2040       };
2041
2042       var ph = _.bindKey.placeholder,
2043           bound = _.bindKey(object, 'fn', ph, 'b', ph);
2044
2045       assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
2046       assert.deepEqual(bound('a'), ['a', 'b', undefined]);
2047       assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
2048       assert.deepEqual(bound(), [undefined, 'b', undefined]);
2049     });
2050
2051     QUnit.test('should use `_.placeholder` when set', function(assert) {
2052       assert.expect(1);
2053
2054       if (!isModularize) {
2055         var object = {
2056           'fn': function() {
2057             return slice.call(arguments);
2058           }
2059         };
2060
2061         var _ph = _.placeholder = {},
2062             ph = _.bindKey.placeholder,
2063             bound = _.bindKey(object, 'fn', _ph, 'b', ph);
2064
2065         assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
2066         delete _.placeholder;
2067       }
2068       else {
2069         skipAssert(assert);
2070       }
2071     });
2072
2073     QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
2074       assert.expect(2);
2075
2076       function Foo(value) {
2077         return value && object;
2078       }
2079
2080       var object = { 'Foo': Foo },
2081           bound = _.bindKey(object, 'Foo');
2082
2083       assert.ok(new bound instanceof Foo);
2084       assert.strictEqual(new bound(true), object);
2085     });
2086   }());
2087
2088   /*--------------------------------------------------------------------------*/
2089
2090   QUnit.module('case methods');
2091
2092   lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
2093     var methodName = caseName + 'Case',
2094         func = _[methodName];
2095
2096     var strings = [
2097       'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
2098       'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'
2099     ];
2100
2101     var converted = (function() {
2102       switch (caseName) {
2103         case 'camel': return 'fooBar';
2104         case 'kebab': return 'foo-bar';
2105         case 'lower': return 'foo bar';
2106         case 'snake': return 'foo_bar';
2107         case 'start': return 'Foo Bar';
2108         case 'upper': return 'FOO BAR';
2109       }
2110     }());
2111
2112     QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
2113       assert.expect(1);
2114
2115       var actual = lodashStable.map(strings, function(string) {
2116         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2117         return func(string) === expected;
2118       });
2119
2120       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2121     });
2122
2123     QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
2124       assert.expect(1);
2125
2126       var actual = lodashStable.map(strings, function(string) {
2127         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2128         return func(func(string)) === expected;
2129       });
2130
2131       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2132     });
2133
2134     QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
2135       assert.expect(1);
2136
2137       var actual = lodashStable.map(burredLetters, function(burred, index) {
2138         var letter = deburredLetters[index];
2139         if (caseName == 'start') {
2140           letter = lodashStable.capitalize(letter);
2141         } else if (caseName == 'upper') {
2142           letter = letter.toUpperCase();
2143         } else {
2144           letter = letter.toLowerCase();
2145         }
2146         return func(burred) === letter;
2147       });
2148
2149       assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue));
2150     });
2151
2152     QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) {
2153       assert.expect(2);
2154
2155       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
2156
2157       lodashStable.each(["'", '\u2019'], function(apos) {
2158         var actual = lodashStable.map(postfixes, function(postfix) {
2159           return func('a b' + apos + postfix +  ' c');
2160         });
2161
2162         var expected = lodashStable.map(postfixes, function(postfix) {
2163           switch (caseName) {
2164             case 'camel': return 'aB'  + postfix + 'C';
2165             case 'kebab': return 'a-b' + postfix + '-c';
2166             case 'lower': return 'a b' + postfix + ' c';
2167             case 'snake': return 'a_b' + postfix + '_c';
2168             case 'start': return 'A B' + postfix + ' C';
2169             case 'upper': return 'A B' + postfix.toUpperCase() + ' C';
2170           }
2171         });
2172
2173         assert.deepEqual(actual, expected);
2174       });
2175     });
2176
2177     QUnit.test('`_.' + methodName + '` should remove latin-1 mathematical operators', function(assert) {
2178       assert.expect(1);
2179
2180       var actual = lodashStable.map(['\xd7', '\xf7'], func);
2181       assert.deepEqual(actual, ['', '']);
2182     });
2183
2184     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2185       assert.expect(2);
2186
2187       var string = 'foo bar';
2188       assert.strictEqual(func(Object(string)), converted);
2189       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2190     });
2191
2192     QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2193       assert.expect(1);
2194
2195       if (!isNpm) {
2196         assert.strictEqual(_('foo bar')[methodName](), converted);
2197       }
2198       else {
2199         skipAssert(assert);
2200       }
2201     });
2202
2203     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2204       assert.expect(1);
2205
2206       if (!isNpm) {
2207         assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2208       }
2209       else {
2210         skipAssert(assert);
2211       }
2212     });
2213   });
2214
2215   (function() {
2216     QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2217       assert.expect(1);
2218
2219       var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase];
2220
2221       var actual = lodashStable.reduce(funcs, function(result, func) {
2222         return func(result);
2223       }, 'enable 6h format');
2224
2225       assert.strictEqual(actual, 'enable6HFormat');
2226     });
2227   }());
2228
2229   /*--------------------------------------------------------------------------*/
2230
2231   QUnit.module('lodash.camelCase');
2232
2233   (function() {
2234     QUnit.test('should work with numbers', function(assert) {
2235       assert.expect(6);
2236
2237       assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2238       assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
2239       assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
2240       assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2241       assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2242       assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2243     });
2244
2245     QUnit.test('should handle acronyms', function(assert) {
2246       assert.expect(6);
2247
2248       lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2249         assert.strictEqual(_.camelCase(string), 'safeHtml');
2250       });
2251
2252       lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2253         assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2254       });
2255
2256       lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2257         assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2258       });
2259     });
2260   }());
2261
2262   /*--------------------------------------------------------------------------*/
2263
2264   QUnit.module('lodash.capitalize');
2265
2266   (function() {
2267     QUnit.test('should capitalize the first character of a string', function(assert) {
2268       assert.expect(3);
2269
2270       assert.strictEqual(_.capitalize('fred'), 'Fred');
2271       assert.strictEqual(_.capitalize('Fred'), 'Fred');
2272       assert.strictEqual(_.capitalize(' fred'), ' fred');
2273     });
2274   }());
2275
2276   /*--------------------------------------------------------------------------*/
2277
2278   QUnit.module('lodash.castArray');
2279
2280   (function() {
2281     QUnit.test('should wrap non-array items in an array', function(assert) {
2282       assert.expect(1);
2283
2284       var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
2285           expected = lodashStable.map(values, function(value) { return [value]; }),
2286           actual = lodashStable.map(values, _.castArray);
2287
2288       assert.deepEqual(actual, expected);
2289     });
2290
2291     QUnit.test('should return array values by reference', function(assert) {
2292       assert.expect(1);
2293
2294       var array = [1];
2295       assert.strictEqual(_.castArray(array), array);
2296     });
2297
2298     QUnit.test('should return an empty array when no arguments are given', function(assert) {
2299       assert.expect(1);
2300
2301       assert.deepEqual(_.castArray(), []);
2302     });
2303   }());
2304
2305   /*--------------------------------------------------------------------------*/
2306
2307   QUnit.module('lodash.chain');
2308
2309   (function() {
2310     QUnit.test('should return a wrapped value', function(assert) {
2311       assert.expect(1);
2312
2313       if (!isNpm) {
2314         var actual = _.chain({ 'a': 0 });
2315         assert.ok(actual instanceof _);
2316       }
2317       else {
2318         skipAssert(assert);
2319       }
2320     });
2321
2322     QUnit.test('should return existing wrapped values', function(assert) {
2323       assert.expect(2);
2324
2325       if (!isNpm) {
2326         var wrapped = _({ 'a': 0 });
2327         assert.strictEqual(_.chain(wrapped), wrapped);
2328         assert.strictEqual(wrapped.chain(), wrapped);
2329       }
2330       else {
2331         skipAssert(assert, 2);
2332       }
2333     });
2334
2335     QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2336       assert.expect(6);
2337
2338       if (!isNpm) {
2339         var array = ['c', 'b', 'a'];
2340
2341         assert.ok(_.chain(array).head() instanceof _);
2342         assert.ok(_(array).chain().head() instanceof _);
2343
2344         assert.ok(_.chain(array).isArray() instanceof _);
2345         assert.ok(_(array).chain().isArray() instanceof _);
2346
2347         assert.ok(_.chain(array).sortBy().head() instanceof _);
2348         assert.ok(_(array).chain().sortBy().head() instanceof _);
2349       }
2350       else {
2351         skipAssert(assert, 6);
2352       }
2353     });
2354
2355     QUnit.test('should chain multiple methods', function(assert) {
2356       assert.expect(6);
2357
2358       if (!isNpm) {
2359         lodashStable.times(2, function(index) {
2360           var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2361               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 },
2362               wrapped = index ? _(array).chain() : _.chain(array);
2363
2364           var actual = wrapped
2365             .chain()
2366             .map(function(value) { return value.split(''); })
2367             .flatten()
2368             .reduce(function(object, chr) {
2369               object[chr] || (object[chr] = 0);
2370               object[chr]++;
2371               return object;
2372             }, {})
2373             .value();
2374
2375           assert.deepEqual(actual, expected);
2376
2377           array = [1, 2, 3, 4, 5, 6];
2378           wrapped = index ? _(array).chain() : _.chain(array);
2379           actual = wrapped
2380             .chain()
2381             .filter(function(n) { return n % 2 != 0; })
2382             .reject(function(n) { return n % 3 == 0; })
2383             .sortBy(function(n) { return -n; })
2384             .value();
2385
2386           assert.deepEqual(actual, [5, 1]);
2387
2388           array = [3, 4];
2389           wrapped = index ? _(array).chain() : _.chain(array);
2390           actual = wrapped
2391             .reverse()
2392             .concat([2, 1])
2393             .unshift(5)
2394             .tap(function(value) { value.pop(); })
2395             .map(square)
2396             .value();
2397
2398           assert.deepEqual(actual, [25, 16, 9, 4]);
2399         });
2400       }
2401       else {
2402         skipAssert(assert, 6);
2403       }
2404     });
2405   }());
2406
2407   /*--------------------------------------------------------------------------*/
2408
2409   QUnit.module('lodash.chunk');
2410
2411   (function() {
2412     var array = [0, 1, 2, 3, 4, 5];
2413
2414     QUnit.test('should return chunked arrays', function(assert) {
2415       assert.expect(1);
2416
2417       var actual = _.chunk(array, 3);
2418       assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2419     });
2420
2421     QUnit.test('should return the last chunk as remaining elements', function(assert) {
2422       assert.expect(1);
2423
2424       var actual = _.chunk(array, 4);
2425       assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2426     });
2427
2428     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
2429       assert.expect(1);
2430
2431       var expected = lodashStable.map(falsey, function(value) {
2432         return value === undefined ? [[0], [1], [2], [3], [4], [5]] : [];
2433       });
2434
2435       var actual = lodashStable.map(falsey, function(size, index) {
2436         return index ? _.chunk(array, size) : _.chunk(array);
2437       });
2438
2439       assert.deepEqual(actual, expected);
2440     });
2441
2442     QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2443       assert.expect(1);
2444
2445       var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity),
2446           expected = lodashStable.map(values, alwaysEmptyArray);
2447
2448       var actual = lodashStable.map(values, function(n) {
2449         return _.chunk(array, n);
2450       });
2451
2452       assert.deepEqual(actual, expected);
2453     });
2454
2455     QUnit.test('should coerce `size` to an integer', function(assert) {
2456       assert.expect(1);
2457
2458       assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2459     });
2460
2461     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
2462       assert.expect(1);
2463
2464       var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk);
2465       assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]);
2466     });
2467   }());
2468
2469   /*--------------------------------------------------------------------------*/
2470
2471   QUnit.module('lodash.clamp');
2472
2473   (function() {
2474     QUnit.test('should work with a `max` argument', function(assert) {
2475       assert.expect(2);
2476
2477       assert.strictEqual(_.clamp(5, 3), 3);
2478       assert.strictEqual(_.clamp(1, 3), 1);
2479     });
2480
2481     QUnit.test('should clamp negative numbers', function(assert) {
2482       assert.expect(3);
2483
2484       assert.strictEqual(_.clamp(-10, -5, 5), -5);
2485       assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2486       assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2487     });
2488
2489     QUnit.test('should clamp positive numbers', function(assert) {
2490       assert.expect(3);
2491
2492       assert.strictEqual(_.clamp(10, -5, 5), 5);
2493       assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2494       assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2495     });
2496
2497     QUnit.test('should not alter negative numbers in range', function(assert) {
2498       assert.expect(3);
2499
2500       assert.strictEqual(_.clamp(-4, -5, 5), -4);
2501       assert.strictEqual(_.clamp(-5, -5, 5), -5);
2502       assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2503     });
2504
2505     QUnit.test('should not alter positive numbers in range', function(assert) {
2506       assert.expect(3);
2507
2508       assert.strictEqual(_.clamp(4, -5, 5), 4);
2509       assert.strictEqual(_.clamp(5, -5, 5), 5);
2510       assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2511     });
2512
2513     QUnit.test('should not alter `0` in range', function(assert) {
2514       assert.expect(1);
2515
2516       assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2517     });
2518
2519     QUnit.test('should clamp to `0`', function(assert) {
2520       assert.expect(1);
2521
2522       assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2523     });
2524
2525     QUnit.test('should not alter `-0` in range', function(assert) {
2526       assert.expect(1);
2527
2528       assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2529     });
2530
2531     QUnit.test('should clamp to `-0`', function(assert) {
2532       assert.expect(1);
2533
2534       assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2535     });
2536
2537     QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2538       assert.expect(1);
2539
2540       assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2541     });
2542
2543     QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2544       assert.expect(2);
2545
2546       assert.deepEqual(_.clamp(1, -5, NaN), 0);
2547       assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2548     });
2549   }());
2550
2551   /*--------------------------------------------------------------------------*/
2552
2553   QUnit.module('clone methods');
2554
2555   (function() {
2556     function Foo() {
2557       this.a = 1;
2558     }
2559     Foo.prototype.b = 1;
2560     Foo.c = function() {};
2561
2562     if (Map) {
2563       var map = new Map;
2564       map.set('a', 1);
2565       map.set('b', 2);
2566     }
2567     if (Set) {
2568       var set = new Set;
2569       set.add(1);
2570       set.add(2);
2571     }
2572     var objects = {
2573       '`arguments` objects': arguments,
2574       'arrays': ['a', ''],
2575       'array-like-objects': { '0': 'a', '1': '', 'length': 3 },
2576       'booleans': false,
2577       'boolean objects': Object(false),
2578       'date objects': new Date,
2579       'Foo instances': new Foo,
2580       'objects': { 'a': 0, 'b': 1, 'c': 2 },
2581       'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2582       'objects from another document': realm.object || {},
2583       'maps': map,
2584       'null values': null,
2585       'numbers': 0,
2586       'number objects': Object(0),
2587       'regexes': /a/gim,
2588       'sets': set,
2589       'strings': 'a',
2590       'string objects': Object('a'),
2591       'undefined values': undefined
2592     };
2593
2594     objects.arrays.length = 3;
2595
2596     var uncloneable = {
2597       'DOM elements': body,
2598       'functions': Foo,
2599       'generators': generator
2600     };
2601
2602     lodashStable.each(errors, function(error) {
2603       uncloneable[error.name + 's'] = error;
2604     });
2605
2606     QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2607       assert.expect(2);
2608
2609       var array = [{ 'a': 0 }, { 'b': 1 }],
2610           actual = _.clone(array);
2611
2612       assert.deepEqual(actual, array);
2613       assert.ok(actual !== array && actual[0] === array[0]);
2614     });
2615
2616     QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2617       assert.expect(1);
2618
2619       var object = {
2620         'foo': { 'b': { 'c': { 'd': {} } } },
2621         'bar': {}
2622       };
2623
2624       object.foo.b.c.d = object;
2625       object.bar.b = object.foo.b;
2626
2627       var actual = _.cloneDeep(object);
2628       assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2629     });
2630
2631     QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2632       assert.expect(2);
2633
2634       var cyclical = {};
2635       lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2636         cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2637       });
2638
2639       var clone = _.cloneDeep(cyclical),
2640           actual = clone['v' + LARGE_ARRAY_SIZE][0];
2641
2642       assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2643       assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2644     });
2645
2646     QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2647       assert.expect(164);
2648
2649       var Stack,
2650           keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
2651
2652       var pairs = lodashStable.map(keys, function(key, index) {
2653         var lastIndex = keys.length - 1;
2654         return [key, keys[lastIndex - index]];
2655       });
2656
2657       _.cloneDeepWith({ 'a': 1 }, function() {
2658         if (arguments.length > 1) {
2659           Stack || (Stack = _.last(arguments).constructor);
2660         }
2661       });
2662
2663       var stacks = [new Stack(pairs), new Stack(pairs)];
2664
2665       lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
2666         stacks[1].set({}, {});
2667       });
2668
2669       lodashStable.each(stacks, function(stack) {
2670         lodashStable.each(keys, function(key, index) {
2671           var value = pairs[index][1];
2672
2673           assert.deepEqual(stack.get(key), value);
2674           assert.strictEqual(stack.has(key), true);
2675           assert.strictEqual(stack['delete'](key), true);
2676           assert.strictEqual(stack.has(key), false);
2677           assert.strictEqual(stack.get(key), undefined);
2678           assert.strictEqual(stack['delete'](key), false);
2679           assert.strictEqual(stack.set(key, value), stack);
2680           assert.strictEqual(stack.has(key), true);
2681         });
2682
2683         assert.strictEqual(stack.clear(), undefined);
2684         assert.ok(lodashStable.every(keys, function(key) {
2685           return !stack.has(key);
2686         }));
2687       });
2688     });
2689
2690     lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2691       var func = _[methodName],
2692           isDeep = methodName == 'cloneDeep';
2693
2694       lodashStable.forOwn(objects, function(object, key) {
2695         QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
2696           assert.expect(2);
2697
2698           var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
2699               actual = func(object);
2700
2701           assert.ok(isEqual(actual, object));
2702
2703           if (lodashStable.isObject(object)) {
2704             assert.notStrictEqual(actual, object);
2705           } else {
2706             assert.strictEqual(actual, object);
2707           }
2708         });
2709       });
2710
2711       QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2712         assert.expect(2);
2713
2714         if (ArrayBuffer) {
2715           var actual = func(arrayBuffer);
2716           assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
2717           assert.notStrictEqual(actual, arrayBuffer);
2718         }
2719         else {
2720           skipAssert(assert, 2);
2721         }
2722       });
2723
2724       QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
2725         assert.expect(4);
2726
2727         if (Buffer) {
2728           var buffer = new Buffer([1, 2]),
2729               actual = func(buffer);
2730
2731           assert.strictEqual(actual.byteLength, buffer.byteLength);
2732           assert.strictEqual(actual.inspect(), buffer.inspect());
2733           assert.notStrictEqual(actual, buffer);
2734
2735           buffer[0] = 2;
2736           assert.strictEqual(actual[0], isDeep ? 2 : 1);
2737         }
2738         else {
2739           skipAssert(assert, 4);
2740         }
2741       });
2742
2743       QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2744         assert.expect(2);
2745
2746         var array = /c/.exec('abcde'),
2747             actual = func(array);
2748
2749         assert.strictEqual(actual.index, 2);
2750         assert.strictEqual(actual.input, 'abcde');
2751       });
2752
2753       QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2754         assert.expect(1);
2755
2756         var regexp = /c/g;
2757         regexp.exec('abcde');
2758
2759         assert.strictEqual(func(regexp).lastIndex, 3);
2760       });
2761
2762       QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
2763         assert.expect(1);
2764
2765         var values = lodashStable.map([false, true, 1, 'a'], function(value) {
2766           var object = Object(value);
2767           object.a = 1;
2768           return object;
2769         });
2770
2771         var expected = lodashStable.map(values, alwaysTrue);
2772
2773         var actual = lodashStable.map(values, function(value) {
2774           return func(value).a === 1;
2775         });
2776
2777         assert.deepEqual(actual, expected);
2778       });
2779
2780       QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
2781         assert.expect(2);
2782
2783         var actual = func(Foo.prototype);
2784
2785         assert.notOk(actual instanceof Foo);
2786         assert.deepEqual(actual, { 'b': 1 });
2787       });
2788
2789       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
2790         assert.expect(1);
2791
2792         assert.ok(func(new Foo) instanceof Foo);
2793       });
2794
2795       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
2796         assert.expect(1);
2797
2798         Foo.prototype.constructor = Object;
2799         assert.ok(func(new Foo) instanceof Foo);
2800         Foo.prototype.constructor = Foo;
2801       });
2802
2803       QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2804         assert.expect(1);
2805
2806         Foo.prototype.constructor = null;
2807         assert.notOk(func(new Foo) instanceof Foo);
2808         Foo.prototype.constructor = Foo;
2809       });
2810
2811       QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2812         assert.expect(2);
2813
2814         var object = {
2815           'constructor': objectProto.constructor,
2816           'hasOwnProperty': objectProto.hasOwnProperty,
2817           'isPrototypeOf': objectProto.isPrototypeOf,
2818           'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2819           'toLocaleString': objectProto.toLocaleString,
2820           'toString': objectProto.toString,
2821           'valueOf': objectProto.valueOf
2822         };
2823
2824         var actual = func(object);
2825
2826         assert.deepEqual(actual, object);
2827         assert.notStrictEqual(actual, object);
2828       });
2829
2830       QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2831         assert.expect(3);
2832
2833         function Foo() {
2834           this[symbol] = { 'c': 1 };
2835         }
2836
2837         if (Symbol) {
2838           var symbol2 = Symbol('b');
2839           Foo.prototype[symbol2] = 2;
2840
2841           var object = { 'a': { 'b': new Foo } };
2842           object[symbol] = { 'b': 1 };
2843
2844           var actual = func(object);
2845
2846           assert.deepEqual(getSymbols(actual.a.b), [symbol]);
2847
2848           if (isDeep) {
2849             assert.deepEqual(actual[symbol], object[symbol]);
2850             assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]);
2851           }
2852           else {
2853             assert.strictEqual(actual[symbol], object[symbol]);
2854             assert.strictEqual(actual.a, object.a);
2855           }
2856         }
2857         else {
2858           skipAssert(assert, 3);
2859         }
2860       });
2861
2862       QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2863         assert.expect(4);
2864
2865         if (Symbol) {
2866           assert.strictEqual(func(symbol), symbol);
2867
2868           var object = Object(symbol),
2869               actual = func(object);
2870
2871           assert.strictEqual(typeof actual, 'object');
2872           assert.strictEqual(typeof actual.valueOf(), 'symbol');
2873           assert.notStrictEqual(actual, object);
2874         }
2875         else {
2876           skipAssert(assert, 4);
2877         }
2878       });
2879
2880       QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2881         assert.expect(1);
2882
2883         if (Symbol) {
2884           assert.strictEqual(func(symbol), symbol);
2885         }
2886         else {
2887           skipAssert(assert);
2888         }
2889       });
2890
2891       QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2892         assert.expect(1);
2893
2894         if (document) {
2895           var element = document.createElement('div');
2896
2897           try {
2898             assert.deepEqual(func(element), {});
2899           } catch (e) {
2900             assert.ok(false, e.message);
2901           }
2902         }
2903         else {
2904           skipAssert(assert);
2905         }
2906       });
2907
2908       QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
2909         assert.expect(1);
2910
2911         var props = [];
2912
2913         var objects = lodashStable.transform(_, function(result, value, key) {
2914           if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
2915               !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
2916               !lodashStable.isFunction(value)) {
2917             props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
2918             result.push(value);
2919           }
2920         }, []);
2921
2922         var expected = lodashStable.map(objects, alwaysTrue);
2923
2924         var actual = lodashStable.map(objects, function(object) {
2925           var Ctor = object.constructor,
2926               result = func(object);
2927
2928           return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
2929         });
2930
2931         assert.deepEqual(actual, expected, props.join(', '));
2932       });
2933
2934       QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
2935         assert.expect(2);
2936
2937         var expected = [{ 'a': [0] }, { 'b': [1] }],
2938             actual = lodashStable.map(expected, func);
2939
2940         assert.deepEqual(actual, expected);
2941
2942         if (isDeep) {
2943           assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
2944         } else {
2945           assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
2946         }
2947       });
2948
2949       QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
2950         assert.expect(2);
2951
2952         if (!isNpm) {
2953           var object = objects.objects,
2954               actual = _(object)[methodName]();
2955
2956           assert.deepEqual(actual, object);
2957           assert.notStrictEqual(actual, object);
2958         }
2959         else {
2960           skipAssert(assert, 2);
2961         }
2962       });
2963
2964       lodashStable.each(arrayViews, function(type) {
2965         QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) {
2966           assert.expect(10);
2967
2968           var Ctor = root[type];
2969
2970           lodashStable.times(2, function(index) {
2971             if (Ctor) {
2972               var buffer = new ArrayBuffer(24),
2973                   view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
2974                   actual = func(view);
2975
2976               assert.deepEqual(actual, view);
2977               assert.notStrictEqual(actual, view);
2978               assert.strictEqual(actual.buffer === view.buffer, !isDeep);
2979               assert.strictEqual(actual.byteOffset, view.byteOffset);
2980               assert.strictEqual(actual.length, view.length);
2981             }
2982             else {
2983               skipAssert(assert, 5);
2984             }
2985           });
2986         });
2987       });
2988
2989       lodashStable.forOwn(uncloneable, function(value, key) {
2990         QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
2991           assert.expect(3);
2992
2993           if (value) {
2994             var object = { 'a': value, 'b': { 'c': value } },
2995                 actual = func(object),
2996                 expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
2997
2998             assert.deepEqual(actual, object);
2999             assert.notStrictEqual(actual, object);
3000             assert.deepEqual(func(value), expected);
3001           }
3002           else {
3003             skipAssert(assert, 3);
3004           }
3005         });
3006       });
3007     });
3008
3009     lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
3010       var func = _[methodName],
3011           isDeep = methodName == 'cloneDeepWith';
3012
3013       QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
3014         assert.expect(1);
3015
3016         var argsList = [],
3017             object = new Foo;
3018
3019         func(object, function() {
3020           var length = arguments.length,
3021               args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
3022
3023           argsList.push(args);
3024         });
3025
3026         assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]);
3027       });
3028
3029       QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` returns `undefined`', function(assert) {
3030         assert.expect(1);
3031
3032         var actual = func({ 'a': { 'b': 'c' } }, noop);
3033         assert.deepEqual(actual, { 'a': { 'b': 'c' } });
3034       });
3035
3036       lodashStable.forOwn(uncloneable, function(value, key) {
3037         QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
3038           assert.expect(4);
3039
3040           var customizer = function(value) {
3041             return lodashStable.isPlainObject(value) ? undefined : value;
3042           };
3043
3044           var actual = func(value, customizer);
3045
3046           assert.deepEqual(actual, value);
3047           assert.strictEqual(actual, value);
3048
3049           var object = { 'a': value, 'b': { 'c': value } };
3050           actual = func(object, customizer);
3051
3052           assert.deepEqual(actual, object);
3053           assert.notStrictEqual(actual, object);
3054         });
3055       });
3056     });
3057   }(1, 2, 3));
3058
3059   /*--------------------------------------------------------------------------*/
3060
3061   QUnit.module('lodash.compact');
3062
3063   (function() {
3064     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
3065
3066     QUnit.test('should filter falsey values', function(assert) {
3067       assert.expect(1);
3068
3069       var array = ['0', '1', '2'];
3070       assert.deepEqual(_.compact(falsey.concat(array)), array);
3071     });
3072
3073     QUnit.test('should work when in-between lazy operators', function(assert) {
3074       assert.expect(2);
3075
3076       if (!isNpm) {
3077         var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
3078         assert.deepEqual(actual, []);
3079
3080         actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
3081         assert.deepEqual(actual, [true, 1, 'a']);
3082       }
3083       else {
3084         skipAssert(assert, 2);
3085       }
3086     });
3087
3088     QUnit.test('should work in a lazy sequence', function(assert) {
3089       assert.expect(1);
3090
3091       if (!isNpm) {
3092         var actual = _(largeArray).slice(1).compact().reverse().take().value();
3093         assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
3094       }
3095       else {
3096         skipAssert(assert);
3097       }
3098     });
3099
3100     QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
3101       assert.expect(1);
3102
3103       if (!isModularize) {
3104         var iteratee = _.iteratee,
3105             pass = false;
3106
3107         _.iteratee = identity;
3108
3109         try {
3110           var actual = _(largeArray).slice(1).compact().value();
3111           pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
3112         } catch (e) {console.log(e);}
3113
3114         assert.ok(pass);
3115         _.iteratee = iteratee;
3116       }
3117       else {
3118         skipAssert(assert);
3119       }
3120     });
3121   }());
3122
3123   /*--------------------------------------------------------------------------*/
3124
3125   QUnit.module('lodash.concat');
3126
3127   (function() {
3128     QUnit.test('should shallow clone `array`', function(assert) {
3129       assert.expect(2);
3130
3131       var array = [1, 2, 3],
3132           actual = _.concat(array);
3133
3134       assert.deepEqual(actual, array);
3135       assert.notStrictEqual(actual, array);
3136     });
3137
3138     QUnit.test('should concat arrays and values', function(assert) {
3139       assert.expect(2);
3140
3141       var array = [1],
3142           actual = _.concat(array, 2, [3], [[4]]);
3143
3144       assert.deepEqual(actual, [1, 2, 3, [4]]);
3145       assert.deepEqual(array, [1]);
3146     });
3147
3148     QUnit.test('should cast non-array `array` values to arrays', function(assert) {
3149       assert.expect(2);
3150
3151       var values = [, null, undefined, false, true, 1, NaN, 'a'];
3152
3153       var expected = lodashStable.map(values, function(value, index) {
3154         return index ? [value] : [];
3155       });
3156
3157       var actual = lodashStable.map(values, function(value, index) {
3158         return index ? _.concat(value) : _.concat();
3159       });
3160
3161       assert.deepEqual(actual, expected);
3162
3163       expected = lodashStable.map(values, function(value) {
3164         return [value, 2, [3]];
3165       });
3166
3167       actual = lodashStable.map(values, function(value) {
3168         return _.concat(value, [2], [[3]]);
3169       });
3170
3171       assert.deepEqual(actual, expected);
3172     });
3173
3174     QUnit.test('should treat sparse arrays as dense', function(assert) {
3175       assert.expect(3);
3176
3177       var expected = [],
3178           actual = _.concat(Array(1), Array(1));
3179
3180       expected.push(undefined, undefined);
3181
3182       assert.ok('0'in actual);
3183       assert.ok('1' in actual);
3184       assert.deepEqual(actual, expected);
3185     });
3186
3187     QUnit.test('should return a new wrapped array', function(assert) {
3188       assert.expect(2);
3189
3190       if (!isNpm) {
3191         var array = [1],
3192             wrapped = _(array).concat([2, 3]),
3193             actual = wrapped.value();
3194
3195         assert.deepEqual(array, [1]);
3196         assert.deepEqual(actual, [1, 2, 3]);
3197       }
3198       else {
3199         skipAssert(assert, 2);
3200       }
3201     });
3202   }());
3203
3204   /*--------------------------------------------------------------------------*/
3205
3206   QUnit.module('lodash.cond');
3207
3208   (function() {
3209     QUnit.test('should create a conditional function', function(assert) {
3210       assert.expect(3);
3211
3212       var cond = _.cond([
3213         [lodashStable.matches({ 'a': 1 }),     alwaysA],
3214         [lodashStable.matchesProperty('b', 1), alwaysB],
3215         [lodashStable.property('c'),           alwaysC]
3216       ]);
3217
3218       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3219       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3220       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3221     });
3222
3223     QUnit.test('should provide arguments to functions', function(assert) {
3224       assert.expect(2);
3225
3226       var args1,
3227           args2,
3228           expected = ['a', 'b', 'c'];
3229
3230       var cond = _.cond([[
3231         function() { args1 || (args1 = slice.call(arguments)); return true; },
3232         function() { args2 || (args2 = slice.call(arguments)); }
3233       ]]);
3234
3235       cond('a', 'b', 'c');
3236
3237       assert.deepEqual(args1, expected);
3238       assert.deepEqual(args2, expected);
3239     });
3240
3241     QUnit.test('should work with predicate shorthands', function(assert) {
3242       assert.expect(3);
3243
3244       var cond = _.cond([
3245         [{ 'a': 1 }, alwaysA],
3246         [['b', 1],   alwaysB],
3247         ['c',        alwaysC]
3248       ]);
3249
3250       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3251       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3252       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3253     });
3254
3255     QUnit.test('should return `undefined` when no condition is met', function(assert) {
3256       assert.expect(1);
3257
3258       var cond = _.cond([[alwaysFalse, alwaysA]]);
3259       assert.strictEqual(cond({ 'a': 1 }), undefined);
3260     });
3261
3262     QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
3263       assert.expect(2);
3264
3265       lodashStable.each([false, true], function(value) {
3266         assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError);
3267       });
3268     });
3269
3270     QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
3271       assert.expect(1);
3272
3273       var cond = _.cond([
3274         [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
3275       ]);
3276
3277       var object = { 'cond': cond, 'a': 1, 'b': 2 };
3278       assert.strictEqual(object.cond('a', 'b'), 2);
3279     });
3280   }());
3281
3282   /*--------------------------------------------------------------------------*/
3283
3284   QUnit.module('lodash.conforms');
3285
3286   (function() {
3287     var objects = [
3288       { 'a': 1, 'b': 8 },
3289       { 'a': 2, 'b': 4 },
3290       { 'a': 3, 'b': 16 }
3291     ];
3292
3293     QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
3294       assert.expect(2);
3295
3296       var conforms = _.conforms({
3297         'b': function(value) { return value > 4; }
3298       });
3299
3300       var actual = lodashStable.filter(objects, conforms);
3301       assert.deepEqual(actual, [objects[0], objects[2]]);
3302
3303       conforms = _.conforms({
3304         'b': function(value) { return value > 8; },
3305         'a': function(value) { return value > 1; }
3306       });
3307
3308       actual = lodashStable.filter(objects, conforms);
3309       assert.deepEqual(actual, [objects[2]]);
3310     });
3311
3312     QUnit.test('should not match by inherited `source` properties', function(assert) {
3313       assert.expect(1);
3314
3315       function Foo() {
3316         this.a = function(value) {
3317           return value > 1;
3318         };
3319       }
3320       Foo.prototype.b = function(value) {
3321         return value > 8;
3322       };
3323
3324       var conforms = _.conforms(new Foo),
3325           actual = lodashStable.filter(objects, conforms);
3326
3327       assert.deepEqual(actual, [objects[1], objects[2]]);
3328     });
3329
3330     QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
3331       assert.expect(2);
3332
3333       var count = 0;
3334
3335       var conforms = _.conforms({
3336         'a': function() { count++; return true; }
3337       });
3338
3339       assert.strictEqual(conforms({}), false);
3340       assert.strictEqual(count, 0);
3341     });
3342
3343     QUnit.test('should work with a function for `object`', function(assert) {
3344       assert.expect(2);
3345
3346       function Foo() {}
3347       Foo.a = 1;
3348
3349       function Bar() {}
3350       Bar.a = 2;
3351
3352       var conforms = _.conforms({
3353         'a': function(value) { return value > 1; }
3354       });
3355
3356       assert.strictEqual(conforms(Foo), false);
3357       assert.strictEqual(conforms(Bar), true);
3358     });
3359
3360     QUnit.test('should work with a function for `source`', function(assert) {
3361       assert.expect(1);
3362
3363       function Foo() {}
3364       Foo.a = function(value) { return value > 1; };
3365
3366       var objects = [{ 'a': 1 }, { 'a': 2 }],
3367           actual = lodashStable.filter(objects, _.conforms(Foo));
3368
3369       assert.deepEqual(actual, [objects[1]]);
3370     });
3371
3372     QUnit.test('should work with a non-plain `object`', function(assert) {
3373       assert.expect(1);
3374
3375       function Foo() {
3376         this.a = 1;
3377       }
3378       Foo.prototype.b = 2;
3379
3380       var conforms = _.conforms({
3381         'b': function(value) { return value > 1; }
3382       });
3383
3384       assert.strictEqual(conforms(new Foo), true);
3385     });
3386
3387     QUnit.test('should return `false` when `object` is nullish', function(assert) {
3388       assert.expect(1);
3389
3390       var values = [, null, undefined],
3391           expected = lodashStable.map(values, alwaysFalse);
3392
3393       var conforms = _.conforms({
3394         'a': function(value) { return value > 1; }
3395       });
3396
3397       var actual = lodashStable.map(values, function(value, index) {
3398         try {
3399           return index ? conforms(value) : conforms();
3400         } catch (e) {}
3401       });
3402
3403       assert.deepEqual(actual, expected);
3404     });
3405
3406     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3407       assert.expect(1);
3408
3409       var values = [, null, undefined],
3410           expected = lodashStable.map(values, alwaysTrue),
3411           conforms = _.conforms({});
3412
3413       var actual = lodashStable.map(values, function(value, index) {
3414         try {
3415           return index ? conforms(value) : conforms();
3416         } catch (e) {}
3417       });
3418
3419       assert.deepEqual(actual, expected);
3420     });
3421
3422     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
3423       assert.expect(1);
3424
3425       var object = { 'a': 1 },
3426           expected = lodashStable.map(empties, alwaysTrue);
3427
3428       var actual = lodashStable.map(empties, function(value) {
3429         var conforms = _.conforms(value);
3430         return conforms(object);
3431       });
3432
3433       assert.deepEqual(actual, expected);
3434     });
3435
3436     QUnit.test('should not change behavior if `source` is modified', function(assert) {
3437       assert.expect(2);
3438
3439       var source = {
3440         'a': function(value) { return value > 1; }
3441       };
3442
3443       var object = { 'a': 2 },
3444           conforms = _.conforms(source);
3445
3446       assert.strictEqual(conforms(object), true);
3447
3448       source.a = function(value) { return value < 2; };
3449       assert.strictEqual(conforms(object), true);
3450     });
3451   }());
3452
3453   /*--------------------------------------------------------------------------*/
3454
3455   QUnit.module('lodash.constant');
3456
3457   (function() {
3458     QUnit.test('should create a function that returns `value`', function(assert) {
3459       assert.expect(1);
3460
3461       var object = { 'a': 1 },
3462           values = Array(2).concat(empties, true, 1, 'a'),
3463           constant = _.constant(object),
3464           expected = lodashStable.map(values, function() { return true; });
3465
3466       var actual = lodashStable.map(values, function(value, index) {
3467         if (index == 0) {
3468           var result = constant();
3469         } else if (index == 1) {
3470           result = constant.call({});
3471         } else {
3472           result = constant(value);
3473         }
3474         return result === object;
3475       });
3476
3477       assert.deepEqual(actual, expected);
3478     });
3479
3480     QUnit.test('should work with falsey values', function(assert) {
3481       assert.expect(1);
3482
3483       var expected = lodashStable.map(falsey, function() { return true; });
3484
3485       var actual = lodashStable.map(falsey, function(value, index) {
3486         var constant = index ? _.constant(value) : _.constant(),
3487             result = constant();
3488
3489         return (result === value) || (result !== result && value !== value);
3490       });
3491
3492       assert.deepEqual(actual, expected);
3493     });
3494
3495     QUnit.test('should return a wrapped value when chaining', function(assert) {
3496       assert.expect(1);
3497
3498       if (!isNpm) {
3499         var wrapped = _(true).constant();
3500         assert.ok(wrapped instanceof _);
3501       }
3502       else {
3503         skipAssert(assert);
3504       }
3505     });
3506   }());
3507
3508   /*--------------------------------------------------------------------------*/
3509
3510   QUnit.module('lodash.countBy');
3511
3512   (function() {
3513     var array = [6.1, 4.2, 6.3];
3514
3515     QUnit.test('should transform keys by `iteratee`', function(assert) {
3516       assert.expect(1);
3517
3518       var actual = _.countBy(array, Math.floor);
3519       assert.deepEqual(actual, { '4': 1, '6': 2 });
3520     });
3521
3522     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3523       assert.expect(1);
3524
3525       var array = [4, 6, 6],
3526           values = [, null, undefined],
3527           expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
3528
3529       var actual = lodashStable.map(values, function(value, index) {
3530         return index ? _.countBy(array, value) : _.countBy(array);
3531       });
3532
3533       assert.deepEqual(actual, expected);
3534     });
3535
3536     QUnit.test('should work with `_.property` shorthands', function(assert) {
3537       assert.expect(1);
3538
3539       var actual = _.countBy(['one', 'two', 'three'], 'length');
3540       assert.deepEqual(actual, { '3': 2, '5': 1 });
3541     });
3542
3543     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3544       assert.expect(2);
3545
3546       var actual = _.countBy(array, function(n) {
3547         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
3548       });
3549
3550       assert.deepEqual(actual.constructor, 1);
3551       assert.deepEqual(actual.hasOwnProperty, 2);
3552     });
3553
3554     QUnit.test('should work with a number for `iteratee`', function(assert) {
3555       assert.expect(2);
3556
3557       var array = [
3558         [1, 'a'],
3559         [2, 'a'],
3560         [2, 'b']
3561       ];
3562
3563       assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3564       assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3565     });
3566
3567     QUnit.test('should work with an object for `collection`', function(assert) {
3568       assert.expect(1);
3569
3570       var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
3571       assert.deepEqual(actual, { '4': 1, '6': 2 });
3572     });
3573
3574     QUnit.test('should work in a lazy sequence', function(assert) {
3575       assert.expect(1);
3576
3577       if (!isNpm) {
3578         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3579           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3580           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3581         );
3582
3583         var actual = _(array).countBy().map(square).filter(isEven).take().value();
3584
3585         assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3586       }
3587       else {
3588         skipAssert(assert);
3589       }
3590     });
3591   }());
3592
3593   /*--------------------------------------------------------------------------*/
3594
3595   QUnit.module('lodash.create');
3596
3597   (function() {
3598     function Shape() {
3599       this.x = 0;
3600       this.y = 0;
3601     }
3602
3603     function Circle() {
3604       Shape.call(this);
3605     }
3606
3607     QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3608       assert.expect(3);
3609
3610       Circle.prototype = _.create(Shape.prototype);
3611       Circle.prototype.constructor = Circle;
3612
3613       var actual = new Circle;
3614
3615       assert.ok(actual instanceof Circle);
3616       assert.ok(actual instanceof Shape);
3617       assert.notStrictEqual(Circle.prototype, Shape.prototype);
3618     });
3619
3620     QUnit.test('should assign `properties` to the created object', function(assert) {
3621       assert.expect(3);
3622
3623       var expected = { 'constructor': Circle, 'radius': 0 };
3624       Circle.prototype = _.create(Shape.prototype, expected);
3625
3626       var actual = new Circle;
3627
3628       assert.ok(actual instanceof Circle);
3629       assert.ok(actual instanceof Shape);
3630       assert.deepEqual(Circle.prototype, expected);
3631     });
3632
3633     QUnit.test('should assign own properties', function(assert) {
3634       assert.expect(1);
3635
3636       function Foo() {
3637         this.a = 1;
3638         this.c = 3;
3639       }
3640       Foo.prototype.b = 2;
3641
3642       assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3643     });
3644
3645     QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
3646       assert.expect(1);
3647
3648       function Foo() {
3649         this.a = 1;
3650       }
3651       var object = _.create(new Foo, { 'a': 1 });
3652       assert.deepEqual(lodashStable.keys(object), ['a']);
3653     });
3654
3655     QUnit.test('should accept a falsey `prototype` argument', function(assert) {
3656       assert.expect(1);
3657
3658       var expected = lodashStable.map(falsey, alwaysEmptyObject);
3659
3660       var actual = lodashStable.map(falsey, function(prototype, index) {
3661         return index ? _.create(prototype) : _.create();
3662       });
3663
3664       assert.deepEqual(actual, expected);
3665     });
3666
3667     QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
3668       assert.expect(1);
3669
3670       var expected = lodashStable.map(primitives, alwaysTrue);
3671
3672       var actual = lodashStable.map(primitives, function(value, index) {
3673         return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3674       });
3675
3676       assert.deepEqual(actual, expected);
3677     });
3678
3679     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3680       assert.expect(1);
3681
3682       var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3683           expected = lodashStable.map(array, alwaysTrue),
3684           objects = lodashStable.map(array, _.create);
3685
3686       var actual = lodashStable.map(objects, function(object) {
3687         return object.a === 1 && !_.keys(object).length;
3688       });
3689
3690       assert.deepEqual(actual, expected);
3691     });
3692   }());
3693
3694   /*--------------------------------------------------------------------------*/
3695
3696   QUnit.module('lodash.curry');
3697
3698   (function() {
3699     function fn(a, b, c, d) {
3700       return slice.call(arguments);
3701     }
3702
3703     QUnit.test('should curry based on the number of arguments given', function(assert) {
3704       assert.expect(3);
3705
3706       var curried = _.curry(fn),
3707           expected = [1, 2, 3, 4];
3708
3709       assert.deepEqual(curried(1)(2)(3)(4), expected);
3710       assert.deepEqual(curried(1, 2)(3, 4), expected);
3711       assert.deepEqual(curried(1, 2, 3, 4), expected);
3712     });
3713
3714     QUnit.test('should allow specifying `arity`', function(assert) {
3715       assert.expect(3);
3716
3717       var curried = _.curry(fn, 3),
3718           expected = [1, 2, 3];
3719
3720       assert.deepEqual(curried(1)(2, 3), expected);
3721       assert.deepEqual(curried(1, 2)(3), expected);
3722       assert.deepEqual(curried(1, 2, 3), expected);
3723     });
3724
3725     QUnit.test('should coerce `arity` to an integer', function(assert) {
3726       assert.expect(2);
3727
3728       var values = ['0', 0.6, 'xyz'],
3729           expected = lodashStable.map(values, alwaysEmptyArray);
3730
3731       var actual = lodashStable.map(values, function(arity) {
3732         return _.curry(fn, arity)();
3733       });
3734
3735       assert.deepEqual(actual, expected);
3736       assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3737     });
3738
3739     QUnit.test('should support placeholders', function(assert) {
3740       assert.expect(4);
3741
3742       var curried = _.curry(fn),
3743           ph = curried.placeholder;
3744
3745       assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3746       assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3747       assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3748       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3749     });
3750
3751     QUnit.test('should persist placeholders', function(assert) {
3752       assert.expect(1);
3753
3754       var curried = _.curry(fn),
3755           ph = curried.placeholder,
3756           actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
3757
3758       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3759     });
3760
3761     QUnit.test('should use `_.placeholder` when set', function(assert) {
3762       assert.expect(1);
3763
3764       if (!isModularize) {
3765         var curried = _.curry(fn),
3766             _ph = _.placeholder = {},
3767             ph = curried.placeholder;
3768
3769         assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
3770         delete _.placeholder;
3771       }
3772       else {
3773         skipAssert(assert);
3774       }
3775     });
3776
3777     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3778       assert.expect(3);
3779
3780       var curried = _.curry(fn, 3);
3781       assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3782       assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3783       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3784     });
3785
3786     QUnit.test('should create a function with a `length` of `0`', function(assert) {
3787       assert.expect(6);
3788
3789       lodashStable.times(2, function(index) {
3790         var curried = index ? _.curry(fn, 4) : _.curry(fn);
3791         assert.strictEqual(curried.length, 0);
3792         assert.strictEqual(curried(1).length, 0);
3793         assert.strictEqual(curried(1, 2).length, 0);
3794       });
3795     });
3796
3797     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3798       assert.expect(2);
3799
3800       function Foo(value) {
3801         return value && object;
3802       }
3803
3804       var curried = _.curry(Foo),
3805           object = {};
3806
3807       assert.ok(new curried(false) instanceof Foo);
3808       assert.strictEqual(new curried(true), object);
3809     });
3810
3811     QUnit.test('should not set a `this` binding', function(assert) {
3812       assert.expect(9);
3813
3814       var fn = function(a, b, c) {
3815         var value = this || {};
3816         return [value[a], value[b], value[c]];
3817       };
3818
3819       var object = { 'a': 1, 'b': 2, 'c': 3 },
3820           expected = [1, 2, 3];
3821
3822       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3823       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3824       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3825
3826       assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3827       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3828       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3829
3830       object.curried = _.curry(fn);
3831       assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3832       assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3833       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3834     });
3835
3836     QUnit.test('should work with partialed methods', function(assert) {
3837       assert.expect(2);
3838
3839       var curried = _.curry(fn),
3840           expected = [1, 2, 3, 4];
3841
3842       var a = _.partial(curried, 1),
3843           b = _.bind(a, null, 2),
3844           c = _.partialRight(b, 4),
3845           d = _.partialRight(b(3), 4);
3846
3847       assert.deepEqual(c(3), expected);
3848       assert.deepEqual(d(), expected);
3849     });
3850   }());
3851
3852   /*--------------------------------------------------------------------------*/
3853
3854   QUnit.module('lodash.curryRight');
3855
3856   (function() {
3857     function fn(a, b, c, d) {
3858       return slice.call(arguments);
3859     }
3860
3861     QUnit.test('should curry based on the number of arguments given', function(assert) {
3862       assert.expect(3);
3863
3864       var curried = _.curryRight(fn),
3865           expected = [1, 2, 3, 4];
3866
3867       assert.deepEqual(curried(4)(3)(2)(1), expected);
3868       assert.deepEqual(curried(3, 4)(1, 2), expected);
3869       assert.deepEqual(curried(1, 2, 3, 4), expected);
3870     });
3871
3872     QUnit.test('should allow specifying `arity`', function(assert) {
3873       assert.expect(3);
3874
3875       var curried = _.curryRight(fn, 3),
3876           expected = [1, 2, 3];
3877
3878       assert.deepEqual(curried(3)(1, 2), expected);
3879       assert.deepEqual(curried(2, 3)(1), expected);
3880       assert.deepEqual(curried(1, 2, 3), expected);
3881     });
3882
3883     QUnit.test('should coerce `arity` to an integer', function(assert) {
3884       assert.expect(2);
3885
3886       var values = ['0', 0.6, 'xyz'],
3887           expected = lodashStable.map(values, alwaysEmptyArray);
3888
3889       var actual = lodashStable.map(values, function(arity) {
3890         return _.curryRight(fn, arity)();
3891       });
3892
3893       assert.deepEqual(actual, expected);
3894       assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
3895     });
3896
3897     QUnit.test('should support placeholders', function(assert) {
3898       assert.expect(4);
3899
3900       var curried = _.curryRight(fn),
3901           expected = [1, 2, 3, 4],
3902           ph = curried.placeholder;
3903
3904       assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
3905       assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
3906       assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
3907       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
3908     });
3909
3910     QUnit.test('should persist placeholders', function(assert) {
3911       assert.expect(1);
3912
3913       var curried = _.curryRight(fn),
3914           ph = curried.placeholder,
3915           actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
3916
3917       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3918     });
3919
3920     QUnit.test('should use `_.placeholder` when set', function(assert) {
3921       assert.expect(1);
3922
3923       if (!isModularize) {
3924         var curried = _.curryRight(fn),
3925             _ph = _.placeholder = {},
3926             ph = curried.placeholder;
3927
3928         assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
3929         delete _.placeholder;
3930       }
3931       else {
3932         skipAssert(assert);
3933       }
3934     });
3935
3936     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3937       assert.expect(3);
3938
3939       var curried = _.curryRight(fn, 3);
3940       assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
3941       assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
3942       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3943     });
3944
3945     QUnit.test('should create a function with a `length` of `0`', function(assert) {
3946       assert.expect(6);
3947
3948       lodashStable.times(2, function(index) {
3949         var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
3950         assert.strictEqual(curried.length, 0);
3951         assert.strictEqual(curried(4).length, 0);
3952         assert.strictEqual(curried(3, 4).length, 0);
3953       });
3954     });
3955
3956     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3957       assert.expect(2);
3958
3959       function Foo(value) {
3960         return value && object;
3961       }
3962
3963       var curried = _.curryRight(Foo),
3964           object = {};
3965
3966       assert.ok(new curried(false) instanceof Foo);
3967       assert.strictEqual(new curried(true), object);
3968     });
3969
3970     QUnit.test('should not set a `this` binding', function(assert) {
3971       assert.expect(9);
3972
3973       var fn = function(a, b, c) {
3974         var value = this || {};
3975         return [value[a], value[b], value[c]];
3976       };
3977
3978       var object = { 'a': 1, 'b': 2, 'c': 3 },
3979           expected = [1, 2, 3];
3980
3981       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
3982       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
3983       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3984
3985       assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
3986       assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
3987       assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
3988
3989       object.curried = _.curryRight(fn);
3990       assert.deepEqual(object.curried('c')('b')('a'), Array(3));
3991       assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
3992       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3993     });
3994
3995     QUnit.test('should work with partialed methods', function(assert) {
3996       assert.expect(2);
3997
3998       var curried = _.curryRight(fn),
3999           expected = [1, 2, 3, 4];
4000
4001       var a = _.partialRight(curried, 4),
4002           b = _.partialRight(a, 3),
4003           c = _.bind(b, null, 1),
4004           d = _.partial(b(2), 1);
4005
4006       assert.deepEqual(c(2), expected);
4007       assert.deepEqual(d(), expected);
4008     });
4009   }());
4010
4011   /*--------------------------------------------------------------------------*/
4012
4013   QUnit.module('curry methods');
4014
4015   lodashStable.each(['curry', 'curryRight'], function(methodName) {
4016     var func = _[methodName],
4017         fn = function(a, b) { return slice.call(arguments); },
4018         isCurry = methodName == 'curry';
4019
4020     QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
4021       assert.expect(1);
4022
4023       function run(a, b) {
4024         return a + b;
4025       }
4026
4027       var curried = func(run);
4028
4029       try {
4030         var actual = curried(1)(2);
4031       } catch (e) {}
4032
4033       assert.strictEqual(actual, 3);
4034     });
4035
4036     QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
4037       assert.expect(1);
4038
4039       var curried = _.curry(function hasOwnProperty(a, b, c) {
4040         return [a, b, c];
4041       });
4042
4043       var expected = [1, 2, 3];
4044
4045       assert.deepEqual(curried(1)(2)(3), expected);
4046     });
4047
4048     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
4049       assert.expect(2);
4050
4051       var array = [fn, fn, fn],
4052           object = { 'a': fn, 'b': fn, 'c': fn };
4053
4054       lodashStable.each([array, object], function(collection) {
4055         var curries = lodashStable.map(collection, func),
4056             expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
4057
4058         var actual = lodashStable.map(curries, function(curried) {
4059           return curried('a')('b');
4060         });
4061
4062         assert.deepEqual(actual, expected);
4063       });
4064     });
4065   });
4066
4067   /*--------------------------------------------------------------------------*/
4068
4069   QUnit.module('lodash.debounce');
4070
4071   (function() {
4072     QUnit.test('should debounce a function', function(assert) {
4073       assert.expect(6);
4074
4075       var done = assert.async();
4076
4077       var callCount = 0;
4078
4079       var debounced = _.debounce(function(value) {
4080         ++callCount;
4081         return value;
4082       }, 32);
4083
4084       var actual = [debounced(0), debounced(1), debounced(2)];
4085       assert.deepEqual(actual, [undefined, undefined, undefined]);
4086       assert.strictEqual(callCount, 0);
4087
4088       setTimeout(function() {
4089         assert.strictEqual(callCount, 1);
4090
4091         var actual = [debounced(3), debounced(4), debounced(5)];
4092         assert.deepEqual(actual, [2, 2, 2]);
4093         assert.strictEqual(callCount, 1);
4094       }, 128);
4095
4096       setTimeout(function() {
4097         assert.strictEqual(callCount, 2);
4098         done();
4099       }, 256);
4100     });
4101
4102     QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
4103       assert.expect(2);
4104
4105       var done = assert.async();
4106
4107       var debounced = _.debounce(identity, 32);
4108       debounced('x');
4109
4110       setTimeout(function() {
4111         assert.notEqual(debounced('y'), 'y');
4112       }, 64);
4113
4114       setTimeout(function() {
4115         assert.notEqual(debounced('z'), 'z');
4116         done();
4117       }, 128);
4118     });
4119
4120     QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) {
4121       assert.expect(2);
4122
4123       var done = assert.async();
4124
4125       var callCount = 0,
4126           debounced = _.debounce(function() { ++callCount; }, 0);
4127
4128       debounced();
4129       debounced();
4130       assert.strictEqual(callCount, 0);
4131
4132       setTimeout(function() {
4133         assert.strictEqual(callCount, 1);
4134         done();
4135       }, 5);
4136     });
4137
4138     QUnit.test('should apply default options', function(assert) {
4139       assert.expect(2);
4140
4141       var done = assert.async();
4142
4143       var callCount = 0,
4144           debounced = _.debounce(function() { callCount++; }, 32, {});
4145
4146       debounced();
4147       assert.strictEqual(callCount, 0);
4148
4149       setTimeout(function() {
4150         assert.strictEqual(callCount, 1);
4151         done();
4152       }, 64);
4153     });
4154
4155     QUnit.test('should support a `leading` option', function(assert) {
4156       assert.expect(4);
4157
4158       var done = assert.async();
4159
4160       var callCounts = [0, 0];
4161
4162       var withLeading = _.debounce(function() {
4163         callCounts[0]++;
4164       }, 32, { 'leading': true });
4165
4166       var withLeadingAndTrailing = _.debounce(function() {
4167         callCounts[1]++;
4168       }, 32, { 'leading': true });
4169
4170       withLeading();
4171       assert.strictEqual(callCounts[0], 1);
4172
4173       withLeadingAndTrailing();
4174       withLeadingAndTrailing();
4175       assert.strictEqual(callCounts[1], 1);
4176
4177       setTimeout(function() {
4178         assert.deepEqual(callCounts, [1, 2]);
4179
4180         withLeading();
4181         assert.strictEqual(callCounts[0], 2);
4182
4183         done();
4184       }, 64);
4185     });
4186
4187     QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) {
4188       assert.expect(2);
4189
4190       var done = assert.async();
4191
4192       var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
4193           result = [debounced('x'), debounced('y')];
4194
4195       assert.deepEqual(result, ['x', 'x']);
4196
4197       setTimeout(function() {
4198         var result = [debounced('a'), debounced('b')];
4199         assert.deepEqual(result, ['a', 'a']);
4200         done();
4201       }, 64);
4202     });
4203
4204     QUnit.test('should support a `trailing` option', function(assert) {
4205       assert.expect(4);
4206
4207       var done = assert.async();
4208
4209       var withCount = 0,
4210           withoutCount = 0;
4211
4212       var withTrailing = _.debounce(function() {
4213         withCount++;
4214       }, 32, { 'trailing': true });
4215
4216       var withoutTrailing = _.debounce(function() {
4217         withoutCount++;
4218       }, 32, { 'trailing': false });
4219
4220       withTrailing();
4221       assert.strictEqual(withCount, 0);
4222
4223       withoutTrailing();
4224       assert.strictEqual(withoutCount, 0);
4225
4226       setTimeout(function() {
4227         assert.strictEqual(withCount, 1);
4228         assert.strictEqual(withoutCount, 0);
4229         done();
4230       }, 64);
4231     });
4232
4233     QUnit.test('should support a `maxWait` option', function(assert) {
4234       assert.expect(4);
4235
4236       var done = assert.async();
4237
4238       var callCount = 0;
4239
4240       var debounced = _.debounce(function(value) {
4241         ++callCount;
4242         return value;
4243       }, 32, { 'maxWait': 64 });
4244
4245       debounced();
4246       debounced();
4247       assert.strictEqual(callCount, 0);
4248
4249       setTimeout(function() {
4250         assert.strictEqual(callCount, 1);
4251         debounced();
4252         debounced();
4253         assert.strictEqual(callCount, 1);
4254       }, 128);
4255
4256       setTimeout(function() {
4257         assert.strictEqual(callCount, 2);
4258         done();
4259       }, 256);
4260     });
4261
4262     QUnit.test('should support `maxWait` in a tight loop', function(assert) {
4263       assert.expect(1);
4264
4265       var done = assert.async();
4266
4267       var limit = (argv || isPhantom) ? 1000 : 320,
4268           withCount = 0,
4269           withoutCount = 0;
4270
4271       var withMaxWait = _.debounce(function() {
4272         withCount++;
4273       }, 64, { 'maxWait': 128 });
4274
4275       var withoutMaxWait = _.debounce(function() {
4276         withoutCount++;
4277       }, 96);
4278
4279       var start = +new Date;
4280       while ((new Date - start) < limit) {
4281         withMaxWait();
4282         withoutMaxWait();
4283       }
4284       var actual = [Boolean(withoutCount), Boolean(withCount)];
4285       setTimeout(function() {
4286         assert.deepEqual(actual, [false, true]);
4287         done();
4288       }, 1);
4289     });
4290
4291     QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) {
4292       assert.expect(1);
4293
4294       var done = assert.async();
4295
4296       var callCount = 0;
4297
4298       var debounced = _.debounce(function() {
4299         ++callCount;
4300       }, 64, { 'maxWait': 64 });
4301
4302       debounced();
4303
4304       lodashStable.times(20, function(index) {
4305         setTimeout(debounced, 54 + index);
4306       });
4307
4308       setTimeout(function() {
4309         assert.strictEqual(callCount, 2);
4310         done();
4311       }, 160);
4312     });
4313
4314     QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
4315       assert.expect(2);
4316
4317       var done = assert.async();
4318
4319       var callCount = 0;
4320
4321       var debounced = _.debounce(function() {
4322         callCount++;
4323       }, 32, { 'maxWait': 64 });
4324
4325       debounced();
4326
4327       setTimeout(function() {
4328         debounced();
4329         assert.strictEqual(callCount, 1);
4330       }, 128);
4331
4332       setTimeout(function() {
4333         assert.strictEqual(callCount, 2);
4334         done();
4335       }, 192);
4336     });
4337
4338     QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) {
4339       assert.expect(2);
4340
4341       var done = assert.async();
4342
4343       var actual,
4344           callCount = 0,
4345           object = {};
4346
4347       var debounced = _.debounce(function(value) {
4348         actual = [this];
4349         push.apply(actual, arguments);
4350         return ++callCount != 2;
4351       }, 32, { 'leading': true, 'maxWait': 64 });
4352
4353       while (true) {
4354         if (!debounced.call(object, 'a')) {
4355           break;
4356         }
4357       }
4358       setTimeout(function() {
4359         assert.strictEqual(callCount, 2);
4360         assert.deepEqual(actual, [object, 'a']);
4361         done();
4362       }, 64);
4363     });
4364   }());
4365
4366   /*--------------------------------------------------------------------------*/
4367
4368   QUnit.module('lodash.deburr');
4369
4370   (function() {
4371     QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
4372       assert.expect(1);
4373
4374       var actual = lodashStable.map(burredLetters, _.deburr);
4375       assert.deepEqual(actual, deburredLetters);
4376     });
4377
4378     QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
4379       assert.expect(1);
4380
4381       var operators = ['\xd7', '\xf7'],
4382           actual = lodashStable.map(operators, _.deburr);
4383
4384       assert.deepEqual(actual, operators);
4385     });
4386
4387     QUnit.test('should deburr combining diacritical marks', function(assert) {
4388       assert.expect(1);
4389
4390       var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
4391
4392       var actual = lodashStable.map(comboMarks, function(chr) {
4393         return _.deburr('e' + chr + 'i');
4394       });
4395
4396       assert.deepEqual(actual, expected);
4397     });
4398   }());
4399
4400   /*--------------------------------------------------------------------------*/
4401
4402   QUnit.module('lodash.defaults');
4403
4404   (function() {
4405     QUnit.test('should assign source properties if missing on `object`', function(assert) {
4406       assert.expect(1);
4407
4408       assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
4409     });
4410
4411     QUnit.test('should accept multiple sources', function(assert) {
4412       assert.expect(2);
4413
4414       var expected = { 'a': 1, 'b': 2, 'c': 3 };
4415       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
4416       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
4417     });
4418
4419     QUnit.test('should not overwrite `null` values', function(assert) {
4420       assert.expect(1);
4421
4422       var actual = _.defaults({ 'a': null }, { 'a': 1 });
4423       assert.strictEqual(actual.a, null);
4424     });
4425
4426     QUnit.test('should overwrite `undefined` values', function(assert) {
4427       assert.expect(1);
4428
4429       var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
4430       assert.strictEqual(actual.a, 1);
4431     });
4432
4433     QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
4434       assert.expect(2);
4435
4436       var object = {
4437         'constructor': objectProto.constructor,
4438         'hasOwnProperty': objectProto.hasOwnProperty,
4439         'isPrototypeOf': objectProto.isPrototypeOf,
4440         'propertyIsEnumerable': objectProto.propertyIsEnumerable,
4441         'toLocaleString': objectProto.toLocaleString,
4442         'toString': objectProto.toString,
4443         'valueOf': objectProto.valueOf
4444       };
4445
4446       var source = {
4447         'constructor': 1,
4448         'hasOwnProperty': 2,
4449         'isPrototypeOf': 3,
4450         'propertyIsEnumerable': 4,
4451         'toLocaleString': 5,
4452         'toString': 6,
4453         'valueOf': 7
4454       };
4455
4456       assert.deepEqual(_.defaults({}, source), source);
4457       assert.deepEqual(_.defaults({}, object, source), object);
4458     });
4459   }());
4460
4461   /*--------------------------------------------------------------------------*/
4462
4463   QUnit.module('lodash.defaultsDeep');
4464
4465   (function() {
4466     QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
4467       assert.expect(1);
4468
4469       var object = { 'a': { 'b': 2 }, 'd': 4 },
4470           source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 },
4471           expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
4472
4473       assert.deepEqual(_.defaultsDeep(object, source), expected);
4474     });
4475
4476     QUnit.test('should accept multiple sources', function(assert) {
4477       assert.expect(2);
4478
4479       var source1 = { 'a': { 'b': 3 } },
4480           source2 = { 'a': { 'c': 3 } },
4481           source3 = { 'a': { 'b': 3, 'c': 3 } },
4482           source4 = { 'a': { 'c': 4 } },
4483           expected = { 'a': { 'b': 2, 'c': 3 } };
4484
4485       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
4486       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
4487     });
4488
4489     QUnit.test('should not overwrite `null` values', function(assert) {
4490       assert.expect(1);
4491
4492       var object = { 'a': { 'b': null } },
4493           source = { 'a': { 'b': 2 } },
4494           actual = _.defaultsDeep(object, source);
4495
4496       assert.strictEqual(actual.a.b, null);
4497     });
4498
4499     QUnit.test('should not overwrite regexp values', function(assert) {
4500       assert.expect(1);
4501
4502       var object = { 'a': { 'b': /x/ } },
4503           source = { 'a': { 'b': /y/ } },
4504           actual = _.defaultsDeep(object, source);
4505
4506       assert.deepEqual(actual.a.b, /x/);
4507     });
4508
4509     QUnit.test('should not convert function properties to objects', function(assert) {
4510       assert.expect(2);
4511
4512       var actual = _.defaultsDeep({}, { 'a': noop });
4513       assert.strictEqual(actual.a, noop);
4514
4515       actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
4516       assert.strictEqual(actual.a.b, noop);
4517     });
4518
4519     QUnit.test('should overwrite `undefined` values', function(assert) {
4520       assert.expect(1);
4521
4522       var object = { 'a': { 'b': undefined } },
4523           source = { 'a': { 'b': 2 } },
4524           actual = _.defaultsDeep(object, source);
4525
4526       assert.strictEqual(actual.a.b, 2);
4527     });
4528
4529     QUnit.test('should merge sources containing circular references', function(assert) {
4530       assert.expect(2);
4531
4532       var object = {
4533         'foo': { 'b': { 'c': { 'd': {} } } },
4534         'bar': { 'a': 2 }
4535       };
4536
4537       var source = {
4538         'foo': { 'b': { 'c': { 'd': {} } } },
4539         'bar': {}
4540       };
4541
4542       object.foo.b.c.d = object;
4543       source.foo.b.c.d = source;
4544       source.bar.b = source.foo.b;
4545
4546       var actual = _.defaultsDeep(object, source);
4547
4548       assert.strictEqual(actual.bar.b, actual.foo.b);
4549       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
4550     });
4551
4552     QUnit.test('should not modify sources', function(assert) {
4553       assert.expect(3);
4554
4555       var source1 = { 'a': 1, 'b': { 'c': 2 } },
4556           source2 = { 'b': { 'c': 3, 'd': 3 } },
4557           actual = _.defaultsDeep({}, source1, source2);
4558
4559       assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4560       assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4561       assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4562     });
4563
4564     QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4565       assert.expect(1);
4566
4567       var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4568       assert.deepEqual(actual, { 'a': ['abc'] });
4569     });
4570   }());
4571
4572   /*--------------------------------------------------------------------------*/
4573
4574   QUnit.module('lodash.defer');
4575
4576   (function() {
4577     QUnit.test('should defer `func` execution', function(assert) {
4578       assert.expect(1);
4579
4580       var done = assert.async();
4581
4582       var pass = false;
4583       _.defer(function() { pass = true; });
4584
4585       setTimeout(function() {
4586         assert.ok(pass);
4587         done();
4588       }, 32);
4589     });
4590
4591     QUnit.test('should provide additional arguments to `func`', function(assert) {
4592       assert.expect(1);
4593
4594       var done = assert.async();
4595
4596       var args;
4597
4598       _.defer(function() {
4599         args = slice.call(arguments);
4600       }, 1, 2);
4601
4602       setTimeout(function() {
4603         assert.deepEqual(args, [1, 2]);
4604         done();
4605       }, 32);
4606     });
4607
4608     QUnit.test('should be cancelable', function(assert) {
4609       assert.expect(1);
4610
4611       var done = assert.async();
4612
4613       var pass = true;
4614
4615       var timerId = _.defer(function() {
4616         pass = false;
4617       });
4618
4619       clearTimeout(timerId);
4620
4621       setTimeout(function() {
4622         assert.ok(pass);
4623         done();
4624       }, 32);
4625     });
4626   }());
4627
4628   /*--------------------------------------------------------------------------*/
4629
4630   QUnit.module('lodash.delay');
4631
4632   (function() {
4633     QUnit.test('should delay `func` execution', function(assert) {
4634       assert.expect(2);
4635
4636       var done = assert.async();
4637
4638       var pass = false;
4639       _.delay(function() { pass = true; }, 32);
4640
4641       setTimeout(function() {
4642         assert.notOk(pass);
4643       }, 1);
4644
4645       setTimeout(function() {
4646         assert.ok(pass);
4647         done();
4648       }, 64);
4649     });
4650
4651     QUnit.test('should provide additional arguments to `func`', function(assert) {
4652       assert.expect(1);
4653
4654       var done = assert.async();
4655
4656       var args;
4657
4658       _.delay(function() {
4659         args = slice.call(arguments);
4660       }, 32, 1, 2);
4661
4662       setTimeout(function() {
4663         assert.deepEqual(args, [1, 2]);
4664         done();
4665       }, 64);
4666     });
4667
4668     QUnit.test('should use a default `wait` of `0`', function(assert) {
4669       assert.expect(2);
4670
4671       var done = assert.async();
4672
4673       var pass = false;
4674
4675       _.delay(function() {
4676         pass = true;
4677       });
4678
4679       assert.notOk(pass);
4680
4681       setTimeout(function() {
4682         assert.ok(pass);
4683         done();
4684       }, 0);
4685     });
4686
4687     QUnit.test('should be cancelable', function(assert) {
4688       assert.expect(1);
4689
4690       var done = assert.async();
4691
4692       var pass = true;
4693
4694       var timerId = _.delay(function() {
4695         pass = false;
4696       }, 32);
4697
4698       clearTimeout(timerId);
4699
4700       setTimeout(function() {
4701         assert.ok(pass);
4702         done();
4703       }, 64);
4704     });
4705   }());
4706
4707   /*--------------------------------------------------------------------------*/
4708
4709   QUnit.module('difference methods');
4710
4711   lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4712     var args = (function() { return arguments; }(1, 2, 3)),
4713         func = _[methodName];
4714
4715     QUnit.test('`_.' + methodName + '` should return the difference of the given arrays', function(assert) {
4716       assert.expect(2);
4717
4718       var actual = func([1, 2, 3, 4, 5], [5, 2, 10]);
4719       assert.deepEqual(actual, [1, 3, 4]);
4720
4721       actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]);
4722       assert.deepEqual(actual, [1, 3]);
4723     });
4724
4725     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
4726       assert.expect(2);
4727
4728       var array = [-0, 0];
4729
4730       var actual = lodashStable.map(array, function(value) {
4731         return func(array, [value]);
4732       });
4733
4734       assert.deepEqual(actual, [[], []]);
4735
4736       actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
4737       assert.deepEqual(actual, ['0']);
4738     });
4739
4740     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4741       assert.expect(1);
4742
4743       assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4744     });
4745
4746     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4747       assert.expect(1);
4748
4749       var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4750           array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4751           a = {},
4752           b = {},
4753           c = {};
4754
4755       array1.push(a, b, c);
4756       array2.push(b, c, a);
4757
4758       assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4759     });
4760
4761     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
4762       assert.expect(2);
4763
4764       var array = [-0, 0];
4765
4766       var actual = lodashStable.map(array, function(value) {
4767         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
4768         return func(array, largeArray);
4769       });
4770
4771       assert.deepEqual(actual, [[], []]);
4772
4773       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne);
4774       actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
4775       assert.deepEqual(actual, ['0']);
4776     });
4777
4778     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4779       assert.expect(1);
4780
4781       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
4782       assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4783     });
4784
4785     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4786       assert.expect(1);
4787
4788       var object1 = {},
4789           object2 = {},
4790           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4791
4792       assert.deepEqual(func([object1, object2], largeArray), [object2]);
4793     });
4794
4795     QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4796       assert.expect(3);
4797
4798       var array = [1, null, 3];
4799
4800       assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4801       assert.deepEqual(func(null, array, 1), []);
4802       assert.deepEqual(func(array, args, null), [null]);
4803     });
4804   });
4805
4806   /*--------------------------------------------------------------------------*/
4807
4808   QUnit.module('lodash.differenceBy');
4809
4810   (function() {
4811     QUnit.test('should accept an `iteratee` argument', function(assert) {
4812       assert.expect(2);
4813
4814       var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
4815       assert.deepEqual(actual, [3.1, 1.3]);
4816
4817       actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4818       assert.deepEqual(actual, [{ 'x': 2 }]);
4819     });
4820
4821     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
4822       assert.expect(1);
4823
4824       var args;
4825
4826       _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() {
4827         args || (args = slice.call(arguments));
4828       });
4829
4830       assert.deepEqual(args, [4.4]);
4831     });
4832   }());
4833
4834   /*--------------------------------------------------------------------------*/
4835
4836   QUnit.module('lodash.differenceWith');
4837
4838   (function() {
4839     QUnit.test('should work with a `comparator` argument', function(assert) {
4840       assert.expect(1);
4841
4842       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
4843           actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
4844
4845       assert.deepEqual(actual, [objects[1]]);
4846     });
4847
4848     QUnit.test('should preserve the sign of `0`', function(assert) {
4849       assert.expect(1);
4850
4851       var array = [-0, 1],
4852           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne),
4853           others = [[1], largeArray],
4854           expected = lodashStable.map(others, lodashStable.constant(['-0']));
4855
4856       var actual = lodashStable.map(others, function(other) {
4857         return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
4858       });
4859
4860       assert.deepEqual(actual, expected);
4861     });
4862   }());
4863
4864   /*--------------------------------------------------------------------------*/
4865
4866   QUnit.module('lodash.divide');
4867
4868   (function() {
4869     QUnit.test('should divide two numbers', function(assert) {
4870       assert.expect(3);
4871
4872       assert.strictEqual(_.divide(6, 4), 1.5);
4873       assert.strictEqual(_.divide(-6, 4), -1.5);
4874       assert.strictEqual(_.divide(-6, -4), 1.5);
4875     });
4876
4877     QUnit.test('should coerce arguments to numbers', function(assert) {
4878       assert.expect(2);
4879
4880       assert.strictEqual(_.divide('6', '4'), 1.5);
4881       assert.deepEqual(_.divide('x', 'y'), NaN);
4882     });
4883   }());
4884
4885   /*--------------------------------------------------------------------------*/
4886
4887   QUnit.module('lodash.drop');
4888
4889   (function() {
4890     var array = [1, 2, 3];
4891
4892     QUnit.test('should drop the first two elements', function(assert) {
4893       assert.expect(1);
4894
4895       assert.deepEqual(_.drop(array, 2), [3]);
4896     });
4897
4898     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4899       assert.expect(1);
4900
4901       var expected = lodashStable.map(falsey, function(value) {
4902         return value === undefined ? [2, 3] : array;
4903       });
4904
4905       var actual = lodashStable.map(falsey, function(n) {
4906         return _.drop(array, n);
4907       });
4908
4909       assert.deepEqual(actual, expected);
4910     });
4911
4912     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4913       assert.expect(3);
4914
4915       lodashStable.each([0, -1, -Infinity], function(n) {
4916         assert.deepEqual(_.drop(array, n), array);
4917       });
4918     });
4919
4920     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4921       assert.expect(4);
4922
4923       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4924         assert.deepEqual(_.drop(array, n), []);
4925       });
4926     });
4927
4928     QUnit.test('should coerce `n` to an integer', function(assert) {
4929       assert.expect(1);
4930
4931       assert.deepEqual(_.drop(array, 1.6), [2, 3]);
4932     });
4933
4934     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4935       assert.expect(1);
4936
4937       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4938           actual = lodashStable.map(array, _.drop);
4939
4940       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
4941     });
4942
4943     QUnit.test('should work in a lazy sequence', function(assert) {
4944       assert.expect(6);
4945
4946       if (!isNpm) {
4947         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4948             predicate = function(value) { values.push(value); return isEven(value); },
4949             values = [],
4950             actual = _(array).drop(2).drop().value();
4951
4952         assert.deepEqual(actual, array.slice(3));
4953
4954         actual = _(array).filter(predicate).drop(2).drop().value();
4955         assert.deepEqual(values, array);
4956         assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
4957
4958         actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
4959         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
4960
4961         values = [];
4962
4963         actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
4964         assert.deepEqual(values, array.slice(1));
4965         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
4966       }
4967       else {
4968         skipAssert(assert, 6);
4969       }
4970     });
4971   }());
4972
4973   /*--------------------------------------------------------------------------*/
4974
4975   QUnit.module('lodash.dropRight');
4976
4977   (function() {
4978     var array = [1, 2, 3];
4979
4980     QUnit.test('should drop the last two elements', function(assert) {
4981       assert.expect(1);
4982
4983       assert.deepEqual(_.dropRight(array, 2), [1]);
4984     });
4985
4986     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4987       assert.expect(1);
4988
4989       var expected = lodashStable.map(falsey, function(value) {
4990         return value === undefined ? [1, 2] : array;
4991       });
4992
4993       var actual = lodashStable.map(falsey, function(n) {
4994         return _.dropRight(array, n);
4995       });
4996
4997       assert.deepEqual(actual, expected);
4998     });
4999
5000     QUnit.test('should return all elements when `n` < `1`', function(assert) {
5001       assert.expect(3);
5002
5003       lodashStable.each([0, -1, -Infinity], function(n) {
5004         assert.deepEqual(_.dropRight(array, n), array);
5005       });
5006     });
5007
5008     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
5009       assert.expect(4);
5010
5011       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5012         assert.deepEqual(_.dropRight(array, n), []);
5013       });
5014     });
5015
5016     QUnit.test('should coerce `n` to an integer', function(assert) {
5017       assert.expect(1);
5018
5019       assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
5020     });
5021
5022     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5023       assert.expect(1);
5024
5025       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5026           actual = lodashStable.map(array, _.dropRight);
5027
5028       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
5029     });
5030
5031     QUnit.test('should work in a lazy sequence', function(assert) {
5032       assert.expect(6);
5033
5034       if (!isNpm) {
5035         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5036             predicate = function(value) { values.push(value); return isEven(value); },
5037             values = [],
5038             actual = _(array).dropRight(2).dropRight().value();
5039
5040         assert.deepEqual(actual, array.slice(0, -3));
5041
5042         actual = _(array).filter(predicate).dropRight(2).dropRight().value();
5043         assert.deepEqual(values, array);
5044         assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
5045
5046         actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
5047         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
5048
5049         values = [];
5050
5051         actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
5052         assert.deepEqual(values, array.slice(0, -1));
5053         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
5054       }
5055       else {
5056         skipAssert(assert, 6);
5057       }
5058     });
5059   }());
5060
5061   /*--------------------------------------------------------------------------*/
5062
5063   QUnit.module('lodash.dropRightWhile');
5064
5065   (function() {
5066     var array = [1, 2, 3, 4];
5067
5068     var objects = [
5069       { 'a': 0, 'b': 0 },
5070       { 'a': 1, 'b': 1 },
5071       { 'a': 2, 'b': 2 }
5072     ];
5073
5074     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5075       assert.expect(1);
5076
5077       var actual = _.dropRightWhile(array, function(n) {
5078         return n > 2;
5079       });
5080
5081       assert.deepEqual(actual, [1, 2]);
5082     });
5083
5084     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5085       assert.expect(1);
5086
5087       var args;
5088
5089       _.dropRightWhile(array, function() {
5090         args = slice.call(arguments);
5091       });
5092
5093       assert.deepEqual(args, [4, 3, array]);
5094     });
5095
5096     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5097       assert.expect(1);
5098
5099       assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
5100     });
5101
5102     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5103       assert.expect(1);
5104
5105       assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
5106     });
5107
5108     QUnit.test('should work with `_.property` shorthands', function(assert) {
5109       assert.expect(1);
5110
5111       assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
5112     });
5113
5114     QUnit.test('should return a wrapped value when chaining', function(assert) {
5115       assert.expect(2);
5116
5117       if (!isNpm) {
5118         var wrapped = _(array).dropRightWhile(function(n) {
5119           return n > 2;
5120         });
5121
5122         assert.ok(wrapped instanceof _);
5123         assert.deepEqual(wrapped.value(), [1, 2]);
5124       }
5125       else {
5126         skipAssert(assert, 2);
5127       }
5128     });
5129   }());
5130
5131   /*--------------------------------------------------------------------------*/
5132
5133   QUnit.module('lodash.dropWhile');
5134
5135   (function() {
5136     var array = [1, 2, 3, 4];
5137
5138     var objects = [
5139       { 'a': 2, 'b': 2 },
5140       { 'a': 1, 'b': 1 },
5141       { 'a': 0, 'b': 0 }
5142     ];
5143
5144     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5145       assert.expect(1);
5146
5147       var actual = _.dropWhile(array, function(n) {
5148         return n < 3;
5149       });
5150
5151       assert.deepEqual(actual, [3, 4]);
5152     });
5153
5154     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5155       assert.expect(1);
5156
5157       var args;
5158
5159       _.dropWhile(array, function() {
5160         args = slice.call(arguments);
5161       });
5162
5163       assert.deepEqual(args, [1, 0, array]);
5164     });
5165
5166     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5167       assert.expect(1);
5168
5169       assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
5170     });
5171
5172     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5173       assert.expect(1);
5174
5175       assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
5176     });
5177
5178     QUnit.test('should work with `_.property` shorthands', function(assert) {
5179       assert.expect(1);
5180
5181       assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
5182     });
5183
5184     QUnit.test('should work in a lazy sequence', function(assert) {
5185       assert.expect(3);
5186
5187       if (!isNpm) {
5188         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
5189             predicate = function(n) { return n < 3; },
5190             expected = _.dropWhile(array, predicate),
5191             wrapped = _(array).dropWhile(predicate);
5192
5193         assert.deepEqual(wrapped.value(), expected);
5194         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
5195         assert.strictEqual(wrapped.last(), _.last(expected));
5196       }
5197       else {
5198         skipAssert(assert, 3);
5199       }
5200     });
5201
5202     QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
5203       assert.expect(1);
5204
5205       if (!isNpm) {
5206         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
5207
5208         var actual = _(array)
5209           .dropWhile(function(n) { return n == 1; })
5210           .drop()
5211           .dropWhile(function(n) { return n == 3; })
5212           .value();
5213
5214         assert.deepEqual(actual, array.slice(3));
5215       }
5216       else {
5217         skipAssert(assert);
5218       }
5219     });
5220   }());
5221
5222   /*--------------------------------------------------------------------------*/
5223
5224   QUnit.module('lodash.endsWith');
5225
5226   (function() {
5227     var string = 'abc';
5228
5229     QUnit.test('should return `true` if a string ends with `target`', function(assert) {
5230       assert.expect(1);
5231
5232       assert.strictEqual(_.endsWith(string, 'c'), true);
5233     });
5234
5235     QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
5236       assert.expect(1);
5237
5238       assert.strictEqual(_.endsWith(string, 'b'), false);
5239     });
5240
5241     QUnit.test('should work with a `position` argument', function(assert) {
5242       assert.expect(1);
5243
5244       assert.strictEqual(_.endsWith(string, 'b', 2), true);
5245     });
5246
5247     QUnit.test('should work with `position` >= `string.length`', function(assert) {
5248       assert.expect(4);
5249
5250       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5251         assert.strictEqual(_.endsWith(string, 'c', position), true);
5252       });
5253     });
5254
5255     QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5256       assert.expect(1);
5257
5258       var expected = lodashStable.map(falsey, alwaysTrue);
5259
5260       var actual = lodashStable.map(falsey, function(position) {
5261         return _.endsWith(string, position === undefined ? 'c' : '', position);
5262       });
5263
5264       assert.deepEqual(actual, expected);
5265     });
5266
5267     QUnit.test('should treat a negative `position` as `0`', function(assert) {
5268       assert.expect(6);
5269
5270       lodashStable.each([-1, -3, -Infinity], function(position) {
5271         assert.ok(lodashStable.every(string, function(chr) {
5272           return _.endsWith(string, chr, position) === false;
5273         }));
5274         assert.strictEqual(_.endsWith(string, '', position), true);
5275       });
5276     });
5277
5278     QUnit.test('should coerce `position` to an integer', function(assert) {
5279       assert.expect(1);
5280
5281       assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5282     });
5283
5284     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
5285       assert.expect(1);
5286
5287       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5288         return _.endsWith(string, '', position, true);
5289       }));
5290     });
5291   }());
5292
5293   /*--------------------------------------------------------------------------*/
5294
5295   QUnit.module('lodash.eq');
5296
5297   (function() {
5298     QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5299       assert.expect(11);
5300
5301       assert.strictEqual(_.eq(), true);
5302       assert.strictEqual(_.eq(undefined), true);
5303       assert.strictEqual(_.eq(0, -0), true);
5304       assert.strictEqual(_.eq(NaN, NaN), true);
5305       assert.strictEqual(_.eq(1, 1), true);
5306
5307       assert.strictEqual(_.eq(null, undefined), false);
5308       assert.strictEqual(_.eq(1, Object(1)), false);
5309       assert.strictEqual(_.eq(1, '1'), false);
5310       assert.strictEqual(_.eq(1, '1'), false);
5311
5312       var object = { 'a': 1 };
5313       assert.strictEqual(_.eq(object, object), true);
5314       assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5315     });
5316   }());
5317
5318   /*--------------------------------------------------------------------------*/
5319
5320   QUnit.module('lodash.escape');
5321
5322   (function() {
5323     var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
5324         unescaped = '&<>"\'`\/';
5325
5326     escaped += escaped;
5327     unescaped += unescaped;
5328
5329     QUnit.test('should escape values', function(assert) {
5330       assert.expect(1);
5331
5332       assert.strictEqual(_.escape(unescaped), escaped);
5333     });
5334
5335     QUnit.test('should not escape the "/" character', function(assert) {
5336       assert.expect(1);
5337
5338       assert.strictEqual(_.escape('/'), '/');
5339     });
5340
5341     QUnit.test('should handle strings with nothing to escape', function(assert) {
5342       assert.expect(1);
5343
5344       assert.strictEqual(_.escape('abc'), 'abc');
5345     });
5346
5347     QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5348       assert.expect(1);
5349
5350       assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5351     });
5352   }());
5353
5354   /*--------------------------------------------------------------------------*/
5355
5356   QUnit.module('lodash.escapeRegExp');
5357
5358   (function() {
5359     var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5360         unescaped = '^$.*+?()[]{}|\\';
5361
5362     QUnit.test('should escape values', function(assert) {
5363       assert.expect(1);
5364
5365       assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5366     });
5367
5368     QUnit.test('should handle strings with nothing to escape', function(assert) {
5369       assert.expect(1);
5370
5371       assert.strictEqual(_.escapeRegExp('abc'), 'abc');
5372     });
5373
5374     QUnit.test('should return an empty string for empty values', function(assert) {
5375       assert.expect(1);
5376
5377       var values = [, null, undefined, ''],
5378           expected = lodashStable.map(values, alwaysEmptyString);
5379
5380       var actual = lodashStable.map(values, function(value, index) {
5381         return index ? _.escapeRegExp(value) : _.escapeRegExp();
5382       });
5383
5384       assert.deepEqual(actual, expected);
5385     });
5386   }());
5387
5388   /*--------------------------------------------------------------------------*/
5389
5390   QUnit.module('lodash.every');
5391
5392   (function() {
5393     QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5394       assert.expect(1);
5395
5396       assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5397     });
5398
5399     QUnit.test('should return `true` for empty collections', function(assert) {
5400       assert.expect(1);
5401
5402       var expected = lodashStable.map(empties, alwaysTrue);
5403
5404       var actual = lodashStable.map(empties, function(value) {
5405         try {
5406           return _.every(value, identity);
5407         } catch (e) {}
5408       });
5409
5410       assert.deepEqual(actual, expected);
5411     });
5412
5413     QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5414       assert.expect(2);
5415
5416       var count = 0;
5417
5418       assert.strictEqual(_.every([true, null, true], function(value) {
5419         count++;
5420         return value;
5421       }), false);
5422
5423       assert.strictEqual(count, 2);
5424     });
5425
5426     QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5427       assert.expect(1);
5428
5429       assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5430     });
5431
5432     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5433       assert.expect(2);
5434
5435       var values = [, null, undefined],
5436           expected = lodashStable.map(values, alwaysFalse);
5437
5438       var actual = lodashStable.map(values, function(value, index) {
5439         var array = [0];
5440         return index ? _.every(array, value) : _.every(array);
5441       });
5442
5443       assert.deepEqual(actual, expected);
5444
5445       expected = lodashStable.map(values, alwaysTrue);
5446       actual = lodashStable.map(values, function(value, index) {
5447         var array = [1];
5448         return index ? _.every(array, value) : _.every(array);
5449       });
5450
5451       assert.deepEqual(actual, expected);
5452     });
5453
5454     QUnit.test('should work with `_.property` shorthands', function(assert) {
5455       assert.expect(2);
5456
5457       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5458       assert.strictEqual(_.every(objects, 'a'), false);
5459       assert.strictEqual(_.every(objects, 'b'), true);
5460     });
5461
5462     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5463       assert.expect(2);
5464
5465       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5466       assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5467       assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5468     });
5469
5470     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5471       assert.expect(1);
5472
5473       var actual = lodashStable.map([[1]], _.every);
5474       assert.deepEqual(actual, [true]);
5475     });
5476   }());
5477
5478   /*--------------------------------------------------------------------------*/
5479
5480   QUnit.module('strict mode checks');
5481
5482   lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
5483     var func = _[methodName],
5484         isBindAll = methodName == 'bindAll';
5485
5486     QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5487       assert.expect(1);
5488
5489       if (freeze) {
5490         var object = freeze({ 'a': undefined, 'b': function() {} }),
5491             pass = !isStrict;
5492
5493         try {
5494           func(object, isBindAll ? 'b' : { 'a': 1 });
5495         } catch (e) {
5496           pass = !pass;
5497         }
5498         assert.ok(pass);
5499       }
5500       else {
5501         skipAssert(assert);
5502       }
5503     });
5504   });
5505
5506   /*--------------------------------------------------------------------------*/
5507
5508   QUnit.module('lodash.fill');
5509
5510   (function() {
5511     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
5512       assert.expect(1);
5513
5514       var array = [1, 2, 3];
5515       assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5516     });
5517
5518     QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5519       assert.expect(2);
5520
5521       var array = [1, 2, 3],
5522           actual = _.fill(array);
5523
5524       assert.deepEqual(actual, Array(3));
5525       assert.ok(lodashStable.every(actual, function(value, index) {
5526         return index in actual;
5527       }));
5528     });
5529
5530     QUnit.test('should work with a positive `start`', function(assert) {
5531       assert.expect(1);
5532
5533       var array = [1, 2, 3];
5534       assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5535     });
5536
5537     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
5538       assert.expect(4);
5539
5540       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5541         var array = [1, 2, 3];
5542         assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5543       });
5544     });
5545
5546     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5547       assert.expect(1);
5548
5549       var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5550
5551       var actual = lodashStable.map(falsey, function(start) {
5552         var array = [1, 2, 3];
5553         return _.fill(array, 'a', start);
5554       });
5555
5556       assert.deepEqual(actual, expected);
5557     });
5558
5559     QUnit.test('should work with a negative `start`', function(assert) {
5560       assert.expect(1);
5561
5562       var array = [1, 2, 3];
5563       assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5564     });
5565
5566     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
5567       assert.expect(3);
5568
5569       lodashStable.each([-3, -4, -Infinity], function(start) {
5570         var array = [1, 2, 3];
5571         assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5572       });
5573     });
5574
5575     QUnit.test('should work with `start` >= `end`', function(assert) {
5576       assert.expect(2);
5577
5578       lodashStable.each([2, 3], function(start) {
5579         var array = [1, 2, 3];
5580         assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5581       });
5582     });
5583
5584     QUnit.test('should work with a positive `end`', function(assert) {
5585       assert.expect(1);
5586
5587       var array = [1, 2, 3];
5588       assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5589     });
5590
5591     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
5592       assert.expect(4);
5593
5594       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5595         var array = [1, 2, 3];
5596         assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5597       });
5598     });
5599
5600     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5601       assert.expect(1);
5602
5603       var expected = lodashStable.map(falsey, function(value) {
5604         return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5605       });
5606
5607       var actual = lodashStable.map(falsey, function(end) {
5608         var array = [1, 2, 3];
5609         return _.fill(array, 'a', 0, end);
5610       });
5611
5612       assert.deepEqual(actual, expected);
5613     });
5614
5615     QUnit.test('should work with a negative `end`', function(assert) {
5616       assert.expect(1);
5617
5618       var array = [1, 2, 3];
5619       assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5620     });
5621
5622     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
5623       assert.expect(3);
5624
5625       lodashStable.each([-3, -4, -Infinity], function(end) {
5626         var array = [1, 2, 3];
5627         assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5628       });
5629     });
5630
5631     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5632       assert.expect(1);
5633
5634       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5635
5636       var actual = lodashStable.map(positions, function(pos) {
5637         var array = [1, 2, 3];
5638         return _.fill.apply(_, [array, 'a'].concat(pos));
5639       });
5640
5641       assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5642     });
5643
5644     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5645       assert.expect(1);
5646
5647       var array = [[1, 2], [3, 4]],
5648           actual = lodashStable.map(array, _.fill);
5649
5650       assert.deepEqual(actual, [[0, 0], [1, 1]]);
5651     });
5652
5653     QUnit.test('should return a wrapped value when chaining', function(assert) {
5654       assert.expect(3);
5655
5656       if (!isNpm) {
5657         var array = [1, 2, 3],
5658             wrapped = _(array).fill('a'),
5659             actual = wrapped.value();
5660
5661         assert.ok(wrapped instanceof _);
5662         assert.deepEqual(actual, ['a', 'a', 'a']);
5663         assert.strictEqual(actual, array);
5664       }
5665       else {
5666         skipAssert(assert, 3);
5667       }
5668     });
5669   }());
5670
5671   /*--------------------------------------------------------------------------*/
5672
5673   QUnit.module('lodash.filter');
5674
5675   (function() {
5676     var array = [1, 2, 3];
5677
5678     QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5679       assert.expect(1);
5680
5681       assert.deepEqual(_.filter(array, isEven), [2]);
5682     });
5683
5684     QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
5685       assert.expect(1);
5686
5687       // Trigger a mobile Safari 8 JIT bug.
5688       // See https://github.com/lodash/lodash/issues/799.
5689       var counter = 0,
5690           object = { '1': 'foo', '8': 'bar', '50': 'baz' };
5691
5692       lodashStable.times(1000, function(assert) {
5693         _.filter([], alwaysTrue);
5694       });
5695
5696       _.filter(object, function() {
5697         counter++;
5698         return true;
5699       });
5700
5701       assert.strictEqual(counter, 3);
5702     });
5703   }());
5704
5705   /*--------------------------------------------------------------------------*/
5706
5707   lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
5708     QUnit.module('lodash.' + methodName);
5709
5710     var func = _[methodName];
5711
5712     (function() {
5713       var objects = [
5714         { 'a': 0, 'b': 0 },
5715         { 'a': 1, 'b': 1 },
5716         { 'a': 2, 'b': 2 }
5717       ];
5718
5719       var expected = ({
5720         'find': [objects[1], undefined, objects[2], objects[1]],
5721         'findLast': [objects[2], undefined, objects[2], objects[2]],
5722         'findIndex': [1, -1, 2, 1],
5723         'findLastIndex': [2, -1, 2, 2],
5724         'findKey': ['1', undefined, '2', '1'],
5725         'findLastKey': ['2', undefined, '2', '2']
5726       })[methodName];
5727
5728       QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
5729         assert.expect(1);
5730
5731         assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5732       });
5733
5734       QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
5735         assert.expect(1);
5736
5737         assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5738       });
5739
5740       QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
5741         assert.expect(1);
5742
5743         assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5744       });
5745
5746       QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
5747         assert.expect(1);
5748
5749         assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5750       });
5751
5752       QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5753         assert.expect(1);
5754
5755         assert.strictEqual(func(objects, 'b'), expected[3]);
5756       });
5757
5758       QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
5759         assert.expect(1);
5760
5761         var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5762             expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5763
5764         var actual = lodashStable.map(emptyValues, function(value) {
5765           try {
5766             return func(value, { 'a': 3 });
5767           } catch (e) {}
5768         });
5769
5770         assert.deepEqual(actual, expecting);
5771       });
5772     }());
5773
5774     (function() {
5775       var array = [1, 2, 3, 4];
5776
5777       var expected = ({
5778         'find': 1,
5779         'findLast': 4,
5780         'findIndex': 0,
5781         'findLastIndex': 3,
5782         'findKey': '0',
5783         'findLastKey': '3'
5784       })[methodName];
5785
5786       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5787         assert.expect(1);
5788
5789         if (!isNpm) {
5790           assert.strictEqual(_(array)[methodName](), expected);
5791         }
5792         else {
5793           skipAssert(assert);
5794         }
5795       });
5796
5797       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5798         assert.expect(1);
5799
5800         if (!isNpm) {
5801           assert.ok(_(array).chain()[methodName]() instanceof _);
5802         }
5803         else {
5804           skipAssert(assert);
5805         }
5806       });
5807
5808       QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
5809         assert.expect(1);
5810
5811         if (!isNpm) {
5812           var wrapped = _(array).chain()[methodName]();
5813           assert.strictEqual(wrapped.__wrapped__, array);
5814         }
5815         else {
5816           skipAssert(assert);
5817         }
5818       });
5819
5820       QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
5821         assert.expect(2);
5822
5823         if (!isNpm) {
5824           var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5825               smallArray = array;
5826
5827           lodashStable.times(2, function(index) {
5828             var array = index ? largeArray : smallArray,
5829                 wrapped = _(array).filter(isEven);
5830
5831             assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5832           });
5833         }
5834         else {
5835           skipAssert(assert, 2);
5836         }
5837       });
5838     }());
5839
5840     (function() {
5841       var expected = ({
5842         'find': 1,
5843         'findLast': 2,
5844         'findKey': 'a',
5845         'findLastKey': 'b'
5846       })[methodName];
5847
5848       if (expected != null) {
5849         QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
5850           assert.expect(1);
5851
5852           var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
5853             return n < 3;
5854           });
5855
5856           assert.strictEqual(actual, expected);
5857         });
5858       }
5859     }());
5860   });
5861
5862   /*--------------------------------------------------------------------------*/
5863
5864   QUnit.module('lodash.find and lodash.findLast');
5865
5866   lodashStable.each(['find', 'findLast'], function(methodName) {
5867     var isFind = methodName == 'find';
5868
5869     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5870       assert.expect(3);
5871
5872       if (!isNpm) {
5873         var findCount = 0,
5874             mapCount = 0,
5875             array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5876             iteratee = function(value) { mapCount++; return square(value); },
5877             predicate = function(value) { findCount++; return isEven(value); },
5878             actual = _(array).map(iteratee)[methodName](predicate);
5879
5880         assert.strictEqual(findCount, isFind ? 2 : 1);
5881         assert.strictEqual(mapCount, isFind ? 2 : 1);
5882         assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
5883       }
5884       else {
5885         skipAssert(assert, 3);
5886       }
5887     });
5888   });
5889
5890   /*--------------------------------------------------------------------------*/
5891
5892   QUnit.module('lodash.flip');
5893
5894   (function() {
5895     function fn() {
5896       return slice.call(arguments);
5897     }
5898
5899     QUnit.test('should flip arguments provided to `func`', function(assert) {
5900       assert.expect(1);
5901
5902       var flipped = _.flip(fn);
5903       assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
5904     });
5905   }());
5906
5907   /*--------------------------------------------------------------------------*/
5908
5909   QUnit.module('lodash.flatMapDepth');
5910
5911   (function() {
5912     var array = [1, [2, [3, [4]], 5]];
5913
5914     QUnit.test('should use a default `depth` of `1`', function(assert) {
5915       assert.expect(1);
5916
5917       assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
5918     });
5919
5920     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
5921       assert.expect(1);
5922
5923       var values = [, null, undefined],
5924           expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
5925
5926       var actual = lodashStable.map(values, function(value, index) {
5927         return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
5928       });
5929
5930       assert.deepEqual(actual, expected);
5931     });
5932
5933     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
5934       assert.expect(2);
5935
5936       lodashStable.each([-1, 0], function(depth) {
5937         assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
5938       });
5939     });
5940
5941     QUnit.test('should coerce `depth` to an integer', function(assert) {
5942       assert.expect(1);
5943
5944       assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
5945     });
5946   }());
5947
5948   /*--------------------------------------------------------------------------*/
5949
5950   QUnit.module('flatMap methods');
5951
5952   lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
5953     var func = _[methodName],
5954         array = [1, 2, 3, 4];
5955
5956     function duplicate(n) {
5957       return [n, n];
5958     }
5959
5960     QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
5961       assert.expect(1);
5962
5963       var actual = func(array, duplicate),
5964           expected = lodashStable.flatten(lodashStable.map(array, duplicate));
5965
5966       assert.deepEqual(actual, expected);
5967     });
5968
5969     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5970       assert.expect(1);
5971
5972       var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
5973       assert.deepEqual(func(objects, 'a'), array);
5974     });
5975
5976     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
5977       assert.expect(1);
5978
5979       function Foo() {
5980         this.a = [1, 2];
5981       }
5982       Foo.prototype.b = [3, 4];
5983
5984       var actual = func(new Foo, identity);
5985       assert.deepEqual(actual, [1, 2]);
5986     });
5987
5988     QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
5989       assert.expect(2);
5990
5991       var array = [[1, 2], [3, 4]],
5992           object = { 'a': [1, 2], 'b': [3, 4] },
5993           values = [, null, undefined],
5994           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
5995
5996       lodashStable.each([array, object], function(collection) {
5997         var actual = lodashStable.map(values, function(value, index) {
5998           return index ? func(collection, value) : func(collection);
5999         });
6000
6001         assert.deepEqual(actual, expected);
6002       });
6003     });
6004
6005     QUnit.test('`_.' + methodName + '` should accept a falsey `collection` argument', function(assert) {
6006       assert.expect(1);
6007
6008       var expected = lodashStable.map(falsey, alwaysEmptyArray);
6009
6010       var actual = lodashStable.map(falsey, function(collection, index) {
6011         try {
6012           return index ? func(collection) : func();
6013         } catch (e) {}
6014       });
6015
6016       assert.deepEqual(actual, expected);
6017     });
6018
6019     QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
6020       assert.expect(1);
6021
6022       assert.deepEqual(func(1), []);
6023     });
6024
6025     QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
6026       assert.expect(1);
6027
6028       var object = { 'length': [1, 2] };
6029       assert.deepEqual(func(object, identity), [1, 2]);
6030     });
6031   });
6032
6033   /*--------------------------------------------------------------------------*/
6034
6035   QUnit.module('lodash.flattenDepth');
6036
6037   (function() {
6038     var array = [1, [2, [3, [4]], 5]];
6039
6040     QUnit.test('should use a default `depth` of `1`', function(assert) {
6041       assert.expect(1);
6042
6043       assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
6044     });
6045
6046     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6047       assert.expect(2);
6048
6049       lodashStable.each([-1, 0], function(depth) {
6050         assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
6051       });
6052     });
6053
6054     QUnit.test('should coerce `depth` to an integer', function(assert) {
6055       assert.expect(1);
6056
6057       assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
6058     });
6059   }());
6060
6061   /*--------------------------------------------------------------------------*/
6062
6063   QUnit.module('flatten methods');
6064
6065   (function() {
6066     var args = arguments,
6067         array = [1, [2, [3, [4]], 5]];
6068
6069     QUnit.test('should flatten `arguments` objects', function(assert) {
6070       assert.expect(3);
6071
6072       var array = [args, [args]];
6073
6074       assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
6075       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
6076       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
6077     });
6078
6079     QUnit.test('should treat sparse arrays as dense', function(assert) {
6080       assert.expect(6);
6081
6082       var array = [[1, 2, 3], Array(3)],
6083           expected = [1, 2, 3];
6084
6085       expected.push(undefined, undefined, undefined);
6086
6087       lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) {
6088         assert.deepEqual(actual, expected);
6089         assert.ok('4' in actual);
6090       });
6091     });
6092
6093     QUnit.test('should work with extremely large arrays', function(assert) {
6094       assert.expect(3);
6095
6096       lodashStable.times(3, function(index) {
6097         var expected = Array(5e5);
6098         try {
6099           var func = _.flatten;
6100           if (index == 1) {
6101             func = _.flattenDeep;
6102           } else if (index == 2) {
6103             func = _.flattenDepth;
6104           }
6105           assert.deepEqual(func([expected]), expected);
6106         } catch (e) {
6107           assert.ok(false, e.message);
6108         }
6109       });
6110     });
6111
6112     QUnit.test('should work with empty arrays', function(assert) {
6113       assert.expect(3);
6114
6115       var array = [[], [[]], [[], [[[]]]]];
6116
6117       assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
6118       assert.deepEqual(_.flattenDeep(array), []);
6119       assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
6120     });
6121
6122     QUnit.test('should support flattening of nested arrays', function(assert) {
6123       assert.expect(3);
6124
6125       assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
6126       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
6127       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
6128     });
6129
6130     QUnit.test('should return an empty array for non array-like objects', function(assert) {
6131       assert.expect(3);
6132
6133       var expected = [],
6134           nonArray = { 'a': 1 };
6135
6136       assert.deepEqual(_.flatten(nonArray), expected);
6137       assert.deepEqual(_.flattenDeep(nonArray), expected);
6138       assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
6139     });
6140
6141     QUnit.test('should return a wrapped value when chaining', function(assert) {
6142       assert.expect(6);
6143
6144       if (!isNpm) {
6145         var wrapped = _(array),
6146             actual = wrapped.flatten();
6147
6148         assert.ok(actual instanceof _);
6149         assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
6150
6151         actual = wrapped.flattenDeep();
6152
6153         assert.ok(actual instanceof _);
6154         assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
6155
6156         actual = wrapped.flattenDepth(2);
6157
6158         assert.ok(actual instanceof _);
6159         assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
6160       }
6161       else {
6162         skipAssert(assert, 6);
6163       }
6164     });
6165   }(1, 2, 3));
6166
6167   /*--------------------------------------------------------------------------*/
6168
6169   QUnit.module('flow methods');
6170
6171   lodashStable.each(['flow', 'flowRight'], function(methodName) {
6172     var func = _[methodName],
6173         isFlow = methodName == 'flow';
6174
6175     QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
6176       assert.expect(1);
6177
6178       var fixed = function(n) { return n.toFixed(1); },
6179           combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
6180
6181       assert.strictEqual(combined(1, 2), '9.0');
6182     });
6183
6184     QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
6185       assert.expect(1);
6186
6187       assert.notStrictEqual(func(noop), noop);
6188     });
6189
6190     QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
6191       assert.expect(6);
6192
6193       _.times(2, function(index) {
6194         try {
6195           var combined = index ? func([]) : func();
6196           assert.strictEqual(combined('a'), 'a');
6197         } catch (e) {
6198           assert.ok(false, e.message);
6199         }
6200         assert.strictEqual(combined.length, 0);
6201         assert.notStrictEqual(combined, identity);
6202       });
6203     });
6204
6205     QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
6206       assert.expect(1);
6207
6208       var curried = _.curry(identity);
6209
6210       var combined = isFlow
6211         ? func(_.head, curried)
6212         : func(curried, _.head);
6213
6214       assert.strictEqual(combined([1]), 1);
6215     });
6216
6217     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6218       assert.expect(6);
6219
6220       var filterCount,
6221           mapCount,
6222           array = lodashStable.range(LARGE_ARRAY_SIZE),
6223           iteratee = function(value) { mapCount++; return square(value); },
6224           predicate = function(value) { filterCount++; return isEven(value); };
6225
6226       lodashStable.times(2, function(index) {
6227         var filter1 = _.filter,
6228             filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
6229             filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
6230
6231         var map1 = _.map,
6232             map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
6233             map3 = (_.map = index ? map2 : map1, map2(iteratee));
6234
6235         var take1 = _.take,
6236             take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
6237             take3 = (_.take = index ? take2 : take1, take2(2));
6238
6239         var combined = isFlow
6240           ? func(map3, filter3, _.compact, take3)
6241           : func(take3, _.compact, filter3, map3);
6242
6243         filterCount = mapCount = 0;
6244         assert.deepEqual(combined(array), [4, 16]);
6245
6246         if (!isNpm && WeakMap && WeakMap.name) {
6247           assert.strictEqual(filterCount, 5, 'filterCount');
6248           assert.strictEqual(mapCount, 5, 'mapCount');
6249         }
6250         else {
6251           skipAssert(assert, 2);
6252         }
6253         _.filter = filter1;
6254         _.map = map1;
6255         _.take = take1;
6256       });
6257     });
6258
6259     QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
6260       assert.expect(1);
6261
6262       var curried = _.curry(_.ary(_.map, 2), 2),
6263           getProp = curried(curried.placeholder, 'a'),
6264           objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
6265
6266       var combined = isFlow
6267         ? func(getProp, _.uniq)
6268         : func(_.uniq, getProp);
6269
6270       assert.deepEqual(combined(objects), [1, 2]);
6271     });
6272
6273     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6274       assert.expect(1);
6275
6276       if (!isNpm) {
6277         var wrapped = _(noop)[methodName]();
6278         assert.ok(wrapped instanceof _);
6279       }
6280       else {
6281         skipAssert(assert);
6282       }
6283     });
6284   });
6285
6286   /*--------------------------------------------------------------------------*/
6287
6288   QUnit.module('lodash.forEach');
6289
6290   (function() {
6291     QUnit.test('should be aliased', function(assert) {
6292       assert.expect(1);
6293
6294       assert.strictEqual(_.each, _.forEach);
6295     });
6296   }());
6297
6298   /*--------------------------------------------------------------------------*/
6299
6300   QUnit.module('lodash.forEachRight');
6301
6302   (function() {
6303     QUnit.test('should be aliased', function(assert) {
6304       assert.expect(1);
6305
6306       assert.strictEqual(_.eachRight, _.forEachRight);
6307     });
6308   }());
6309
6310   /*--------------------------------------------------------------------------*/
6311
6312   QUnit.module('forIn methods');
6313
6314   lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6315     var func = _[methodName];
6316
6317     QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
6318       assert.expect(1);
6319
6320       function Foo() {
6321         this.a = 1;
6322       }
6323       Foo.prototype.b = 2;
6324
6325       var keys = [];
6326       func(new Foo, function(value, key) { keys.push(key); });
6327       assert.deepEqual(keys.sort(), ['a', 'b']);
6328     });
6329   });
6330
6331   /*--------------------------------------------------------------------------*/
6332
6333   QUnit.module('forOwn methods');
6334
6335   lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6336     var func = _[methodName];
6337
6338     QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
6339       assert.expect(1);
6340
6341       var object = { '0': 'zero', '1': 'one', 'length': 2 },
6342           props = [];
6343
6344       func(object, function(value, prop) { props.push(prop); });
6345       assert.deepEqual(props.sort(), ['0', '1', 'length']);
6346     });
6347   });
6348
6349   /*--------------------------------------------------------------------------*/
6350
6351   QUnit.module('iteration methods');
6352
6353   (function() {
6354     var methods = [
6355       '_baseEach',
6356       'countBy',
6357       'every',
6358       'filter',
6359       'find',
6360       'findIndex',
6361       'findKey',
6362       'findLast',
6363       'findLastIndex',
6364       'findLastKey',
6365       'forEach',
6366       'forEachRight',
6367       'forIn',
6368       'forInRight',
6369       'forOwn',
6370       'forOwnRight',
6371       'groupBy',
6372       'keyBy',
6373       'map',
6374       'mapKeys',
6375       'mapValues',
6376       'maxBy',
6377       'minBy',
6378       'omitBy',
6379       'partition',
6380       'pickBy',
6381       'reject',
6382       'some'
6383     ];
6384
6385     var arrayMethods = [
6386       'findIndex',
6387       'findLastIndex',
6388       'maxBy',
6389       'minBy'
6390     ];
6391
6392     var collectionMethods = [
6393       '_baseEach',
6394       'countBy',
6395       'every',
6396       'filter',
6397       'find',
6398       'findLast',
6399       'forEach',
6400       'forEachRight',
6401       'groupBy',
6402       'keyBy',
6403       'map',
6404       'partition',
6405       'reduce',
6406       'reduceRight',
6407       'reject',
6408       'some'
6409     ];
6410
6411     var forInMethods = [
6412       'forIn',
6413       'forInRight',
6414       'omitBy',
6415       'pickBy'
6416     ];
6417
6418     var iterationMethods = [
6419       '_baseEach',
6420       'forEach',
6421       'forEachRight',
6422       'forIn',
6423       'forInRight',
6424       'forOwn',
6425       'forOwnRight'
6426     ];
6427
6428     var objectMethods = [
6429       'findKey',
6430       'findLastKey',
6431       'forIn',
6432       'forInRight',
6433       'forOwn',
6434       'forOwnRight',
6435       'mapKeys',
6436       'mapValues',
6437       'omitBy',
6438       'pickBy'
6439     ];
6440
6441     var rightMethods = [
6442       'findLast',
6443       'findLastIndex',
6444       'findLastKey',
6445       'forEachRight',
6446       'forInRight',
6447       'forOwnRight'
6448     ];
6449
6450     var unwrappedMethods = [
6451       'each',
6452       'eachRight',
6453       'every',
6454       'find',
6455       'findIndex',
6456       'findKey',
6457       'findLast',
6458       'findLastIndex',
6459       'findLastKey',
6460       'forEach',
6461       'forEachRight',
6462       'forIn',
6463       'forInRight',
6464       'forOwn',
6465       'forOwnRight',
6466       'max',
6467       'maxBy',
6468       'min',
6469       'minBy',
6470       'some'
6471     ];
6472
6473     lodashStable.each(methods, function(methodName) {
6474       var array = [1, 2, 3],
6475           func = _[methodName],
6476           isBy = /(^partition|By)$/.test(methodName),
6477           isFind = /^find/.test(methodName),
6478           isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6479           isSome = methodName == 'some';
6480
6481       QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
6482         assert.expect(1);
6483
6484         if (func) {
6485           var args,
6486               expected = [1, 0, array];
6487
6488           func(array, function() {
6489             args || (args = slice.call(arguments));
6490           });
6491
6492           if (lodashStable.includes(rightMethods, methodName)) {
6493             expected[0] = 3;
6494             expected[1] = 2;
6495           }
6496           if (lodashStable.includes(objectMethods, methodName)) {
6497             expected[1] += '';
6498           }
6499           if (isBy) {
6500             expected.length = isOmitPick ? 2 : 1;
6501           }
6502           assert.deepEqual(args, expected);
6503         }
6504         else {
6505           skipAssert(assert);
6506         }
6507       });
6508
6509       QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
6510         assert.expect(1);
6511
6512         if (func) {
6513           var array = [1];
6514           array[2] = 3;
6515
6516           var expected = lodashStable.includes(objectMethods, methodName)
6517             ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
6518             : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
6519
6520           if (isBy) {
6521             expected = lodashStable.map(expected, function(args) {
6522               return args.slice(0, isOmitPick ? 2 : 1);
6523             });
6524           }
6525           else if (lodashStable.includes(objectMethods, methodName)) {
6526             expected = lodashStable.map(expected, function(args) {
6527               args[1] += '';
6528               return args;
6529             });
6530           }
6531           if (lodashStable.includes(rightMethods, methodName)) {
6532             expected.reverse();
6533           }
6534           var argsList = [];
6535           func(array, function() {
6536             argsList.push(slice.call(arguments));
6537             return !(isFind || isSome);
6538           });
6539
6540           assert.deepEqual(argsList, expected);
6541         }
6542         else {
6543           skipAssert(assert);
6544         }
6545       });
6546     });
6547
6548     lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
6549       var array = [1, 2, 3],
6550           func = _[methodName],
6551           isEvery = methodName == 'every';
6552
6553       array.a = 1;
6554
6555       QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
6556         assert.expect(1);
6557
6558         if (func) {
6559           var keys = [];
6560           func(array, function(value, key) {
6561             keys.push(key);
6562             return isEvery;
6563           });
6564
6565           assert.notOk(lodashStable.includes(keys, 'a'));
6566         }
6567         else {
6568           skipAssert(assert);
6569         }
6570       });
6571     });
6572
6573     lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
6574       var array = [1, 2, 3],
6575           isBaseEach = methodName == '_baseEach';
6576
6577       QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
6578         assert.expect(1);
6579
6580         if (!(isBaseEach || isNpm)) {
6581           var wrapped = _(array)[methodName](noop);
6582           assert.ok(wrapped instanceof _);
6583         }
6584         else {
6585           skipAssert(assert);
6586         }
6587       });
6588     });
6589
6590     lodashStable.each(unwrappedMethods, function(methodName) {
6591       var array = [1, 2, 3];
6592
6593       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
6594         assert.expect(1);
6595
6596         if (!isNpm) {
6597           var actual = _(array)[methodName](noop);
6598           assert.notOk(actual instanceof _);
6599         }
6600         else {
6601           skipAssert(assert);
6602         }
6603       });
6604
6605       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
6606         assert.expect(2);
6607
6608         if (!isNpm) {
6609           var wrapped = _(array).chain(),
6610               actual = wrapped[methodName](noop);
6611
6612           assert.ok(actual instanceof _);
6613           assert.notStrictEqual(actual, wrapped);
6614         }
6615         else {
6616           skipAssert(assert, 2);
6617         }
6618       });
6619     });
6620
6621     lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
6622       var func = _[methodName];
6623
6624       QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
6625         assert.expect(1);
6626
6627         function Foo() {
6628           this.a = 1;
6629         }
6630         Foo.prototype.b = 2;
6631
6632         if (func) {
6633           var values = [];
6634           func(new Foo, function(value) { values.push(value); });
6635           assert.deepEqual(values, [1]);
6636         }
6637         else {
6638           skipAssert(assert);
6639         }
6640       });
6641     });
6642
6643     lodashStable.each(iterationMethods, function(methodName) {
6644       var array = [1, 2, 3],
6645           func = _[methodName];
6646
6647       QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
6648         assert.expect(1);
6649
6650         if (func) {
6651           assert.strictEqual(func(array, Boolean), array);
6652         }
6653         else {
6654           skipAssert(assert);
6655         }
6656       });
6657     });
6658
6659     lodashStable.each(collectionMethods, function(methodName) {
6660       var func = _[methodName];
6661
6662       QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
6663         assert.expect(3);
6664
6665         if (func) {
6666           var isIteratedAsObject = function(object) {
6667             var result = false;
6668             func(object, function() { result = true; }, 0);
6669             return result;
6670           };
6671
6672           var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
6673               expected = lodashStable.map(values, alwaysTrue);
6674
6675           var actual = lodashStable.map(values, function(length) {
6676             return isIteratedAsObject({ 'length': length });
6677           });
6678
6679           var Foo = function(a) {};
6680           Foo.a = 1;
6681
6682           assert.deepEqual(actual, expected);
6683           assert.ok(isIteratedAsObject(Foo));
6684           assert.notOk(isIteratedAsObject({ 'length': 0 }));
6685         }
6686         else {
6687           skipAssert(assert, 3);
6688         }
6689       });
6690     });
6691
6692     lodashStable.each(methods, function(methodName) {
6693       var func = _[methodName],
6694           isFind = /^find/.test(methodName),
6695           isSome = methodName == 'some',
6696           isReduce = /^reduce/.test(methodName);
6697
6698       QUnit.test('`_.' + methodName + '` should ignore changes to `array.length`', function(assert) {
6699         assert.expect(1);
6700
6701         if (func) {
6702           var count = 0,
6703               array = [1];
6704
6705           func(array, function() {
6706             if (++count == 1) {
6707               array.push(2);
6708             }
6709             return !(isFind || isSome);
6710           }, isReduce ? array : null);
6711
6712           assert.strictEqual(count, 1);
6713         }
6714         else {
6715           skipAssert(assert);
6716         }
6717       });
6718     });
6719
6720     lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
6721       var func = _[methodName],
6722           isFind = /^find/.test(methodName),
6723           isSome = methodName == 'some',
6724           isReduce = /^reduce/.test(methodName);
6725
6726       QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
6727         assert.expect(1);
6728
6729         if (func) {
6730           var count = 0,
6731               object = { 'a': 1 };
6732
6733           func(object, function() {
6734             if (++count == 1) {
6735               object.b = 2;
6736             }
6737             return !(isFind || isSome);
6738           }, isReduce ? object : null);
6739
6740           assert.strictEqual(count, 1);
6741         }
6742         else {
6743           skipAssert(assert);
6744         }
6745       });
6746     });
6747   }());
6748
6749   /*--------------------------------------------------------------------------*/
6750
6751   QUnit.module('object assignments');
6752
6753   lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
6754     var func = _[methodName],
6755         isAssign = methodName == 'assign',
6756         isDefaults = methodName == 'defaults';
6757
6758     QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
6759       assert.expect(1);
6760
6761       var expected = lodashStable.map(primitives, function(value) {
6762         var object = Object(value);
6763         object.a = 1;
6764         return object;
6765       });
6766
6767       var actual = lodashStable.map(primitives, function(value) {
6768         return func(value, { 'a': 1 });
6769       });
6770
6771       assert.deepEqual(actual, expected);
6772     });
6773
6774     QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
6775       assert.expect(1);
6776
6777       function Foo() {
6778         this.a = 1;
6779       }
6780       Foo.prototype.b = 2;
6781
6782       var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
6783       assert.deepEqual(func({}, new Foo), expected);
6784     });
6785
6786     QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
6787       assert.expect(1);
6788
6789       try {
6790         assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
6791       } catch (e) {
6792         assert.ok(false, e.message);
6793       }
6794     });
6795
6796     QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
6797       assert.expect(2);
6798
6799       var source = { 'a': 1 },
6800           values = [null, undefined],
6801           expected = lodashStable.map(values, alwaysTrue);
6802
6803       var actual = lodashStable.map(values, function(value) {
6804         var object = func(value, source);
6805         return object !== source && lodashStable.isEqual(object, source);
6806       });
6807
6808       assert.deepEqual(actual, expected);
6809
6810       actual = lodashStable.map(values, function(value) {
6811         return lodashStable.isEqual(func(value), {});
6812       });
6813
6814       assert.deepEqual(actual, expected);
6815     });
6816
6817     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
6818       assert.expect(2);
6819
6820       var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
6821           expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
6822
6823       assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
6824
6825       var fn = function() {};
6826       fn.a = array[0];
6827       fn.b = array[1];
6828       fn.c = array[2];
6829
6830       assert.deepEqual(_.reduce(fn, func, { 'a': 0 }), expected);
6831     });
6832
6833     QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
6834       assert.expect(1);
6835
6836       if (!isNpm) {
6837         var wrapped = _({ 'a': 1 }),
6838             actual = wrapped[methodName]({ 'b': 2 });
6839
6840         assert.notStrictEqual(actual, wrapped);
6841       }
6842       else {
6843         skipAssert(assert);
6844       }
6845     });
6846   });
6847
6848   lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
6849     var func = _[methodName];
6850
6851     QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
6852       assert.expect(1);
6853
6854       function Foo() {}
6855       Foo.prototype.a = 1;
6856
6857       var actual = func(new Foo, { 'b': 2 });
6858       assert.notOk(_.has(actual, 'a'));
6859     });
6860   });
6861
6862   lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
6863     var func = _[methodName];
6864
6865     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
6866       assert.expect(4);
6867
6868       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
6869         if (defineProperty) {
6870           var object = {},
6871               pass = true;
6872
6873           defineProperty(object, 'a', {
6874             'enumerable': true,
6875             'configurable': true,
6876             'get': lodashStable.constant(value),
6877             'set': function() { pass = false; }
6878           });
6879
6880           func(object, { 'a': value });
6881           assert.ok(pass);
6882         }
6883         else {
6884           skipAssert(assert);
6885         }
6886       });
6887     });
6888   });
6889
6890   lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
6891     var func = _[methodName],
6892         isMergeWith = methodName == 'mergeWith';
6893
6894     QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
6895       assert.expect(3);
6896
6897       var args,
6898           object = { 'a': 1 },
6899           source = { 'a': 2 },
6900           expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
6901
6902       func(object, source, function() {
6903         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6904       });
6905
6906       assert.deepEqual(args, expected, 'primitive property values');
6907
6908       args = undefined;
6909       object = { 'a': 1 };
6910       source = { 'b': 2 };
6911       expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
6912
6913       func(object, source, function() {
6914         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6915       });
6916
6917       assert.deepEqual(args, expected, 'missing destination property');
6918
6919       var argsList = [],
6920           objectValue = [1, 2],
6921           sourceValue = { 'b': 2 };
6922
6923       object = { 'a': objectValue };
6924       source = { 'a': sourceValue };
6925       expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
6926
6927       if (isMergeWith) {
6928         expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
6929       }
6930       func(object, source, function() {
6931         argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6932       });
6933
6934       assert.deepEqual(argsList, expected, 'object property values');
6935     });
6936
6937     QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
6938       assert.expect(2);
6939
6940       function callback() {}
6941       callback.b = 2;
6942
6943       var actual = func({ 'a': 1 }, callback);
6944       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
6945
6946       actual = func({ 'a': 1 }, callback, { 'c': 3 });
6947       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
6948     });
6949   });
6950
6951   /*--------------------------------------------------------------------------*/
6952
6953   QUnit.module('exit early');
6954
6955   lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
6956     var func = _[methodName];
6957
6958     QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
6959       assert.expect(1);
6960
6961       if (func) {
6962         var array = [1, 2, 3],
6963             values = [];
6964
6965         func(array, function(value, other) {
6966           values.push(lodashStable.isArray(value) ? other : value);
6967           return false;
6968         });
6969
6970         assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
6971       }
6972       else {
6973         skipAssert(assert);
6974       }
6975     });
6976
6977     QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
6978       assert.expect(1);
6979
6980       if (func) {
6981         var object = { 'a': 1, 'b': 2, 'c': 3 },
6982             values = [];
6983
6984         func(object, function(value, other) {
6985           values.push(lodashStable.isArray(value) ? other : value);
6986           return false;
6987         });
6988
6989         assert.strictEqual(values.length, 1);
6990       }
6991       else {
6992         skipAssert(assert);
6993       }
6994     });
6995   });
6996
6997   /*--------------------------------------------------------------------------*/
6998
6999   QUnit.module('`__proto__` property bugs');
7000
7001   (function() {
7002     QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
7003       assert.expect(4);
7004
7005       var stringLiteral = '__proto__',
7006           stringObject = Object(stringLiteral),
7007           expected = [stringLiteral, stringObject];
7008
7009       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
7010         return isEven(count) ? stringLiteral : stringObject;
7011       });
7012
7013       assert.deepEqual(_.difference(largeArray, largeArray), []);
7014       assert.deepEqual(_.intersection(largeArray, largeArray), expected);
7015       assert.deepEqual(_.uniq(largeArray), expected);
7016       assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
7017     });
7018   }());
7019
7020   /*--------------------------------------------------------------------------*/
7021
7022   QUnit.module('lodash.fromPairs');
7023
7024   (function() {
7025     QUnit.test('should accept a two dimensional array', function(assert) {
7026       assert.expect(1);
7027
7028       var array = [['a', 1], ['b', 2]],
7029           object = { 'a': 1, 'b': 2 },
7030           actual = _.fromPairs(array);
7031
7032       assert.deepEqual(actual, object);
7033     });
7034
7035     QUnit.test('should accept a falsey `array` argument', function(assert) {
7036       assert.expect(1);
7037
7038       var expected = lodashStable.map(falsey, alwaysEmptyObject);
7039
7040       var actual = lodashStable.map(falsey, function(array, index) {
7041         try {
7042           return index ? _.fromPairs(array) : _.fromPairs();
7043         } catch (e) {}
7044       });
7045
7046       assert.deepEqual(actual, expected);
7047     });
7048
7049     QUnit.test('should not support deep paths', function(assert) {
7050       assert.expect(1);
7051
7052       var actual = _.fromPairs([['a.b', 1]]);
7053       assert.deepEqual(actual, { 'a.b': 1 });
7054     });
7055
7056     QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
7057       assert.expect(1);
7058
7059       var object = { 'a.b': 1 };
7060       assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
7061     });
7062
7063     QUnit.test('should work in a lazy sequence', function(assert) {
7064       assert.expect(1);
7065
7066       if (!isNpm) {
7067         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7068           return ['key' + index, index];
7069         });
7070
7071         var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
7072
7073         assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
7074       }
7075       else {
7076         skipAssert(assert);
7077       }
7078     });
7079   }());
7080
7081   /*--------------------------------------------------------------------------*/
7082
7083   QUnit.module('lodash.functions');
7084
7085   (function() {
7086     QUnit.test('should return the function names of an object', function(assert) {
7087       assert.expect(1);
7088
7089       var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
7090           actual = _.functions(object).sort();
7091
7092       assert.deepEqual(actual, ['b', 'd']);
7093     });
7094
7095     QUnit.test('should not include inherited functions', function(assert) {
7096       assert.expect(1);
7097
7098       function Foo() {
7099         this.a = identity;
7100         this.b = 'b';
7101       }
7102       Foo.prototype.c = noop;
7103
7104       assert.deepEqual(_.functions(new Foo), ['a']);
7105     });
7106   }());
7107
7108   /*--------------------------------------------------------------------------*/
7109
7110   QUnit.module('lodash.groupBy');
7111
7112   (function() {
7113     var array = [6.1, 4.2, 6.3];
7114
7115     QUnit.test('should transform keys by `iteratee`', function(assert) {
7116       assert.expect(1);
7117
7118       var actual = _.groupBy(array, Math.floor);
7119       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7120     });
7121
7122     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7123       assert.expect(1);
7124
7125       var array = [6, 4, 6],
7126           values = [, null, undefined],
7127           expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
7128
7129       var actual = lodashStable.map(values, function(value, index) {
7130         return index ? _.groupBy(array, value) : _.groupBy(array);
7131       });
7132
7133       assert.deepEqual(actual, expected);
7134     });
7135
7136     QUnit.test('should work with `_.property` shorthands', function(assert) {
7137       assert.expect(1);
7138
7139       var actual = _.groupBy(['one', 'two', 'three'], 'length');
7140       assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
7141     });
7142
7143     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
7144       assert.expect(2);
7145
7146       var actual = _.groupBy(array, function(n) {
7147         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
7148       });
7149
7150       assert.deepEqual(actual.constructor, [4.2]);
7151       assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
7152     });
7153
7154     QUnit.test('should work with a number for `iteratee`', function(assert) {
7155       assert.expect(2);
7156
7157       var array = [
7158         [1, 'a'],
7159         [2, 'a'],
7160         [2, 'b']
7161       ];
7162
7163       assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
7164       assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
7165     });
7166
7167     QUnit.test('should work with an object for `collection`', function(assert) {
7168       assert.expect(1);
7169
7170       var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
7171       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7172     });
7173
7174     QUnit.test('should work in a lazy sequence', function(assert) {
7175       assert.expect(1);
7176
7177       if (!isNpm) {
7178         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
7179           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
7180           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
7181         );
7182
7183         var iteratee = function(value) { value.push(value[0]); return value; },
7184             predicate = function(value) { return isEven(value[0]); },
7185             actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
7186
7187         assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
7188       }
7189       else {
7190         skipAssert(assert);
7191       }
7192     });
7193   }());
7194
7195   /*--------------------------------------------------------------------------*/
7196
7197   QUnit.module('lodash.gt');
7198
7199   (function() {
7200     QUnit.test('should return `true` if `value` > `other`', function(assert) {
7201       assert.expect(2);
7202
7203       assert.strictEqual(_.gt(3, 1), true);
7204       assert.strictEqual(_.gt('def', 'abc'), true);
7205     });
7206
7207     QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
7208       assert.expect(4);
7209
7210       assert.strictEqual(_.gt(1, 3), false);
7211       assert.strictEqual(_.gt(3, 3), false);
7212       assert.strictEqual(_.gt('abc', 'def'), false);
7213       assert.strictEqual(_.gt('def', 'def'), false);
7214     });
7215   }());
7216
7217   /*--------------------------------------------------------------------------*/
7218
7219   QUnit.module('lodash.gte');
7220
7221   (function() {
7222     QUnit.test('should return `true` if `value` >= `other`', function(assert) {
7223       assert.expect(4);
7224
7225       assert.strictEqual(_.gte(3, 1), true);
7226       assert.strictEqual(_.gte(3, 3), true);
7227       assert.strictEqual(_.gte('def', 'abc'), true);
7228       assert.strictEqual(_.gte('def', 'def'), true);
7229     });
7230
7231     QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
7232       assert.expect(2);
7233
7234       assert.strictEqual(_.gte(1, 3), false);
7235       assert.strictEqual(_.gte('abc', 'def'), false);
7236     });
7237   }());
7238
7239   /*--------------------------------------------------------------------------*/
7240
7241   QUnit.module('has methods');
7242
7243   lodashStable.each(['has', 'hasIn'], function(methodName) {
7244     var args = (function() { return arguments; }(1, 2, 3)),
7245         func = _[methodName],
7246         isHas = methodName == 'has';
7247
7248     QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
7249       assert.expect(2);
7250
7251       var object = { 'a': 1 };
7252
7253       lodashStable.each(['a', ['a']], function(path) {
7254         assert.strictEqual(func(object, path), true);
7255       });
7256     });
7257
7258     QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
7259       assert.expect(1);
7260
7261       var object = { 'hasOwnProperty': null, 'a': 1 };
7262       assert.strictEqual(func(object, 'a'), true);
7263     });
7264
7265     QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
7266       assert.expect(4);
7267
7268       var object = { 'a': { 'b': 2 } };
7269
7270       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7271         assert.strictEqual(func(object, path), true);
7272       });
7273
7274       lodashStable.each(['a.a', ['a', 'a']], function(path) {
7275         assert.strictEqual(func(object, path), false);
7276       });
7277     });
7278
7279     QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
7280       assert.expect(1);
7281
7282       function fn() {}
7283       fn.toString = lodashStable.constant('fn');
7284
7285       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
7286           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
7287           values = [null, undefined, fn, {}];
7288
7289       var actual = lodashStable.transform(objects, function(result, object, index) {
7290         var key = values[index];
7291         lodashStable.each([key, [key]], function(path) {
7292           var prop = _.property(key);
7293           result.push(prop(object));
7294         });
7295       });
7296
7297       assert.deepEqual(actual, expected);
7298     });
7299
7300     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7301       assert.expect(1);
7302
7303       assert.strictEqual(func(args, 1), true);
7304     });
7305
7306     QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
7307       assert.expect(2);
7308
7309       var array = [1, 2, 3];
7310
7311       lodashStable.each([1, [1]], function(path) {
7312         assert.strictEqual(func(array, path), true);
7313       });
7314     });
7315
7316     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
7317       assert.expect(1);
7318
7319       var object = { '-0': 'a', '0': 'b' },
7320           props = [-0, Object(-0), 0, Object(0)],
7321           expected = lodashStable.map(props, alwaysTrue);
7322
7323       var actual = lodashStable.map(props, function(key) {
7324         return func(object, key);
7325       });
7326
7327       assert.deepEqual(actual, expected);
7328     });
7329
7330     QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
7331       assert.expect(1);
7332
7333       function Foo() {
7334         this[symbol] = 1;
7335       }
7336
7337       if (Symbol) {
7338         var symbol2 = Symbol('b');
7339         Foo.prototype[symbol2] = 2;
7340         var path = isHas ? symbol : symbol2;
7341
7342         assert.strictEqual(func(new Foo, path), true);
7343       }
7344       else {
7345         skipAssert(assert);
7346       }
7347     });
7348
7349     QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
7350       assert.expect(1);
7351
7352       if (create)  {
7353         var object = create(null);
7354         object[1] = 'a';
7355         assert.strictEqual(func(object, 1), true);
7356       }
7357       else {
7358         skipAssert(assert);
7359       }
7360     });
7361
7362     QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7363       assert.expect(2);
7364
7365       var object = { 'a.b': 1 };
7366
7367       lodashStable.each(['a.b', ['a.b']], function(path) {
7368         assert.strictEqual(func(object, path), true);
7369       });
7370     });
7371
7372     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7373       assert.expect(2);
7374
7375       function Foo() {}
7376       Foo.prototype.a = 1;
7377
7378       lodashStable.each(['a', ['a']], function(path) {
7379         assert.strictEqual(func(new Foo, path), !isHas);
7380       });
7381     });
7382
7383     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
7384       assert.expect(2);
7385
7386       function Foo() {}
7387       Foo.prototype.a = { 'b': 1 };
7388
7389       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7390         assert.strictEqual(func(new Foo, path), !isHas);
7391       });
7392     });
7393
7394     QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
7395       assert.expect(2);
7396
7397       var string = Object('abc');
7398       delete args[0];
7399       delete string[0];
7400
7401       var values = [Array(3), args, string],
7402           expected = lodashStable.map(values, alwaysTrue);
7403
7404       var actual = lodashStable.map(values, function(value) {
7405         return func(value, 0);
7406       });
7407
7408       assert.deepEqual(actual, expected);
7409
7410       expected = lodashStable.map(values, lodashStable.constant([true, true]));
7411
7412       actual = lodashStable.map(values, function(value) {
7413         return lodashStable.map(['a[0]', ['a', '0']], function(path) {
7414           return func({ 'a': value }, path);
7415         });
7416       });
7417
7418       assert.deepEqual(actual, expected);
7419       args[0] = 1;
7420     });
7421
7422     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7423       assert.expect(2);
7424
7425       var values = [null, undefined],
7426           expected = lodashStable.map(values, alwaysFalse);
7427
7428       lodashStable.each(['constructor', ['constructor']], function(path) {
7429         var actual = lodashStable.map(values, function(value) {
7430           return func(value, path);
7431         });
7432
7433         assert.deepEqual(actual, expected);
7434       });
7435     });
7436
7437     QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
7438       assert.expect(2);
7439
7440       var values = [null, undefined],
7441           expected = lodashStable.map(values, alwaysFalse);
7442
7443       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
7444         var actual = lodashStable.map(values, function(value) {
7445           return func(value, path);
7446         });
7447
7448         assert.deepEqual(actual, expected);
7449       });
7450     });
7451
7452     QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
7453       assert.expect(2);
7454
7455       var values = [, null, undefined],
7456           expected = lodashStable.map(values, alwaysFalse);
7457
7458       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7459         var actual = lodashStable.map(values, function(value, index) {
7460           var object = index ? { 'a': value } : {};
7461           return func(object, path);
7462         });
7463
7464         assert.deepEqual(actual, expected);
7465       });
7466     });
7467   });
7468
7469   /*--------------------------------------------------------------------------*/
7470
7471   QUnit.module('lodash.head');
7472
7473   (function() {
7474     var array = [1, 2, 3, 4];
7475
7476     QUnit.test('should return the first element', function(assert) {
7477       assert.expect(1);
7478
7479       assert.strictEqual(_.head(array), 1);
7480     });
7481
7482     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
7483       assert.expect(1);
7484
7485       arrayProto[0] = 1;
7486       assert.strictEqual(_.head([]), undefined);
7487       arrayProto.length = 0;
7488     });
7489
7490     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7491       assert.expect(1);
7492
7493       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7494           actual = lodashStable.map(array, _.head);
7495
7496       assert.deepEqual(actual, [1, 4, 7]);
7497     });
7498
7499     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7500       assert.expect(1);
7501
7502       if (!isNpm) {
7503         assert.strictEqual(_(array).head(), 1);
7504       }
7505       else {
7506         skipAssert(assert);
7507       }
7508     });
7509
7510     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7511       assert.expect(1);
7512
7513       if (!isNpm) {
7514         assert.ok(_(array).chain().head() instanceof _);
7515       }
7516       else {
7517         skipAssert(assert);
7518       }
7519     });
7520
7521     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
7522       assert.expect(1);
7523
7524       if (!isNpm) {
7525         var wrapped = _(array).chain().head();
7526         assert.strictEqual(wrapped.__wrapped__, array);
7527       }
7528       else {
7529         skipAssert(assert);
7530       }
7531     });
7532
7533     QUnit.test('should work in a lazy sequence', function(assert) {
7534       assert.expect(2);
7535
7536       if (!isNpm) {
7537         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
7538             smallArray = array;
7539
7540         lodashStable.times(2, function(index) {
7541           var array = index ? largeArray : smallArray,
7542               wrapped = _(array).filter(isEven);
7543
7544           assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
7545         });
7546       }
7547       else {
7548         skipAssert(assert, 2);
7549       }
7550     });
7551
7552     QUnit.test('should be aliased', function(assert) {
7553       assert.expect(1);
7554
7555       assert.strictEqual(_.first, _.head);
7556     });
7557   }());
7558
7559   /*--------------------------------------------------------------------------*/
7560
7561   QUnit.module('lodash.identity');
7562
7563   (function() {
7564     QUnit.test('should return the first argument given', function(assert) {
7565       assert.expect(1);
7566
7567       var object = { 'name': 'fred' };
7568       assert.strictEqual(_.identity(object), object);
7569     });
7570   }());
7571
7572   /*--------------------------------------------------------------------------*/
7573
7574   QUnit.module('lodash.includes');
7575
7576   (function() {
7577     lodashStable.each({
7578       'an `arguments` object': arguments,
7579       'an array': [1, 2, 3, 4],
7580       'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
7581       'a string': '1234'
7582     },
7583     function(collection, key) {
7584       var isStr = typeof collection == 'string',
7585           values = _.toArray(collection),
7586           length = values.length;
7587
7588       QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
7589         assert.expect(1);
7590
7591         assert.strictEqual(_.includes(collection, 3), true);
7592       });
7593
7594       QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
7595         assert.expect(1);
7596
7597         assert.strictEqual(_.includes(collection, 5), false);
7598       });
7599
7600       QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
7601         assert.expect(2);
7602
7603         assert.strictEqual(_.includes(collection, values[2], 2), true);
7604         assert.strictEqual(_.includes(collection, values[1], 2), false);
7605       });
7606
7607       QUnit.test('should work with ' + key + ' and a `fromIndex` >= `collection.length`', function(assert) {
7608         assert.expect(12);
7609
7610         lodashStable.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) {
7611           assert.strictEqual(_.includes(collection, 1, fromIndex), false);
7612           assert.strictEqual(_.includes(collection, undefined, fromIndex), false);
7613           assert.strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length));
7614         });
7615       });
7616
7617       QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
7618         assert.expect(1);
7619
7620         var expected = lodashStable.map(falsey, alwaysTrue);
7621
7622         var actual = lodashStable.map(falsey, function(fromIndex) {
7623           return _.includes(collection, values[0], fromIndex);
7624         });
7625
7626         assert.deepEqual(actual, expected);
7627       });
7628
7629       QUnit.test('should work with ' + key + ' and coerce non-integer `fromIndex` values to integers', function(assert) {
7630         assert.expect(3);
7631
7632         assert.strictEqual(_.includes(collection, values[0], '1'), false);
7633         assert.strictEqual(_.includes(collection, values[0], 0.1), true);
7634         assert.strictEqual(_.includes(collection, values[0], NaN), true);
7635       });
7636
7637       QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
7638         assert.expect(2);
7639
7640         assert.strictEqual(_.includes(collection, values[2], -2), true);
7641         assert.strictEqual(_.includes(collection, values[1], -2), false);
7642       });
7643
7644       QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= negative `collection.length`', function(assert) {
7645         assert.expect(3);
7646
7647         lodashStable.each([-4, -6, -Infinity], function(fromIndex) {
7648           assert.strictEqual(_.includes(collection, values[0], fromIndex), true);
7649         });
7650       });
7651
7652       QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
7653         assert.expect(1);
7654
7655         assert.strictEqual(_.includes(collection, 2, 1.2), true);
7656       });
7657
7658       QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
7659         assert.expect(1);
7660
7661         if (!isNpm) {
7662           assert.strictEqual(_(collection).includes(3), true);
7663         }
7664         else {
7665           skipAssert(assert);
7666         }
7667       });
7668
7669       QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
7670         assert.expect(1);
7671
7672         if (!isNpm) {
7673           assert.ok(_(collection).chain().includes(3) instanceof _);
7674         }
7675         else {
7676           skipAssert(assert);
7677         }
7678       });
7679     });
7680
7681     lodashStable.each({
7682       'literal': 'abc',
7683       'object': Object('abc')
7684     },
7685     function(collection, key) {
7686       QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
7687         assert.expect(2);
7688
7689         assert.strictEqual(_.includes(collection, 'bc'), true);
7690         assert.strictEqual(_.includes(collection, 'd'), false);
7691       });
7692     });
7693
7694     QUnit.test('should return `false` for empty collections', function(assert) {
7695       assert.expect(1);
7696
7697       var expected = lodashStable.map(empties, alwaysFalse);
7698
7699       var actual = lodashStable.map(empties, function(value) {
7700         try {
7701           return _.includes(value);
7702         } catch (e) {}
7703       });
7704
7705       assert.deepEqual(actual, expected);
7706     });
7707
7708     QUnit.test('should match `NaN`', function(assert) {
7709       assert.expect(1);
7710
7711       assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
7712     });
7713
7714     QUnit.test('should match `-0` as `0`', function(assert) {
7715       assert.expect(2);
7716
7717       assert.strictEqual(_.includes([-0], 0), true);
7718       assert.strictEqual(_.includes([0], -0), true);
7719     });
7720
7721     QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
7722       assert.expect(1);
7723
7724       var array1 = [1, 2, 3],
7725           array2 = [2, 3, 1];
7726
7727       assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
7728     });
7729   }(1, 2, 3, 4));
7730
7731   /*--------------------------------------------------------------------------*/
7732
7733   QUnit.module('lodash.indexOf');
7734
7735   (function() {
7736     var array = [1, 2, 3, 1, 2, 3];
7737
7738     QUnit.test('should return the index of the first matched value', function(assert) {
7739       assert.expect(1);
7740
7741       assert.strictEqual(_.indexOf(array, 3), 2);
7742     });
7743
7744     QUnit.test('should work with a positive `fromIndex`', function(assert) {
7745       assert.expect(1);
7746
7747       assert.strictEqual(_.indexOf(array, 1, 2), 3);
7748     });
7749
7750     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
7751       assert.expect(1);
7752
7753       var values = [6, 8, Math.pow(2, 32), Infinity],
7754           expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
7755
7756       var actual = lodashStable.map(values, function(fromIndex) {
7757         return [
7758           _.indexOf(array, undefined, fromIndex),
7759           _.indexOf(array, 1, fromIndex),
7760           _.indexOf(array, '', fromIndex)
7761         ];
7762       });
7763
7764       assert.deepEqual(actual, expected);
7765     });
7766
7767     QUnit.test('should work with a negative `fromIndex`', function(assert) {
7768       assert.expect(1);
7769
7770       assert.strictEqual(_.indexOf(array, 2, -3), 4);
7771     });
7772
7773     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
7774       assert.expect(1);
7775
7776       var values = [-6, -8, -Infinity],
7777           expected = lodashStable.map(values, alwaysZero);
7778
7779       var actual = lodashStable.map(values, function(fromIndex) {
7780         return _.indexOf(array, 1, fromIndex);
7781       });
7782
7783       assert.deepEqual(actual, expected);
7784     });
7785
7786     QUnit.test('should treat falsey `fromIndex` values as `0`', function(assert) {
7787       assert.expect(1);
7788
7789       var expected = lodashStable.map(falsey, alwaysZero);
7790
7791       var actual = lodashStable.map(falsey, function(fromIndex) {
7792         return _.indexOf(array, 1, fromIndex);
7793       });
7794
7795       assert.deepEqual(actual, expected);
7796     });
7797
7798     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
7799       assert.expect(1);
7800
7801       assert.strictEqual(_.indexOf(array, 2, 1.2), 1);
7802     });
7803   }());
7804
7805   /*--------------------------------------------------------------------------*/
7806
7807   QUnit.module('lodash.initial');
7808
7809   (function() {
7810     var array = [1, 2, 3];
7811
7812     QUnit.test('should accept a falsey `array` argument', function(assert) {
7813       assert.expect(1);
7814
7815       var expected = lodashStable.map(falsey, alwaysEmptyArray);
7816
7817       var actual = lodashStable.map(falsey, function(array, index) {
7818         try {
7819           return index ? _.initial(array) : _.initial();
7820         } catch (e) {}
7821       });
7822
7823       assert.deepEqual(actual, expected);
7824     });
7825
7826     QUnit.test('should exclude last element', function(assert) {
7827       assert.expect(1);
7828
7829       assert.deepEqual(_.initial(array), [1, 2]);
7830     });
7831
7832     QUnit.test('should return an empty when querying empty arrays', function(assert) {
7833       assert.expect(1);
7834
7835       assert.deepEqual(_.initial([]), []);
7836     });
7837
7838     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7839       assert.expect(1);
7840
7841       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7842           actual = lodashStable.map(array, _.initial);
7843
7844       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
7845     });
7846
7847     QUnit.test('should work in a lazy sequence', function(assert) {
7848       assert.expect(4);
7849
7850       if (!isNpm) {
7851         var array = lodashStable.range(LARGE_ARRAY_SIZE),
7852             values = [];
7853
7854         var actual = _(array).initial().filter(function(value) {
7855           values.push(value);
7856           return false;
7857         })
7858         .value();
7859
7860         assert.deepEqual(actual, []);
7861         assert.deepEqual(values, _.initial(array));
7862
7863         values = [];
7864
7865         actual = _(array).filter(function(value) {
7866           values.push(value);
7867           return isEven(value);
7868         })
7869         .initial()
7870         .value();
7871
7872         assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
7873         assert.deepEqual(values, array);
7874       }
7875       else {
7876         skipAssert(assert, 4);
7877       }
7878     });
7879   }());
7880
7881   /*--------------------------------------------------------------------------*/
7882
7883   QUnit.module('lodash.inRange');
7884
7885   (function() {
7886     QUnit.test('should work with an `end` argument', function(assert) {
7887       assert.expect(3);
7888
7889       assert.strictEqual(_.inRange(3, 5), true);
7890       assert.strictEqual(_.inRange(5, 5), false);
7891       assert.strictEqual(_.inRange(6, 5), false);
7892     });
7893
7894     QUnit.test('should work with `start` and `end` arguments', function(assert) {
7895       assert.expect(4);
7896
7897       assert.strictEqual(_.inRange(1, 1, 5), true);
7898       assert.strictEqual(_.inRange(3, 1, 5), true);
7899       assert.strictEqual(_.inRange(0, 1, 5), false);
7900       assert.strictEqual(_.inRange(5, 1, 5), false);
7901     });
7902
7903     QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
7904       assert.expect(13);
7905
7906       lodashStable.each(falsey, function(value, index) {
7907         if (index) {
7908           assert.strictEqual(_.inRange(0, value), false);
7909           assert.strictEqual(_.inRange(0, value, 1), true);
7910         } else {
7911           assert.strictEqual(_.inRange(0), false);
7912         }
7913       });
7914     });
7915
7916     QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
7917       assert.expect(2);
7918
7919       assert.strictEqual(_.inRange(2, 5, 1), true);
7920       assert.strictEqual(_.inRange(-3, -2, -6), true);
7921     });
7922
7923     QUnit.test('should work with a floating point `n` value', function(assert) {
7924       assert.expect(4);
7925
7926       assert.strictEqual(_.inRange(0.5, 5), true);
7927       assert.strictEqual(_.inRange(1.2, 1, 5), true);
7928       assert.strictEqual(_.inRange(5.2, 5), false);
7929       assert.strictEqual(_.inRange(0.5, 1, 5), false);
7930     });
7931
7932     QUnit.test('should coerce arguments to finite numbers', function(assert) {
7933       assert.expect(1);
7934
7935       var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
7936           expected = lodashStable.map(actual, alwaysTrue);
7937
7938       assert.deepEqual(actual, expected);
7939     });
7940   }());
7941
7942   /*--------------------------------------------------------------------------*/
7943
7944   QUnit.module('intersection methods');
7945
7946   lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
7947     var args = (function() { return arguments; }(1, 2, 3)),
7948         func = _[methodName];
7949
7950     QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
7951       assert.expect(2);
7952
7953       var actual = func([1, 3, 2], [5, 2, 1, 4]);
7954       assert.deepEqual(actual, [1, 2]);
7955
7956       actual = func([5, 2, 1, 4], [1, 3, 2]);
7957       assert.deepEqual(actual, [2, 1]);
7958     });
7959
7960     QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
7961       assert.expect(2);
7962
7963       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
7964       assert.deepEqual(actual, [1, 2]);
7965
7966       actual = func([5, 2, 1, 4], [2, 1], [1, 3, 2]);
7967       assert.deepEqual(actual, [2, 1]);
7968     });
7969
7970     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
7971       assert.expect(1);
7972
7973       var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
7974       assert.deepEqual(actual, [1, 2]);
7975     });
7976
7977     QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
7978       assert.expect(1);
7979
7980       var actual = func([1, 1, 3, 2, 2]);
7981       assert.deepEqual(actual, [1, 3, 2]);
7982     });
7983
7984     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7985       assert.expect(2);
7986
7987       var array = [0, 1, null, 3],
7988           expected = [1, 3];
7989
7990       assert.deepEqual(func(array, args), expected);
7991       assert.deepEqual(func(args, array), expected);
7992     });
7993
7994     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
7995       assert.expect(1);
7996
7997       var values = [-0, 0],
7998           expected = lodashStable.map(values, lodashStable.constant(['0']));
7999
8000       var actual = lodashStable.map(values, function(value) {
8001         return lodashStable.map(func(values, [value]), lodashStable.toString);
8002       });
8003
8004       assert.deepEqual(actual, expected);
8005     });
8006
8007     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
8008       assert.expect(1);
8009
8010       var actual = func([1, NaN, 3], [NaN, 5, NaN]);
8011       assert.deepEqual(actual, [NaN]);
8012     });
8013
8014     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
8015       assert.expect(1);
8016
8017       var values = [-0, 0],
8018           expected = lodashStable.map(values, lodashStable.constant(['0']));
8019
8020       var actual = lodashStable.map(values, function(value) {
8021         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
8022         return lodashStable.map(func(values, largeArray), lodashStable.toString);
8023       });
8024
8025       assert.deepEqual(actual, expected);
8026     });
8027
8028     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
8029       assert.expect(1);
8030
8031       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
8032       assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
8033     });
8034
8035     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
8036       assert.expect(2);
8037
8038       var object = {},
8039           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
8040
8041       assert.deepEqual(func([object], largeArray), [object]);
8042       assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
8043     });
8044
8045     QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
8046       assert.expect(3);
8047
8048       var array = [0, 1, null, 3];
8049       assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
8050       assert.deepEqual(func(null, array, null, [2, 3]), []);
8051       assert.deepEqual(func(array, null, args, null), []);
8052     });
8053
8054     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
8055       assert.expect(2);
8056
8057       if (!isNpm) {
8058         var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
8059         assert.ok(wrapped instanceof _);
8060         assert.deepEqual(wrapped.value(), [1, 2]);
8061       }
8062       else {
8063         skipAssert(assert, 2);
8064       }
8065     });
8066   });
8067
8068   /*--------------------------------------------------------------------------*/
8069
8070   QUnit.module('lodash.intersectionBy');
8071
8072   (function() {
8073     QUnit.test('should accept an `iteratee` argument', function(assert) {
8074       assert.expect(2);
8075
8076       var actual = _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
8077       assert.deepEqual(actual, [2.1]);
8078
8079       actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8080       assert.deepEqual(actual, [{ 'x': 1 }]);
8081     });
8082
8083     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
8084       assert.expect(1);
8085
8086       var args;
8087
8088       _.intersectionBy([2.1, 1.2], [4.3, 2.4], function() {
8089         args || (args = slice.call(arguments));
8090       });
8091
8092       assert.deepEqual(args, [4.3]);
8093     });
8094   }());
8095
8096   /*--------------------------------------------------------------------------*/
8097
8098   QUnit.module('lodash.intersectionWith');
8099
8100   (function() {
8101     QUnit.test('should work with a `comparator` argument', function(assert) {
8102       assert.expect(1);
8103
8104       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
8105           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
8106           actual = _.intersectionWith(objects, others, lodashStable.isEqual);
8107
8108       assert.deepEqual(actual, [objects[0]]);
8109     });
8110
8111     QUnit.test('should preserve the sign of `0`', function(assert) {
8112       assert.expect(1);
8113
8114       var array = [-0],
8115           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysZero),
8116           others = [[0], largeArray],
8117           expected = lodashStable.map(others, lodashStable.constant(['-0']));
8118
8119       var actual = lodashStable.map(others, function(other) {
8120         return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
8121       });
8122
8123       assert.deepEqual(actual, expected);
8124     });
8125   }());
8126
8127   /*--------------------------------------------------------------------------*/
8128
8129   QUnit.module('lodash.invert');
8130
8131   (function() {
8132     QUnit.test('should invert an object', function(assert) {
8133       assert.expect(2);
8134
8135       var object = { 'a': 1, 'b': 2 },
8136           actual = _.invert(object);
8137
8138       assert.deepEqual(actual, { '1': 'a', '2': 'b' });
8139       assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
8140     });
8141
8142     QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
8143       assert.expect(1);
8144
8145       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
8146       assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
8147     });
8148
8149     QUnit.test('should work with an object that has a `length` property', function(assert) {
8150       assert.expect(1);
8151
8152       var object = { '0': 'a', '1': 'b', 'length': 2 };
8153       assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
8154     });
8155
8156     QUnit.test('should return a wrapped value when chaining', function(assert) {
8157       assert.expect(2);
8158
8159       if (!isNpm) {
8160         var object = { 'a': 1, 'b': 2 },
8161             wrapped = _(object).invert();
8162
8163         assert.ok(wrapped instanceof _);
8164         assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
8165       }
8166       else {
8167         skipAssert(assert, 2);
8168       }
8169     });
8170   }());
8171
8172   /*--------------------------------------------------------------------------*/
8173
8174   QUnit.module('lodash.invertBy');
8175
8176   (function() {
8177     var object = { 'a': 1, 'b': 2, 'c': 1 };
8178
8179     QUnit.test('should transform keys by `iteratee`', function(assert) {
8180       assert.expect(1);
8181
8182       var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
8183
8184       var actual = _.invertBy(object, function(value) {
8185         return 'group' + value;
8186       });
8187
8188       assert.deepEqual(actual, expected);
8189     });
8190
8191     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
8192       assert.expect(1);
8193
8194       var values = [, null, undefined],
8195           expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
8196
8197       var actual = lodashStable.map(values, function(value, index) {
8198         return index ? _.invertBy(object, value) : _.invertBy(object);
8199       });
8200
8201       assert.deepEqual(actual, expected);
8202     });
8203
8204     QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
8205       assert.expect(1);
8206
8207       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
8208           expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
8209
8210       assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
8211     });
8212
8213     QUnit.test('should return a wrapped value when chaining', function(assert) {
8214       assert.expect(2);
8215
8216       if (!isNpm) {
8217         var wrapped = _(object).invertBy();
8218
8219         assert.ok(wrapped instanceof _);
8220         assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
8221       }
8222       else {
8223         skipAssert(assert, 2);
8224       }
8225     });
8226   }());
8227
8228   /*--------------------------------------------------------------------------*/
8229
8230   QUnit.module('lodash.invoke');
8231
8232   (function() {
8233     QUnit.test('should invoke a method on `object`', function(assert) {
8234       assert.expect(1);
8235
8236       var object = { 'a': lodashStable.constant('A') },
8237           actual = _.invoke(object, 'a');
8238
8239       assert.strictEqual(actual, 'A');
8240     });
8241
8242     QUnit.test('should support invoking with arguments', function(assert) {
8243       assert.expect(1);
8244
8245       var object = { 'a': function(a, b) { return [a, b]; } },
8246           actual = _.invoke(object, 'a', 1, 2);
8247
8248       assert.deepEqual(actual, [1, 2]);
8249     });
8250
8251     QUnit.test('should not error on nullish elements', function(assert) {
8252       assert.expect(1);
8253
8254       var values = [null, undefined],
8255           expected = lodashStable.map(values, noop);
8256
8257       var actual = lodashStable.map(values, function(value) {
8258         try {
8259           return _.invoke(value, 'a.b', 1, 2);
8260         } catch (e) {}
8261       });
8262
8263       assert.deepEqual(actual, expected);
8264     });
8265
8266     QUnit.test('should preserve the sign of `0`', function(assert) {
8267       assert.expect(1);
8268
8269       var object = { '-0': alwaysA, '0': alwaysB },
8270           props = [-0, Object(-0), 0, Object(0)];
8271
8272       var actual = lodashStable.map(props, function(key) {
8273         return _.invoke(object, key);
8274       });
8275
8276       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
8277     });
8278
8279     QUnit.test('should support deep paths', function(assert) {
8280       assert.expect(2);
8281
8282       var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
8283
8284       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8285         var actual = _.invoke(object, path, 1, 2);
8286         assert.deepEqual(actual, [1, 2]);
8287       });
8288     });
8289
8290     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8291       assert.expect(2);
8292
8293       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8294
8295       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8296         assert.deepEqual(_.invoke(object, path), 1);
8297       });
8298     });
8299
8300     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8301       assert.expect(1);
8302
8303       if (!isNpm) {
8304         var object = { 'a': alwaysOne };
8305         assert.strictEqual(_(object).invoke('a'), 1);
8306       }
8307       else {
8308         skipAssert(assert);
8309       }
8310     });
8311
8312     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8313       assert.expect(1);
8314
8315       if (!isNpm) {
8316         var object = { 'a': alwaysOne };
8317         assert.ok(_(object).chain().invoke('a') instanceof _);
8318       }
8319       else {
8320         skipAssert(assert);
8321       }
8322     });
8323   }());
8324
8325   /*--------------------------------------------------------------------------*/
8326
8327   QUnit.module('lodash.invokeMap');
8328
8329   (function() {
8330     QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
8331       assert.expect(1);
8332
8333       var array = ['a', 'b', 'c'],
8334           actual = _.invokeMap(array, 'toUpperCase');
8335
8336       assert.deepEqual(actual, ['A', 'B', 'C']);
8337     });
8338
8339     QUnit.test('should support invoking with arguments', function(assert) {
8340       assert.expect(1);
8341
8342       var array = [function() { return slice.call(arguments); }],
8343           actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
8344
8345       assert.deepEqual(actual, [['a', 'b', 'c']]);
8346     });
8347
8348     QUnit.test('should work with a function for `methodName`', function(assert) {
8349       assert.expect(1);
8350
8351       var array = ['a', 'b', 'c'];
8352
8353       var actual = _.invokeMap(array, function(left, right) {
8354         return left + this.toUpperCase() + right;
8355       }, '(', ')');
8356
8357       assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
8358     });
8359
8360     QUnit.test('should work with an object for `collection`', function(assert) {
8361       assert.expect(1);
8362
8363       var object = { 'a': 1, 'b': 2, 'c': 3 },
8364           actual = _.invokeMap(object, 'toFixed', 1);
8365
8366       assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
8367     });
8368
8369     QUnit.test('should treat number values for `collection` as empty', function(assert) {
8370       assert.expect(1);
8371
8372       assert.deepEqual(_.invokeMap(1), []);
8373     });
8374
8375     QUnit.test('should not error on nullish elements', function(assert) {
8376       assert.expect(1);
8377
8378       var array = ['a', null, undefined, 'd'];
8379
8380       try {
8381         var actual = _.invokeMap(array, 'toUpperCase');
8382       } catch (e) {}
8383
8384       assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
8385     });
8386
8387     QUnit.test('should not error on elements with missing properties', function(assert) {
8388       assert.expect(1);
8389
8390       var objects = lodashStable.map([null, undefined, alwaysOne], function(value) {
8391         return { 'a': value };
8392       });
8393
8394       var expected = lodashStable.map(objects, function(object) {
8395         return object.a ? object.a() : undefined;
8396       });
8397
8398       try {
8399         var actual = _.invokeMap(objects, 'a');
8400       } catch (e) {}
8401
8402       assert.deepEqual(actual, expected);
8403     });
8404
8405     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8406       assert.expect(2);
8407
8408       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8409
8410       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8411         assert.deepEqual(_.invokeMap([object], path), [1]);
8412       });
8413     });
8414
8415     QUnit.test('should return a wrapped value when chaining', function(assert) {
8416       assert.expect(4);
8417
8418       if (!isNpm) {
8419         var array = ['a', 'b', 'c'],
8420             wrapped = _(array),
8421             actual = wrapped.invokeMap('toUpperCase');
8422
8423         assert.ok(actual instanceof _);
8424         assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8425
8426         actual = wrapped.invokeMap(function(left, right) {
8427           return left + this.toUpperCase() + right;
8428         }, '(', ')');
8429
8430         assert.ok(actual instanceof _);
8431         assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8432       }
8433       else {
8434         skipAssert(assert, 4);
8435       }
8436     });
8437
8438     QUnit.test('should support shortcut fusion', function(assert) {
8439       assert.expect(2);
8440
8441       if (!isNpm) {
8442         var count = 0,
8443             method = function() { count++; return this.index; };
8444
8445         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8446           return { 'index': index, 'method': method };
8447         });
8448
8449         var actual = _(array).invokeMap('method').take(1).value();
8450
8451         assert.strictEqual(count, 1);
8452         assert.deepEqual(actual, [0]);
8453       }
8454       else {
8455         skipAssert(assert, 2);
8456       }
8457     });
8458   }());
8459
8460   /*--------------------------------------------------------------------------*/
8461
8462   QUnit.module('lodash.isArguments');
8463
8464   (function() {
8465     var args = (function() { return arguments; }(1, 2, 3)),
8466         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
8467
8468     QUnit.test('should return `true` for `arguments` objects', function(assert) {
8469       assert.expect(2);
8470
8471       assert.strictEqual(_.isArguments(args), true);
8472       assert.strictEqual(_.isArguments(strictArgs), true);
8473     });
8474
8475     QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8476       assert.expect(12);
8477
8478       var expected = lodashStable.map(falsey, alwaysFalse);
8479
8480       var actual = lodashStable.map(falsey, function(value, index) {
8481         return index ? _.isArguments(value) : _.isArguments();
8482       });
8483
8484       assert.deepEqual(actual, expected);
8485
8486       assert.strictEqual(_.isArguments([1, 2, 3]), false);
8487       assert.strictEqual(_.isArguments(true), false);
8488       assert.strictEqual(_.isArguments(new Date), false);
8489       assert.strictEqual(_.isArguments(new Error), false);
8490       assert.strictEqual(_.isArguments(_), false);
8491       assert.strictEqual(_.isArguments(slice), false);
8492       assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8493       assert.strictEqual(_.isArguments(1), false);
8494       assert.strictEqual(_.isArguments(/x/), false);
8495       assert.strictEqual(_.isArguments('a'), false);
8496       assert.strictEqual(_.isArguments(symbol), false);
8497     });
8498
8499     QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8500       assert.expect(1);
8501
8502       if (realm.arguments) {
8503         assert.strictEqual(_.isArguments(realm.arguments), true);
8504       }
8505       else {
8506         skipAssert(assert);
8507       }
8508     });
8509   }());
8510
8511   /*--------------------------------------------------------------------------*/
8512
8513   QUnit.module('lodash.isArray');
8514
8515   (function() {
8516     var args = arguments;
8517
8518     QUnit.test('should return `true` for arrays', function(assert) {
8519       assert.expect(1);
8520
8521       assert.strictEqual(_.isArray([1, 2, 3]), true);
8522     });
8523
8524     QUnit.test('should return `false` for non-arrays', function(assert) {
8525       assert.expect(12);
8526
8527       var expected = lodashStable.map(falsey, alwaysFalse);
8528
8529       var actual = lodashStable.map(falsey, function(value, index) {
8530         return index ? _.isArray(value) : _.isArray();
8531       });
8532
8533       assert.deepEqual(actual, expected);
8534
8535       assert.strictEqual(_.isArray(args), false);
8536       assert.strictEqual(_.isArray(true), false);
8537       assert.strictEqual(_.isArray(new Date), false);
8538       assert.strictEqual(_.isArray(new Error), false);
8539       assert.strictEqual(_.isArray(_), false);
8540       assert.strictEqual(_.isArray(slice), false);
8541       assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
8542       assert.strictEqual(_.isArray(1), false);
8543       assert.strictEqual(_.isArray(/x/), false);
8544       assert.strictEqual(_.isArray('a'), false);
8545       assert.strictEqual(_.isArray(symbol), false);
8546     });
8547
8548     QUnit.test('should work with an array from another realm', function(assert) {
8549       assert.expect(1);
8550
8551       if (realm.array) {
8552         assert.strictEqual(_.isArray(realm.array), true);
8553       }
8554       else {
8555         skipAssert(assert);
8556       }
8557     });
8558   }(1, 2, 3));
8559
8560   /*--------------------------------------------------------------------------*/
8561
8562   QUnit.module('lodash.isArrayBuffer');
8563
8564   (function() {
8565     var args = arguments;
8566
8567     QUnit.test('should return `true` for array buffers', function(assert) {
8568       assert.expect(1);
8569
8570       if (ArrayBuffer) {
8571         assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
8572       }
8573       else {
8574         skipAssert(assert);
8575       }
8576     });
8577
8578     QUnit.test('should return `false` for non array buffers', function(assert) {
8579       assert.expect(13);
8580
8581       var expected = lodashStable.map(falsey, alwaysFalse);
8582
8583       var actual = lodashStable.map(falsey, function(value, index) {
8584         return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
8585       });
8586
8587       assert.deepEqual(actual, expected);
8588
8589       assert.strictEqual(_.isArrayBuffer(args), false);
8590       assert.strictEqual(_.isArrayBuffer([1, 2, 3]), false);
8591       assert.strictEqual(_.isArrayBuffer(true), false);
8592       assert.strictEqual(_.isArrayBuffer(new Date), false);
8593       assert.strictEqual(_.isArrayBuffer(new Error), false);
8594       assert.strictEqual(_.isArrayBuffer(_), false);
8595       assert.strictEqual(_.isArrayBuffer(slice), false);
8596       assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
8597       assert.strictEqual(_.isArrayBuffer(1), false);
8598       assert.strictEqual(_.isArrayBuffer(/x/), false);
8599       assert.strictEqual(_.isArrayBuffer('a'), false);
8600       assert.strictEqual(_.isArrayBuffer(symbol), false);
8601     });
8602
8603     QUnit.test('should work with array buffers from another realm', function(assert) {
8604       assert.expect(1);
8605
8606       if (realm.arrayBuffer) {
8607         assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
8608       }
8609       else {
8610         skipAssert(assert);
8611       }
8612     });
8613   }(1, 2, 3));
8614
8615   /*--------------------------------------------------------------------------*/
8616
8617   QUnit.module('lodash.isArrayLike');
8618
8619   (function() {
8620     var args = arguments;
8621
8622     QUnit.test('should return `true` for array-like values', function(assert) {
8623       assert.expect(1);
8624
8625       var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
8626           expected = lodashStable.map(values, alwaysTrue),
8627           actual = lodashStable.map(values, _.isArrayLike);
8628
8629       assert.deepEqual(actual, expected);
8630     });
8631
8632     QUnit.test('should return `false` for non-arrays', function(assert) {
8633       assert.expect(11);
8634
8635       var expected = lodashStable.map(falsey, function(value) {
8636         return value === '';
8637       });
8638
8639       var actual = lodashStable.map(falsey, function(value, index) {
8640         return index ? _.isArrayLike(value) : _.isArrayLike();
8641       });
8642
8643       assert.deepEqual(actual, expected);
8644
8645       assert.strictEqual(_.isArrayLike(true), false);
8646       assert.strictEqual(_.isArrayLike(new Date), false);
8647       assert.strictEqual(_.isArrayLike(new Error), false);
8648       assert.strictEqual(_.isArrayLike(_), false);
8649       assert.strictEqual(_.isArrayLike(generator), false);
8650       assert.strictEqual(_.isArrayLike(slice), false);
8651       assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
8652       assert.strictEqual(_.isArrayLike(1), false);
8653       assert.strictEqual(_.isArrayLike(/x/), false);
8654       assert.strictEqual(_.isArrayLike(symbol), false);
8655     });
8656
8657     QUnit.test('should work with an array from another realm', function(assert) {
8658       assert.expect(1);
8659
8660       if (realm.object) {
8661         var values = [realm.arguments, realm.array, realm.string],
8662             expected = lodashStable.map(values, alwaysTrue),
8663             actual = lodashStable.map(values, _.isArrayLike);
8664
8665         assert.deepEqual(actual, expected);
8666       }
8667       else {
8668         skipAssert(assert);
8669       }
8670     });
8671   }(1, 2, 3));
8672
8673   /*--------------------------------------------------------------------------*/
8674
8675   QUnit.module('lodash.isBoolean');
8676
8677   (function() {
8678     var args = arguments;
8679
8680     QUnit.test('should return `true` for booleans', function(assert) {
8681       assert.expect(4);
8682
8683       assert.strictEqual(_.isBoolean(true), true);
8684       assert.strictEqual(_.isBoolean(false), true);
8685       assert.strictEqual(_.isBoolean(Object(true)), true);
8686       assert.strictEqual(_.isBoolean(Object(false)), true);
8687     });
8688
8689     QUnit.test('should return `false` for non-booleans', function(assert) {
8690       assert.expect(12);
8691
8692       var expected = lodashStable.map(falsey, function(value) {
8693         return value === false;
8694       });
8695
8696       var actual = lodashStable.map(falsey, function(value, index) {
8697         return index ? _.isBoolean(value) : _.isBoolean();
8698       });
8699
8700       assert.deepEqual(actual, expected);
8701
8702       assert.strictEqual(_.isBoolean(args), false);
8703       assert.strictEqual(_.isBoolean([1, 2, 3]), false);
8704       assert.strictEqual(_.isBoolean(new Date), false);
8705       assert.strictEqual(_.isBoolean(new Error), false);
8706       assert.strictEqual(_.isBoolean(_), false);
8707       assert.strictEqual(_.isBoolean(slice), false);
8708       assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
8709       assert.strictEqual(_.isBoolean(1), false);
8710       assert.strictEqual(_.isBoolean(/x/), false);
8711       assert.strictEqual(_.isBoolean('a'), false);
8712       assert.strictEqual(_.isBoolean(symbol), false);
8713     });
8714
8715     QUnit.test('should work with a boolean from another realm', function(assert) {
8716       assert.expect(1);
8717
8718       if (realm.boolean) {
8719         assert.strictEqual(_.isBoolean(realm.boolean), true);
8720       }
8721       else {
8722         skipAssert(assert);
8723       }
8724     });
8725   }(1, 2, 3));
8726
8727   /*--------------------------------------------------------------------------*/
8728
8729   QUnit.module('lodash.isBuffer');
8730
8731   (function() {
8732     var args = arguments;
8733
8734     QUnit.test('should return `true` for buffers', function(assert) {
8735       assert.expect(1);
8736
8737       if (Buffer) {
8738         assert.strictEqual(_.isBuffer(new Buffer(2)), true);
8739       }
8740       else {
8741         skipAssert(assert);
8742       }
8743     });
8744
8745     QUnit.test('should return `false` for non-buffers', function(assert) {
8746       assert.expect(13);
8747
8748       var expected = lodashStable.map(falsey, alwaysFalse);
8749
8750       var actual = lodashStable.map(falsey, function(value, index) {
8751         return index ? _.isBuffer(value) : _.isBuffer();
8752       });
8753
8754       assert.deepEqual(actual, expected);
8755
8756       assert.strictEqual(_.isBuffer(args), false);
8757       assert.strictEqual(_.isBuffer([1, 2, 3]), false);
8758       assert.strictEqual(_.isBuffer(true), false);
8759       assert.strictEqual(_.isBuffer(new Date), false);
8760       assert.strictEqual(_.isBuffer(new Error), false);
8761       assert.strictEqual(_.isBuffer(_), false);
8762       assert.strictEqual(_.isBuffer(slice), false);
8763       assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
8764       assert.strictEqual(_.isBuffer(1), false);
8765       assert.strictEqual(_.isBuffer(/x/), false);
8766       assert.strictEqual(_.isBuffer('a'), false);
8767       assert.strictEqual(_.isBuffer(symbol), false);
8768     });
8769
8770     QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
8771       assert.expect(1);
8772
8773       if (!isStrict && Buffer && lodashBizarro) {
8774         assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
8775       }
8776       else {
8777         skipAssert(assert);
8778       }
8779     });
8780   }(1, 2, 3));
8781
8782   /*--------------------------------------------------------------------------*/
8783
8784   QUnit.module('lodash.isDate');
8785
8786   (function() {
8787     var args = arguments;
8788
8789     QUnit.test('should return `true` for dates', function(assert) {
8790       assert.expect(1);
8791
8792       assert.strictEqual(_.isDate(new Date), true);
8793     });
8794
8795     QUnit.test('should return `false` for non-dates', function(assert) {
8796       assert.expect(12);
8797
8798       var expected = lodashStable.map(falsey, alwaysFalse);
8799
8800       var actual = lodashStable.map(falsey, function(value, index) {
8801         return index ? _.isDate(value) : _.isDate();
8802       });
8803
8804       assert.deepEqual(actual, expected);
8805
8806       assert.strictEqual(_.isDate(args), false);
8807       assert.strictEqual(_.isDate([1, 2, 3]), false);
8808       assert.strictEqual(_.isDate(true), false);
8809       assert.strictEqual(_.isDate(new Error), false);
8810       assert.strictEqual(_.isDate(_), false);
8811       assert.strictEqual(_.isDate(slice), false);
8812       assert.strictEqual(_.isDate({ 'a': 1 }), false);
8813       assert.strictEqual(_.isDate(1), false);
8814       assert.strictEqual(_.isDate(/x/), false);
8815       assert.strictEqual(_.isDate('a'), false);
8816       assert.strictEqual(_.isDate(symbol), false);
8817     });
8818
8819     QUnit.test('should work with a date object from another realm', function(assert) {
8820       assert.expect(1);
8821
8822       if (realm.date) {
8823         assert.strictEqual(_.isDate(realm.date), true);
8824       }
8825       else {
8826         skipAssert(assert);
8827       }
8828     });
8829   }(1, 2, 3));
8830
8831   /*--------------------------------------------------------------------------*/
8832
8833   QUnit.module('lodash.isElement');
8834
8835   (function() {
8836     var args = arguments;
8837
8838     function Element() {
8839       this.nodeType = 1;
8840     }
8841
8842     QUnit.test('should return `false` for plain objects', function(assert) {
8843       assert.expect(7);
8844
8845       var element = body || new Element;
8846
8847       assert.strictEqual(_.isElement(element), true);
8848       assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
8849       assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
8850       assert.strictEqual(_.isElement({ 'nodeType': true }), false);
8851       assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
8852       assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
8853       assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
8854     });
8855
8856     QUnit.test('should return `false` for non DOM elements', function(assert) {
8857       assert.expect(13);
8858
8859       var expected = lodashStable.map(falsey, alwaysFalse);
8860
8861       var actual = lodashStable.map(falsey, function(value, index) {
8862         return index ? _.isElement(value) : _.isElement();
8863       });
8864
8865       assert.deepEqual(actual, expected);
8866
8867       assert.strictEqual(_.isElement(args), false);
8868       assert.strictEqual(_.isElement([1, 2, 3]), false);
8869       assert.strictEqual(_.isElement(true), false);
8870       assert.strictEqual(_.isElement(new Date), false);
8871       assert.strictEqual(_.isElement(new Error), false);
8872       assert.strictEqual(_.isElement(_), false);
8873       assert.strictEqual(_.isElement(slice), false);
8874       assert.strictEqual(_.isElement({ 'a': 1 }), false);
8875       assert.strictEqual(_.isElement(1), false);
8876       assert.strictEqual(_.isElement(/x/), false);
8877       assert.strictEqual(_.isElement('a'), false);
8878       assert.strictEqual(_.isElement(symbol), false);
8879     });
8880
8881     QUnit.test('should work with a DOM element from another realm', function(assert) {
8882       assert.expect(1);
8883
8884       if (realm.element) {
8885         assert.strictEqual(_.isElement(realm.element), true);
8886       }
8887       else {
8888         skipAssert(assert);
8889       }
8890     });
8891   }(1, 2, 3));
8892
8893   /*--------------------------------------------------------------------------*/
8894
8895   QUnit.module('lodash.isEmpty');
8896
8897   (function() {
8898     var args = arguments;
8899
8900     QUnit.test('should return `true` for empty values', function(assert) {
8901       assert.expect(10);
8902
8903       var expected = lodashStable.map(empties, alwaysTrue),
8904           actual = lodashStable.map(empties, _.isEmpty);
8905
8906       assert.deepEqual(actual, expected);
8907
8908       assert.strictEqual(_.isEmpty(true), true);
8909       assert.strictEqual(_.isEmpty(slice), true);
8910       assert.strictEqual(_.isEmpty(1), true);
8911       assert.strictEqual(_.isEmpty(NaN), true);
8912       assert.strictEqual(_.isEmpty(/x/), true);
8913       assert.strictEqual(_.isEmpty(symbol), true);
8914       assert.strictEqual(_.isEmpty(), true);
8915
8916       if (Buffer) {
8917         assert.strictEqual(_.isEmpty(new Buffer(0)), true);
8918         assert.strictEqual(_.isEmpty(new Buffer(1)), false);
8919       }
8920       else {
8921         skipAssert(assert, 2);
8922       }
8923     });
8924
8925     QUnit.test('should return `false` for non-empty values', function(assert) {
8926       assert.expect(3);
8927
8928       assert.strictEqual(_.isEmpty([0]), false);
8929       assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
8930       assert.strictEqual(_.isEmpty('a'), false);
8931     });
8932
8933     QUnit.test('should work with an object that has a `length` property', function(assert) {
8934       assert.expect(1);
8935
8936       assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
8937     });
8938
8939     QUnit.test('should work with `arguments` objects', function(assert) {
8940       assert.expect(1);
8941
8942       assert.strictEqual(_.isEmpty(args), false);
8943     });
8944
8945     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
8946       assert.expect(1);
8947
8948       function Foo(elements) {
8949         push.apply(this, elements);
8950       }
8951       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
8952
8953       assert.strictEqual(_.isEmpty(new Foo([])), true);
8954     });
8955
8956     QUnit.test('should work with maps', function(assert) {
8957       assert.expect(4);
8958
8959       if (Map) {
8960         lodashStable.each([new Map, realm.map], function(map) {
8961           assert.strictEqual(_.isEmpty(map), true);
8962           map.set('a', 1);
8963           assert.strictEqual(_.isEmpty(map), false);
8964           map.clear();
8965         });
8966       }
8967       else {
8968         skipAssert(assert, 4);
8969       }
8970     });
8971
8972     QUnit.test('should work with sets', function(assert) {
8973       assert.expect(4);
8974
8975       if (Set) {
8976         lodashStable.each([new Set, realm.set], function(set) {
8977           assert.strictEqual(_.isEmpty(set), true);
8978           set.add(1);
8979           assert.strictEqual(_.isEmpty(set), false);
8980           set.clear();
8981         });
8982       }
8983       else {
8984         skipAssert(assert, 4);
8985       }
8986     });
8987
8988     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
8989       assert.expect(1);
8990
8991       function Foo() {}
8992       Foo.prototype.length = -1;
8993
8994       assert.strictEqual(_.isEmpty(new Foo), true);
8995     });
8996
8997     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
8998       assert.expect(1);
8999
9000       function Foo() {}
9001       Foo.prototype.length = MAX_SAFE_INTEGER + 1;
9002
9003       assert.strictEqual(_.isEmpty(new Foo), true);
9004     });
9005
9006     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
9007       assert.expect(1);
9008
9009       assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
9010     });
9011
9012     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9013       assert.expect(1);
9014
9015       if (!isNpm) {
9016         assert.strictEqual(_({}).isEmpty(), true);
9017       }
9018       else {
9019         skipAssert(assert);
9020       }
9021     });
9022
9023     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9024       assert.expect(1);
9025
9026       if (!isNpm) {
9027         assert.ok(_({}).chain().isEmpty() instanceof _);
9028       }
9029       else {
9030         skipAssert(assert);
9031       }
9032     });
9033   }(1, 2, 3));
9034
9035   /*--------------------------------------------------------------------------*/
9036
9037   QUnit.module('lodash.isEqual');
9038
9039   (function() {
9040     var symbol1 = Symbol ? Symbol('a') : true,
9041         symbol2 = Symbol ? Symbol('b') : false;
9042
9043     QUnit.test('should compare primitives', function(assert) {
9044       assert.expect(1);
9045
9046       var pairs = [
9047         [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
9048         [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
9049         [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
9050         ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
9051         [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
9052         [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
9053         [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
9054         [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
9055         [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
9056       ];
9057
9058       var expected = lodashStable.map(pairs, function(pair) {
9059         return pair[2];
9060       });
9061
9062       var actual = lodashStable.map(pairs, function(pair) {
9063         return _.isEqual(pair[0], pair[1]);
9064       });
9065
9066       assert.deepEqual(actual, expected);
9067     });
9068
9069     QUnit.test('should compare arrays', function(assert) {
9070       assert.expect(6);
9071
9072       var array1 = [true, null, 1, 'a', undefined],
9073           array2 = [true, null, 1, 'a', undefined];
9074
9075       assert.strictEqual(_.isEqual(array1, array2), true);
9076
9077       array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9078       array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9079
9080       assert.strictEqual(_.isEqual(array1, array2), true);
9081
9082       array1 = [1];
9083       array1[2] = 3;
9084
9085       array2 = [1];
9086       array2[1] = undefined;
9087       array2[2] = 3;
9088
9089       assert.strictEqual(_.isEqual(array1, array2), true);
9090
9091       array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
9092       array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
9093
9094       assert.strictEqual(_.isEqual(array1, array2), true);
9095
9096       array1 = [1, 2, 3];
9097       array2 = [3, 2, 1];
9098
9099       assert.strictEqual(_.isEqual(array1, array2), false);
9100
9101       array1 = [1, 2];
9102       array2 = [1, 2, 3];
9103
9104       assert.strictEqual(_.isEqual(array1, array2), false);
9105     });
9106
9107     QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
9108       assert.expect(3);
9109
9110       var array1 = [1, 2, 3],
9111           array2 = [1, 2, 3];
9112
9113       array1.every = array1.filter = array1.forEach =
9114       array1.indexOf = array1.lastIndexOf = array1.map =
9115       array1.some = array1.reduce = array1.reduceRight = null;
9116
9117       array2.concat = array2.join = array2.pop =
9118       array2.reverse = array2.shift = array2.slice =
9119       array2.sort = array2.splice = array2.unshift = null;
9120
9121       assert.strictEqual(_.isEqual(array1, array2), true);
9122
9123       array1 = [1, 2, 3];
9124       array1.a = 1;
9125
9126       array2 = [1, 2, 3];
9127       array2.b = 1;
9128
9129       assert.strictEqual(_.isEqual(array1, array2), true);
9130
9131       array1 = /c/.exec('abcde');
9132       array2 = ['c'];
9133
9134       assert.strictEqual(_.isEqual(array1, array2), true);
9135     });
9136
9137     QUnit.test('should compare sparse arrays', function(assert) {
9138       assert.expect(3);
9139
9140       var array = Array(1);
9141
9142       assert.strictEqual(_.isEqual(array, Array(1)), true);
9143       assert.strictEqual(_.isEqual(array, [undefined]), true);
9144       assert.strictEqual(_.isEqual(array, Array(2)), false);
9145     });
9146
9147     QUnit.test('should compare plain objects', function(assert) {
9148       assert.expect(5);
9149
9150       var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
9151           object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
9152
9153       assert.strictEqual(_.isEqual(object1, object2), true);
9154
9155       object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9156       object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9157
9158       assert.strictEqual(_.isEqual(object1, object2), true);
9159
9160       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9161       object2 = { 'a': 3, 'b': 2, 'c': 1 };
9162
9163       assert.strictEqual(_.isEqual(object1, object2), false);
9164
9165       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9166       object2 = { 'd': 1, 'e': 2, 'f': 3 };
9167
9168       assert.strictEqual(_.isEqual(object1, object2), false);
9169
9170       object1 = { 'a': 1, 'b': 2 };
9171       object2 = { 'a': 1, 'b': 2, 'c': 3 };
9172
9173       assert.strictEqual(_.isEqual(object1, object2), false);
9174     });
9175
9176     QUnit.test('should compare objects regardless of key order', function(assert) {
9177       assert.expect(1);
9178
9179       var object1 = { 'a': 1, 'b': 2, 'c': 3 },
9180           object2 = { 'c': 3, 'a': 1, 'b': 2 };
9181
9182       assert.strictEqual(_.isEqual(object1, object2), true);
9183     });
9184
9185     QUnit.test('should compare nested objects', function(assert) {
9186       assert.expect(1);
9187
9188       var object1 = {
9189         'a': [1, 2, 3],
9190         'b': true,
9191         'c': Object(1),
9192         'd': 'a',
9193         'e': {
9194           'f': ['a', Object('b'), 'c'],
9195           'g': Object(false),
9196           'h': new Date(2012, 4, 23),
9197           'i': noop,
9198           'j': 'a'
9199         }
9200       };
9201
9202       var object2 = {
9203         'a': [1, Object(2), 3],
9204         'b': Object(true),
9205         'c': 1,
9206         'd': Object('a'),
9207         'e': {
9208           'f': ['a', 'b', 'c'],
9209           'g': false,
9210           'h': new Date(2012, 4, 23),
9211           'i': noop,
9212           'j': 'a'
9213         }
9214       };
9215
9216       assert.strictEqual(_.isEqual(object1, object2), true);
9217     });
9218
9219     QUnit.test('should compare object instances', function(assert) {
9220       assert.expect(4);
9221
9222       function Foo() {
9223         this.a = 1;
9224       }
9225       Foo.prototype.a = 1;
9226
9227       function Bar() {
9228         this.a = 1;
9229       }
9230       Bar.prototype.a = 2;
9231
9232       assert.strictEqual(_.isEqual(new Foo, new Foo), true);
9233       assert.strictEqual(_.isEqual(new Foo, new Bar), false);
9234       assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
9235       assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
9236     });
9237
9238     QUnit.test('should compare objects with constructor properties', function(assert) {
9239       assert.expect(5);
9240
9241       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
9242       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
9243       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
9244       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
9245       assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
9246     });
9247
9248     QUnit.test('should compare arrays with circular references', function(assert) {
9249       assert.expect(4);
9250
9251       var array1 = [],
9252           array2 = [];
9253
9254       array1.push(array1);
9255       array2.push(array2);
9256
9257       assert.strictEqual(_.isEqual(array1, array2), true);
9258
9259       array1.push('b');
9260       array2.push('b');
9261
9262       assert.strictEqual(_.isEqual(array1, array2), true);
9263
9264       array1.push('c');
9265       array2.push('d');
9266
9267       assert.strictEqual(_.isEqual(array1, array2), false);
9268
9269       array1 = ['a', 'b', 'c'];
9270       array1[1] = array1;
9271       array2 = ['a', ['a', 'b', 'c'], 'c'];
9272
9273       assert.strictEqual(_.isEqual(array1, array2), false);
9274     });
9275
9276     QUnit.test('should compare objects with circular references', function(assert) {
9277       assert.expect(4);
9278
9279       var object1 = {},
9280           object2 = {};
9281
9282       object1.a = object1;
9283       object2.a = object2;
9284
9285       assert.strictEqual(_.isEqual(object1, object2), true);
9286
9287       object1.b = 0;
9288       object2.b = Object(0);
9289
9290       assert.strictEqual(_.isEqual(object1, object2), true);
9291
9292       object1.c = Object(1);
9293       object2.c = Object(2);
9294
9295       assert.strictEqual(_.isEqual(object1, object2), false);
9296
9297       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9298       object1.b = object1;
9299       object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
9300
9301       assert.strictEqual(_.isEqual(object1, object2), false);
9302     });
9303
9304     QUnit.test('should compare objects with multiple circular references', function(assert) {
9305       assert.expect(3);
9306
9307       var array1 = [{}],
9308           array2 = [{}];
9309
9310       (array1[0].a = array1).push(array1);
9311       (array2[0].a = array2).push(array2);
9312
9313       assert.strictEqual(_.isEqual(array1, array2), true);
9314
9315       array1[0].b = 0;
9316       array2[0].b = Object(0);
9317
9318       assert.strictEqual(_.isEqual(array1, array2), true);
9319
9320       array1[0].c = Object(1);
9321       array2[0].c = Object(2);
9322
9323       assert.strictEqual(_.isEqual(array1, array2), false);
9324     });
9325
9326     QUnit.test('should compare objects with complex circular references', function(assert) {
9327       assert.expect(1);
9328
9329       var object1 = {
9330         'foo': { 'b': { 'c': { 'd': {} } } },
9331         'bar': { 'a': 2 }
9332       };
9333
9334       var object2 = {
9335         'foo': { 'b': { 'c': { 'd': {} } } },
9336         'bar': { 'a': 2 }
9337       };
9338
9339       object1.foo.b.c.d = object1;
9340       object1.bar.b = object1.foo.b;
9341
9342       object2.foo.b.c.d = object2;
9343       object2.bar.b = object2.foo.b;
9344
9345       assert.strictEqual(_.isEqual(object1, object2), true);
9346     });
9347
9348     QUnit.test('should compare objects with shared property values', function(assert) {
9349       assert.expect(1);
9350
9351       var object1 = {
9352         'a': [1, 2]
9353       };
9354
9355       var object2 = {
9356         'a': [1, 2],
9357         'b': [1, 2]
9358       };
9359
9360       object1.b = object1.a;
9361
9362       assert.strictEqual(_.isEqual(object1, object2), true);
9363     });
9364
9365     QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
9366       assert.expect(2);
9367
9368       function Foo() {
9369         this.a = 1;
9370       }
9371       Foo.prototype.constructor = null;
9372
9373       var object2 = { 'a': 1 };
9374       assert.strictEqual(_.isEqual(new Foo, object2), false);
9375
9376       if (create)  {
9377         var object1 = create(null);
9378         object1.a = 1;
9379         assert.strictEqual(_.isEqual(object1, object2), true);
9380       }
9381       else {
9382         skipAssert(assert);
9383       }
9384     });
9385
9386     QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
9387       assert.expect(1);
9388
9389       var primitive,
9390           object = { 'toString': function() { return primitive; } },
9391           values = [true, null, 1, 'a', undefined],
9392           expected = lodashStable.map(values, alwaysFalse);
9393
9394       var actual = lodashStable.map(values, function(value) {
9395         primitive = value;
9396         return _.isEqual(object, value);
9397       });
9398
9399       assert.deepEqual(actual, expected);
9400     });
9401
9402     QUnit.test('should avoid common type coercions', function(assert) {
9403       assert.expect(9);
9404
9405       assert.strictEqual(_.isEqual(true, Object(false)), false);
9406       assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
9407       assert.strictEqual(_.isEqual(false, Object('')), false);
9408       assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
9409       assert.strictEqual(_.isEqual(0, ''), false);
9410       assert.strictEqual(_.isEqual(1, true), false);
9411       assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
9412       assert.strictEqual(_.isEqual('36', 36), false);
9413       assert.strictEqual(_.isEqual(36, '36'), false);
9414     });
9415
9416     QUnit.test('should compare `arguments` objects', function(assert) {
9417       assert.expect(2);
9418
9419       var args1 = (function() { return arguments; }(1, 2, 3)),
9420           args2 = (function() { return arguments; }(1, 2, 3)),
9421           args3 = (function() { return arguments; }(1, 2));
9422
9423       assert.strictEqual(_.isEqual(args1, args2), true);
9424       assert.strictEqual(_.isEqual(args1, args3), false);
9425     });
9426
9427     QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
9428       assert.expect(4);
9429
9430       var args = (function() { return arguments; }(1, 2, 3)),
9431           object = { '0': 1, '1': 2, '2': 3 };
9432
9433       function Foo() {}
9434       Foo.prototype = object;
9435
9436       assert.strictEqual(_.isEqual(args, object), true);
9437       assert.strictEqual(_.isEqual(object, args), true);
9438
9439       assert.strictEqual(_.isEqual(args, new Foo), false);
9440       assert.strictEqual(_.isEqual(new Foo, args), false);
9441     });
9442
9443     QUnit.test('should compare array buffers', function(assert) {
9444       assert.expect(2);
9445
9446       if (ArrayBuffer) {
9447         var buffer1 = new ArrayBuffer(4),
9448             buffer2 = new ArrayBuffer(8);
9449
9450         assert.strictEqual(_.isEqual(buffer1, buffer2), false);
9451
9452         buffer1 = new Int8Array([-1]).buffer;
9453         buffer2 = new Uint8Array([255]).buffer;
9454
9455         assert.strictEqual(_.isEqual(buffer1, buffer2), true);
9456       }
9457       else {
9458         skipAssert(assert, 2);
9459       }
9460     });
9461
9462     QUnit.test('should compare array views', function(assert) {
9463       assert.expect(2);
9464
9465       lodashStable.times(2, function(index) {
9466         var ns = index ? realm : root;
9467
9468         var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
9469           var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
9470               CtorA = ns[type] || function(n) { this.n = n; },
9471               CtorB = ns[otherType] || function(n) { this.n = n; },
9472               bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
9473               bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
9474               bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
9475
9476           return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
9477         });
9478
9479         var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9480
9481         var actual = lodashStable.map(pairs, function(pair) {
9482           return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9483         });
9484
9485         assert.deepEqual(actual, expected);
9486       });
9487     });
9488
9489     QUnit.test('should compare date objects', function(assert) {
9490       assert.expect(4);
9491
9492       var date = new Date(2012, 4, 23);
9493
9494       assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
9495       assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
9496       assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
9497       assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
9498     });
9499
9500     QUnit.test('should compare error objects', function(assert) {
9501       assert.expect(1);
9502
9503       var pairs = lodashStable.map([
9504         'Error',
9505         'EvalError',
9506         'RangeError',
9507         'ReferenceError',
9508         'SyntaxError',
9509         'TypeError',
9510         'URIError'
9511       ], function(type, index, errorTypes) {
9512         var otherType = errorTypes[++index % errorTypes.length],
9513             CtorA = root[type],
9514             CtorB = root[otherType];
9515
9516         return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
9517       });
9518
9519       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9520
9521       var actual = lodashStable.map(pairs, function(pair) {
9522         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9523       });
9524
9525       assert.deepEqual(actual, expected);
9526     });
9527
9528     QUnit.test('should compare functions', function(assert) {
9529       assert.expect(2);
9530
9531       function a() { return 1 + 2; }
9532       function b() { return 1 + 2; }
9533
9534       assert.strictEqual(_.isEqual(a, a), true);
9535       assert.strictEqual(_.isEqual(a, b), false);
9536     });
9537
9538     QUnit.test('should compare maps', function(assert) {
9539       assert.expect(8);
9540
9541       if (Map) {
9542         lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
9543           var map1 = maps[0],
9544               map2 = maps[1];
9545
9546           map1.set('a', 1);
9547           map2.set('b', 2);
9548           assert.strictEqual(_.isEqual(map1, map2), false);
9549
9550           map1.set('b', 2);
9551           map2.set('a', 1);
9552           assert.strictEqual(_.isEqual(map1, map2), true);
9553
9554           map1['delete']('a');
9555           map1.set('a', 1);
9556           assert.strictEqual(_.isEqual(map1, map2), true);
9557
9558           map2['delete']('a');
9559           assert.strictEqual(_.isEqual(map1, map2), false);
9560
9561           map1.clear();
9562           map2.clear();
9563         });
9564       }
9565       else {
9566         skipAssert(assert, 8);
9567       }
9568     });
9569
9570     QUnit.test('should compare maps with circular references', function(assert) {
9571       assert.expect(2);
9572
9573       if (Map) {
9574         var map1 = new Map,
9575             map2 = new Map;
9576
9577         map1.set('a', map1);
9578         map2.set('a', map2);
9579         assert.strictEqual(_.isEqual(map1, map2), true);
9580
9581         map1.set('b', 1);
9582         map2.set('b', 2);
9583         assert.strictEqual(_.isEqual(map1, map2), false);
9584       }
9585       else {
9586         skipAssert(assert, 2);
9587       }
9588     });
9589
9590     QUnit.test('should compare promises by reference', function(assert) {
9591       assert.expect(4);
9592
9593       if (promise) {
9594         lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
9595           var promise1 = promises[0],
9596               promise2 = promises[1];
9597
9598           assert.strictEqual(_.isEqual(promise1, promise2), false);
9599           assert.strictEqual(_.isEqual(promise1, promise1), true);
9600         });
9601       }
9602       else {
9603         skipAssert(assert, 4);
9604       }
9605     });
9606
9607     QUnit.test('should compare regexes', function(assert) {
9608       assert.expect(5);
9609
9610       assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
9611       assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
9612       assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
9613       assert.strictEqual(_.isEqual(/x/, /y/), false);
9614       assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
9615     });
9616
9617     QUnit.test('should compare sets', function(assert) {
9618       assert.expect(8);
9619
9620       if (Set) {
9621         lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
9622           var set1 = sets[0],
9623               set2 = sets[1];
9624
9625           set1.add(1);
9626           set2.add(2);
9627           assert.strictEqual(_.isEqual(set1, set2), false);
9628
9629           set1.add(2);
9630           set2.add(1);
9631           assert.strictEqual(_.isEqual(set1, set2), true);
9632
9633           set1['delete'](1);
9634           set1.add(1);
9635           assert.strictEqual(_.isEqual(set1, set2), true);
9636
9637           set2['delete'](1);
9638           assert.strictEqual(_.isEqual(set1, set2), false);
9639
9640           set1.clear();
9641           set2.clear();
9642         });
9643       }
9644       else {
9645         skipAssert(assert, 8);
9646       }
9647     });
9648
9649     QUnit.test('should compare sets with circular references', function(assert) {
9650       assert.expect(2);
9651
9652       if (Set) {
9653         var set1 = new Set,
9654             set2 = new Set;
9655
9656         set1.add(set1);
9657         set2.add(set2);
9658         assert.strictEqual(_.isEqual(set1, set2), true);
9659
9660         set1.add(1);
9661         set2.add(2);
9662         assert.strictEqual(_.isEqual(set1, set2), false);
9663       }
9664       else {
9665         skipAssert(assert, 2);
9666       }
9667     });
9668
9669     QUnit.test('should work as an iteratee for `_.every`', function(assert) {
9670       assert.expect(1);
9671
9672       var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
9673       assert.ok(actual);
9674     });
9675
9676     QUnit.test('should return `true` for like-objects from different documents', function(assert) {
9677       assert.expect(4);
9678
9679       if (realm.object) {
9680         assert.strictEqual(_.isEqual([1], realm.array), true);
9681         assert.strictEqual(_.isEqual([2], realm.array), false);
9682         assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
9683         assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
9684       }
9685       else {
9686         skipAssert(assert, 4);
9687       }
9688     });
9689
9690     QUnit.test('should not error on DOM elements', function(assert) {
9691       assert.expect(1);
9692
9693       if (document) {
9694         var element1 = document.createElement('div'),
9695             element2 = element1.cloneNode(true);
9696
9697         try {
9698           assert.strictEqual(_.isEqual(element1, element2), false);
9699         } catch (e) {
9700           assert.ok(false, e.message);
9701         }
9702       }
9703       else {
9704         skipAssert(assert);
9705       }
9706     });
9707
9708     QUnit.test('should compare wrapped values', function(assert) {
9709       assert.expect(32);
9710
9711       var stamp = +new Date;
9712
9713       var values = [
9714         [[1, 2], [1, 2], [1, 2, 3]],
9715         [true, true, false],
9716         [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
9717         [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
9718         [1, 1, 2],
9719         [NaN, NaN, Infinity],
9720         [/x/, /x/, /x/i],
9721         ['a', 'a', 'A']
9722       ];
9723
9724       lodashStable.each(values, function(vals) {
9725         if (!isNpm) {
9726           var wrapped1 = _(vals[0]),
9727               wrapped2 = _(vals[1]),
9728               actual = wrapped1.isEqual(wrapped2);
9729
9730           assert.strictEqual(actual, true);
9731           assert.strictEqual(_.isEqual(_(actual), _(true)), true);
9732
9733           wrapped1 = _(vals[0]);
9734           wrapped2 = _(vals[2]);
9735
9736           actual = wrapped1.isEqual(wrapped2);
9737           assert.strictEqual(actual, false);
9738           assert.strictEqual(_.isEqual(_(actual), _(false)), true);
9739         }
9740         else {
9741           skipAssert(assert, 4);
9742         }
9743       });
9744     });
9745
9746     QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
9747       assert.expect(4);
9748
9749       if (!isNpm) {
9750         var object1 = _({ 'a': 1, 'b': 2 }),
9751             object2 = { 'a': 1, 'b': 2 };
9752
9753         assert.strictEqual(object1.isEqual(object2), true);
9754         assert.strictEqual(_.isEqual(object1, object2), true);
9755
9756         object1 = _({ 'a': 1, 'b': 2 });
9757         object2 = { 'a': 1, 'b': 1 };
9758
9759         assert.strictEqual(object1.isEqual(object2), false);
9760         assert.strictEqual(_.isEqual(object1, object2), false);
9761       }
9762       else {
9763         skipAssert(assert, 4);
9764       }
9765     });
9766
9767     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9768       assert.expect(1);
9769
9770       if (!isNpm) {
9771         assert.strictEqual(_('a').isEqual('a'), true);
9772       }
9773       else {
9774         skipAssert(assert);
9775       }
9776     });
9777
9778     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9779       assert.expect(1);
9780
9781       if (!isNpm) {
9782         assert.ok(_('a').chain().isEqual('a') instanceof _);
9783       }
9784       else {
9785         skipAssert(assert);
9786       }
9787     });
9788   }());
9789
9790   /*--------------------------------------------------------------------------*/
9791
9792   QUnit.module('lodash.isEqualWith');
9793
9794   (function() {
9795     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
9796       assert.expect(1);
9797
9798       var argsList = [],
9799           object1 = { 'a': [1, 2], 'b': null },
9800           object2 = { 'a': [1, 2], 'b': null };
9801
9802       object1.b = object2;
9803       object2.b = object1;
9804
9805       var expected = [
9806         [object1, object2],
9807         [object1.a, object2.a, 'a', object1, object2],
9808         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
9809         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
9810         [object1.b, object2.b, 'b', object1.b, object2.b],
9811         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
9812         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
9813         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
9814         [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
9815       ];
9816
9817       _.isEqualWith(object1, object2, function(assert) {
9818         var length = arguments.length,
9819             args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9820
9821         argsList.push(args);
9822       });
9823
9824       assert.deepEqual(argsList, expected);
9825     });
9826
9827     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
9828       assert.expect(3);
9829
9830       assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
9831       assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
9832       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
9833     });
9834
9835     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
9836       assert.expect(3);
9837
9838       var customizer = function(value) {
9839         return _.isString(value) || undefined;
9840       };
9841
9842       assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
9843       assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
9844       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
9845     });
9846
9847     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
9848       assert.expect(3);
9849
9850       var customizer = function(value) {
9851         return _.isString(value) ? false : undefined;
9852       };
9853
9854       assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
9855       assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
9856       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
9857     });
9858
9859     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
9860       assert.expect(2);
9861
9862       var actual = _.isEqualWith('a', 'b', alwaysC);
9863       assert.strictEqual(actual, true);
9864
9865       var values = _.without(falsey, undefined),
9866           expected = lodashStable.map(values, alwaysFalse);
9867
9868       actual = [];
9869       lodashStable.each(values, function(value) {
9870         actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
9871       });
9872
9873       assert.deepEqual(actual, expected);
9874     });
9875
9876     QUnit.test('should ensure `customizer` is a function', function(assert) {
9877       assert.expect(1);
9878
9879       var array = [1, 2, 3],
9880           eq = _.partial(_.isEqualWith, array),
9881           actual = lodashStable.map([array, [1, 0, 3]], eq);
9882
9883       assert.deepEqual(actual, [true, false]);
9884     });
9885
9886     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
9887       assert.expect(2);
9888
9889       var value = { 'a': { 'b': 2 } };
9890
9891       if (Map) {
9892         var map1 = new Map;
9893         map1.set('a', value);
9894
9895         var map2 = new Map;
9896         map2.set('a', value);
9897       }
9898       if (Set) {
9899         var set1 = new Set;
9900         set1.add(value);
9901
9902         var set2 = new Set;
9903         set2.add(value);
9904       }
9905       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
9906         if (pair[0]) {
9907           var argsList = [],
9908               array = _.toArray(pair[0]);
9909
9910           var expected = [
9911             [pair[0], pair[1]],
9912             [array[0], array[0], 0, array, array],
9913             [array[0][0], array[0][0], 0, array[0], array[0]],
9914             [array[0][1], array[0][1], 1, array[0], array[0]]
9915           ];
9916
9917           if (index) {
9918             expected.length = 2;
9919           }
9920           _.isEqualWith(pair[0], pair[1], function() {
9921             var length = arguments.length,
9922                 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9923
9924             argsList.push(args);
9925           });
9926
9927           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
9928         }
9929         else {
9930           skipAssert(assert);
9931         }
9932       });
9933     });
9934   }());
9935
9936   /*--------------------------------------------------------------------------*/
9937
9938   QUnit.module('lodash.isError');
9939
9940   (function() {
9941     var args = arguments;
9942
9943     QUnit.test('should return `true` for error objects', function(assert) {
9944       assert.expect(1);
9945
9946       var expected = lodashStable.map(errors, alwaysTrue);
9947
9948       var actual = lodashStable.map(errors, function(error) {
9949         return _.isError(error) === true;
9950       });
9951
9952       assert.deepEqual(actual, expected);
9953     });
9954
9955     QUnit.test('should return `true` for subclassed values', function(assert) {
9956       assert.expect(1);
9957
9958       assert.strictEqual(_.isError(new CustomError('x')), true);
9959     });
9960
9961     QUnit.test('should return `false` for non error objects', function(assert) {
9962       assert.expect(12);
9963
9964       var expected = lodashStable.map(falsey, alwaysFalse);
9965
9966       var actual = lodashStable.map(falsey, function(value, index) {
9967         return index ? _.isError(value) : _.isError();
9968       });
9969
9970       assert.deepEqual(actual, expected);
9971
9972       assert.strictEqual(_.isError(args), false);
9973       assert.strictEqual(_.isError([1, 2, 3]), false);
9974       assert.strictEqual(_.isError(true), false);
9975       assert.strictEqual(_.isError(new Date), false);
9976       assert.strictEqual(_.isError(_), false);
9977       assert.strictEqual(_.isError(slice), false);
9978       assert.strictEqual(_.isError({ 'a': 1 }), false);
9979       assert.strictEqual(_.isError(1), false);
9980       assert.strictEqual(_.isError(/x/), false);
9981       assert.strictEqual(_.isError('a'), false);
9982       assert.strictEqual(_.isError(symbol), false);
9983     });
9984
9985     QUnit.test('should work with an error object from another realm', function(assert) {
9986       assert.expect(1);
9987
9988       if (realm.errors) {
9989         var expected = lodashStable.map(realm.errors, alwaysTrue);
9990
9991         var actual = lodashStable.map(realm.errors, function(error) {
9992           return _.isError(error) === true;
9993         });
9994
9995         assert.deepEqual(actual, expected);
9996       }
9997       else {
9998         skipAssert(assert);
9999       }
10000     });
10001   }(1, 2, 3));
10002
10003   /*--------------------------------------------------------------------------*/
10004
10005   QUnit.module('lodash.isFinite');
10006
10007   (function() {
10008     var args = arguments;
10009
10010     QUnit.test('should return `true` for finite values', function(assert) {
10011       assert.expect(1);
10012
10013       var values = [0, 1, 3.14, -1],
10014           expected = lodashStable.map(values, alwaysTrue),
10015           actual = lodashStable.map(values, _.isFinite);
10016
10017       assert.deepEqual(actual, expected);
10018     });
10019
10020     QUnit.test('should return `false` for non-finite values', function(assert) {
10021       assert.expect(1);
10022
10023       var values = [NaN, Infinity, -Infinity, Object(1)],
10024           expected = lodashStable.map(values, alwaysFalse),
10025           actual = lodashStable.map(values, _.isFinite);
10026
10027       assert.deepEqual(actual, expected);
10028     });
10029
10030     QUnit.test('should return `false` for non-numeric values', function(assert) {
10031       assert.expect(10);
10032
10033       var values = [undefined, [], true, '', ' ', '2px'],
10034           expected = lodashStable.map(values, alwaysFalse),
10035           actual = lodashStable.map(values, _.isFinite);
10036
10037       assert.deepEqual(actual, expected);
10038
10039       assert.strictEqual(_.isFinite(args), false);
10040       assert.strictEqual(_.isFinite([1, 2, 3]), false);
10041       assert.strictEqual(_.isFinite(true), false);
10042       assert.strictEqual(_.isFinite(new Date), false);
10043       assert.strictEqual(_.isFinite(new Error), false);
10044       assert.strictEqual(_.isFinite({ 'a': 1 }), false);
10045       assert.strictEqual(_.isFinite(/x/), false);
10046       assert.strictEqual(_.isFinite('a'), false);
10047       assert.strictEqual(_.isFinite(symbol), false);
10048     });
10049
10050     QUnit.test('should return `false` for numeric string values', function(assert) {
10051       assert.expect(1);
10052
10053       var values = ['2', '0', '08'],
10054           expected = lodashStable.map(values, alwaysFalse),
10055           actual = lodashStable.map(values, _.isFinite);
10056
10057       assert.deepEqual(actual, expected);
10058     });
10059   }(1, 2, 3));
10060
10061   /*--------------------------------------------------------------------------*/
10062
10063   QUnit.module('lodash.isFunction');
10064
10065   (function() {
10066     var args = arguments;
10067
10068     QUnit.test('should return `true` for functions', function(assert) {
10069       assert.expect(2);
10070
10071       assert.strictEqual(_.isFunction(_), true);
10072       assert.strictEqual(_.isFunction(slice), true);
10073     });
10074
10075     QUnit.test('should return `true` for generator functions', function(assert) {
10076       assert.expect(1);
10077
10078       assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
10079     });
10080
10081     QUnit.test('should return `true` for array view constructors', function(assert) {
10082       assert.expect(1);
10083
10084       var expected = lodashStable.map(arrayViews, function(type) {
10085         return objToString.call(root[type]) == funcTag;
10086       });
10087
10088       var actual = lodashStable.map(arrayViews, function(type) {
10089         return _.isFunction(root[type]);
10090       });
10091
10092       assert.deepEqual(actual, expected);
10093     });
10094
10095     QUnit.test('should return `false` for non-functions', function(assert) {
10096       assert.expect(12);
10097
10098       var expected = lodashStable.map(falsey, alwaysFalse);
10099
10100       var actual = lodashStable.map(falsey, function(value, index) {
10101         return index ? _.isFunction(value) : _.isFunction();
10102       });
10103
10104       assert.deepEqual(actual, expected);
10105
10106       assert.strictEqual(_.isFunction(args), false);
10107       assert.strictEqual(_.isFunction([1, 2, 3]), false);
10108       assert.strictEqual(_.isFunction(true), false);
10109       assert.strictEqual(_.isFunction(new Date), false);
10110       assert.strictEqual(_.isFunction(new Error), false);
10111       assert.strictEqual(_.isFunction({ 'a': 1 }), false);
10112       assert.strictEqual(_.isFunction(1), false);
10113       assert.strictEqual(_.isFunction(/x/), false);
10114       assert.strictEqual(_.isFunction('a'), false);
10115       assert.strictEqual(_.isFunction(symbol), false);
10116
10117       if (document) {
10118         assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
10119       } else {
10120         skipAssert(assert);
10121       }
10122     });
10123
10124     QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
10125       assert.expect(2);
10126
10127       // Trigger a Chakra JIT bug.
10128       // See https://github.com/jashkenas/underscore/issues/1621.
10129       lodashStable.each([body, xml], function(object) {
10130         if (object) {
10131           lodashStable.times(100, _.isFunction);
10132           assert.strictEqual(_.isFunction(object), false);
10133         }
10134         else {
10135           skipAssert(assert);
10136         }
10137       });
10138     });
10139
10140     QUnit.test('should work with a function from another realm', function(assert) {
10141       assert.expect(1);
10142
10143       if (realm.function) {
10144         assert.strictEqual(_.isFunction(realm.function), true);
10145       }
10146       else {
10147         skipAssert(assert);
10148       }
10149     });
10150   }(1, 2, 3));
10151
10152   /*--------------------------------------------------------------------------*/
10153
10154   QUnit.module('isInteger methods');
10155
10156   lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
10157     var args = arguments,
10158         func = _[methodName],
10159         isSafe = methodName == 'isSafeInteger';
10160
10161     QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
10162       assert.expect(2);
10163
10164       var values = [-1, 0, 1],
10165           expected = lodashStable.map(values, alwaysTrue);
10166
10167       var actual = lodashStable.map(values, function(value) {
10168         return func(value);
10169       });
10170
10171       assert.deepEqual(actual, expected);
10172       assert.strictEqual(func(MAX_INTEGER), !isSafe);
10173     });
10174
10175     QUnit.test('should return `false` for non-integer number values', function(assert) {
10176       assert.expect(1);
10177
10178       var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
10179           expected = lodashStable.map(values, alwaysFalse);
10180
10181       var actual = lodashStable.map(values, function(value) {
10182         return func(value);
10183       });
10184
10185       assert.deepEqual(actual, expected);
10186     });
10187
10188     QUnit.test('should return `false` for non-numeric values', function(assert) {
10189       assert.expect(10);
10190
10191       var expected = lodashStable.map(falsey, function(value) {
10192         return value === 0;
10193       });
10194
10195       var actual = lodashStable.map(falsey, function(value, index) {
10196         return index ? func(value) : func();
10197       });
10198
10199       assert.deepEqual(actual, expected);
10200
10201       assert.strictEqual(func(args), false);
10202       assert.strictEqual(func([1, 2, 3]), false);
10203       assert.strictEqual(func(true), false);
10204       assert.strictEqual(func(new Date), false);
10205       assert.strictEqual(func(new Error), false);
10206       assert.strictEqual(func({ 'a': 1 }), false);
10207       assert.strictEqual(func(/x/), false);
10208       assert.strictEqual(func('a'), false);
10209       assert.strictEqual(func(symbol), false);
10210     });
10211   });
10212
10213   /*--------------------------------------------------------------------------*/
10214
10215   QUnit.module('lodash.isLength');
10216
10217   (function() {
10218     QUnit.test('should return `true` for lengths', function(assert) {
10219       assert.expect(1);
10220
10221       var values = [0, 3, MAX_SAFE_INTEGER],
10222           expected = lodashStable.map(values, alwaysTrue),
10223           actual = lodashStable.map(values, _.isLength);
10224
10225       assert.deepEqual(actual, expected);
10226     });
10227
10228     QUnit.test('should return `false` for non-lengths', function(assert) {
10229       assert.expect(1);
10230
10231       var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
10232           expected = lodashStable.map(values, alwaysFalse),
10233           actual = lodashStable.map(values, _.isLength);
10234
10235       assert.deepEqual(actual, expected);
10236     });
10237   }());
10238
10239   /*--------------------------------------------------------------------------*/
10240
10241   QUnit.module('lodash.isMap');
10242
10243   (function() {
10244     var args = arguments;
10245
10246     QUnit.test('should return `true` for maps', function(assert) {
10247       assert.expect(1);
10248
10249       if (Map) {
10250         assert.strictEqual(_.isMap(map), true);
10251       }
10252       else {
10253         skipAssert(assert);
10254       }
10255     });
10256
10257     QUnit.test('should return `false` for non-maps', function(assert) {
10258       assert.expect(14);
10259
10260       var expected = lodashStable.map(falsey, alwaysFalse);
10261
10262       var actual = lodashStable.map(falsey, function(value, index) {
10263         return index ? _.isMap(value) : _.isMap();
10264       });
10265
10266       assert.deepEqual(actual, expected);
10267
10268       assert.strictEqual(_.isMap(args), false);
10269       assert.strictEqual(_.isMap([1, 2, 3]), false);
10270       assert.strictEqual(_.isMap(true), false);
10271       assert.strictEqual(_.isMap(new Date), false);
10272       assert.strictEqual(_.isMap(new Error), false);
10273       assert.strictEqual(_.isMap(_), false);
10274       assert.strictEqual(_.isMap(slice), false);
10275       assert.strictEqual(_.isMap({ 'a': 1 }), false);
10276       assert.strictEqual(_.isMap(1), false);
10277       assert.strictEqual(_.isMap(/x/), false);
10278       assert.strictEqual(_.isMap('a'), false);
10279       assert.strictEqual(_.isMap(symbol), false);
10280       assert.strictEqual(_.isMap(weakMap), false);
10281     });
10282
10283     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
10284       assert.expect(1);
10285
10286       var values = [false, true],
10287           expected = lodashStable.map(values, alwaysFalse);
10288
10289       var actual = lodashStable.map(values, function(value) {
10290         return _.isMap({ 'constructor': value });
10291       });
10292
10293       assert.deepEqual(actual, expected);
10294     });
10295
10296     QUnit.test('should work with maps from another realm', function(assert) {
10297       assert.expect(1);
10298
10299       if (realm.map) {
10300         assert.strictEqual(_.isMap(realm.map), true);
10301       }
10302       else {
10303         skipAssert(assert);
10304       }
10305     });
10306   }(1, 2, 3));
10307
10308   /*--------------------------------------------------------------------------*/
10309
10310   QUnit.module('lodash.isMatch');
10311
10312   (function() {
10313     QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
10314       assert.expect(5);
10315
10316       var object = { 'a': 1, 'b': 2, 'c': 3 };
10317       assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
10318       assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
10319       assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
10320       assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
10321
10322       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
10323       assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
10324     });
10325
10326     QUnit.test('should match inherited string keyed `object` properties', function(assert) {
10327       assert.expect(1);
10328
10329       function Foo() {
10330         this.a = 1;
10331       }
10332       Foo.prototype.b = 2;
10333
10334       assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
10335     });
10336
10337     QUnit.test('should not match by inherited `source` properties', function(assert) {
10338       assert.expect(1);
10339
10340       function Foo() {
10341         this.a = 1;
10342       }
10343       Foo.prototype.b = 2;
10344
10345       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
10346           source = new Foo,
10347           expected = lodashStable.map(objects, alwaysTrue);
10348
10349       var actual = lodashStable.map(objects, function(object) {
10350         return _.isMatch(object, source);
10351       });
10352
10353       assert.deepEqual(actual, expected);
10354     });
10355
10356     QUnit.test('should compare a variety of `source` property values', function(assert) {
10357       assert.expect(2);
10358
10359       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
10360           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
10361
10362       assert.strictEqual(_.isMatch(object1, object1), true);
10363       assert.strictEqual(_.isMatch(object1, object2), false);
10364     });
10365
10366     QUnit.test('should match `-0` as `0`', function(assert) {
10367       assert.expect(2);
10368
10369       var object1 = { 'a': -0 },
10370           object2 = { 'a': 0 };
10371
10372       assert.strictEqual(_.isMatch(object1, object2), true);
10373       assert.strictEqual(_.isMatch(object2, object1), true);
10374     });
10375
10376     QUnit.test('should compare functions by reference', function(assert) {
10377       assert.expect(3);
10378
10379       var object1 = { 'a': lodashStable.noop },
10380           object2 = { 'a': noop },
10381           object3 = { 'a': {} };
10382
10383       assert.strictEqual(_.isMatch(object1, object1), true);
10384       assert.strictEqual(_.isMatch(object2, object1), false);
10385       assert.strictEqual(_.isMatch(object3, object1), false);
10386     });
10387
10388     QUnit.test('should work with a function for `object`', function(assert) {
10389       assert.expect(1);
10390
10391       function Foo() {}
10392       Foo.a = { 'b': 1, 'c': 2 };
10393
10394       assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 1 } }), true);
10395     });
10396
10397     QUnit.test('should work with a function for `source`', function(assert) {
10398       assert.expect(1);
10399
10400       function Foo() {}
10401       Foo.a = 1;
10402       Foo.b = function() {};
10403       Foo.c = 3;
10404
10405       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
10406
10407       var actual = lodashStable.map(objects, function(object) {
10408         return _.isMatch(object, Foo);
10409       });
10410
10411       assert.deepEqual(actual, [false, true]);
10412     });
10413
10414     QUnit.test('should work with a non-plain `object`', function(assert) {
10415       assert.expect(1);
10416
10417       function Foo(object) { lodashStable.assign(this, object); }
10418
10419       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) });
10420       assert.strictEqual(_.isMatch(object, { 'a': { 'b': 1 } }), true);
10421     });
10422
10423     QUnit.test('should partial match arrays', function(assert) {
10424       assert.expect(3);
10425
10426       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
10427           source = { 'a': ['d'] },
10428           predicate = function(object) { return _.isMatch(object, source); },
10429           actual = lodashStable.filter(objects, predicate);
10430
10431       assert.deepEqual(actual, [objects[1]]);
10432
10433       source = { 'a': ['b', 'd'] };
10434       actual = lodashStable.filter(objects, predicate);
10435
10436       assert.deepEqual(actual, []);
10437
10438       source = { 'a': ['d', 'b'] };
10439       actual = lodashStable.filter(objects, predicate);
10440       assert.deepEqual(actual, []);
10441     });
10442
10443     QUnit.test('should partial match arrays of objects', function(assert) {
10444       assert.expect(1);
10445
10446       var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
10447
10448       var objects = [
10449         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
10450         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
10451       ];
10452
10453       var actual = lodashStable.filter(objects, function(object) {
10454         return _.isMatch(object, source);
10455       });
10456
10457       assert.deepEqual(actual, [objects[0]]);
10458     });
10459
10460     QUnit.test('should partial match maps', function(assert) {
10461       assert.expect(3);
10462
10463       if (Map) {
10464         var objects = [{ 'a': new Map }, { 'a': new Map }];
10465         objects[0].a.set('a', 1);
10466         objects[1].a.set('a', 1);
10467         objects[1].a.set('b', 2);
10468
10469         var map = new Map;
10470         map.set('b', 2);
10471
10472         var source = { 'a': map },
10473             predicate = function(object) { return _.isMatch(object, source); },
10474             actual = lodashStable.filter(objects, predicate);
10475
10476         assert.deepEqual(actual, [objects[1]]);
10477
10478         map['delete']('b');
10479         actual = lodashStable.filter(objects, predicate);
10480
10481         assert.deepEqual(actual, objects);
10482
10483         map.set('c', 3);
10484         actual = lodashStable.filter(objects, predicate);
10485
10486         assert.deepEqual(actual, []);
10487       }
10488       else {
10489         skipAssert(assert, 3);
10490       }
10491     });
10492
10493     QUnit.test('should partial match sets', function(assert) {
10494       assert.expect(3);
10495
10496       if (Set) {
10497         var objects = [{ 'a': new Set }, { 'a': new Set }];
10498         objects[0].a.add(1);
10499         objects[1].a.add(1);
10500         objects[1].a.add(2);
10501
10502         var set = new Set;
10503         set.add(2);
10504
10505         var source = { 'a': set },
10506             predicate = function(object) { return _.isMatch(object, source); },
10507             actual = lodashStable.filter(objects, predicate);
10508
10509         assert.deepEqual(actual, [objects[1]]);
10510
10511         set['delete'](2);
10512         actual = lodashStable.filter(objects, predicate);
10513
10514         assert.deepEqual(actual, objects);
10515
10516         set.add(3);
10517         actual = lodashStable.filter(objects, predicate);
10518
10519         assert.deepEqual(actual, []);
10520       }
10521       else {
10522         skipAssert(assert, 3);
10523       }
10524     });
10525
10526     QUnit.test('should match `undefined` values', function(assert) {
10527       assert.expect(3);
10528
10529       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
10530           source = { 'b': undefined },
10531           predicate = function(object) { return _.isMatch(object, source); },
10532           actual = lodashStable.map(objects, predicate),
10533           expected = [false, false, true];
10534
10535       assert.deepEqual(actual, expected);
10536
10537       source = { 'a': 1, 'b': undefined };
10538       actual = lodashStable.map(objects, predicate);
10539
10540       assert.deepEqual(actual, expected);
10541
10542       objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
10543       source = { 'a': { 'c': undefined } };
10544       actual = lodashStable.map(objects, predicate);
10545
10546       assert.deepEqual(actual, expected);
10547     });
10548
10549     QUnit.test('should match `undefined` values on primitives', function(assert) {
10550       assert.expect(3);
10551
10552       numberProto.a = 1;
10553       numberProto.b = undefined;
10554
10555       try {
10556         assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
10557       } catch (e) {
10558         assert.ok(false, e.message);
10559       }
10560       try {
10561         assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
10562       } catch (e) {
10563         assert.ok(false, e.message);
10564       }
10565       numberProto.a = { 'b': 1, 'c': undefined };
10566       try {
10567         assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
10568       } catch (e) {
10569         assert.ok(false, e.message);
10570       }
10571       delete numberProto.a;
10572       delete numberProto.b;
10573     });
10574
10575     QUnit.test('should return `false` when `object` is nullish', function(assert) {
10576       assert.expect(1);
10577
10578       var values = [null, undefined],
10579           expected = lodashStable.map(values, alwaysFalse),
10580           source = { 'a': 1 };
10581
10582       var actual = lodashStable.map(values, function(value) {
10583         try {
10584           return _.isMatch(value, source);
10585         } catch (e) {}
10586       });
10587
10588       assert.deepEqual(actual, expected);
10589     });
10590
10591     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
10592       assert.expect(1);
10593
10594       var values = [null, undefined],
10595           expected = lodashStable.map(values, alwaysTrue),
10596           source = {};
10597
10598       var actual = lodashStable.map(values, function(value) {
10599         try {
10600           return _.isMatch(value, source);
10601         } catch (e) {}
10602       });
10603
10604       assert.deepEqual(actual, expected);
10605     });
10606
10607     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
10608       assert.expect(1);
10609
10610       var object = { 'a': 1 },
10611           expected = lodashStable.map(empties, alwaysTrue);
10612
10613       var actual = lodashStable.map(empties, function(value) {
10614         return _.isMatch(object, value);
10615       });
10616
10617       assert.deepEqual(actual, expected);
10618     });
10619
10620     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
10621       assert.expect(1);
10622
10623       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
10624           source = { 'a': [], 'b': {} };
10625
10626       var actual = lodashStable.filter(objects, function(object) {
10627         return _.isMatch(object, source);
10628       });
10629
10630       assert.deepEqual(actual, objects);
10631     });
10632   }());
10633
10634   /*--------------------------------------------------------------------------*/
10635
10636   QUnit.module('lodash.isMatchWith');
10637
10638   (function() {
10639     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
10640       assert.expect(1);
10641
10642       var argsList = [],
10643           object1 = { 'a': [1, 2], 'b': null },
10644           object2 = { 'a': [1, 2], 'b': null };
10645
10646       object1.b = object2;
10647       object2.b = object1;
10648
10649       var expected = [
10650         [object1.a, object2.a, 'a', object1, object2],
10651         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10652         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10653         [object1.b, object2.b, 'b', object1, object2],
10654         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10655         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10656         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10657         [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
10658         [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
10659         [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
10660         [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
10661         [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
10662       ];
10663
10664       _.isMatchWith(object1, object2, function(assert) {
10665         argsList.push(slice.call(arguments, 0, -1));
10666       });
10667
10668       assert.deepEqual(argsList, expected);
10669     });
10670
10671     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
10672       assert.expect(1);
10673
10674       assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10675     });
10676
10677     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
10678       assert.expect(2);
10679
10680       var customizer = function(value) {
10681         return _.isString(value) || undefined;
10682       };
10683
10684       assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10685       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10686     });
10687
10688     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
10689       assert.expect(2);
10690
10691       var customizer = function(value) {
10692         return _.isString(value) ? false : undefined;
10693       };
10694
10695       assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10696       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10697     });
10698
10699     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
10700       assert.expect(2);
10701
10702       var object = { 'a': 1 },
10703           actual = _.isMatchWith(object, { 'a': 1 }, alwaysA);
10704
10705       assert.strictEqual(actual, true);
10706
10707       var expected = lodashStable.map(falsey, alwaysFalse);
10708
10709       actual = [];
10710       lodashStable.each(falsey, function(value) {
10711         actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
10712       });
10713
10714       assert.deepEqual(actual, expected);
10715     });
10716
10717     QUnit.test('should ensure `customizer` is a function', function(assert) {
10718       assert.expect(1);
10719
10720       var object = { 'a': 1 },
10721           matches = _.partial(_.isMatchWith, object),
10722           actual = lodashStable.map([object, { 'a': 2 }], matches);
10723
10724       assert.deepEqual(actual, [true, false]);
10725     });
10726
10727     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10728       assert.expect(2);
10729
10730       var value = { 'a': { 'b': 2 } };
10731
10732       if (Map) {
10733         var map1 = new Map;
10734         map1.set('a', value);
10735
10736         var map2 = new Map;
10737         map2.set('a', value);
10738       }
10739       if (Set) {
10740         var set1 = new Set;
10741         set1.add(value);
10742
10743         var set2 = new Set;
10744         set2.add(value);
10745       }
10746       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10747         if (pair[0]) {
10748           var argsList = [],
10749               array = _.toArray(pair[0]),
10750               object1 = { 'a': pair[0] },
10751               object2 = { 'a': pair[1] };
10752
10753           var expected = [
10754             [pair[0], pair[1], 'a', object1, object2],
10755             [array[0], array[0], 0, array, array],
10756             [array[0][0], array[0][0], 0, array[0], array[0]],
10757             [array[0][1], array[0][1], 1, array[0], array[0]]
10758           ];
10759
10760           if (index) {
10761             expected.length = 2;
10762           }
10763           _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
10764             argsList.push(slice.call(arguments, 0, -1));
10765           });
10766
10767           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10768         }
10769         else {
10770           skipAssert(assert);
10771         }
10772       });
10773     });
10774   }());
10775
10776   /*--------------------------------------------------------------------------*/
10777
10778   QUnit.module('lodash.isNaN');
10779
10780   (function() {
10781     var args = arguments;
10782
10783     QUnit.test('should return `true` for NaNs', function(assert) {
10784       assert.expect(2);
10785
10786       assert.strictEqual(_.isNaN(NaN), true);
10787       assert.strictEqual(_.isNaN(Object(NaN)), true);
10788     });
10789
10790     QUnit.test('should return `false` for non-NaNs', function(assert) {
10791       assert.expect(14);
10792
10793       var expected = lodashStable.map(falsey, function(value) {
10794         return value !== value;
10795       });
10796
10797       var actual = lodashStable.map(falsey, function(value, index) {
10798         return index ? _.isNaN(value) : _.isNaN();
10799       });
10800
10801       assert.deepEqual(actual, expected);
10802
10803       assert.strictEqual(_.isNaN(args), false);
10804       assert.strictEqual(_.isNaN([1, 2, 3]), false);
10805       assert.strictEqual(_.isNaN(true), false);
10806       assert.strictEqual(_.isNaN(new Date), false);
10807       assert.strictEqual(_.isNaN(new Error), false);
10808       assert.strictEqual(_.isNaN(_), false);
10809       assert.strictEqual(_.isNaN(slice), false);
10810       assert.strictEqual(_.isNaN({ 'a': 1 }), false);
10811       assert.strictEqual(_.isNaN(1), false);
10812       assert.strictEqual(_.isNaN(Object(1)), false);
10813       assert.strictEqual(_.isNaN(/x/), false);
10814       assert.strictEqual(_.isNaN('a'), false);
10815       assert.strictEqual(_.isNaN(symbol), false);
10816     });
10817
10818     QUnit.test('should work with `NaN` from another realm', function(assert) {
10819       assert.expect(1);
10820
10821       if (realm.object) {
10822         assert.strictEqual(_.isNaN(realm.nan), true);
10823       }
10824       else {
10825         skipAssert(assert);
10826       }
10827     });
10828   }(1, 2, 3));
10829
10830   /*--------------------------------------------------------------------------*/
10831
10832   QUnit.module('lodash.isNative');
10833
10834   (function() {
10835     var args = arguments;
10836
10837     QUnit.test('should return `true` for native methods', function(assert) {
10838       assert.expect(1);
10839
10840       var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
10841           expected = lodashStable.map(values, Boolean),
10842           actual = lodashStable.map(values, _.isNative);
10843
10844       assert.deepEqual(actual, expected);
10845     });
10846
10847     QUnit.test('should return `false` for non-native methods', function(assert) {
10848       assert.expect(12);
10849
10850       var expected = lodashStable.map(falsey, alwaysFalse);
10851
10852       var actual = lodashStable.map(falsey, function(value, index) {
10853         return index ? _.isNative(value) : _.isNative();
10854       });
10855
10856       assert.deepEqual(actual, expected);
10857
10858       assert.strictEqual(_.isNative(args), false);
10859       assert.strictEqual(_.isNative([1, 2, 3]), false);
10860       assert.strictEqual(_.isNative(true), false);
10861       assert.strictEqual(_.isNative(new Date), false);
10862       assert.strictEqual(_.isNative(new Error), false);
10863       assert.strictEqual(_.isNative(_), false);
10864       assert.strictEqual(_.isNative({ 'a': 1 }), false);
10865       assert.strictEqual(_.isNative(1), false);
10866       assert.strictEqual(_.isNative(/x/), false);
10867       assert.strictEqual(_.isNative('a'), false);
10868       assert.strictEqual(_.isNative(symbol), false);
10869     });
10870
10871     QUnit.test('should work with native functions from another realm', function(assert) {
10872       assert.expect(2);
10873
10874       if (realm.element) {
10875         assert.strictEqual(_.isNative(realm.element.cloneNode), true);
10876       }
10877       else {
10878         skipAssert(assert);
10879       }
10880       if (realm.object) {
10881         assert.strictEqual(_.isNative(realm.object.valueOf), true);
10882       }
10883       else {
10884         skipAssert(assert);
10885       }
10886     });
10887   }(1, 2, 3));
10888
10889   /*--------------------------------------------------------------------------*/
10890
10891   QUnit.module('lodash.isNil');
10892
10893   (function() {
10894     var args = arguments;
10895
10896     QUnit.test('should return `true` for nullish values', function(assert) {
10897       assert.expect(3);
10898
10899       assert.strictEqual(_.isNil(null), true);
10900       assert.strictEqual(_.isNil(), true);
10901       assert.strictEqual(_.isNil(undefined), true);
10902     });
10903
10904     QUnit.test('should return `false` for non-nullish values', function(assert) {
10905       assert.expect(13);
10906
10907       var expected = lodashStable.map(falsey, function(value) {
10908         return value == null;
10909       });
10910
10911       var actual = lodashStable.map(falsey, function(value, index) {
10912         return index ? _.isNil(value) : _.isNil();
10913       });
10914
10915       assert.deepEqual(actual, expected);
10916
10917       assert.strictEqual(_.isNil(args), false);
10918       assert.strictEqual(_.isNil([1, 2, 3]), false);
10919       assert.strictEqual(_.isNil(true), false);
10920       assert.strictEqual(_.isNil(new Date), false);
10921       assert.strictEqual(_.isNil(new Error), false);
10922       assert.strictEqual(_.isNil(_), false);
10923       assert.strictEqual(_.isNil(slice), false);
10924       assert.strictEqual(_.isNil({ 'a': 1 }), false);
10925       assert.strictEqual(_.isNil(1), false);
10926       assert.strictEqual(_.isNil(/x/), false);
10927       assert.strictEqual(_.isNil('a'), false);
10928
10929       if (Symbol) {
10930         assert.strictEqual(_.isNil(symbol), false);
10931       }
10932       else {
10933         skipAssert(assert);
10934       }
10935     });
10936
10937     QUnit.test('should work with nulls from another realm', function(assert) {
10938       assert.expect(2);
10939
10940       if (realm.object) {
10941         assert.strictEqual(_.isNil(realm.null), true);
10942         assert.strictEqual(_.isNil(realm.undefined), true);
10943       }
10944       else {
10945         skipAssert(assert, 2);
10946       }
10947     });
10948   }(1, 2, 3));
10949
10950   /*--------------------------------------------------------------------------*/
10951
10952   QUnit.module('lodash.isNull');
10953
10954   (function() {
10955     var args = arguments;
10956
10957     QUnit.test('should return `true` for `null` values', function(assert) {
10958       assert.expect(1);
10959
10960       assert.strictEqual(_.isNull(null), true);
10961     });
10962
10963     QUnit.test('should return `false` for non `null` values', function(assert) {
10964       assert.expect(13);
10965
10966       var expected = lodashStable.map(falsey, function(value) {
10967         return value === null;
10968       });
10969
10970       var actual = lodashStable.map(falsey, function(value, index) {
10971         return index ? _.isNull(value) : _.isNull();
10972       });
10973
10974       assert.deepEqual(actual, expected);
10975
10976       assert.strictEqual(_.isNull(args), false);
10977       assert.strictEqual(_.isNull([1, 2, 3]), false);
10978       assert.strictEqual(_.isNull(true), false);
10979       assert.strictEqual(_.isNull(new Date), false);
10980       assert.strictEqual(_.isNull(new Error), false);
10981       assert.strictEqual(_.isNull(_), false);
10982       assert.strictEqual(_.isNull(slice), false);
10983       assert.strictEqual(_.isNull({ 'a': 1 }), false);
10984       assert.strictEqual(_.isNull(1), false);
10985       assert.strictEqual(_.isNull(/x/), false);
10986       assert.strictEqual(_.isNull('a'), false);
10987       assert.strictEqual(_.isNull(symbol), false);
10988     });
10989
10990     QUnit.test('should work with nulls from another realm', function(assert) {
10991       assert.expect(1);
10992
10993       if (realm.object) {
10994         assert.strictEqual(_.isNull(realm.null), true);
10995       }
10996       else {
10997         skipAssert(assert);
10998       }
10999     });
11000   }(1, 2, 3));
11001
11002   /*--------------------------------------------------------------------------*/
11003
11004   QUnit.module('lodash.isNumber');
11005
11006   (function() {
11007     var args = arguments;
11008
11009     QUnit.test('should return `true` for numbers', function(assert) {
11010       assert.expect(3);
11011
11012       assert.strictEqual(_.isNumber(0), true);
11013       assert.strictEqual(_.isNumber(Object(0)), true);
11014       assert.strictEqual(_.isNumber(NaN), true);
11015     });
11016
11017     QUnit.test('should return `false` for non-numbers', function(assert) {
11018       assert.expect(12);
11019
11020       var expected = lodashStable.map(falsey, function(value) {
11021         return typeof value == 'number';
11022       });
11023
11024       var actual = lodashStable.map(falsey, function(value, index) {
11025         return index ? _.isNumber(value) : _.isNumber();
11026       });
11027
11028       assert.deepEqual(actual, expected);
11029
11030       assert.strictEqual(_.isNumber(args), false);
11031       assert.strictEqual(_.isNumber([1, 2, 3]), false);
11032       assert.strictEqual(_.isNumber(true), false);
11033       assert.strictEqual(_.isNumber(new Date), false);
11034       assert.strictEqual(_.isNumber(new Error), false);
11035       assert.strictEqual(_.isNumber(_), false);
11036       assert.strictEqual(_.isNumber(slice), false);
11037       assert.strictEqual(_.isNumber({ 'a': 1 }), false);
11038       assert.strictEqual(_.isNumber(/x/), false);
11039       assert.strictEqual(_.isNumber('a'), false);
11040       assert.strictEqual(_.isNumber(symbol), false);
11041     });
11042
11043     QUnit.test('should work with numbers from another realm', function(assert) {
11044       assert.expect(1);
11045
11046       if (realm.number) {
11047         assert.strictEqual(_.isNumber(realm.number), true);
11048       }
11049       else {
11050         skipAssert(assert);
11051       }
11052     });
11053
11054     QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
11055       assert.expect(1);
11056
11057       assert.strictEqual(_.isNumber(+'2'), true);
11058     });
11059   }(1, 2, 3));
11060
11061   /*--------------------------------------------------------------------------*/
11062
11063   QUnit.module('lodash.isObject');
11064
11065   (function() {
11066     var args = arguments;
11067
11068     QUnit.test('should return `true` for objects', function(assert) {
11069       assert.expect(13);
11070
11071       assert.strictEqual(_.isObject(args), true);
11072       assert.strictEqual(_.isObject([1, 2, 3]), true);
11073       assert.strictEqual(_.isObject(Object(false)), true);
11074       assert.strictEqual(_.isObject(new Date), true);
11075       assert.strictEqual(_.isObject(new Error), true);
11076       assert.strictEqual(_.isObject(_), true);
11077       assert.strictEqual(_.isObject(slice), true);
11078       assert.strictEqual(_.isObject({ 'a': 1 }), true);
11079       assert.strictEqual(_.isObject(Object(0)), true);
11080       assert.strictEqual(_.isObject(/x/), true);
11081       assert.strictEqual(_.isObject(Object('a')), true);
11082
11083       if (document) {
11084         assert.strictEqual(_.isObject(body), true);
11085       }
11086       else {
11087         skipAssert(assert);
11088       }
11089       if (Symbol) {
11090         assert.strictEqual(_.isObject(Object(symbol)), true);
11091       }
11092       else {
11093         skipAssert(assert);
11094       }
11095     });
11096
11097     QUnit.test('should return `false` for non-objects', function(assert) {
11098       assert.expect(1);
11099
11100       var values = falsey.concat(true, 1, 'a', symbol),
11101           expected = lodashStable.map(values, alwaysFalse);
11102
11103       var actual = lodashStable.map(values, function(value, index) {
11104         return index ? _.isObject(value) : _.isObject();
11105       });
11106
11107       assert.deepEqual(actual, expected);
11108     });
11109
11110     QUnit.test('should work with objects from another realm', function(assert) {
11111       assert.expect(8);
11112
11113       if (realm.element) {
11114         assert.strictEqual(_.isObject(realm.element), true);
11115       }
11116       else {
11117         skipAssert(assert);
11118       }
11119       if (realm.object) {
11120         assert.strictEqual(_.isObject(realm.boolean), true);
11121         assert.strictEqual(_.isObject(realm.date), true);
11122         assert.strictEqual(_.isObject(realm.function), true);
11123         assert.strictEqual(_.isObject(realm.number), true);
11124         assert.strictEqual(_.isObject(realm.object), true);
11125         assert.strictEqual(_.isObject(realm.regexp), true);
11126         assert.strictEqual(_.isObject(realm.string), true);
11127       }
11128       else {
11129         skipAssert(assert, 7);
11130       }
11131     });
11132
11133     QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
11134       assert.expect(1);
11135
11136       // Trigger a V8 JIT bug.
11137       // See https://code.google.com/p/v8/issues/detail?id=2291.
11138       var object = {};
11139
11140       // First, have a comparison statement.
11141       object == object;
11142
11143       // Then perform the check with `object`.
11144       _.isObject(object);
11145
11146       assert.strictEqual(_.isObject('a'), false);
11147     });
11148   }(1, 2, 3));
11149
11150   /*--------------------------------------------------------------------------*/
11151
11152   QUnit.module('lodash.isObjectLike');
11153
11154   (function() {
11155     var args = arguments;
11156
11157     QUnit.test('should return `true` for objects', function(assert) {
11158       assert.expect(9);
11159
11160       assert.strictEqual(_.isObjectLike(args), true);
11161       assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
11162       assert.strictEqual(_.isObjectLike(Object(false)), true);
11163       assert.strictEqual(_.isObjectLike(new Date), true);
11164       assert.strictEqual(_.isObjectLike(new Error), true);
11165       assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
11166       assert.strictEqual(_.isObjectLike(Object(0)), true);
11167       assert.strictEqual(_.isObjectLike(/x/), true);
11168       assert.strictEqual(_.isObjectLike(Object('a')), true);
11169     });
11170
11171     QUnit.test('should return `false` for non-objects', function(assert) {
11172       assert.expect(1);
11173
11174       var values = falsey.concat(true, _, slice, 1, 'a', symbol),
11175           expected = lodashStable.map(values, alwaysFalse);
11176
11177       var actual = lodashStable.map(values, function(value, index) {
11178         return index ? _.isObjectLike(value) : _.isObjectLike();
11179       });
11180
11181       assert.deepEqual(actual, expected);
11182     });
11183
11184     QUnit.test('should work with objects from another realm', function(assert) {
11185       assert.expect(6);
11186
11187       if (realm.object) {
11188         assert.strictEqual(_.isObjectLike(realm.boolean), true);
11189         assert.strictEqual(_.isObjectLike(realm.date), true);
11190         assert.strictEqual(_.isObjectLike(realm.number), true);
11191         assert.strictEqual(_.isObjectLike(realm.object), true);
11192         assert.strictEqual(_.isObjectLike(realm.regexp), true);
11193         assert.strictEqual(_.isObjectLike(realm.string), true);
11194       }
11195       else {
11196         skipAssert(assert, 6);
11197       }
11198     });
11199   }(1, 2, 3));
11200
11201   /*--------------------------------------------------------------------------*/
11202
11203   QUnit.module('lodash.isPlainObject');
11204
11205   (function() {
11206     var element = document && document.createElement('div');
11207
11208     QUnit.test('should detect plain objects', function(assert) {
11209       assert.expect(5);
11210
11211       function Foo(a) {
11212         this.a = 1;
11213       }
11214
11215       assert.strictEqual(_.isPlainObject({}), true);
11216       assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
11217       assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
11218       assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
11219       assert.strictEqual(_.isPlainObject(new Foo(1)), false);
11220     });
11221
11222     QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
11223       assert.expect(2);
11224
11225       if (create) {
11226         var object = create(null);
11227         assert.strictEqual(_.isPlainObject(object), true);
11228
11229         object.constructor = objectProto.constructor;
11230         assert.strictEqual(_.isPlainObject(object), true);
11231       }
11232       else {
11233         skipAssert(assert, 2);
11234       }
11235     });
11236
11237     QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
11238       assert.expect(2);
11239
11240       assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
11241
11242       if (element) {
11243         var valueOf = element.valueOf;
11244         element.valueOf = 0;
11245
11246         assert.strictEqual(_.isPlainObject(element), false);
11247         element.valueOf = valueOf;
11248       }
11249       else {
11250         skipAssert(assert);
11251       }
11252     });
11253
11254     QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
11255       assert.expect(1);
11256
11257       if (create) {
11258         var object = create({ 'a': 1 });
11259         assert.strictEqual(_.isPlainObject(object), false);
11260       }
11261       else {
11262         skipAssert(assert);
11263       }
11264     });
11265
11266     QUnit.test('should return `false` for DOM elements', function(assert) {
11267       assert.expect(1);
11268
11269       if (element) {
11270         assert.strictEqual(_.isPlainObject(element), false);
11271       } else {
11272         skipAssert(assert);
11273       }
11274     });
11275
11276     QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
11277       assert.expect(3);
11278
11279       assert.strictEqual(_.isPlainObject(arguments), false);
11280       assert.strictEqual(_.isPlainObject(Error), false);
11281       assert.strictEqual(_.isPlainObject(Math), false);
11282     });
11283
11284     QUnit.test('should return `false` for non-objects', function(assert) {
11285       assert.expect(4);
11286
11287       var expected = lodashStable.map(falsey, alwaysFalse);
11288
11289       var actual = lodashStable.map(falsey, function(value, index) {
11290         return index ? _.isPlainObject(value) : _.isPlainObject();
11291       });
11292
11293       assert.deepEqual(actual, expected);
11294
11295       assert.strictEqual(_.isPlainObject(true), false);
11296       assert.strictEqual(_.isPlainObject('a'), false);
11297       assert.strictEqual(_.isPlainObject(symbol), false);
11298     });
11299
11300     QUnit.test('should work with objects from another realm', function(assert) {
11301       assert.expect(1);
11302
11303       if (realm.object) {
11304         assert.strictEqual(_.isPlainObject(realm.object), true);
11305       }
11306       else {
11307         skipAssert(assert);
11308       }
11309     });
11310   }());
11311
11312   /*--------------------------------------------------------------------------*/
11313
11314   QUnit.module('lodash.isRegExp');
11315
11316   (function() {
11317     var args = arguments;
11318
11319     QUnit.test('should return `true` for regexes', function(assert) {
11320       assert.expect(2);
11321
11322       assert.strictEqual(_.isRegExp(/x/), true);
11323       assert.strictEqual(_.isRegExp(RegExp('x')), true);
11324     });
11325
11326     QUnit.test('should return `false` for non-regexes', function(assert) {
11327       assert.expect(12);
11328
11329       var expected = lodashStable.map(falsey, alwaysFalse);
11330
11331       var actual = lodashStable.map(falsey, function(value, index) {
11332         return index ? _.isRegExp(value) : _.isRegExp();
11333       });
11334
11335       assert.deepEqual(actual, expected);
11336
11337       assert.strictEqual(_.isRegExp(args), false);
11338       assert.strictEqual(_.isRegExp([1, 2, 3]), false);
11339       assert.strictEqual(_.isRegExp(true), false);
11340       assert.strictEqual(_.isRegExp(new Date), false);
11341       assert.strictEqual(_.isRegExp(new Error), false);
11342       assert.strictEqual(_.isRegExp(_), false);
11343       assert.strictEqual(_.isRegExp(slice), false);
11344       assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
11345       assert.strictEqual(_.isRegExp(1), false);
11346       assert.strictEqual(_.isRegExp('a'), false);
11347       assert.strictEqual(_.isRegExp(symbol), false);
11348     });
11349
11350     QUnit.test('should work with regexes from another realm', function(assert) {
11351       assert.expect(1);
11352
11353       if (realm.regexp) {
11354         assert.strictEqual(_.isRegExp(realm.regexp), true);
11355       }
11356       else {
11357         skipAssert(assert);
11358       }
11359     });
11360   }(1, 2, 3));
11361
11362   /*--------------------------------------------------------------------------*/
11363
11364   QUnit.module('lodash.isSet');
11365
11366   (function() {
11367     var args = arguments;
11368
11369     QUnit.test('should return `true` for sets', function(assert) {
11370       assert.expect(1);
11371
11372       if (Set) {
11373         assert.strictEqual(_.isSet(set), true);
11374       }
11375       else {
11376         skipAssert(assert);
11377       }
11378     });
11379
11380     QUnit.test('should return `false` for non-sets', function(assert) {
11381       assert.expect(14);
11382
11383       var expected = lodashStable.map(falsey, alwaysFalse);
11384
11385       var actual = lodashStable.map(falsey, function(value, index) {
11386         return index ? _.isSet(value) : _.isSet();
11387       });
11388
11389       assert.deepEqual(actual, expected);
11390
11391       assert.strictEqual(_.isSet(args), false);
11392       assert.strictEqual(_.isSet([1, 2, 3]), false);
11393       assert.strictEqual(_.isSet(true), false);
11394       assert.strictEqual(_.isSet(new Date), false);
11395       assert.strictEqual(_.isSet(new Error), false);
11396       assert.strictEqual(_.isSet(_), false);
11397       assert.strictEqual(_.isSet(slice), false);
11398       assert.strictEqual(_.isSet({ 'a': 1 }), false);
11399       assert.strictEqual(_.isSet(1), false);
11400       assert.strictEqual(_.isSet(/x/), false);
11401       assert.strictEqual(_.isSet('a'), false);
11402       assert.strictEqual(_.isSet(symbol), false);
11403       assert.strictEqual(_.isSet(weakSet), false);
11404     });
11405
11406     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11407       assert.expect(1);
11408
11409       var values = [false, true],
11410           expected = lodashStable.map(values, alwaysFalse);
11411
11412       var actual = lodashStable.map(values, function(value) {
11413         return _.isSet({ 'constructor': value });
11414       });
11415
11416       assert.deepEqual(actual, expected);
11417     });
11418
11419     QUnit.test('should work with weak sets from another realm', function(assert) {
11420       assert.expect(1);
11421
11422       if (realm.set) {
11423         assert.strictEqual(_.isSet(realm.set), true);
11424       }
11425       else {
11426         skipAssert(assert);
11427       }
11428     });
11429   }(1, 2, 3));
11430
11431   /*--------------------------------------------------------------------------*/
11432
11433   QUnit.module('lodash.isString');
11434
11435   (function() {
11436     var args = arguments;
11437
11438     QUnit.test('should return `true` for strings', function(assert) {
11439       assert.expect(2);
11440
11441       assert.strictEqual(_.isString('a'), true);
11442       assert.strictEqual(_.isString(Object('a')), true);
11443     });
11444
11445     QUnit.test('should return `false` for non-strings', function(assert) {
11446       assert.expect(12);
11447
11448       var expected = lodashStable.map(falsey, function(value) {
11449         return value === '';
11450       });
11451
11452       var actual = lodashStable.map(falsey, function(value, index) {
11453         return index ? _.isString(value) : _.isString();
11454       });
11455
11456       assert.deepEqual(actual, expected);
11457
11458       assert.strictEqual(_.isString(args), false);
11459       assert.strictEqual(_.isString([1, 2, 3]), false);
11460       assert.strictEqual(_.isString(true), false);
11461       assert.strictEqual(_.isString(new Date), false);
11462       assert.strictEqual(_.isString(new Error), false);
11463       assert.strictEqual(_.isString(_), false);
11464       assert.strictEqual(_.isString(slice), false);
11465       assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
11466       assert.strictEqual(_.isString(1), false);
11467       assert.strictEqual(_.isString(/x/), false);
11468       assert.strictEqual(_.isString(symbol), false);
11469     });
11470
11471     QUnit.test('should work with strings from another realm', function(assert) {
11472       assert.expect(1);
11473
11474       if (realm.string) {
11475         assert.strictEqual(_.isString(realm.string), true);
11476       }
11477       else {
11478         skipAssert(assert);
11479       }
11480     });
11481   }(1, 2, 3));
11482
11483   /*--------------------------------------------------------------------------*/
11484
11485   QUnit.module('lodash.isSymbol');
11486
11487   (function() {
11488     var args = arguments;
11489
11490     QUnit.test('should return `true` for symbols', function(assert) {
11491       assert.expect(2);
11492
11493       if (Symbol) {
11494         assert.strictEqual(_.isSymbol(symbol), true);
11495         assert.strictEqual(_.isSymbol(Object(symbol)), true);
11496       }
11497       else {
11498         skipAssert(assert, 2);
11499       }
11500     });
11501
11502     QUnit.test('should return `false` for non-symbols', function(assert) {
11503       assert.expect(12);
11504
11505       var expected = lodashStable.map(falsey, alwaysFalse);
11506
11507       var actual = lodashStable.map(falsey, function(value, index) {
11508         return index ? _.isSymbol(value) : _.isSymbol();
11509       });
11510
11511       assert.deepEqual(actual, expected);
11512
11513       assert.strictEqual(_.isSymbol(args), false);
11514       assert.strictEqual(_.isSymbol([1, 2, 3]), false);
11515       assert.strictEqual(_.isSymbol(true), false);
11516       assert.strictEqual(_.isSymbol(new Date), false);
11517       assert.strictEqual(_.isSymbol(new Error), false);
11518       assert.strictEqual(_.isSymbol(_), false);
11519       assert.strictEqual(_.isSymbol(slice), false);
11520       assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
11521       assert.strictEqual(_.isSymbol(1), false);
11522       assert.strictEqual(_.isSymbol(/x/), false);
11523       assert.strictEqual(_.isSymbol('a'), false);
11524     });
11525
11526     QUnit.test('should work with symbols from another realm', function(assert) {
11527       assert.expect(1);
11528
11529       if (Symbol && realm.symbol) {
11530         assert.strictEqual(_.isSymbol(realm.symbol), true);
11531       }
11532       else {
11533         skipAssert(assert);
11534       }
11535     });
11536   }(1, 2, 3));
11537
11538   /*--------------------------------------------------------------------------*/
11539
11540   QUnit.module('lodash.isTypedArray');
11541
11542   (function() {
11543     var args = arguments;
11544
11545     QUnit.test('should return `true` for typed arrays', function(assert) {
11546       assert.expect(1);
11547
11548       var expected = lodashStable.map(typedArrays, function(type) {
11549         return type in root;
11550       });
11551
11552       var actual = lodashStable.map(typedArrays, function(type) {
11553         var Ctor = root[type];
11554         return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11555       });
11556
11557       assert.deepEqual(actual, expected);
11558     });
11559
11560     QUnit.test('should return `false` for non typed arrays', function(assert) {
11561       assert.expect(13);
11562
11563       var expected = lodashStable.map(falsey, alwaysFalse);
11564
11565       var actual = lodashStable.map(falsey, function(value, index) {
11566         return index ? _.isTypedArray(value) : _.isTypedArray();
11567       });
11568
11569       assert.deepEqual(actual, expected);
11570
11571       assert.strictEqual(_.isTypedArray(args), false);
11572       assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11573       assert.strictEqual(_.isTypedArray(true), false);
11574       assert.strictEqual(_.isTypedArray(new Date), false);
11575       assert.strictEqual(_.isTypedArray(new Error), false);
11576       assert.strictEqual(_.isTypedArray(_), false);
11577       assert.strictEqual(_.isTypedArray(slice), false);
11578       assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11579       assert.strictEqual(_.isTypedArray(1), false);
11580       assert.strictEqual(_.isTypedArray(/x/), false);
11581       assert.strictEqual(_.isTypedArray('a'), false);
11582       assert.strictEqual(_.isTypedArray(symbol), false);
11583     });
11584
11585     QUnit.test('should work with typed arrays from another realm', function(assert) {
11586       assert.expect(1);
11587
11588       if (realm.object) {
11589         var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11590
11591         var expected = lodashStable.map(props, function(key) {
11592           return realm[key] !== undefined;
11593         });
11594
11595         var actual = lodashStable.map(props, function(key) {
11596           var value = realm[key];
11597           return value ? _.isTypedArray(value) : false;
11598         });
11599
11600         assert.deepEqual(actual, expected);
11601       }
11602       else {
11603         skipAssert(assert);
11604       }
11605     });
11606   }(1, 2, 3));
11607
11608   /*--------------------------------------------------------------------------*/
11609
11610   QUnit.module('lodash.isUndefined');
11611
11612   (function() {
11613     var args = arguments;
11614
11615     QUnit.test('should return `true` for `undefined` values', function(assert) {
11616       assert.expect(2);
11617
11618       assert.strictEqual(_.isUndefined(), true);
11619       assert.strictEqual(_.isUndefined(undefined), true);
11620     });
11621
11622     QUnit.test('should return `false` for non `undefined` values', function(assert) {
11623       assert.expect(13);
11624
11625       var expected = lodashStable.map(falsey, function(value) {
11626         return value === undefined;
11627       });
11628
11629       var actual = lodashStable.map(falsey, function(value, index) {
11630         return index ? _.isUndefined(value) : _.isUndefined();
11631       });
11632
11633       assert.deepEqual(actual, expected);
11634
11635       assert.strictEqual(_.isUndefined(args), false);
11636       assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11637       assert.strictEqual(_.isUndefined(true), false);
11638       assert.strictEqual(_.isUndefined(new Date), false);
11639       assert.strictEqual(_.isUndefined(new Error), false);
11640       assert.strictEqual(_.isUndefined(_), false);
11641       assert.strictEqual(_.isUndefined(slice), false);
11642       assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11643       assert.strictEqual(_.isUndefined(1), false);
11644       assert.strictEqual(_.isUndefined(/x/), false);
11645       assert.strictEqual(_.isUndefined('a'), false);
11646
11647       if (Symbol) {
11648         assert.strictEqual(_.isUndefined(symbol), false);
11649       }
11650       else {
11651         skipAssert(assert);
11652       }
11653     });
11654
11655     QUnit.test('should work with `undefined` from another realm', function(assert) {
11656       assert.expect(1);
11657
11658       if (realm.object) {
11659         assert.strictEqual(_.isUndefined(realm.undefined), true);
11660       }
11661       else {
11662         skipAssert(assert);
11663       }
11664     });
11665   }(1, 2, 3));
11666
11667   /*--------------------------------------------------------------------------*/
11668
11669   QUnit.module('lodash.isWeakMap');
11670
11671   (function() {
11672     var args = arguments;
11673
11674     QUnit.test('should return `true` for weak maps', function(assert) {
11675       assert.expect(1);
11676
11677       if (WeakMap) {
11678         assert.strictEqual(_.isWeakMap(weakMap), true);
11679       }
11680       else {
11681         skipAssert(assert);
11682       }
11683     });
11684
11685     QUnit.test('should return `false` for non weak maps', function(assert) {
11686       assert.expect(14);
11687
11688       var expected = lodashStable.map(falsey, alwaysFalse);
11689
11690       var actual = lodashStable.map(falsey, function(value, index) {
11691         return index ? _.isWeakMap(value) : _.isWeakMap();
11692       });
11693
11694       assert.deepEqual(actual, expected);
11695
11696       assert.strictEqual(_.isWeakMap(args), false);
11697       assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
11698       assert.strictEqual(_.isWeakMap(true), false);
11699       assert.strictEqual(_.isWeakMap(new Date), false);
11700       assert.strictEqual(_.isWeakMap(new Error), false);
11701       assert.strictEqual(_.isWeakMap(_), false);
11702       assert.strictEqual(_.isWeakMap(slice), false);
11703       assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
11704       assert.strictEqual(_.isWeakMap(map), false);
11705       assert.strictEqual(_.isWeakMap(1), false);
11706       assert.strictEqual(_.isWeakMap(/x/), false);
11707       assert.strictEqual(_.isWeakMap('a'), false);
11708       assert.strictEqual(_.isWeakMap(symbol), false);
11709     });
11710
11711     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11712       assert.expect(1);
11713
11714       var values = [false, true],
11715           expected = lodashStable.map(values, alwaysFalse);
11716
11717       var actual = lodashStable.map(values, function(value) {
11718         return _.isWeakMap({ 'constructor': value });
11719       });
11720
11721       assert.deepEqual(actual, expected);
11722     });
11723
11724     QUnit.test('should work with weak maps from another realm', function(assert) {
11725       assert.expect(1);
11726
11727       if (realm.weakMap) {
11728         assert.strictEqual(_.isWeakMap(realm.weakMap), true);
11729       }
11730       else {
11731         skipAssert(assert);
11732       }
11733     });
11734   }(1, 2, 3));
11735
11736   /*--------------------------------------------------------------------------*/
11737
11738   QUnit.module('lodash.isWeakSet');
11739
11740   (function() {
11741     var args = arguments;
11742
11743     QUnit.test('should return `true` for weak sets', function(assert) {
11744       assert.expect(1);
11745
11746       if (WeakSet) {
11747         assert.strictEqual(_.isWeakSet(weakSet), true);
11748       }
11749       else {
11750         skipAssert(assert);
11751       }
11752     });
11753
11754     QUnit.test('should return `false` for non weak sets', function(assert) {
11755       assert.expect(14);
11756
11757       var expected = lodashStable.map(falsey, alwaysFalse);
11758
11759       var actual = lodashStable.map(falsey, function(value, index) {
11760         return index ? _.isWeakSet(value) : _.isWeakSet();
11761       });
11762
11763       assert.deepEqual(actual, expected);
11764
11765       assert.strictEqual(_.isWeakSet(args), false);
11766       assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
11767       assert.strictEqual(_.isWeakSet(true), false);
11768       assert.strictEqual(_.isWeakSet(new Date), false);
11769       assert.strictEqual(_.isWeakSet(new Error), false);
11770       assert.strictEqual(_.isWeakSet(_), false);
11771       assert.strictEqual(_.isWeakSet(slice), false);
11772       assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
11773       assert.strictEqual(_.isWeakSet(1), false);
11774       assert.strictEqual(_.isWeakSet(/x/), false);
11775       assert.strictEqual(_.isWeakSet('a'), false);
11776       assert.strictEqual(_.isWeakSet(set), false);
11777       assert.strictEqual(_.isWeakSet(symbol), false);
11778     });
11779
11780     QUnit.test('should work with weak sets from another realm', function(assert) {
11781       assert.expect(1);
11782
11783       if (realm.weakSet) {
11784         assert.strictEqual(_.isWeakSet(realm.weakSet), true);
11785       }
11786       else {
11787         skipAssert(assert);
11788       }
11789     });
11790   }(1, 2, 3));
11791
11792   /*--------------------------------------------------------------------------*/
11793
11794   QUnit.module('isType checks');
11795
11796   (function() {
11797     QUnit.test('should return `false` for subclassed values', function(assert) {
11798       assert.expect(7);
11799
11800       var funcs = [
11801         'isArray', 'isBoolean', 'isDate', 'isFunction',
11802         'isNumber', 'isRegExp', 'isString'
11803       ];
11804
11805       lodashStable.each(funcs, function(methodName) {
11806         function Foo() {}
11807         Foo.prototype = root[methodName.slice(2)].prototype;
11808
11809         var object = new Foo;
11810         if (objToString.call(object) == objectTag) {
11811           assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
11812         }
11813         else {
11814           skipAssert(assert);
11815         }
11816       });
11817     });
11818
11819     QUnit.test('should not error on host objects (test in IE)', function(assert) {
11820       assert.expect(26);
11821
11822       var funcs = [
11823         'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
11824         'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
11825         'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
11826         'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
11827         'isUndefined', 'isWeakMap', 'isWeakSet'
11828       ];
11829
11830       lodashStable.each(funcs, function(methodName) {
11831         if (xml) {
11832           var pass = true;
11833
11834           try {
11835             _[methodName](xml);
11836           } catch (e) {
11837             pass = false;
11838           }
11839           assert.ok(pass, '`_.' + methodName + '` should not error');
11840         }
11841         else {
11842           skipAssert(assert);
11843         }
11844       });
11845     });
11846   }());
11847
11848   /*--------------------------------------------------------------------------*/
11849
11850   QUnit.module('lodash.iteratee');
11851
11852   (function() {
11853     QUnit.test('should provide arguments to `func`', function(assert) {
11854       assert.expect(1);
11855
11856       var fn = function() { return slice.call(arguments); },
11857           iteratee = _.iteratee(fn),
11858           actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
11859
11860       assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
11861     });
11862
11863     QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
11864       assert.expect(1);
11865
11866       var object = {},
11867           values = [, null, undefined],
11868           expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
11869
11870       var actual = lodashStable.map(values, function(value, index) {
11871         var identity = index ? _.iteratee(value) : _.iteratee();
11872         return [!isNpm && identity, identity(object)];
11873       });
11874
11875       assert.deepEqual(actual, expected);
11876     });
11877
11878     QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
11879       assert.expect(2);
11880
11881       var matches = _.iteratee({ 'a': 1, 'b': 2 });
11882       assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
11883       assert.strictEqual(matches({ 'b': 2 }), false);
11884     });
11885
11886     QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
11887       assert.expect(9);
11888
11889       var sources = [
11890         { 'a': { 'b': 2, 'c': 3 } },
11891         { 'a': 1, 'b': 2 },
11892         { 'a': 1 }
11893       ];
11894
11895       lodashStable.each(sources, function(source, index) {
11896         var object = lodashStable.cloneDeep(source),
11897             matches = _.iteratee(source);
11898
11899         assert.strictEqual(matches(object), true);
11900
11901         if (index) {
11902           source.a = 2;
11903           source.b = 1;
11904           source.c = 3;
11905         } else {
11906           source.a.b = 1;
11907           source.a.c = 2;
11908           source.a.d = 3;
11909         }
11910         assert.strictEqual(matches(object), true);
11911         assert.strictEqual(matches(source), false);
11912       });
11913     });
11914
11915     QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
11916       assert.expect(3);
11917
11918       var array = ['a', undefined],
11919           matches = _.iteratee([0, 'a']);
11920
11921       assert.strictEqual(matches(array), true);
11922
11923       matches = _.iteratee(['0', 'a']);
11924       assert.strictEqual(matches(array), true);
11925
11926       matches = _.iteratee([1, undefined]);
11927       assert.strictEqual(matches(array), true);
11928     });
11929
11930     QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
11931       assert.expect(1);
11932
11933       var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
11934           matches = _.iteratee(['a.b', { 'c': 1 }]);
11935
11936       assert.strictEqual(matches(object), true);
11937     });
11938
11939     QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
11940       assert.expect(9);
11941
11942       var sources = [
11943         { 'a': { 'b': 2, 'c': 3 } },
11944         { 'a': 1, 'b': 2 },
11945         { 'a': 1 }
11946       ];
11947
11948       lodashStable.each(sources, function(source, index) {
11949         var object = { 'a': lodashStable.cloneDeep(source) },
11950             matches = _.iteratee(['a', source]);
11951
11952         assert.strictEqual(matches(object), true);
11953
11954         if (index) {
11955           source.a = 2;
11956           source.b = 1;
11957           source.c = 3;
11958         } else {
11959           source.a.b = 1;
11960           source.a.c = 2;
11961           source.a.d = 3;
11962         }
11963         assert.strictEqual(matches(object), true);
11964         assert.strictEqual(matches({ 'a': source }), false);
11965       });
11966     });
11967
11968     QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
11969       assert.expect(2);
11970
11971       var array = ['a'],
11972           prop = _.iteratee(0);
11973
11974       assert.strictEqual(prop(array), 'a');
11975
11976       prop = _.iteratee('0');
11977       assert.strictEqual(prop(array), 'a');
11978     });
11979
11980     QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
11981       assert.expect(1);
11982
11983       var object = { 'a': { 'b': 2 } },
11984           prop = _.iteratee('a.b');
11985
11986       assert.strictEqual(prop(object), 2);
11987     });
11988
11989     QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
11990       assert.expect(2);
11991
11992       var fn = function() {
11993         var result = [this.a];
11994         push.apply(result, arguments);
11995         return result;
11996       };
11997
11998       var expected = [1, 2, 3],
11999           object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
12000
12001       assert.deepEqual(object.iteratee(3), expected);
12002
12003       object.iteratee = _.iteratee(_.partialRight(fn, 3));
12004       assert.deepEqual(object.iteratee(2), expected);
12005     });
12006
12007     QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
12008       assert.expect(1);
12009
12010       var iteratee = _.iteratee;
12011       delete _.iteratee;
12012
12013       assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
12014
12015       _.iteratee = iteratee;
12016     });
12017
12018     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12019       assert.expect(1);
12020
12021       var fn = function() { return this instanceof Number; },
12022           array = [fn, fn, fn],
12023           iteratees = lodashStable.map(array, _.iteratee),
12024           expected = lodashStable.map(array, alwaysFalse);
12025
12026       var actual = lodashStable.map(iteratees, function(iteratee) {
12027         return iteratee();
12028       });
12029
12030       assert.deepEqual(actual, expected);
12031     });
12032   }());
12033
12034   /*--------------------------------------------------------------------------*/
12035
12036   QUnit.module('custom `_.iteratee` methods');
12037
12038   (function() {
12039     var array = ['one', 'two', 'three'],
12040         getPropA = _.partial(_.property, 'a'),
12041         getPropB = _.partial(_.property, 'b'),
12042         getLength = _.partial(_.property, 'length'),
12043         iteratee = _.iteratee;
12044
12045     var getSum = function() {
12046       return function(result, object) {
12047         return result + object.a;
12048       };
12049     };
12050
12051     var objects = [
12052       { 'a': 0, 'b': 0 },
12053       { 'a': 1, 'b': 0 },
12054       { 'a': 1, 'b': 1 }
12055     ];
12056
12057     QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
12058       assert.expect(1);
12059
12060       if (!isModularize) {
12061         _.iteratee = getLength;
12062         assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
12063         _.iteratee = iteratee;
12064       }
12065       else {
12066         skipAssert(assert);
12067       }
12068     });
12069
12070     QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
12071       assert.expect(1);
12072
12073       if (!isModularize) {
12074         _.iteratee = getPropA;
12075         assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
12076         _.iteratee = iteratee;
12077       }
12078       else {
12079         skipAssert(assert);
12080       }
12081     });
12082
12083     QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
12084       assert.expect(1);
12085
12086       if (!isModularize) {
12087         _.iteratee = getPropB;
12088         assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
12089         _.iteratee = iteratee;
12090       }
12091       else {
12092         skipAssert(assert);
12093       }
12094     });
12095
12096     QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
12097       assert.expect(1);
12098
12099       if (!isModularize) {
12100         _.iteratee = getPropB;
12101         assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
12102         _.iteratee = iteratee;
12103       }
12104       else {
12105         skipAssert(assert);
12106       }
12107     });
12108
12109     QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
12110       assert.expect(1);
12111
12112       if (!isModularize) {
12113         _.iteratee = getPropA;
12114         assert.strictEqual(_.every(objects.slice(1)), true);
12115         _.iteratee = iteratee;
12116       }
12117       else {
12118         skipAssert(assert);
12119       }
12120     });
12121
12122     QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
12123       assert.expect(1);
12124
12125       if (!isModularize) {
12126         var objects = [{ 'a': 0 }, { 'a': 1 }];
12127
12128         _.iteratee = getPropA;
12129         assert.deepEqual(_.filter(objects), [objects[1]]);
12130         _.iteratee = iteratee;
12131       }
12132       else {
12133         skipAssert(assert);
12134       }
12135     });
12136
12137     QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
12138       assert.expect(1);
12139
12140       if (!isModularize) {
12141         _.iteratee = getPropA;
12142         assert.strictEqual(_.find(objects), objects[1]);
12143         _.iteratee = iteratee;
12144       }
12145       else {
12146         skipAssert(assert);
12147       }
12148     });
12149
12150     QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
12151       assert.expect(1);
12152
12153       if (!isModularize) {
12154         _.iteratee = getPropA;
12155         assert.strictEqual(_.findIndex(objects), 1);
12156         _.iteratee = iteratee;
12157       }
12158       else {
12159         skipAssert(assert);
12160       }
12161     });
12162
12163     QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
12164       assert.expect(1);
12165
12166       if (!isModularize) {
12167         _.iteratee = getPropA;
12168         assert.strictEqual(_.findLast(objects), objects[2]);
12169         _.iteratee = iteratee;
12170       }
12171       else {
12172         skipAssert(assert);
12173       }
12174     });
12175
12176     QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
12177       assert.expect(1);
12178
12179       if (!isModularize) {
12180         _.iteratee = getPropA;
12181         assert.strictEqual(_.findLastIndex(objects), 2);
12182         _.iteratee = iteratee;
12183       }
12184       else {
12185         skipAssert(assert);
12186       }
12187     });
12188
12189     QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
12190       assert.expect(1);
12191
12192       if (!isModularize) {
12193         _.iteratee = getPropB;
12194         assert.strictEqual(_.findKey(objects), '2');
12195         _.iteratee = iteratee;
12196       }
12197       else {
12198         skipAssert(assert);
12199       }
12200     });
12201
12202     QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
12203       assert.expect(1);
12204
12205       if (!isModularize) {
12206         _.iteratee = getPropB;
12207         assert.strictEqual(_.findLastKey(objects), '2');
12208         _.iteratee = iteratee;
12209       }
12210       else {
12211         skipAssert(assert);
12212       }
12213     });
12214
12215     QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
12216       assert.expect(1);
12217
12218       if (!isModularize) {
12219         _.iteratee = getLength;
12220         assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
12221         _.iteratee = iteratee;
12222       }
12223       else {
12224         skipAssert(assert);
12225       }
12226     });
12227
12228     QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
12229       assert.expect(1);
12230
12231       if (!isModularize) {
12232         _.iteratee = getPropA;
12233         assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
12234         _.iteratee = iteratee;
12235       }
12236       else {
12237         skipAssert(assert);
12238       }
12239     });
12240
12241     QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
12242       assert.expect(1);
12243
12244       if (!isModularize) {
12245         _.iteratee = getLength;
12246         assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
12247         _.iteratee = iteratee;
12248       }
12249       else {
12250         skipAssert(assert);
12251       }
12252     });
12253
12254     QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
12255       assert.expect(1);
12256
12257       if (!isModularize) {
12258         _.iteratee = getPropA;
12259         assert.deepEqual(_.map(objects), [0, 1, 1]);
12260         _.iteratee = iteratee;
12261       }
12262       else {
12263         skipAssert(assert);
12264       }
12265     });
12266
12267     QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
12268       assert.expect(1);
12269
12270       if (!isModularize) {
12271         _.iteratee = getPropB;
12272         assert.deepEqual(_.mapKeys({ 'a': { 'b': 1 } }), { '1':  { 'b': 1 } });
12273         _.iteratee = iteratee;
12274       }
12275       else {
12276         skipAssert(assert);
12277       }
12278     });
12279
12280     QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
12281       assert.expect(1);
12282
12283       if (!isModularize) {
12284         _.iteratee = getPropB;
12285         assert.deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 });
12286         _.iteratee = iteratee;
12287       }
12288       else {
12289         skipAssert(assert);
12290       }
12291     });
12292
12293     QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
12294       assert.expect(1);
12295
12296       if (!isModularize) {
12297         _.iteratee = getPropB;
12298         assert.deepEqual(_.maxBy(objects), objects[2]);
12299         _.iteratee = iteratee;
12300       }
12301       else {
12302         skipAssert(assert);
12303       }
12304     });
12305
12306     QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
12307       assert.expect(1);
12308
12309       if (!isModularize) {
12310         _.iteratee = getPropA;
12311         assert.strictEqual(_.meanBy(objects), 2 / 3);
12312         _.iteratee = iteratee;
12313       }
12314       else {
12315         skipAssert(assert);
12316       }
12317     });
12318
12319     QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
12320       assert.expect(1);
12321
12322       if (!isModularize) {
12323         _.iteratee = getPropB;
12324         assert.deepEqual(_.minBy(objects), objects[0]);
12325         _.iteratee = iteratee;
12326       }
12327       else {
12328         skipAssert(assert);
12329       }
12330     });
12331
12332     QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
12333       assert.expect(1);
12334
12335       if (!isModularize) {
12336         var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
12337
12338         _.iteratee = getPropA;
12339         assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
12340         _.iteratee = iteratee;
12341       }
12342       else {
12343         skipAssert(assert);
12344       }
12345     });
12346
12347     QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
12348       assert.expect(1);
12349
12350       if (!isModularize) {
12351         _.iteratee = getPropA;
12352         assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
12353         _.iteratee = iteratee;
12354       }
12355       else {
12356         skipAssert(assert);
12357       }
12358     });
12359
12360     QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
12361       assert.expect(1);
12362
12363       if (!isModularize) {
12364         _.iteratee = getSum;
12365         assert.strictEqual(_.reduce(objects, undefined, 0), 2);
12366         _.iteratee = iteratee;
12367       }
12368       else {
12369         skipAssert(assert);
12370       }
12371     });
12372
12373     QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
12374       assert.expect(1);
12375
12376       if (!isModularize) {
12377         _.iteratee = getSum;
12378         assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
12379         _.iteratee = iteratee;
12380       }
12381       else {
12382         skipAssert(assert);
12383       }
12384     });
12385
12386     QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
12387       assert.expect(1);
12388
12389       if (!isModularize) {
12390         var objects = [{ 'a': 0 }, { 'a': 1 }];
12391
12392         _.iteratee = getPropA;
12393         assert.deepEqual(_.reject(objects), [objects[0]]);
12394         _.iteratee = iteratee;
12395       }
12396       else {
12397         skipAssert(assert);
12398       }
12399     });
12400
12401     QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
12402       assert.expect(1);
12403
12404       if (!isModularize) {
12405         var objects = [{ 'a': 0 }, { 'a': 1 }];
12406
12407         _.iteratee = getPropA;
12408         _.remove(objects);
12409         assert.deepEqual(objects, [{ 'a': 0 }]);
12410         _.iteratee = iteratee;
12411       }
12412       else {
12413         skipAssert(assert);
12414       }
12415     });
12416
12417     QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
12418       assert.expect(1);
12419
12420       if (!isModularize) {
12421         _.iteratee = getPropB;
12422         assert.strictEqual(_.some(objects), true);
12423         _.iteratee = iteratee;
12424       }
12425       else {
12426         skipAssert(assert);
12427       }
12428     });
12429
12430     QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
12431       assert.expect(1);
12432
12433       if (!isModularize) {
12434         _.iteratee = getPropA;
12435         assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
12436         _.iteratee = iteratee;
12437       }
12438       else {
12439         skipAssert(assert);
12440       }
12441     });
12442
12443     QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
12444       assert.expect(1);
12445
12446       if (!isModularize) {
12447         var objects = [{ 'a': 30 }, { 'a': 50 }];
12448
12449         _.iteratee = getPropA;
12450         assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
12451         _.iteratee = iteratee;
12452       }
12453       else {
12454         skipAssert(assert);
12455       }
12456     });
12457
12458     QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
12459       assert.expect(1);
12460
12461       if (!isModularize) {
12462         var objects = [{ 'a': 30 }, { 'a': 50 }];
12463
12464         _.iteratee = getPropA;
12465         assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
12466         _.iteratee = iteratee;
12467       }
12468       else {
12469         skipAssert(assert);
12470       }
12471     });
12472
12473     QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
12474       assert.expect(1);
12475
12476       if (!isModularize) {
12477         _.iteratee = getPropB;
12478         assert.strictEqual(_.sumBy(objects), 1);
12479         _.iteratee = iteratee;
12480       }
12481       else {
12482         skipAssert(assert);
12483       }
12484     });
12485
12486     QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
12487       assert.expect(1);
12488
12489       if (!isModularize) {
12490         _.iteratee = getPropB;
12491         assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
12492         _.iteratee = iteratee;
12493       }
12494       else {
12495         skipAssert(assert);
12496       }
12497     });
12498
12499     QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
12500       assert.expect(1);
12501
12502       if (!isModularize) {
12503         _.iteratee = getPropB;
12504         assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
12505         _.iteratee = iteratee;
12506       }
12507       else {
12508         skipAssert(assert);
12509       }
12510     });
12511
12512     QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
12513       assert.expect(1);
12514
12515       if (!isModularize) {
12516         _.iteratee = function() {
12517           return function(result, object) {
12518             result.sum += object.a;
12519           };
12520         };
12521
12522         assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
12523         _.iteratee = iteratee;
12524       }
12525       else {
12526         skipAssert(assert);
12527       }
12528     });
12529
12530     QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
12531       assert.expect(1);
12532
12533       if (!isModularize) {
12534         _.iteratee = getPropB;
12535         assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
12536         _.iteratee = iteratee;
12537       }
12538       else {
12539         skipAssert(assert);
12540       }
12541     });
12542
12543     QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
12544       assert.expect(1);
12545
12546       if (!isModularize) {
12547         _.iteratee = getPropB;
12548         assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
12549         _.iteratee = iteratee;
12550       }
12551       else {
12552         skipAssert(assert);
12553       }
12554     });
12555
12556     QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
12557       assert.expect(1);
12558
12559       if (!isModularize) {
12560         _.iteratee = getPropA;
12561         assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
12562         _.iteratee = iteratee;
12563       }
12564       else {
12565         skipAssert(assert);
12566       }
12567     });
12568   }());
12569
12570   /*--------------------------------------------------------------------------*/
12571
12572   QUnit.module('lodash.join');
12573
12574   (function() {
12575     var array = ['a', 'b', 'c'];
12576
12577     QUnit.test('should return join all array elements into a string', function(assert) {
12578       assert.expect(1);
12579
12580       assert.strictEqual(_.join(array, '~'), 'a~b~c');
12581     });
12582
12583     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12584       assert.expect(2);
12585
12586       if (!isNpm) {
12587         var wrapped = _(array);
12588         assert.strictEqual(wrapped.join('~'), 'a~b~c');
12589         assert.strictEqual(wrapped.value(), array);
12590       }
12591       else {
12592         skipAssert(assert, 2);
12593       }
12594     });
12595
12596     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12597       assert.expect(1);
12598
12599       if (!isNpm) {
12600         assert.ok(_(array).chain().join('~') instanceof _);
12601       }
12602       else {
12603         skipAssert(assert);
12604       }
12605     });
12606   }());
12607
12608   /*--------------------------------------------------------------------------*/
12609
12610   QUnit.module('lodash.keyBy');
12611
12612   (function() {
12613     var array = [
12614       { 'dir': 'left', 'code': 97 },
12615       { 'dir': 'right', 'code': 100 }
12616     ];
12617
12618     QUnit.test('should transform keys by `iteratee`', function(assert) {
12619       assert.expect(1);
12620
12621       var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12622
12623       var actual = _.keyBy(array, function(object) {
12624         return String.fromCharCode(object.code);
12625       });
12626
12627       assert.deepEqual(actual, expected);
12628     });
12629
12630     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12631       assert.expect(1);
12632
12633       var array = [4, 6, 6],
12634           values = [, null, undefined],
12635           expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12636
12637       var actual = lodashStable.map(values, function(value, index) {
12638         return index ? _.keyBy(array, value) : _.keyBy(array);
12639       });
12640
12641       assert.deepEqual(actual, expected);
12642     });
12643
12644     QUnit.test('should work with `_.property` shorthands', function(assert) {
12645       assert.expect(1);
12646
12647       var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
12648           actual = _.keyBy(array, 'dir');
12649
12650       assert.deepEqual(actual, expected);
12651     });
12652
12653     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
12654       assert.expect(2);
12655
12656       var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
12657         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
12658       });
12659
12660       assert.deepEqual(actual.constructor, 4.2);
12661       assert.deepEqual(actual.hasOwnProperty, 6.3);
12662     });
12663
12664     QUnit.test('should work with a number for `iteratee`', function(assert) {
12665       assert.expect(2);
12666
12667       var array = [
12668         [1, 'a'],
12669         [2, 'a'],
12670         [2, 'b']
12671       ];
12672
12673       assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
12674       assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
12675     });
12676
12677     QUnit.test('should work with an object for `collection`', function(assert) {
12678       assert.expect(1);
12679
12680       var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
12681       assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
12682     });
12683
12684     QUnit.test('should work in a lazy sequence', function(assert) {
12685       assert.expect(1);
12686
12687       if (!isNpm) {
12688         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
12689           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
12690           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
12691         );
12692
12693         var actual = _(array).keyBy().map(square).filter(isEven).take().value();
12694
12695         assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
12696       }
12697       else {
12698         skipAssert(assert);
12699       }
12700     });
12701   }());
12702
12703   /*--------------------------------------------------------------------------*/
12704
12705   QUnit.module('keys methods');
12706
12707   lodashStable.each(['keys', 'keysIn'], function(methodName) {
12708     var args = (function() { return arguments; }(1, 2, 3)),
12709         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
12710         func = _[methodName],
12711         isKeys = methodName == 'keys';
12712
12713     QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
12714       assert.expect(1);
12715
12716       var actual = func({ 'a': 1, 'b': 1 }).sort();
12717
12718       assert.deepEqual(actual, ['a', 'b']);
12719     });
12720
12721     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
12722       assert.expect(1);
12723
12724       function Foo() {
12725         this.a = 1;
12726       }
12727       Foo.prototype.b = 2;
12728
12729       var expected = isKeys ? ['a'] : ['a', 'b'],
12730           actual = func(new Foo).sort();
12731
12732       assert.deepEqual(actual, expected);
12733     });
12734
12735     QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
12736       assert.expect(2);
12737
12738       var expected = lodashStable.map(primitives, function(value) {
12739         return typeof value == 'string' ? ['0'] : [];
12740       });
12741
12742       var actual = lodashStable.map(primitives, func);
12743       assert.deepEqual(actual, expected);
12744
12745       // IE 9 doesn't box numbers in for-in loops.
12746       numberProto.a = 1;
12747       assert.deepEqual(func(0), isKeys ? [] : ['a']);
12748       delete numberProto.a;
12749     });
12750
12751     QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
12752       assert.expect(1);
12753
12754       var array = [1];
12755       array[2] = 3;
12756
12757       var actual = func(array).sort();
12758
12759       assert.deepEqual(actual, ['0', '1', '2']);
12760     });
12761
12762     QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
12763       assert.expect(2);
12764
12765       objectProto.a = 1;
12766       lodashStable.each([null, undefined], function(value) {
12767         assert.deepEqual(func(value), []);
12768       });
12769       delete objectProto.a;
12770     });
12771
12772     QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
12773       assert.expect(1);
12774
12775       var array = [1];
12776       array.a = 1;
12777
12778       var actual = func(array).sort();
12779
12780       assert.deepEqual(actual, ['0', 'a']);
12781     });
12782
12783     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
12784       assert.expect(1);
12785
12786       arrayProto.a = 1;
12787
12788       var expected = isKeys ? ['0'] : ['0', 'a'],
12789           actual = func([1]).sort();
12790
12791       assert.deepEqual(actual, expected);
12792
12793       delete arrayProto.a;
12794     });
12795
12796     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
12797       assert.expect(1);
12798
12799       var values = [args, strictArgs],
12800           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
12801
12802       var actual = lodashStable.map(values, function(value) {
12803         return func(value).sort();
12804       });
12805
12806       assert.deepEqual(actual, expected);
12807     });
12808
12809     QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
12810       assert.expect(1);
12811
12812       var values = [args, strictArgs],
12813           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
12814
12815       var actual = lodashStable.map(values, function(value) {
12816         value.a = 1;
12817         var result = func(value).sort();
12818         delete value.a;
12819         return result;
12820       });
12821
12822       assert.deepEqual(actual, expected);
12823     });
12824
12825     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
12826       assert.expect(1);
12827
12828       var values = [args, strictArgs],
12829           expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
12830
12831       var actual = lodashStable.map(values, function(value) {
12832         objectProto.a = 1;
12833         var result = func(value).sort();
12834         delete objectProto.a;
12835         return result;
12836       });
12837
12838       assert.deepEqual(actual, expected);
12839     });
12840
12841     QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
12842       assert.expect(1);
12843
12844       var actual = func(Object('abc')).sort();
12845
12846       assert.deepEqual(actual, ['0', '1', '2']);
12847     });
12848
12849     QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
12850       assert.expect(1);
12851
12852       var object = Object('a');
12853       object.a = 1;
12854
12855       var actual = func(object).sort();
12856
12857       assert.deepEqual(actual, ['0', 'a']);
12858     });
12859
12860     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
12861       assert.expect(1);
12862
12863       stringProto.a = 1;
12864
12865       var expected = isKeys ? ['0'] : ['0', 'a'],
12866           actual = func(Object('a')).sort();
12867
12868       assert.deepEqual(actual, expected);
12869
12870       delete stringProto.a;
12871     });
12872
12873     QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
12874       assert.expect(3);
12875
12876       function Foo() {}
12877       Foo.prototype.a = 1;
12878
12879       var expected = ['a'];
12880       assert.deepEqual(func(Foo.prototype), expected);
12881
12882       Foo.prototype = { 'constructor': Foo, 'a': 1 };
12883       assert.deepEqual(func(Foo.prototype), expected);
12884
12885       var Fake = { 'prototype': {} };
12886       Fake.prototype.constructor = Fake;
12887       assert.deepEqual(func(Fake.prototype), ['constructor']);
12888     });
12889   });
12890
12891   /*--------------------------------------------------------------------------*/
12892
12893   QUnit.module('lodash.last');
12894
12895   (function() {
12896     var array = [1, 2, 3, 4];
12897
12898     QUnit.test('should return the last element', function(assert) {
12899       assert.expect(1);
12900
12901       assert.strictEqual(_.last(array), 4);
12902     });
12903
12904     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
12905       assert.expect(1);
12906
12907       var array = [];
12908       array['-1'] = 1;
12909
12910       assert.strictEqual(_.last([]), undefined);
12911     });
12912
12913     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12914       assert.expect(1);
12915
12916       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
12917           actual = lodashStable.map(array, _.last);
12918
12919       assert.deepEqual(actual, [3, 6, 9]);
12920     });
12921
12922     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12923       assert.expect(1);
12924
12925       if (!isNpm) {
12926         assert.strictEqual(_(array).last(), 4);
12927       }
12928       else {
12929         skipAssert(assert);
12930       }
12931     });
12932
12933     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12934       assert.expect(1);
12935
12936       if (!isNpm) {
12937         assert.ok(_(array).chain().last() instanceof _);
12938       }
12939       else {
12940         skipAssert(assert);
12941       }
12942     });
12943
12944     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
12945       assert.expect(1);
12946
12947       if (!isNpm) {
12948         var wrapped = _(array).chain().last();
12949         assert.strictEqual(wrapped.__wrapped__, array);
12950       }
12951       else {
12952         skipAssert(assert);
12953       }
12954     });
12955
12956     QUnit.test('should work in a lazy sequence', function(assert) {
12957       assert.expect(2);
12958
12959       if (!isNpm) {
12960         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
12961             smallArray = array;
12962
12963         lodashStable.times(2, function(index) {
12964           var array = index ? largeArray : smallArray,
12965               wrapped = _(array).filter(isEven);
12966
12967           assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
12968         });
12969       }
12970       else {
12971         skipAssert(assert, 2);
12972       }
12973     });
12974   }());
12975
12976   /*--------------------------------------------------------------------------*/
12977
12978   QUnit.module('lodash.lowerCase');
12979
12980   (function() {
12981     QUnit.test('should lowercase as space-separated words', function(assert) {
12982       assert.expect(3);
12983
12984       assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
12985       assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
12986       assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
12987     });
12988   }());
12989
12990   /*--------------------------------------------------------------------------*/
12991
12992   QUnit.module('lodash.lowerFirst');
12993
12994   (function() {
12995     QUnit.test('should lowercase only the first character', function(assert) {
12996       assert.expect(3);
12997
12998       assert.strictEqual(_.lowerFirst('fred'), 'fred');
12999       assert.strictEqual(_.lowerFirst('Fred'), 'fred');
13000       assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
13001     });
13002   }());
13003
13004   /*--------------------------------------------------------------------------*/
13005
13006   QUnit.module('lodash.lt');
13007
13008   (function() {
13009     QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
13010       assert.expect(2);
13011
13012       assert.strictEqual(_.lt(1, 3), true);
13013       assert.strictEqual(_.lt('abc', 'def'), true);
13014     });
13015
13016     QUnit.test('should return `false` if `value` >= `other`', function(assert) {
13017       assert.expect(4);
13018
13019       assert.strictEqual(_.lt(3, 1), false);
13020       assert.strictEqual(_.lt(3, 3), false);
13021       assert.strictEqual(_.lt('def', 'abc'), false);
13022       assert.strictEqual(_.lt('def', 'def'), false);
13023     });
13024   }());
13025
13026   /*--------------------------------------------------------------------------*/
13027
13028   QUnit.module('lodash.lte');
13029
13030   (function() {
13031     QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
13032       assert.expect(4);
13033
13034       assert.strictEqual(_.lte(1, 3), true);
13035       assert.strictEqual(_.lte(3, 3), true);
13036       assert.strictEqual(_.lte('abc', 'def'), true);
13037       assert.strictEqual(_.lte('def', 'def'), true);
13038     });
13039
13040     QUnit.test('should return `false` if `value` > `other`', function(assert) {
13041       assert.expect(2);
13042
13043       assert.strictEqual(_.lt(3, 1), false);
13044       assert.strictEqual(_.lt('def', 'abc'), false);
13045     });
13046   }());
13047
13048   /*--------------------------------------------------------------------------*/
13049
13050   QUnit.module('lodash.lastIndexOf');
13051
13052   (function() {
13053     var array = [1, 2, 3, 1, 2, 3];
13054
13055     QUnit.test('should return the index of the last matched value', function(assert) {
13056       assert.expect(1);
13057
13058       assert.strictEqual(_.lastIndexOf(array, 3), 5);
13059     });
13060
13061     QUnit.test('should work with a positive `fromIndex`', function(assert) {
13062       assert.expect(1);
13063
13064       assert.strictEqual(_.lastIndexOf(array, 1, 2), 0);
13065     });
13066
13067     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
13068       assert.expect(1);
13069
13070       var values = [6, 8, Math.pow(2, 32), Infinity],
13071           expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
13072
13073       var actual = lodashStable.map(values, function(fromIndex) {
13074         return [
13075           _.lastIndexOf(array, undefined, fromIndex),
13076           _.lastIndexOf(array, 1, fromIndex),
13077           _.lastIndexOf(array, '', fromIndex)
13078         ];
13079       });
13080
13081       assert.deepEqual(actual, expected);
13082     });
13083
13084     QUnit.test('should work with a negative `fromIndex`', function(assert) {
13085       assert.expect(1);
13086
13087       assert.strictEqual(_.lastIndexOf(array, 2, -3), 1);
13088     });
13089
13090     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
13091       assert.expect(1);
13092
13093       var values = [-6, -8, -Infinity],
13094           expected = lodashStable.map(values, alwaysZero);
13095
13096       var actual = lodashStable.map(values, function(fromIndex) {
13097         return _.lastIndexOf(array, 1, fromIndex);
13098       });
13099
13100       assert.deepEqual(actual, expected);
13101     });
13102
13103     QUnit.test('should treat falsey `fromIndex` values correctly', function(assert) {
13104       assert.expect(1);
13105
13106       var expected = lodashStable.map(falsey, function(value) {
13107         return value === undefined ? 5 : -1;
13108       });
13109
13110       var actual = lodashStable.map(falsey, function(fromIndex) {
13111         return _.lastIndexOf(array, 3, fromIndex);
13112       });
13113
13114       assert.deepEqual(actual, expected);
13115     });
13116
13117     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
13118       assert.expect(1);
13119
13120       assert.strictEqual(_.lastIndexOf(array, 2, 4.2), 4);
13121     });
13122   }());
13123
13124   /*--------------------------------------------------------------------------*/
13125
13126   QUnit.module('indexOf methods');
13127
13128   lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
13129     var func = _[methodName],
13130         isIndexOf = !/last/i.test(methodName),
13131         isSorted = /^sorted/.test(methodName);
13132
13133     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
13134       assert.expect(1);
13135
13136       var expected = lodashStable.map(falsey, lodashStable.constant(-1));
13137
13138       var actual = lodashStable.map(falsey, function(array, index) {
13139         try {
13140           return index ? func(array) : func();
13141         } catch (e) {}
13142       });
13143
13144       assert.deepEqual(actual, expected);
13145     });
13146
13147     QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
13148       assert.expect(5);
13149
13150       var array = [1, 2, 3],
13151           empty = [];
13152
13153       assert.strictEqual(func(array, 4), -1);
13154       assert.strictEqual(func(array, 4, true), -1);
13155       assert.strictEqual(func(array, undefined, true), -1);
13156
13157       assert.strictEqual(func(empty, undefined), -1);
13158       assert.strictEqual(func(empty, undefined, true), -1);
13159     });
13160
13161     QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
13162       assert.expect(2);
13163
13164       var array = [];
13165       array[-1] = 0;
13166
13167       assert.strictEqual(func(array, undefined), -1);
13168       assert.strictEqual(func(array, 0, true), -1);
13169     });
13170
13171     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
13172       assert.expect(3);
13173
13174       var array = isSorted
13175         ? [1, 2, NaN, NaN]
13176         : [1, NaN, 3, NaN, 5, NaN];
13177
13178       if (isSorted) {
13179         assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
13180         skipAssert(assert, 2);
13181       }
13182       else {
13183         assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
13184         assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
13185         assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
13186       }
13187     });
13188
13189     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13190       assert.expect(2);
13191
13192       assert.strictEqual(func([-0], 0), 0);
13193       assert.strictEqual(func([0], -0), 0);
13194     });
13195   });
13196
13197   /*--------------------------------------------------------------------------*/
13198
13199   QUnit.module('lodash.map');
13200
13201   (function() {
13202     var array = [1, 2];
13203
13204     QUnit.test('should map values in `collection` to a new array', function(assert) {
13205       assert.expect(2);
13206
13207       var object = { 'a': 1, 'b': 2 },
13208           expected = ['1', '2'];
13209
13210       assert.deepEqual(_.map(array, String), expected);
13211       assert.deepEqual(_.map(object, String), expected);
13212     });
13213
13214     QUnit.test('should work with `_.property` shorthands', function(assert) {
13215       assert.expect(1);
13216
13217       var objects = [{ 'a': 'x' }, { 'a': 'y' }];
13218       assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
13219     });
13220
13221     QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
13222       assert.expect(1);
13223
13224       function Foo() {
13225         this.a = 1;
13226       }
13227       Foo.prototype.b = 2;
13228
13229       var actual = _.map(new Foo, identity);
13230       assert.deepEqual(actual, [1]);
13231     });
13232
13233     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13234       assert.expect(2);
13235
13236       var object = { 'a': 1, 'b': 2 },
13237           values = [, null, undefined],
13238           expected = lodashStable.map(values, lodashStable.constant([1, 2]));
13239
13240       lodashStable.each([array, object], function(collection) {
13241         var actual = lodashStable.map(values, function(value, index) {
13242           return index ? _.map(collection, value) : _.map(collection);
13243         });
13244
13245         assert.deepEqual(actual, expected);
13246       });
13247     });
13248
13249     QUnit.test('should accept a falsey `collection` argument', function(assert) {
13250       assert.expect(1);
13251
13252       var expected = lodashStable.map(falsey, alwaysEmptyArray);
13253
13254       var actual = lodashStable.map(falsey, function(collection, index) {
13255         try {
13256           return index ? _.map(collection) : _.map();
13257         } catch (e) {}
13258       });
13259
13260       assert.deepEqual(actual, expected);
13261     });
13262
13263     QUnit.test('should treat number values for `collection` as empty', function(assert) {
13264       assert.expect(1);
13265
13266       assert.deepEqual(_.map(1), []);
13267     });
13268
13269     QUnit.test('should treat a nodelist as an array-like object', function(assert) {
13270       assert.expect(1);
13271
13272       if (document) {
13273         var actual = _.map(document.getElementsByTagName('body'), function(element) {
13274           return element.nodeName.toLowerCase();
13275         });
13276
13277         assert.deepEqual(actual, ['body']);
13278       }
13279       else {
13280         skipAssert(assert);
13281       }
13282     });
13283
13284     QUnit.test('should work with objects with non-number length properties', function(assert) {
13285       assert.expect(1);
13286
13287       var value = { 'value': 'x' },
13288           object = { 'length': { 'value': 'x' } };
13289
13290       assert.deepEqual(_.map(object, identity), [value]);
13291     });
13292
13293     QUnit.test('should return a wrapped value when chaining', function(assert) {
13294       assert.expect(1);
13295
13296       if (!isNpm) {
13297         assert.ok(_(array).map(noop) instanceof _);
13298       }
13299       else {
13300         skipAssert(assert);
13301       }
13302     });
13303
13304     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
13305       assert.expect(5);
13306
13307       if (!isNpm) {
13308         var args,
13309             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
13310             expected = [1, 0, _.map(array.slice(1), square)];
13311
13312         _(array).slice(1).map(function(value, index, array) {
13313           args || (args = slice.call(arguments));
13314         }).value();
13315
13316         assert.deepEqual(args, [1, 0, array.slice(1)]);
13317
13318         args = undefined;
13319         _(array).slice(1).map(square).map(function(value, index, array) {
13320           args || (args = slice.call(arguments));
13321         }).value();
13322
13323         assert.deepEqual(args, expected);
13324
13325         args = undefined;
13326         _(array).slice(1).map(square).map(function(value, index) {
13327           args || (args = slice.call(arguments));
13328         }).value();
13329
13330         assert.deepEqual(args, expected);
13331
13332         args = undefined;
13333         _(array).slice(1).map(square).map(function(value) {
13334           args || (args = slice.call(arguments));
13335         }).value();
13336
13337         assert.deepEqual(args, [1]);
13338
13339         args = undefined;
13340         _(array).slice(1).map(square).map(function() {
13341           args || (args = slice.call(arguments));
13342         }).value();
13343
13344         assert.deepEqual(args, expected);
13345       }
13346       else {
13347         skipAssert(assert, 5);
13348       }
13349     });
13350   }());
13351
13352   /*--------------------------------------------------------------------------*/
13353
13354   QUnit.module('lodash.mapKeys');
13355
13356   (function() {
13357     var array = [1, 2],
13358         object = { 'a': 1, 'b': 2 };
13359
13360     QUnit.test('should map keys in `object` to a new object', function(assert) {
13361       assert.expect(1);
13362
13363       var actual = _.mapKeys(object, String);
13364       assert.deepEqual(actual, { '1': 1, '2': 2 });
13365     });
13366
13367     QUnit.test('should treat arrays like objects', function(assert) {
13368       assert.expect(1);
13369
13370       var actual = _.mapKeys(array, String);
13371       assert.deepEqual(actual, { '1': 1, '2': 2 });
13372     });
13373
13374     QUnit.test('should work with `_.property` shorthands', function(assert) {
13375       assert.expect(1);
13376
13377       var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
13378       assert.deepEqual(actual, { 'c': { 'b': 'c' } });
13379     });
13380
13381     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13382       assert.expect(1);
13383
13384       var object = { 'a': 1, 'b': 2 },
13385           values = [, null, undefined],
13386           expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
13387
13388       var actual = lodashStable.map(values, function(value, index) {
13389         return index ? _.mapKeys(object, value) : _.mapKeys(object);
13390       });
13391
13392       assert.deepEqual(actual, expected);
13393     });
13394   }());
13395
13396   /*--------------------------------------------------------------------------*/
13397
13398   QUnit.module('lodash.mapValues');
13399
13400   (function() {
13401     var array = [1, 2],
13402         object = { 'a': 1, 'b': 2 };
13403
13404     QUnit.test('should map values in `object` to a new object', function(assert) {
13405       assert.expect(1);
13406
13407       var actual = _.mapValues(object, String);
13408       assert.deepEqual(actual, { 'a': '1', 'b': '2' });
13409     });
13410
13411     QUnit.test('should treat arrays like objects', function(assert) {
13412       assert.expect(1);
13413
13414       var actual = _.mapValues(array, String);
13415       assert.deepEqual(actual, { '0': '1', '1': '2' });
13416     });
13417
13418     QUnit.test('should work with `_.property` shorthands', function(assert) {
13419       assert.expect(1);
13420
13421       var actual = _.mapValues({ 'a': { 'b': 1 } }, 'b');
13422       assert.deepEqual(actual, { 'a': 1 });
13423     });
13424
13425     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13426       assert.expect(1);
13427
13428       var object = { 'a': 1, 'b': 2 },
13429           values = [, null, undefined],
13430           expected = lodashStable.map(values, lodashStable.constant([true, false]));
13431
13432       var actual = lodashStable.map(values, function(value, index) {
13433         var result = index ? _.mapValues(object, value) : _.mapValues(object);
13434         return [lodashStable.isEqual(result, object), result === object];
13435       });
13436
13437       assert.deepEqual(actual, expected);
13438     });
13439   }());
13440
13441   /*--------------------------------------------------------------------------*/
13442
13443   QUnit.module('lodash.mapKeys and lodash.mapValues');
13444
13445   lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
13446     var func = _[methodName],
13447         object = { 'a': 1, 'b': 2 };
13448
13449     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
13450       assert.expect(1);
13451
13452       function Foo() {
13453         this.a = 'a';
13454       }
13455       Foo.prototype.b = 'b';
13456
13457       var actual = func(new Foo, function(value, key) { return key; });
13458       assert.deepEqual(actual, { 'a': 'a' });
13459     });
13460
13461     QUnit.test('`_.' + methodName + '` should accept a falsey `object` argument', function(assert) {
13462       assert.expect(1);
13463
13464       var expected = lodashStable.map(falsey, alwaysEmptyObject);
13465
13466       var actual = lodashStable.map(falsey, function(object, index) {
13467         try {
13468           return index ? func(object) : func();
13469         } catch (e) {}
13470       });
13471
13472       assert.deepEqual(actual, expected);
13473     });
13474
13475     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
13476       assert.expect(1);
13477
13478       if (!isNpm) {
13479         assert.ok(_(object)[methodName](noop) instanceof _);
13480       }
13481       else {
13482         skipAssert(assert);
13483       }
13484     });
13485   });
13486
13487   /*--------------------------------------------------------------------------*/
13488
13489   QUnit.module('lodash.matches');
13490
13491   (function() {
13492     QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
13493       assert.expect(6);
13494
13495       var object = { 'a': 1, 'b': 2, 'c': 3 },
13496           matches = _.matches({ 'a': 1 });
13497
13498       assert.strictEqual(matches.length, 1);
13499       assert.strictEqual(matches(object), true);
13500
13501       matches = _.matches({ 'b': 1 });
13502       assert.strictEqual(matches(object), false);
13503
13504       matches = _.matches({ 'a': 1, 'c': 3 });
13505       assert.strictEqual(matches(object), true);
13506
13507       matches = _.matches({ 'c': 3, 'd': 4 });
13508       assert.strictEqual(matches(object), false);
13509
13510       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13511       matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
13512
13513       assert.strictEqual(matches(object), true);
13514     });
13515
13516     QUnit.test('should match inherited string keyed `object` properties', function(assert) {
13517       assert.expect(1);
13518
13519       function Foo() {
13520         this.a = 1;
13521       }
13522       Foo.prototype.b = 2;
13523
13524       var object = { 'a': new Foo },
13525           matches = _.matches({ 'a': { 'b': 2 } });
13526
13527       assert.strictEqual(matches(object), true);
13528     });
13529
13530     QUnit.test('should not match by inherited `source` properties', function(assert) {
13531       assert.expect(1);
13532
13533       function Foo() {
13534         this.a = 1;
13535       }
13536       Foo.prototype.b = 2;
13537
13538       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
13539           source = new Foo,
13540           actual = lodashStable.map(objects, _.matches(source)),
13541           expected = lodashStable.map(objects, alwaysTrue);
13542
13543       assert.deepEqual(actual, expected);
13544     });
13545
13546     QUnit.test('should compare a variety of `source` property values', function(assert) {
13547       assert.expect(2);
13548
13549       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13550           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13551           matches = _.matches(object1);
13552
13553       assert.strictEqual(matches(object1), true);
13554       assert.strictEqual(matches(object2), false);
13555     });
13556
13557     QUnit.test('should match `-0` as `0`', function(assert) {
13558       assert.expect(2);
13559
13560       var object1 = { 'a': -0 },
13561           object2 = { 'a': 0 },
13562           matches = _.matches(object1);
13563
13564       assert.strictEqual(matches(object2), true);
13565
13566       matches = _.matches(object2);
13567       assert.strictEqual(matches(object1), true);
13568     });
13569
13570     QUnit.test('should compare functions by reference', function(assert) {
13571       assert.expect(3);
13572
13573       var object1 = { 'a': lodashStable.noop },
13574           object2 = { 'a': noop },
13575           object3 = { 'a': {} },
13576           matches = _.matches(object1);
13577
13578       assert.strictEqual(matches(object1), true);
13579       assert.strictEqual(matches(object2), false);
13580       assert.strictEqual(matches(object3), false);
13581     });
13582
13583     QUnit.test('should work with a function for `object`', function(assert) {
13584       assert.expect(1);
13585
13586       function Foo() {}
13587       Foo.a = { 'b': 1, 'c': 2 };
13588
13589       var matches = _.matches({ 'a': { 'b': 1 } });
13590       assert.strictEqual(matches(Foo), true);
13591     });
13592
13593     QUnit.test('should work with a function for `source`', function(assert) {
13594       assert.expect(1);
13595
13596       function Foo() {}
13597       Foo.a = 1;
13598       Foo.b = function() {};
13599       Foo.c = 3;
13600
13601       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
13602           actual = lodashStable.map(objects, _.matches(Foo));
13603
13604       assert.deepEqual(actual, [false, true]);
13605     });
13606
13607     QUnit.test('should work with a non-plain `object`', function(assert) {
13608       assert.expect(1);
13609
13610       function Foo(object) { lodashStable.assign(this, object); }
13611
13612       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
13613           matches = _.matches({ 'a': { 'b': 1 } });
13614
13615       assert.strictEqual(matches(object), true);
13616     });
13617
13618     QUnit.test('should partial match arrays', function(assert) {
13619       assert.expect(3);
13620
13621       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13622           actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
13623
13624       assert.deepEqual(actual, [objects[1]]);
13625
13626       actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
13627       assert.deepEqual(actual, []);
13628
13629       actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
13630       assert.deepEqual(actual, []);
13631     });
13632
13633     QUnit.test('should partial match arrays of objects', function(assert) {
13634       assert.expect(1);
13635
13636       var objects = [
13637         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
13638         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
13639       ];
13640
13641       var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
13642       assert.deepEqual(actual, [objects[0]]);
13643     });
13644
13645     QUnit.test('should partial match maps', function(assert) {
13646       assert.expect(3);
13647
13648       if (Map) {
13649         var objects = [{ 'a': new Map }, { 'a': new Map }];
13650         objects[0].a.set('a', 1);
13651         objects[1].a.set('a', 1);
13652         objects[1].a.set('b', 2);
13653
13654         var map = new Map;
13655         map.set('b', 2);
13656         var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13657
13658         assert.deepEqual(actual, [objects[1]]);
13659
13660         map['delete']('b');
13661         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13662
13663         assert.deepEqual(actual, objects);
13664
13665         map.set('c', 3);
13666         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13667
13668         assert.deepEqual(actual, []);
13669       }
13670       else {
13671         skipAssert(assert, 3);
13672       }
13673     });
13674
13675     QUnit.test('should partial match sets', function(assert) {
13676       assert.expect(3);
13677
13678       if (Set) {
13679         var objects = [{ 'a': new Set }, { 'a': new Set }];
13680         objects[0].a.add(1);
13681         objects[1].a.add(1);
13682         objects[1].a.add(2);
13683
13684         var set = new Set;
13685         set.add(2);
13686         var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13687
13688         assert.deepEqual(actual, [objects[1]]);
13689
13690         set['delete'](2);
13691         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13692
13693         assert.deepEqual(actual, objects);
13694
13695         set.add(3);
13696         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13697
13698         assert.deepEqual(actual, []);
13699       }
13700       else {
13701         skipAssert(assert, 3);
13702       }
13703     });
13704
13705     QUnit.test('should match `undefined` values', function(assert) {
13706       assert.expect(3);
13707
13708       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
13709           actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
13710           expected = [false, false, true];
13711
13712       assert.deepEqual(actual, expected);
13713
13714       actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
13715
13716       assert.deepEqual(actual, expected);
13717
13718       objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
13719       actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
13720
13721       assert.deepEqual(actual, expected);
13722     });
13723
13724     QUnit.test('should match `undefined` values on primitives', function(assert) {
13725       assert.expect(3);
13726
13727       numberProto.a = 1;
13728       numberProto.b = undefined;
13729
13730       try {
13731         var matches = _.matches({ 'b': undefined });
13732         assert.strictEqual(matches(1), true);
13733       } catch (e) {
13734         assert.ok(false, e.message);
13735       }
13736       try {
13737         matches = _.matches({ 'a': 1, 'b': undefined });
13738         assert.strictEqual(matches(1), true);
13739       } catch (e) {
13740         assert.ok(false, e.message);
13741       }
13742       numberProto.a = { 'b': 1, 'c': undefined };
13743       try {
13744         matches = _.matches({ 'a': { 'c': undefined } });
13745         assert.strictEqual(matches(1), true);
13746       } catch (e) {
13747         assert.ok(false, e.message);
13748       }
13749       delete numberProto.a;
13750       delete numberProto.b;
13751     });
13752
13753     QUnit.test('should return `false` when `object` is nullish', function(assert) {
13754       assert.expect(1);
13755
13756       var values = [, null, undefined],
13757           expected = lodashStable.map(values, alwaysFalse),
13758           matches = _.matches({ 'a': 1 });
13759
13760       var actual = lodashStable.map(values, function(value, index) {
13761         try {
13762           return index ? matches(value) : matches();
13763         } catch (e) {}
13764       });
13765
13766       assert.deepEqual(actual, expected);
13767     });
13768
13769     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
13770       assert.expect(1);
13771
13772       var values = [, null, undefined],
13773           expected = lodashStable.map(values, alwaysTrue),
13774           matches = _.matches({});
13775
13776       var actual = lodashStable.map(values, function(value, index) {
13777         try {
13778           return index ? matches(value) : matches();
13779         } catch (e) {}
13780       });
13781
13782       assert.deepEqual(actual, expected);
13783     });
13784
13785     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
13786       assert.expect(1);
13787
13788       var object = { 'a': 1 },
13789           expected = lodashStable.map(empties, alwaysTrue);
13790
13791       var actual = lodashStable.map(empties, function(value) {
13792         var matches = _.matches(value);
13793         return matches(object);
13794       });
13795
13796       assert.deepEqual(actual, expected);
13797     });
13798
13799     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
13800       assert.expect(1);
13801
13802       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
13803           actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
13804
13805       assert.deepEqual(actual, objects);
13806     });
13807
13808     QUnit.test('should not change behavior if `source` is modified', function(assert) {
13809       assert.expect(9);
13810
13811       var sources = [
13812         { 'a': { 'b': 2, 'c': 3 } },
13813         { 'a': 1, 'b': 2 },
13814         { 'a': 1 }
13815       ];
13816
13817       lodashStable.each(sources, function(source, index) {
13818         var object = lodashStable.cloneDeep(source),
13819             matches = _.matches(source);
13820
13821         assert.strictEqual(matches(object), true);
13822
13823         if (index) {
13824           source.a = 2;
13825           source.b = 1;
13826           source.c = 3;
13827         } else {
13828           source.a.b = 1;
13829           source.a.c = 2;
13830           source.a.d = 3;
13831         }
13832         assert.strictEqual(matches(object), true);
13833         assert.strictEqual(matches(source), false);
13834       });
13835     });
13836   }());
13837
13838   /*--------------------------------------------------------------------------*/
13839
13840   QUnit.module('lodash.matchesProperty');
13841
13842   (function() {
13843     QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
13844       assert.expect(6);
13845
13846       var object = { 'a': 1, 'b': 2, 'c': 3 },
13847           matches = _.matchesProperty('a', 1);
13848
13849       assert.strictEqual(matches.length, 1);
13850       assert.strictEqual(matches(object), true);
13851
13852       matches = _.matchesProperty('b', 3);
13853       assert.strictEqual(matches(object), false);
13854
13855       matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
13856       assert.strictEqual(matches({ 'a': object }), true);
13857
13858       matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
13859       assert.strictEqual(matches(object), false);
13860
13861       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13862       matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
13863
13864       assert.strictEqual(matches(object), true);
13865     });
13866
13867     QUnit.test('should support deep paths', function(assert) {
13868       assert.expect(2);
13869
13870       var object = { 'a': { 'b': 2 } };
13871
13872       lodashStable.each(['a.b', ['a', 'b']], function(path) {
13873         var matches = _.matchesProperty(path, 2);
13874         assert.strictEqual(matches(object), true);
13875       });
13876     });
13877
13878     QUnit.test('should work with a non-string `path`', function(assert) {
13879       assert.expect(2);
13880
13881       var array = [1, 2, 3];
13882
13883       lodashStable.each([1, [1]], function(path) {
13884         var matches = _.matchesProperty(path, 2);
13885         assert.strictEqual(matches(array), true);
13886       });
13887     });
13888
13889     QUnit.test('should preserve the sign of `0`', function(assert) {
13890       assert.expect(1);
13891
13892       var object1 = { '-0': 'a' },
13893           object2 = { '0': 'b' },
13894           pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
13895           props = [-0, Object(-0), 0, Object(0)],
13896           values = ['a', 'a', 'b', 'b'],
13897           expected = lodashStable.map(props, lodashStable.constant([true, false]));
13898
13899       var actual = lodashStable.map(props, function(key, index) {
13900         var matches = _.matchesProperty(key, values[index]),
13901             pair = pairs[index];
13902
13903         return [matches(pair[0]), matches(pair[1])];
13904       });
13905
13906       assert.deepEqual(actual, expected);
13907     });
13908
13909     QUnit.test('should coerce key to a string', function(assert) {
13910       assert.expect(1);
13911
13912       function fn() {}
13913       fn.toString = lodashStable.constant('fn');
13914
13915       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
13916           values = [null, undefined, fn, {}];
13917
13918       var expected = lodashStable.transform(values, function(result) {
13919         result.push(true, true);
13920       });
13921
13922       var actual = lodashStable.transform(objects, function(result, object, index) {
13923         var key = values[index];
13924         lodashStable.each([key, [key]], function(path) {
13925           var matches = _.matchesProperty(path, object[key]);
13926           result.push(matches(object));
13927         });
13928       });
13929
13930       assert.deepEqual(actual, expected);
13931     });
13932
13933     QUnit.test('should match a key over a path', function(assert) {
13934       assert.expect(2);
13935
13936       var object = { 'a.b': 1, 'a': { 'b': 2 } };
13937
13938       lodashStable.each(['a.b', ['a.b']], function(path) {
13939         var matches = _.matchesProperty(path, 1);
13940         assert.strictEqual(matches(object), true);
13941       });
13942     });
13943
13944     QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
13945       assert.expect(4);
13946
13947       var object = {};
13948
13949       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
13950         var matches = _.matchesProperty(path, 1);
13951         assert.strictEqual(matches(object), false);
13952       });
13953     });
13954
13955     QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
13956       assert.expect(2);
13957
13958       var values = [, null, undefined],
13959           expected = lodashStable.map(values, alwaysFalse);
13960
13961       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
13962         var matches = _.matchesProperty(path, 1);
13963
13964         var actual = lodashStable.map(values, function(value, index) {
13965           try {
13966             return index ? matches(value) : matches();
13967           } catch (e) {}
13968         });
13969
13970         assert.deepEqual(actual, expected);
13971       });
13972     });
13973
13974     QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
13975       assert.expect(2);
13976
13977       function Foo() {}
13978       Foo.prototype.b = 2;
13979
13980       var object = { 'a': new Foo };
13981
13982       lodashStable.each(['a', ['a']], function(path) {
13983         var matches = _.matchesProperty(path, { 'b': 2 });
13984         assert.strictEqual(matches(object), true);
13985       });
13986     });
13987
13988     QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
13989       assert.expect(2);
13990
13991       function Foo() {
13992         this.a = 1;
13993       }
13994       Foo.prototype.b = 2;
13995
13996       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
13997           expected = lodashStable.map(objects, alwaysTrue);
13998
13999       lodashStable.each(['a', ['a']], function(path) {
14000         assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
14001       });
14002     });
14003
14004     QUnit.test('should compare a variety of values', function(assert) {
14005       assert.expect(2);
14006
14007       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
14008           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
14009           matches = _.matchesProperty('a', object1);
14010
14011       assert.strictEqual(matches({ 'a': object1 }), true);
14012       assert.strictEqual(matches({ 'a': object2 }), false);
14013     });
14014
14015     QUnit.test('should match `-0` as `0`', function(assert) {
14016       assert.expect(2);
14017
14018       var matches = _.matchesProperty('a', -0);
14019       assert.strictEqual(matches({ 'a': 0 }), true);
14020
14021       matches = _.matchesProperty('a', 0);
14022       assert.strictEqual(matches({ 'a': -0 }), true);
14023     });
14024
14025     QUnit.test('should compare functions by reference', function(assert) {
14026       assert.expect(3);
14027
14028       var object1 = { 'a': lodashStable.noop },
14029           object2 = { 'a': noop },
14030           object3 = { 'a': {} },
14031           matches = _.matchesProperty('a', object1);
14032
14033       assert.strictEqual(matches({ 'a': object1 }), true);
14034       assert.strictEqual(matches({ 'a': object2 }), false);
14035       assert.strictEqual(matches({ 'a': object3 }), false);
14036     });
14037
14038     QUnit.test('should work with a function for `srcValue`', function(assert) {
14039       assert.expect(1);
14040
14041       function Foo() {}
14042       Foo.a = 1;
14043       Foo.b = function() {};
14044       Foo.c = 3;
14045
14046       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
14047           actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
14048
14049       assert.deepEqual(actual, [false, true]);
14050     });
14051
14052     QUnit.test('should work with a non-plain `srcValue`', function(assert) {
14053       assert.expect(1);
14054
14055       function Foo(object) { lodashStable.assign(this, object); }
14056
14057       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
14058           matches = _.matchesProperty('a', { 'b': 1 });
14059
14060       assert.strictEqual(matches(object), true);
14061     });
14062
14063     QUnit.test('should partial match arrays', function(assert) {
14064       assert.expect(3);
14065
14066       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
14067           actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
14068
14069       assert.deepEqual(actual, [objects[1]]);
14070
14071       actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
14072       assert.deepEqual(actual, []);
14073
14074       actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
14075       assert.deepEqual(actual, []);
14076     });
14077
14078     QUnit.test('should partial match arrays of objects', function(assert) {
14079       assert.expect(1);
14080
14081       var objects = [
14082         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
14083         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
14084       ];
14085
14086       var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
14087       assert.deepEqual(actual, [objects[0]]);
14088     });
14089     QUnit.test('should partial match maps', function(assert) {
14090       assert.expect(3);
14091
14092       if (Map) {
14093         var objects = [{ 'a': new Map }, { 'a': new Map }];
14094         objects[0].a.set('a', 1);
14095         objects[1].a.set('a', 1);
14096         objects[1].a.set('b', 2);
14097
14098         var map = new Map;
14099         map.set('b', 2);
14100         var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14101
14102         assert.deepEqual(actual, [objects[1]]);
14103
14104         map['delete']('b');
14105         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14106
14107         assert.deepEqual(actual, objects);
14108
14109         map.set('c', 3);
14110         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14111
14112         assert.deepEqual(actual, []);
14113       }
14114       else {
14115         skipAssert(assert, 3);
14116       }
14117     });
14118
14119     QUnit.test('should partial match sets', function(assert) {
14120       assert.expect(3);
14121
14122       if (Set) {
14123         var objects = [{ 'a': new Set }, { 'a': new Set }];
14124         objects[0].a.add(1);
14125         objects[1].a.add(1);
14126         objects[1].a.add(2);
14127
14128         var set = new Set;
14129         set.add(2);
14130         var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14131
14132         assert.deepEqual(actual, [objects[1]]);
14133
14134         set['delete'](2);
14135         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14136
14137         assert.deepEqual(actual, objects);
14138
14139         set.add(3);
14140         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14141
14142         assert.deepEqual(actual, []);
14143       }
14144       else {
14145         skipAssert(assert, 3);
14146       }
14147     });
14148
14149     QUnit.test('should match `undefined` values', function(assert) {
14150       assert.expect(2);
14151
14152       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14153           actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
14154           expected = [false, false, true];
14155
14156       assert.deepEqual(actual, expected);
14157
14158       objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
14159       actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
14160
14161       assert.deepEqual(actual, expected);
14162     });
14163
14164     QUnit.test('should match `undefined` values of nested objects', function(assert) {
14165       assert.expect(4);
14166
14167       var object = { 'a': { 'b': undefined } };
14168
14169       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14170         var matches = _.matchesProperty(path, undefined);
14171         assert.strictEqual(matches(object), true);
14172       });
14173
14174       lodashStable.each(['a.a', ['a', 'a']], function(path) {
14175         var matches = _.matchesProperty(path, undefined);
14176         assert.strictEqual(matches(object), false);
14177       });
14178     });
14179
14180     QUnit.test('should match `undefined` values on primitives', function(assert) {
14181       assert.expect(2);
14182
14183       numberProto.a = 1;
14184       numberProto.b = undefined;
14185
14186       try {
14187         var matches = _.matchesProperty('b', undefined);
14188         assert.strictEqual(matches(1), true);
14189       } catch (e) {
14190         assert.ok(false, e.message);
14191       }
14192       numberProto.a = { 'b': 1, 'c': undefined };
14193       try {
14194         matches = _.matchesProperty('a', { 'c': undefined });
14195         assert.strictEqual(matches(1), true);
14196       } catch (e) {
14197         assert.ok(false, e.message);
14198       }
14199       delete numberProto.a;
14200       delete numberProto.b;
14201     });
14202
14203     QUnit.test('should return `false` when `object` is nullish', function(assert) {
14204       assert.expect(2);
14205
14206       var values = [, null, undefined],
14207           expected = lodashStable.map(values, alwaysFalse);
14208
14209       lodashStable.each(['constructor', ['constructor']], function(path) {
14210         var matches = _.matchesProperty(path, 1);
14211
14212         var actual = lodashStable.map(values, function(value, index) {
14213           try {
14214             return index ? matches(value) : matches();
14215           } catch (e) {}
14216         });
14217
14218         assert.deepEqual(actual, expected);
14219       });
14220     });
14221
14222     QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
14223       assert.expect(1);
14224
14225       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14226           matches = _.matchesProperty('a', { 'a': [], 'b': {} });
14227
14228       var actual = lodashStable.filter(objects, function(object) {
14229         return matches({ 'a': object });
14230       });
14231
14232       assert.deepEqual(actual, objects);
14233     });
14234
14235     QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
14236       assert.expect(9);
14237
14238       lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
14239         var object = lodashStable.cloneDeep(source),
14240             matches = _.matchesProperty('a', source);
14241
14242         assert.strictEqual(matches({ 'a': object }), true);
14243
14244         if (index) {
14245           source.a = 2;
14246           source.b = 1;
14247           source.c = 3;
14248         } else {
14249           source.a.b = 1;
14250           source.a.c = 2;
14251           source.a.d = 3;
14252         }
14253         assert.strictEqual(matches({ 'a': object }), true);
14254         assert.strictEqual(matches({ 'a': source }), false);
14255       });
14256     });
14257   }());
14258
14259   /*--------------------------------------------------------------------------*/
14260
14261   QUnit.module('lodash.max');
14262
14263   (function() {
14264     QUnit.test('should return the largest value from a collection', function(assert) {
14265       assert.expect(1);
14266
14267       assert.strictEqual(_.max([1, 2, 3]), 3);
14268     });
14269
14270     QUnit.test('should return `undefined` for empty collections', function(assert) {
14271       assert.expect(1);
14272
14273       var values = falsey.concat([[]]),
14274           expected = lodashStable.map(values, noop);
14275
14276       var actual = lodashStable.map(values, function(value, index) {
14277         try {
14278           return index ? _.max(value) : _.max();
14279         } catch (e) {}
14280       });
14281
14282       assert.deepEqual(actual, expected);
14283     });
14284
14285     QUnit.test('should work with non-numeric collection values', function(assert) {
14286       assert.expect(1);
14287
14288       assert.strictEqual(_.max(['a', 'b']), 'b');
14289     });
14290   }());
14291
14292   /*--------------------------------------------------------------------------*/
14293
14294   QUnit.module('lodash.mean');
14295
14296   (function() {
14297     QUnit.test('should return the mean of an array of numbers', function(assert) {
14298       assert.expect(1);
14299
14300       var array = [4, 2, 8, 6];
14301       assert.strictEqual(_.mean(array), 5);
14302     });
14303
14304     QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
14305       assert.expect(1);
14306
14307       var expected = lodashStable.map(empties, alwaysNaN),
14308           actual = lodashStable.map(empties, _.mean);
14309
14310       assert.deepEqual(actual, expected);
14311     });
14312   }());
14313
14314   /*--------------------------------------------------------------------------*/
14315
14316   QUnit.module('lodash.meanBy');
14317
14318   (function() {
14319     var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
14320
14321     QUnit.test('should work with an `iteratee` argument', function(assert) {
14322       assert.expect(1);
14323
14324       var actual = _.meanBy(objects, function(object) {
14325         return object.a;
14326       });
14327
14328       assert.deepEqual(actual, 2);
14329     });
14330
14331     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
14332       assert.expect(1);
14333
14334       var args;
14335
14336       _.meanBy(objects, function() {
14337         args || (args = slice.call(arguments));
14338       });
14339
14340       assert.deepEqual(args, [{ 'a': 2 }]);
14341     });
14342
14343     QUnit.test('should work with `_.property` shorthands', function(assert) {
14344       assert.expect(2);
14345
14346       var arrays = [[2], [3], [1]];
14347       assert.strictEqual(_.meanBy(arrays, 0), 2);
14348       assert.strictEqual(_.meanBy(objects, 'a'), 2);
14349     });
14350   }());
14351
14352   /*--------------------------------------------------------------------------*/
14353
14354   QUnit.module('lodash.memoize');
14355
14356   (function() {
14357     QUnit.test('should memoize results based on the first argument given', function(assert) {
14358       assert.expect(2);
14359
14360       var memoized = _.memoize(function(a, b, c) {
14361         return a + b + c;
14362       });
14363
14364       assert.strictEqual(memoized(1, 2, 3), 6);
14365       assert.strictEqual(memoized(1, 3, 5), 6);
14366     });
14367
14368     QUnit.test('should support a `resolver` argument', function(assert) {
14369       assert.expect(2);
14370
14371       var fn = function(a, b, c) { return a + b + c; },
14372           memoized = _.memoize(fn, fn);
14373
14374       assert.strictEqual(memoized(1, 2, 3), 6);
14375       assert.strictEqual(memoized(1, 3, 5), 9);
14376     });
14377
14378     QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
14379       assert.expect(2);
14380
14381       var fn = function(a, b, c) { return a + this.b + this.c; },
14382           memoized = _.memoize(fn, fn);
14383
14384       var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
14385       assert.strictEqual(object.memoized(1), 6);
14386
14387       object.b = 3;
14388       object.c = 5;
14389       assert.strictEqual(object.memoized(1), 9);
14390     });
14391
14392     QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
14393       assert.expect(1);
14394
14395       assert.raises(function() { _.memoize(noop, true); }, TypeError);
14396     });
14397
14398     QUnit.test('should not error if `resolver` is falsey', function(assert) {
14399       assert.expect(1);
14400
14401       var expected = lodashStable.map(falsey, alwaysTrue);
14402
14403       var actual = lodashStable.map(falsey, function(resolver, index) {
14404         try {
14405           return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
14406         } catch (e) {}
14407       });
14408
14409       assert.deepEqual(actual, expected);
14410     });
14411
14412     QUnit.test('should check cache for own properties', function(assert) {
14413       assert.expect(1);
14414
14415       var props = [
14416         'constructor',
14417         'hasOwnProperty',
14418         'isPrototypeOf',
14419         'propertyIsEnumerable',
14420         'toLocaleString',
14421         'toString',
14422         'valueOf'
14423       ];
14424
14425       var memoized = _.memoize(identity);
14426
14427       var actual = lodashStable.map(props, function(value) {
14428         return memoized(value);
14429       });
14430
14431       assert.deepEqual(actual, props);
14432     });
14433
14434     QUnit.test('should cache the `__proto__` key', function(assert) {
14435       assert.expect(8);
14436
14437       var array = [],
14438           key = '__proto__';
14439
14440       lodashStable.times(2, function(index) {
14441         var count = 0,
14442             resolver = index && identity;
14443
14444         var memoized = _.memoize(function() {
14445           count++;
14446           return array;
14447         }, resolver);
14448
14449         var cache = memoized.cache;
14450
14451         memoized(key);
14452         memoized(key);
14453
14454         assert.strictEqual(count, 1);
14455         assert.strictEqual(cache.get(key), array);
14456         assert.notOk(cache.__data__ instanceof Array);
14457         assert.strictEqual(cache['delete'](key), true);
14458       });
14459     });
14460
14461     QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
14462       assert.expect(4);
14463
14464       var oldCache = _.memoize.Cache;
14465
14466       function Cache() {
14467         this.__data__ = [];
14468       }
14469
14470       Cache.prototype = {
14471         'get': function(key) {
14472           var entry = _.find(this.__data__, function(entry) {
14473             return key === entry.key;
14474           });
14475           return entry && entry.value;
14476         },
14477         'has': function(key) {
14478           return _.some(this.__data__, function(entry) {
14479             return key === entry.key;
14480           });
14481         },
14482         'set': function(key, value) {
14483           this.__data__.push({ 'key': key, 'value': value });
14484           return this;
14485         }
14486       };
14487
14488       _.memoize.Cache = Cache;
14489
14490       var memoized = _.memoize(function(object) {
14491         return 'value:' + object.id;
14492       });
14493
14494       var cache = memoized.cache,
14495           key1 = { 'id': 'a' },
14496           key2 = { 'id': 'b' };
14497
14498       assert.strictEqual(memoized(key1), 'value:a');
14499       assert.strictEqual(cache.has(key1), true);
14500
14501       assert.strictEqual(memoized(key2), 'value:b');
14502       assert.strictEqual(cache.has(key2), true);
14503
14504       _.memoize.Cache = oldCache;
14505     });
14506
14507     QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
14508       assert.expect(2);
14509
14510       var oldCache = _.memoize.Cache;
14511
14512       function Cache() {
14513         this.__data__ = [];
14514       }
14515
14516       Cache.prototype = {
14517         'get': function(key) {
14518           return _.find(this.__data__, function(entry) {
14519             return key === entry.key;
14520           }).value;
14521         },
14522         'has': function(key) {
14523           return _.some(this.__data__, function(entry) {
14524             return key === entry.key;
14525           });
14526         },
14527         'set': function(key, value) {
14528           var result = new Cache;
14529           result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
14530           return result;
14531         }
14532       };
14533
14534       _.memoize.Cache = Cache;
14535
14536       var memoized = _.memoize(function(object) {
14537         return object.id;
14538       });
14539
14540       var key1 = { 'id': 'a' },
14541           key2 = { 'id': 'b' };
14542
14543       memoized(key1);
14544       memoized(key2);
14545
14546       var cache = memoized.cache;
14547       assert.strictEqual(cache.has(key1), true);
14548       assert.strictEqual(cache.has(key2), true);
14549
14550       _.memoize.Cache = oldCache;
14551     });
14552
14553     QUnit.test('should implement a `Map` interface on the cache object', function(assert) {
14554       assert.expect(164);
14555
14556       var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
14557
14558       var pairs = lodashStable.map(keys, function(key, index) {
14559         var lastIndex = keys.length - 1;
14560         return [key, keys[lastIndex - index]];
14561       });
14562
14563       lodashStable.times(2, function(index) {
14564         var memoize = (index ? (lodashBizarro || {}) : _).memoize,
14565             Cache = memoize ? memoize.Cache : undefined,
14566             cache = Cache ? new Cache(pairs) : undefined;
14567
14568         lodashStable.each(keys, function(key, index) {
14569           if (cache) {
14570             var value = pairs[index][1];
14571
14572             assert.deepEqual(cache.get(key), value);
14573             assert.strictEqual(cache.has(key), true);
14574             assert.strictEqual(cache['delete'](key), true);
14575             assert.strictEqual(cache.has(key), false);
14576             assert.strictEqual(cache.get(key), undefined);
14577             assert.strictEqual(cache['delete'](key), false);
14578             assert.strictEqual(cache.set(key, value), cache);
14579             assert.strictEqual(cache.has(key), true);
14580           }
14581           else {
14582             skipAssert(assert, 8);
14583           }
14584         });
14585
14586         if (cache) {
14587           assert.strictEqual(cache.clear(), undefined);
14588           assert.ok(lodashStable.every(keys, function(key) {
14589             return !cache.has(key);
14590           }));
14591         }
14592         else {
14593           skipAssert(assert, 2);
14594         }
14595       });
14596     });
14597   }());
14598
14599   /*--------------------------------------------------------------------------*/
14600
14601   QUnit.module('lodash.merge');
14602
14603   (function() {
14604     var args = arguments;
14605
14606     QUnit.test('should merge `source` into `object`', function(assert) {
14607       assert.expect(1);
14608
14609       var names = {
14610         'characters': [
14611           { 'name': 'barney' },
14612           { 'name': 'fred' }
14613         ]
14614       };
14615
14616       var ages = {
14617         'characters': [
14618           { 'age': 36 },
14619           { 'age': 40 }
14620         ]
14621       };
14622
14623       var heights = {
14624         'characters': [
14625           { 'height': '5\'4"' },
14626           { 'height': '5\'5"' }
14627         ]
14628       };
14629
14630       var expected = {
14631         'characters': [
14632           { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
14633           { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
14634         ]
14635       };
14636
14637       assert.deepEqual(_.merge(names, ages, heights), expected);
14638     });
14639
14640     QUnit.test('should merge sources containing circular references', function(assert) {
14641       assert.expect(2);
14642
14643       var object = {
14644         'foo': { 'a': 1 },
14645         'bar': { 'a': 2 }
14646       };
14647
14648       var source = {
14649         'foo': { 'b': { 'c': { 'd': {} } } },
14650         'bar': {}
14651       };
14652
14653       source.foo.b.c.d = source;
14654       source.bar.b = source.foo.b;
14655
14656       var actual = _.merge(object, source);
14657
14658       assert.notStrictEqual(actual.bar.b, actual.foo.b);
14659       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
14660     });
14661
14662     QUnit.test('should work with four arguments', function(assert) {
14663       assert.expect(1);
14664
14665       var expected = { 'a': 4 },
14666           actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
14667
14668       assert.deepEqual(actual, expected);
14669     });
14670
14671     QUnit.test('should merge onto function `object` values', function(assert) {
14672       assert.expect(2);
14673
14674       function Foo() {}
14675
14676       var source = { 'a': 1 },
14677           actual = _.merge(Foo, source);
14678
14679       assert.strictEqual(actual, Foo);
14680       assert.strictEqual(Foo.a, 1);
14681     });
14682
14683     QUnit.test('should not merge onto nested function values', function(assert) {
14684       assert.expect(3);
14685
14686       var source1 = { 'a': function() {} },
14687           source2 = { 'a': { 'b': 1 } },
14688           actual = _.merge({}, source1, source2),
14689           expected = { 'a': { 'b': 1 } };
14690
14691       assert.deepEqual(actual, expected);
14692
14693       source1 = { 'a': function() {} };
14694       source2 = { 'a': { 'b': 1 } };
14695
14696       expected = { 'a': function() {} };
14697       expected.a.b = 1;
14698
14699       actual = _.merge(source1, source2);
14700       assert.strictEqual(typeof actual.a, 'function');
14701       assert.strictEqual(actual.a.b, 1);
14702     });
14703
14704     QUnit.test('should merge onto non-plain `object` values', function(assert) {
14705       assert.expect(2);
14706
14707       function Foo() {}
14708
14709       var object = new Foo,
14710           actual = _.merge(object, { 'a': 1 });
14711
14712       assert.strictEqual(actual, object);
14713       assert.strictEqual(object.a, 1);
14714     });
14715
14716     QUnit.test('should treat sparse array sources as dense', function(assert) {
14717       assert.expect(2);
14718
14719       var array = [1];
14720       array[2] = 3;
14721
14722       var actual = _.merge([], array),
14723           expected = array.slice();
14724
14725       expected[1] = undefined;
14726
14727       assert.ok('1' in actual);
14728       assert.deepEqual(actual, expected);
14729     });
14730
14731     QUnit.test('should merge `arguments` objects', function(assert) {
14732       assert.expect(7);
14733
14734       var object1 = { 'value': args },
14735           object2 = { 'value': { '3': 4 } },
14736           expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
14737           actual = _.merge(object1, object2);
14738
14739       assert.notOk('3' in args);
14740       assert.notOk(_.isArguments(actual.value));
14741       assert.deepEqual(actual.value, expected);
14742       object1.value = args;
14743
14744       actual = _.merge(object2, object1);
14745       assert.notOk(_.isArguments(actual.value));
14746       assert.deepEqual(actual.value, expected);
14747
14748       expected = { '0': 1, '1': 2, '2': 3 };
14749
14750       actual = _.merge({}, object1);
14751       assert.notOk(_.isArguments(actual.value));
14752       assert.deepEqual(actual.value, expected);
14753     });
14754
14755     QUnit.test('should merge typed arrays', function(assert) {
14756       assert.expect(4);
14757
14758       var array1 = [0],
14759           array2 = [0, 0],
14760           array3 = [0, 0, 0, 0],
14761           array4 = [0, 0, 0, 0, 0, 0, 0, 0];
14762
14763       var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
14764           buffer = ArrayBuffer && new ArrayBuffer(8);
14765
14766       // Juggle for `Float64Array` shim.
14767       if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
14768         arrays[1] = array4;
14769       }
14770       var expected = lodashStable.map(typedArrays, function(type, index) {
14771         var array = arrays[index].slice();
14772         array[0] = 1;
14773         return root[type] ? { 'value': array } : false;
14774       });
14775
14776       var actual = lodashStable.map(typedArrays, function(type) {
14777         var Ctor = root[type];
14778         return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
14779       });
14780
14781       assert.ok(lodashStable.isArray(actual));
14782       assert.deepEqual(actual, expected);
14783
14784       expected = lodashStable.map(typedArrays, function(type, index) {
14785         var array = arrays[index].slice();
14786         array.push(1);
14787         return root[type] ? { 'value': array } : false;
14788       });
14789
14790       actual = lodashStable.map(typedArrays, function(type, index) {
14791         var Ctor = root[type],
14792             array = lodashStable.range(arrays[index].length);
14793
14794         array.push(1);
14795         return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
14796       });
14797
14798       assert.ok(lodashStable.isArray(actual));
14799       assert.deepEqual(actual, expected);
14800     });
14801
14802     QUnit.test('should assign `null` values', function(assert) {
14803       assert.expect(1);
14804
14805       var actual = _.merge({ 'a': 1 }, { 'a': null });
14806       assert.strictEqual(actual.a, null);
14807     });
14808
14809     QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
14810       assert.expect(1);
14811
14812       function Foo() {}
14813
14814       var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
14815           expected = lodashStable.map(values, alwaysTrue);
14816
14817       var actual = lodashStable.map(values, function(value) {
14818         var object = _.merge({}, { 'value': value });
14819         return object.value === value;
14820       });
14821
14822       assert.deepEqual(actual, expected);
14823     });
14824
14825     QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) {
14826       assert.expect(1);
14827
14828       var typedArray = Uint8Array
14829         ? new Uint8Array(new ArrayBuffer(2))
14830         : { 'buffer': [0, 0] };
14831
14832       var props = ['0', 'a', 'buffer'],
14833           values = [[{ 'a': 1 }], { 'a': [1] }, typedArray],
14834           expected = lodashStable.map(values, alwaysTrue);
14835
14836       var actual = lodashStable.map(values, function(value, index) {
14837         var key = props[index],
14838             object = _.merge({}, { 'value': value }),
14839             newValue = object.value;
14840
14841         return (
14842           newValue !== value &&
14843           newValue[key] !== value[key] &&
14844           lodashStable.isEqual(newValue, value)
14845         );
14846       });
14847
14848       assert.deepEqual(actual, expected);
14849     });
14850
14851     QUnit.test('should not augment source objects', function(assert) {
14852       assert.expect(6);
14853
14854       var source1 = { 'a': [{ 'a': 1 }] },
14855           source2 = { 'a': [{ 'b': 2 }] },
14856           actual = _.merge({}, source1, source2);
14857
14858       assert.deepEqual(source1.a, [{ 'a': 1 }]);
14859       assert.deepEqual(source2.a, [{ 'b': 2 }]);
14860       assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
14861
14862       var source1 = { 'a': [[1, 2, 3]] },
14863           source2 = { 'a': [[3, 4]] },
14864           actual = _.merge({}, source1, source2);
14865
14866       assert.deepEqual(source1.a, [[1, 2, 3]]);
14867       assert.deepEqual(source2.a, [[3, 4]]);
14868       assert.deepEqual(actual.a, [[3, 4, 3]]);
14869     });
14870
14871     QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
14872       assert.expect(4);
14873
14874       function Foo(object) {
14875         lodashStable.assign(this, object);
14876       }
14877
14878       var object = { 'a': 1 },
14879           actual = _.merge(new Foo, object);
14880
14881       assert.ok(actual instanceof Foo);
14882       assert.deepEqual(actual, new Foo(object));
14883
14884       actual = _.merge([new Foo], [object]);
14885       assert.ok(actual[0] instanceof Foo);
14886       assert.deepEqual(actual, [new Foo(object)]);
14887     });
14888
14889     QUnit.test('should not assign `undefined` values', function(assert) {
14890       assert.expect(1);
14891
14892       var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
14893       assert.deepEqual(actual, { 'a': 1 });
14894     });
14895
14896     QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
14897       assert.expect(2);
14898
14899       var array = [1];
14900       array[2] = 3;
14901
14902       var actual = _.merge([4, 5, 6], array),
14903           expected = [1, 5, 3];
14904
14905       assert.deepEqual(actual, expected);
14906
14907       array = [1, , 3];
14908       array[1] = undefined;
14909
14910       actual = _.merge([4, 5, 6], array);
14911       assert.deepEqual(actual, expected);
14912     });
14913
14914     QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
14915       assert.expect(1);
14916
14917       if (defineProperty) {
14918         var object = {},
14919             pass = true;
14920
14921         defineProperty(object, 'a', {
14922           'enumerable': true,
14923           'configurable': true,
14924           'get': function() { pass = false; },
14925           'set': function() { pass = false; }
14926         });
14927
14928         _.merge(object, object);
14929         assert.ok(pass);
14930       }
14931       else {
14932         skipAssert(assert);
14933       }
14934     });
14935
14936     QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
14937       assert.expect(2);
14938
14939       var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
14940           actual = _.merge(object, { 'a': ['x'] });
14941
14942       assert.deepEqual(actual, { 'a': ['x', 'y'] });
14943
14944       actual = _.merge({ 'a': {} }, { 'a': [] });
14945       assert.deepEqual(actual, { 'a': [] });
14946     });
14947
14948     QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
14949       assert.expect(1);
14950
14951       var object = { 'a': 'abcde' },
14952           actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
14953
14954       assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
14955     });
14956
14957     QUnit.test('should not error on DOM elements', function(assert) {
14958       assert.expect(1);
14959
14960       var object1 = { 'el': document && document.createElement('div') },
14961           object2 = { 'el': document && document.createElement('div') },
14962           pairs = [[{}, object1], [object1, object2]],
14963           expected = lodashStable.map(pairs, alwaysTrue);
14964
14965       var actual = lodashStable.map(pairs, function(pair) {
14966         try {
14967           return _.merge(pair[0], pair[1]).el === pair[1].el;
14968         } catch (e) {}
14969       });
14970
14971       assert.deepEqual(actual, expected);
14972     });
14973   }(1, 2, 3));
14974
14975   /*--------------------------------------------------------------------------*/
14976
14977   QUnit.module('lodash.mergeWith');
14978
14979   (function() {
14980     QUnit.test('should handle merging if `customizer` returns `undefined`', function(assert) {
14981       assert.expect(2);
14982
14983       var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
14984       assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
14985
14986       actual = _.mergeWith([], [undefined], identity);
14987       assert.deepEqual(actual, [undefined]);
14988     });
14989
14990     QUnit.test('should defer to `customizer` when it returns a non `undefined` value', function(assert) {
14991       assert.expect(1);
14992
14993       var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
14994         return lodashStable.isArray(a) ? a.concat(b) : undefined;
14995       });
14996
14997       assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
14998     });
14999
15000     QUnit.test('should overwrite primitives with source object clones', function(assert) {
15001       assert.expect(1);
15002
15003       var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
15004         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15005       });
15006
15007       assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
15008     });
15009
15010     QUnit.test('should clone sources when `customizer` result is `undefined`', function(assert) {
15011       assert.expect(1);
15012
15013       var source1 = { 'a': { 'b': { 'c': 1 } } },
15014           source2 = { 'a': { 'b': { 'd': 2 } } };
15015
15016       _.mergeWith({}, source1, source2, noop);
15017       assert.deepEqual(source1.a.b, { 'c': 1 });
15018     });
15019
15020     QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
15021       assert.expect(1);
15022
15023       var array = ['b', 'c'],
15024           object = { 'a': ['a'] },
15025           source = { 'a': array, 'b': array };
15026
15027       var actual = _.mergeWith(object, source, function(a, b) {
15028         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15029       });
15030
15031       assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
15032     });
15033   }());
15034
15035   /*--------------------------------------------------------------------------*/
15036
15037   QUnit.module('lodash.method');
15038
15039   (function() {
15040     QUnit.test('should create a function that calls a method of a given object', function(assert) {
15041       assert.expect(4);
15042
15043       var object = { 'a': alwaysOne };
15044
15045       lodashStable.each(['a', ['a']], function(path) {
15046         var method = _.method(path);
15047         assert.strictEqual(method.length, 1);
15048         assert.strictEqual(method(object), 1);
15049       });
15050     });
15051
15052     QUnit.test('should work with deep property values', function(assert) {
15053       assert.expect(2);
15054
15055       var object = { 'a': { 'b': alwaysTwo } };
15056
15057       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15058         var method = _.method(path);
15059         assert.strictEqual(method(object), 2);
15060       });
15061     });
15062
15063     QUnit.test('should work with a non-string `path`', function(assert) {
15064       assert.expect(2);
15065
15066       var array = lodashStable.times(3, _.constant);
15067
15068       lodashStable.each([1, [1]], function(path) {
15069         var method = _.method(path);
15070         assert.strictEqual(method(array), 1);
15071       });
15072     });
15073
15074     QUnit.test('should coerce key to a string', function(assert) {
15075       assert.expect(1);
15076
15077       function fn() {}
15078       fn.toString = lodashStable.constant('fn');
15079
15080       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15081           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
15082           values = [null, undefined, fn, {}];
15083
15084       var actual = lodashStable.transform(objects, function(result, object, index) {
15085         var key = values[index];
15086         lodashStable.each([key, [key]], function(path) {
15087           var method = _.method(key);
15088           result.push(method(object));
15089         });
15090       });
15091
15092       assert.deepEqual(actual, expected);
15093     });
15094
15095     QUnit.test('should work with inherited property values', function(assert) {
15096       assert.expect(2);
15097
15098       function Foo() {}
15099       Foo.prototype.a = alwaysOne;
15100
15101       lodashStable.each(['a', ['a']], function(path) {
15102         var method = _.method(path);
15103         assert.strictEqual(method(new Foo), 1);
15104       });
15105     });
15106
15107     QUnit.test('should use a key over a path', function(assert) {
15108       assert.expect(2);
15109
15110       var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
15111
15112       lodashStable.each(['a.b', ['a.b']], function(path) {
15113         var method = _.method(path);
15114         assert.strictEqual(method(object), 1);
15115       });
15116     });
15117
15118     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15119       assert.expect(2);
15120
15121       var values = [, null, undefined],
15122           expected = lodashStable.map(values, noop);
15123
15124       lodashStable.each(['constructor', ['constructor']], function(path) {
15125         var method = _.method(path);
15126
15127         var actual = lodashStable.map(values, function(value, index) {
15128           return index ? method(value) : method();
15129         });
15130
15131         assert.deepEqual(actual, expected);
15132       });
15133     });
15134
15135     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15136       assert.expect(2);
15137
15138       var values = [, null, undefined],
15139           expected = lodashStable.map(values, noop);
15140
15141       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15142         var method = _.method(path);
15143
15144         var actual = lodashStable.map(values, function(value, index) {
15145           return index ? method(value) : method();
15146         });
15147
15148         assert.deepEqual(actual, expected);
15149       });
15150     });
15151
15152     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15153       assert.expect(4);
15154
15155       var object = {};
15156
15157       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15158         var method = _.method(path);
15159         assert.strictEqual(method(object), undefined);
15160       });
15161     });
15162
15163     QUnit.test('should apply partial arguments to function', function(assert) {
15164       assert.expect(2);
15165
15166       var object = {
15167         'fn': function() {
15168           return slice.call(arguments);
15169         }
15170       };
15171
15172       lodashStable.each(['fn', ['fn']], function(path) {
15173         var method = _.method(path, 1, 2, 3);
15174         assert.deepEqual(method(object), [1, 2, 3]);
15175       });
15176     });
15177
15178     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15179       assert.expect(2);
15180
15181       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
15182
15183       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15184         var method = _.method(path);
15185         assert.strictEqual(method(object), 1);
15186       });
15187     });
15188   }());
15189
15190   /*--------------------------------------------------------------------------*/
15191
15192   QUnit.module('lodash.methodOf');
15193
15194   (function() {
15195     QUnit.test('should create a function that calls a method of a given key', function(assert) {
15196       assert.expect(4);
15197
15198       var object = { 'a': alwaysOne };
15199
15200       lodashStable.each(['a', ['a']], function(path) {
15201         var methodOf = _.methodOf(object);
15202         assert.strictEqual(methodOf.length, 1);
15203         assert.strictEqual(methodOf(path), 1);
15204       });
15205     });
15206
15207     QUnit.test('should work with deep property values', function(assert) {
15208       assert.expect(2);
15209
15210       var object = { 'a': { 'b': alwaysTwo } };
15211
15212       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15213         var methodOf = _.methodOf(object);
15214         assert.strictEqual(methodOf(path), 2);
15215       });
15216     });
15217
15218     QUnit.test('should work with a non-string `path`', function(assert) {
15219       assert.expect(2);
15220
15221       var array = lodashStable.times(3, _.constant);
15222
15223       lodashStable.each([1, [1]], function(path) {
15224         var methodOf = _.methodOf(array);
15225         assert.strictEqual(methodOf(path), 1);
15226       });
15227     });
15228
15229     QUnit.test('should coerce key to a string', function(assert) {
15230       assert.expect(1);
15231
15232       function fn() {}
15233       fn.toString = lodashStable.constant('fn');
15234
15235       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15236           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
15237           values = [null, undefined, fn, {}];
15238
15239       var actual = lodashStable.transform(objects, function(result, object, index) {
15240         var key = values[index];
15241         lodashStable.each([key, [key]], function(path) {
15242           var methodOf = _.methodOf(object);
15243           result.push(methodOf(key));
15244         });
15245       });
15246
15247       assert.deepEqual(actual, expected);
15248     });
15249
15250     QUnit.test('should work with inherited property values', function(assert) {
15251       assert.expect(2);
15252
15253       function Foo() {}
15254       Foo.prototype.a = alwaysOne;
15255
15256       lodashStable.each(['a', ['a']], function(path) {
15257         var methodOf = _.methodOf(new Foo);
15258         assert.strictEqual(methodOf(path), 1);
15259       });
15260     });
15261
15262     QUnit.test('should use a key over a path', function(assert) {
15263       assert.expect(2);
15264
15265       var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
15266
15267       lodashStable.each(['a.b', ['a.b']], function(path) {
15268         var methodOf = _.methodOf(object);
15269         assert.strictEqual(methodOf(path), 1);
15270       });
15271     });
15272
15273     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15274       assert.expect(2);
15275
15276       var values = [, null, undefined],
15277           expected = lodashStable.map(values, noop);
15278
15279       lodashStable.each(['constructor', ['constructor']], function(path) {
15280         var actual = lodashStable.map(values, function(value, index) {
15281           var methodOf = index ? _.methodOf() : _.methodOf(value);
15282           return methodOf(path);
15283         });
15284
15285         assert.deepEqual(actual, expected);
15286       });
15287     });
15288
15289     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15290       assert.expect(2);
15291
15292       var values = [, null, undefined],
15293           expected = lodashStable.map(values, noop);
15294
15295       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15296         var actual = lodashStable.map(values, function(value, index) {
15297           var methodOf = index ? _.methodOf() : _.methodOf(value);
15298           return methodOf(path);
15299         });
15300
15301         assert.deepEqual(actual, expected);
15302       });
15303     });
15304
15305     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15306       assert.expect(4);
15307
15308       var object = {},
15309           methodOf = _.methodOf(object);
15310
15311       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15312         assert.strictEqual(methodOf(path), undefined);
15313       });
15314     });
15315
15316     QUnit.test('should apply partial arguments to function', function(assert) {
15317       assert.expect(2);
15318
15319       var object = {
15320         'fn': function() {
15321           return slice.call(arguments);
15322         }
15323       };
15324
15325       var methodOf = _.methodOf(object, 1, 2, 3);
15326
15327       lodashStable.each(['fn', ['fn']], function(path) {
15328         assert.deepEqual(methodOf(path), [1, 2, 3]);
15329       });
15330     });
15331
15332     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15333       assert.expect(2);
15334
15335       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
15336           methodOf = _.methodOf(object);
15337
15338       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15339         assert.strictEqual(methodOf(path), 1);
15340       });
15341     });
15342   }());
15343
15344   /*--------------------------------------------------------------------------*/
15345
15346   QUnit.module('lodash.min');
15347
15348   (function() {
15349     QUnit.test('should return the smallest value from a collection', function(assert) {
15350       assert.expect(1);
15351
15352       assert.strictEqual(_.min([1, 2, 3]), 1);
15353     });
15354
15355     QUnit.test('should return `undefined` for empty collections', function(assert) {
15356       assert.expect(1);
15357
15358       var values = falsey.concat([[]]),
15359           expected = lodashStable.map(values, noop);
15360
15361       var actual = lodashStable.map(values, function(value, index) {
15362         try {
15363           return index ? _.min(value) : _.min();
15364         } catch (e) {}
15365       });
15366
15367       assert.deepEqual(actual, expected);
15368     });
15369
15370     QUnit.test('should work with non-numeric collection values', function(assert) {
15371       assert.expect(1);
15372
15373       assert.strictEqual(_.min(['a', 'b']), 'a');
15374     });
15375   }());
15376
15377   /*--------------------------------------------------------------------------*/
15378
15379   QUnit.module('extremum methods');
15380
15381   lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
15382     var func = _[methodName],
15383         isMax = /^max/.test(methodName);
15384
15385     QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
15386       assert.expect(1);
15387
15388       var curr = new Date,
15389           past = new Date(0);
15390
15391       assert.strictEqual(func([curr, past]), isMax ? curr : past);
15392     });
15393
15394     QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
15395       assert.expect(1);
15396
15397       var array = lodashStable.range(0, 5e5);
15398       assert.strictEqual(func(array), isMax ? 499999 : 0);
15399     });
15400
15401     QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
15402       assert.expect(1);
15403
15404       if (!isNpm) {
15405         var actual = _([40])[methodName]();
15406         assert.strictEqual(actual, 40);
15407       }
15408       else {
15409         skipAssert(assert);
15410       }
15411     });
15412   });
15413
15414   lodashStable.each(['maxBy', 'minBy'], function(methodName) {
15415     var array = [1, 2, 3],
15416         func = _[methodName],
15417         isMax = methodName == 'maxBy';
15418
15419     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
15420       assert.expect(1);
15421
15422       var actual = func(array, function(n) {
15423         return -n;
15424       });
15425
15426       assert.strictEqual(actual, isMax ? 1 : 3);
15427     });
15428
15429     QUnit.test('should work with `_.property` shorthands', function(assert) {
15430       assert.expect(2);
15431
15432       var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
15433           actual = func(objects, 'a');
15434
15435       assert.deepEqual(actual, objects[isMax ? 1 : 2]);
15436
15437       var arrays = [[2], [3], [1]];
15438       actual = func(arrays, 0);
15439
15440       assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
15441     });
15442
15443     QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
15444       assert.expect(1);
15445
15446       var value = isMax ? -Infinity : Infinity,
15447           object = { 'a': value };
15448
15449       var actual = func([object, { 'a': value }], function(object) {
15450         return object.a;
15451       });
15452
15453       assert.strictEqual(actual, object);
15454     });
15455   });
15456
15457   /*--------------------------------------------------------------------------*/
15458
15459   QUnit.module('lodash.mixin');
15460
15461   (function() {
15462     function reset(wrapper) {
15463       delete wrapper.a;
15464       delete wrapper.prototype.a;
15465       delete wrapper.b;
15466       delete wrapper.prototype.b;
15467     }
15468
15469     function Wrapper(value) {
15470       if (!(this instanceof Wrapper)) {
15471         return new Wrapper(value);
15472       }
15473       if (_.has(value, '__wrapped__')) {
15474         var actions = slice.call(value.__actions__),
15475             chain = value.__chain__;
15476
15477         value = value.__wrapped__;
15478       }
15479       this.__wrapped__ = value;
15480       this.__actions__ = actions || [];
15481       this.__chain__ = chain || false;
15482     }
15483
15484     Wrapper.prototype.value = function() {
15485       return getUnwrappedValue(this);
15486     };
15487
15488     var array = ['a'],
15489         source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
15490
15491     QUnit.test('should mixin `source` methods into lodash', function(assert) {
15492       assert.expect(4);
15493
15494       if (!isNpm) {
15495         _.mixin(source);
15496
15497         assert.strictEqual(_.a(array), 'a');
15498         assert.strictEqual(_(array).a().value(), 'a');
15499         assert.notOk('b' in _);
15500         assert.notOk('b' in _.prototype);
15501
15502         reset(_);
15503       }
15504       else {
15505         skipAssert(assert, 4);
15506       }
15507     });
15508
15509     QUnit.test('should mixin chaining methods by reference', function(assert) {
15510       assert.expect(2);
15511
15512       if (!isNpm) {
15513         _.mixin(source);
15514         _.a = alwaysB;
15515
15516         assert.strictEqual(_.a(array), 'b');
15517         assert.strictEqual(_(array).a().value(), 'a');
15518
15519         reset(_);
15520       }
15521       else {
15522         skipAssert(assert, 2);
15523       }
15524     });
15525
15526     QUnit.test('should use a default `object` of `this`', function(assert) {
15527       assert.expect(3);
15528
15529       var object = lodashStable.create(_);
15530       object.mixin(source);
15531
15532       assert.strictEqual(object.a(array), 'a');
15533       assert.notOk('a' in _);
15534       assert.notOk('a' in _.prototype);
15535
15536       reset(_);
15537     });
15538
15539     QUnit.test('should accept an `object` argument', function(assert) {
15540       assert.expect(1);
15541
15542       var object = {};
15543       _.mixin(object, source);
15544       assert.strictEqual(object.a(array), 'a');
15545     });
15546
15547     QUnit.test('should accept a function `object`', function(assert) {
15548       assert.expect(2);
15549
15550       _.mixin(Wrapper, source);
15551
15552       var wrapped = Wrapper(array),
15553           actual = wrapped.a();
15554
15555       assert.strictEqual(actual.value(), 'a');
15556       assert.ok(actual instanceof Wrapper);
15557
15558       reset(Wrapper);
15559     });
15560
15561     QUnit.test('should return `object`', function(assert) {
15562       assert.expect(3);
15563
15564       var object = {};
15565       assert.strictEqual(_.mixin(object, source), object);
15566       assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
15567       assert.strictEqual(_.mixin(), _);
15568
15569       reset(Wrapper);
15570     });
15571
15572     QUnit.test('should not assign inherited `source` methods', function(assert) {
15573       assert.expect(1);
15574
15575       function Foo() {}
15576       Foo.prototype.a = noop;
15577
15578       var object = {};
15579       assert.strictEqual(_.mixin(object, new Foo), object);
15580     });
15581
15582     QUnit.test('should accept an `options` argument', function(assert) {
15583       assert.expect(8);
15584
15585       function message(func, chain) {
15586         return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
15587       }
15588
15589       lodashStable.each([_, Wrapper], function(func) {
15590         lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
15591           if (!isNpm) {
15592             if (func === _) {
15593               _.mixin(source, options);
15594             } else {
15595               _.mixin(func, source, options);
15596             }
15597             var wrapped = func(array),
15598                 actual = wrapped.a();
15599
15600             if (options.chain) {
15601               assert.strictEqual(actual.value(), 'a', message(func, true));
15602               assert.ok(actual instanceof func, message(func, true));
15603             } else {
15604               assert.strictEqual(actual, 'a', message(func, false));
15605               assert.notOk(actual instanceof func, message(func, false));
15606             }
15607             reset(func);
15608           }
15609           else {
15610             skipAssert(assert, 2);
15611           }
15612         });
15613       });
15614     });
15615
15616     QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
15617       assert.expect(1);
15618
15619       _.mixin({ 'a': noop }, {});
15620       assert.notOk('a' in _);
15621       reset(_);
15622     });
15623
15624     QUnit.test('should not error for non-object `options` values', function(assert) {
15625       assert.expect(2);
15626
15627       var pass = true;
15628
15629       try {
15630         _.mixin({}, source, 1);
15631       } catch (e) {
15632         pass = false;
15633       }
15634       assert.ok(pass);
15635
15636       pass = true;
15637
15638       try {
15639         _.mixin(source, 1);
15640       } catch (e) {
15641         pass = false;
15642       }
15643       assert.ok(pass);
15644
15645       reset(_);
15646     });
15647
15648     QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
15649       assert.expect(2);
15650
15651       lodashStable.each([_, Wrapper], function(func) {
15652         if (!isNpm) {
15653           if (func === _) {
15654             var wrapped = _(source),
15655                 actual = wrapped.mixin();
15656
15657             assert.strictEqual(actual.value(), _);
15658           }
15659           else {
15660             wrapped = _(func);
15661             actual = wrapped.mixin(source);
15662             assert.notStrictEqual(actual, wrapped);
15663           }
15664           reset(func);
15665         }
15666         else {
15667           skipAssert(assert);
15668         }
15669       });
15670     });
15671
15672     QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
15673       assert.expect(1);
15674
15675       if (!isNpm) {
15676         _.mixin({ 'a': _.countBy, 'b': _.filter });
15677
15678         var array = lodashStable.range(LARGE_ARRAY_SIZE),
15679             actual = _(array).a().map(square).b(isEven).take().value();
15680
15681         assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
15682
15683         reset(_);
15684       }
15685       else {
15686         skipAssert(assert);
15687       }
15688     });
15689   }());
15690
15691   /*--------------------------------------------------------------------------*/
15692
15693   QUnit.module('lodash.multiply');
15694
15695   (function() {
15696     QUnit.test('should multiply two numbers', function(assert) {
15697       assert.expect(3);
15698
15699       assert.strictEqual(_.multiply(6, 4), 24);
15700       assert.strictEqual(_.multiply(-6, 4), -24);
15701       assert.strictEqual(_.multiply(-6, -4), 24);
15702     });
15703
15704     QUnit.test('should coerce arguments to numbers', function(assert) {
15705       assert.expect(2);
15706
15707       assert.strictEqual(_.multiply('6', '4'), 24);
15708       assert.deepEqual(_.multiply('x', 'y'), NaN);
15709     });
15710   }());
15711
15712   /*--------------------------------------------------------------------------*/
15713
15714   QUnit.module('lodash.orderBy');
15715
15716   (function() {
15717     var objects = [
15718       { 'a': 'x', 'b': 3 },
15719       { 'a': 'y', 'b': 4 },
15720       { 'a': 'x', 'b': 1 },
15721       { 'a': 'y', 'b': 2 }
15722     ];
15723
15724     QUnit.test('should sort by a single property by a specified order', function(assert) {
15725       assert.expect(1);
15726
15727       var actual = _.orderBy(objects, 'a', 'desc');
15728       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15729     });
15730
15731     QUnit.test('should sort by multiple properties by specified orders', function(assert) {
15732       assert.expect(1);
15733
15734       var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
15735       assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
15736     });
15737
15738     QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
15739       assert.expect(2);
15740
15741       var expected = [objects[2], objects[0], objects[3], objects[1]],
15742           actual = _.orderBy(objects, ['a', 'b']);
15743
15744       assert.deepEqual(actual, expected);
15745
15746       expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
15747
15748       actual = lodashStable.map(falsey, function(order, index) {
15749         return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
15750       });
15751
15752       assert.deepEqual(actual, expected);
15753     });
15754
15755     QUnit.test('should work with `orders` specified as string objects', function(assert) {
15756       assert.expect(1);
15757
15758       var actual = _.orderBy(objects, ['a'], [Object('desc')]);
15759       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15760     });
15761   }());
15762
15763   /*--------------------------------------------------------------------------*/
15764
15765   QUnit.module('lodash.overArgs');
15766
15767   (function() {
15768     function fn() {
15769       return slice.call(arguments);
15770     }
15771
15772     QUnit.test('should transform each argument', function(assert) {
15773       assert.expect(1);
15774
15775       var over = _.overArgs(fn, doubled, square);
15776       assert.deepEqual(over(5, 10), [10, 100]);
15777     });
15778
15779     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
15780       assert.expect(1);
15781
15782       var over = _.overArgs(fn, undefined, null);
15783       assert.deepEqual(over('a', 'b'), ['a', 'b']);
15784     });
15785
15786     QUnit.test('should work with `_.property` shorthands', function(assert) {
15787       assert.expect(1);
15788
15789       var over = _.overArgs(fn, 'b', 'a');
15790       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
15791     });
15792
15793     QUnit.test('should work with `_.matches` shorthands', function(assert) {
15794       assert.expect(1);
15795
15796       var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
15797       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
15798     });
15799
15800     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
15801       assert.expect(1);
15802
15803       var over = _.overArgs(fn, ['b', 1], [['a', 1]]);
15804       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
15805     });
15806
15807     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
15808       assert.expect(2);
15809
15810       var over = _.overArgs(fn, ['a', 1]);
15811       assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
15812
15813       over = _.overArgs(fn, [['a', 1]]);
15814       assert.deepEqual(over({ 'a': 1 }), [true]);
15815     });
15816
15817     QUnit.test('should flatten `transforms`', function(assert) {
15818       assert.expect(1);
15819
15820       var over = _.overArgs(fn, [doubled, square], String);
15821       assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
15822     });
15823
15824     QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
15825       assert.expect(1);
15826
15827       var over = _.overArgs(fn, doubled, square);
15828       assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
15829     });
15830
15831     QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
15832       assert.expect(1);
15833
15834       var over = _.overArgs(fn);
15835       assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
15836     });
15837
15838     QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
15839       assert.expect(1);
15840
15841       var over = _.overArgs(fn, doubled, identity);
15842       assert.deepEqual(over(5), [10]);
15843     });
15844
15845     QUnit.test('should provide the correct argument to each transform', function(assert) {
15846       assert.expect(1);
15847
15848       var argsList = [],
15849           transform = function() { argsList.push(slice.call(arguments)); },
15850           over = _.overArgs(noop, transform, transform, transform);
15851
15852       over('a', 'b');
15853       assert.deepEqual(argsList, [['a'], ['b']]);
15854     });
15855
15856     QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
15857       assert.expect(1);
15858
15859       var over = _.overArgs(function(x) {
15860         return this[x];
15861       }, function(x) {
15862         return this === x;
15863       });
15864
15865       var object = { 'over': over, 'true': 1 };
15866       assert.strictEqual(object.over(object), 1);
15867     });
15868   }());
15869
15870   /*--------------------------------------------------------------------------*/
15871
15872   QUnit.module('lodash.negate');
15873
15874   (function() {
15875     QUnit.test('should create a function that negates the result of `func`', function(assert) {
15876       assert.expect(2);
15877
15878       var negate = _.negate(isEven);
15879
15880       assert.strictEqual(negate(1), true);
15881       assert.strictEqual(negate(2), false);
15882     });
15883   }());
15884
15885   /*--------------------------------------------------------------------------*/
15886
15887   QUnit.module('lodash.noop');
15888
15889   (function() {
15890     QUnit.test('should return `undefined`', function(assert) {
15891       assert.expect(1);
15892
15893       var values = empties.concat(true, new Date, _, 1, /x/, 'a'),
15894           expected = lodashStable.map(values, noop);
15895
15896       var actual = lodashStable.map(values, function(value, index) {
15897         return index ? _.noop(value) : _.noop();
15898       });
15899
15900       assert.deepEqual(actual, expected);
15901     });
15902   }());
15903
15904   /*--------------------------------------------------------------------------*/
15905
15906   QUnit.module('lodash.noConflict');
15907
15908   (function() {
15909     QUnit.test('should return the `lodash` function', function(assert) {
15910       assert.expect(2);
15911
15912       if (!isModularize) {
15913         assert.strictEqual(_.noConflict(), oldDash);
15914         assert.notStrictEqual(root._, oldDash);
15915         root._ = oldDash;
15916       }
15917       else {
15918         skipAssert(assert, 2);
15919       }
15920     });
15921
15922     QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
15923       assert.expect(2);
15924
15925       if (!isModularize) {
15926         var object = root._ = {};
15927         assert.strictEqual(_.noConflict(), oldDash);
15928         assert.strictEqual(root._, object);
15929         root._ = oldDash;
15930       }
15931       else {
15932         skipAssert(assert, 2);
15933       }
15934     });
15935
15936     QUnit.test('should work with a `root` of `this`', function(assert) {
15937       assert.expect(2);
15938
15939       if (!isModularize && !coverage && (!document && realm.object)) {
15940         var fs = require('fs'),
15941             vm = require('vm'),
15942             expected = {},
15943             context = vm.createContext({ '_': expected, 'console': console }),
15944             source = fs.readFileSync(filePath, 'utf8');
15945
15946         vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
15947
15948         assert.strictEqual(context._, expected);
15949         assert.ok(context.lodash);
15950       }
15951       else {
15952         skipAssert(assert, 2);
15953       }
15954     });
15955   }());
15956
15957   /*--------------------------------------------------------------------------*/
15958
15959   QUnit.module('lodash.now');
15960
15961   (function() {
15962     QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
15963       assert.expect(2);
15964
15965       var done = assert.async();
15966
15967       var stamp = +new Date,
15968           actual = _.now();
15969
15970       assert.ok(actual >= stamp);
15971
15972       setTimeout(function() {
15973         assert.ok(_.now() > actual);
15974         done();
15975       }, 32);
15976     });
15977   }());
15978
15979   /*--------------------------------------------------------------------------*/
15980
15981   QUnit.module('lodash.nth');
15982
15983   (function() {
15984     var array = ['a', 'b', 'c', 'd'];
15985
15986     QUnit.test('should get the nth element of `array`', function(assert) {
15987       assert.expect(1);
15988
15989       var actual = lodashStable.map(array, function(value, index) {
15990         return _.nth(array, index);
15991       });
15992
15993       assert.deepEqual(actual, array);
15994     });
15995
15996     QUnit.test('should work with a negative `n`', function(assert) {
15997       assert.expect(1);
15998
15999       var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
16000         return _.nth(array, -n);
16001       });
16002
16003       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16004     });
16005
16006     QUnit.test('should coerce `n` to an integer', function(assert) {
16007       assert.expect(2);
16008
16009       var values = falsey,
16010           expected = lodashStable.map(values, alwaysA);
16011
16012       var actual = lodashStable.map(values, function(n) {
16013         return n ? _.nth(array, n) : _.nth(array);
16014       });
16015
16016       assert.deepEqual(actual, expected);
16017
16018       values = ['1', 1.6];
16019       expected = lodashStable.map(values, alwaysB);
16020
16021       actual = lodashStable.map(values, function(n) {
16022         return _.nth(array, n);
16023       });
16024
16025       assert.deepEqual(actual, expected);
16026     });
16027
16028     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16029       assert.expect(1);
16030
16031       var values = [null, undefined, []],
16032           expected = lodashStable.map(values, noop);
16033
16034       var actual = lodashStable.map(values, function(array) {
16035         return _.nth(array, 1);
16036       });
16037
16038       assert.deepEqual(actual, expected);
16039     });
16040
16041     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16042       assert.expect(1);
16043
16044       var array = [1, 2],
16045           values = [Infinity, array.length],
16046           expected = lodashStable.map(values, noop);
16047
16048       array[-1] = 3;
16049
16050       var actual = lodashStable.map(values, function(n) {
16051         return _.nth(array, n);
16052       });
16053
16054       assert.deepEqual(actual, expected);
16055     });
16056   }());
16057
16058   /*--------------------------------------------------------------------------*/
16059
16060   QUnit.module('lodash.nthArg');
16061
16062   (function() {
16063     var args = ['a', 'b', 'c', 'd'];
16064
16065     QUnit.test('should create a function that returns its nth argument', function(assert) {
16066       assert.expect(1);
16067
16068       var actual = lodashStable.map(args, function(value, index) {
16069         var func = _.nthArg(index);
16070         return func.apply(undefined, args);
16071       });
16072
16073       assert.deepEqual(actual, args);
16074     });
16075
16076     QUnit.test('should work with a negative `n`', function(assert) {
16077       assert.expect(1);
16078
16079       var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
16080         var func = _.nthArg(-n);
16081         return func.apply(undefined, args);
16082       });
16083
16084       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16085     });
16086
16087     QUnit.test('should coerce `n` to an integer', function(assert) {
16088       assert.expect(2);
16089
16090       var values = falsey,
16091           expected = lodashStable.map(values, alwaysA);
16092
16093       var actual = lodashStable.map(values, function(n) {
16094         var func = n ? _.nthArg(n) : _.nthArg();
16095         return func.apply(undefined, args);
16096       });
16097
16098       assert.deepEqual(actual, expected);
16099
16100       values = ['1', 1.6];
16101       expected = lodashStable.map(values, alwaysB);
16102
16103       actual = lodashStable.map(values, function(n) {
16104         var func = _.nthArg(n);
16105         return func.apply(undefined, args);
16106       });
16107
16108       assert.deepEqual(actual, expected);
16109     });
16110
16111     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16112       assert.expect(1);
16113
16114       var func = _.nthArg(1);
16115       assert.strictEqual(func(), undefined);
16116     });
16117
16118     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16119       assert.expect(1);
16120
16121       var values = [Infinity, args.length],
16122           expected = lodashStable.map(values, noop);
16123
16124       var actual = lodashStable.map(values, function(n) {
16125         var func = _.nthArg(n);
16126         return func.apply(undefined, args);
16127       });
16128
16129       assert.deepEqual(actual, expected);
16130     });
16131   }());
16132
16133   /*--------------------------------------------------------------------------*/
16134
16135   QUnit.module('lodash.omit');
16136
16137   (function() {
16138     var args = arguments,
16139         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16140
16141     QUnit.test('should flatten `props`', function(assert) {
16142       assert.expect(2);
16143
16144       assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
16145       assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
16146     });
16147
16148     QUnit.test('should work with a primitive `object` argument', function(assert) {
16149       assert.expect(1);
16150
16151       stringProto.a = 1;
16152       stringProto.b = 2;
16153
16154       assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
16155
16156       delete stringProto.a;
16157       delete stringProto.b;
16158     });
16159
16160     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16161       assert.expect(2);
16162
16163       objectProto.a = 1;
16164       lodashStable.each([null, undefined], function(value) {
16165         assert.deepEqual(_.omit(value, 'valueOf'), {});
16166       });
16167       delete objectProto.a;
16168     });
16169
16170     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
16171       assert.expect(1);
16172
16173       assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
16174     });
16175
16176     QUnit.test('should coerce property names to strings', function(assert) {
16177       assert.expect(1);
16178
16179       assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
16180     });
16181   }('a', 'c'));
16182
16183   /*--------------------------------------------------------------------------*/
16184
16185   QUnit.module('lodash.omitBy');
16186
16187   (function() {
16188     QUnit.test('should work with a predicate argument', function(assert) {
16189       assert.expect(1);
16190
16191       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16192
16193       var actual = _.omitBy(object, function(n) {
16194         return n != 2 && n != 4;
16195       });
16196
16197       assert.deepEqual(actual, { 'b': 2, 'd': 4 });
16198     });
16199   }());
16200
16201   /*--------------------------------------------------------------------------*/
16202
16203   QUnit.module('omit methods');
16204
16205   lodashStable.each(['omit', 'omitBy'], function(methodName) {
16206     var expected = { 'b': 2, 'd': 4 },
16207         func = _[methodName],
16208         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16209         prop = lodashStable.nthArg(1);
16210
16211     if (methodName == 'omitBy') {
16212       prop = function(object, props) {
16213         props = lodashStable.castArray(props);
16214         return function(value) {
16215           return lodashStable.some(props, function(key) {
16216             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
16217             return object[key] === value;
16218           });
16219         };
16220       };
16221     }
16222     QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
16223       assert.expect(2);
16224
16225       assert.deepEqual(func(object, prop(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
16226       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
16227     });
16228
16229     QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
16230       assert.expect(1);
16231
16232       function Foo() {}
16233       Foo.prototype = object;
16234
16235       assert.deepEqual(func(new Foo, prop(object, ['a', 'c'])), expected);
16236     });
16237
16238     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
16239       assert.expect(1);
16240
16241       var object = { '-0': 'a', '0': 'b' },
16242           props = [-0, Object(-0), 0, Object(0)],
16243           expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
16244
16245       var actual = lodashStable.map(props, function(key) {
16246         return func(object, prop(object, key));
16247       });
16248
16249       assert.deepEqual(actual, expected);
16250     });
16251
16252     QUnit.test('`_.' + methodName + '` should include symbol properties', function(assert) {
16253       assert.expect(2);
16254
16255       function Foo() {
16256         this.a = 0;
16257         this[symbol] = 1;
16258       }
16259
16260       if (Symbol) {
16261         var symbol2 = Symbol('b');
16262         Foo.prototype[symbol2] = 2;
16263
16264         var foo = new Foo,
16265             actual = func(foo, prop(foo, 'a'));
16266
16267         assert.strictEqual(actual[symbol], 1);
16268         assert.strictEqual(actual[symbol2], 2);
16269       }
16270       else {
16271         skipAssert(assert, 2);
16272       }
16273     });
16274
16275     QUnit.test('`_.' + methodName + '` should create an object with omitted symbol properties', function(assert) {
16276       assert.expect(6);
16277
16278       function Foo() {
16279         this.a = 0;
16280         this[symbol] = 1;
16281       }
16282
16283       if (Symbol) {
16284         var symbol2 = Symbol('b');
16285         Foo.prototype[symbol2] = 2;
16286
16287         var foo = new Foo,
16288             actual = func(foo, prop(foo, symbol));
16289
16290         assert.strictEqual(actual.a, 0);
16291         assert.strictEqual(actual[symbol], undefined);
16292         assert.strictEqual(actual[symbol2], 2);
16293
16294         actual = func(foo, prop(foo, symbol2));
16295
16296         assert.strictEqual(actual.a, 0);
16297         assert.strictEqual(actual[symbol], 1);
16298         assert.strictEqual(actual[symbol2], undefined);
16299       }
16300       else {
16301         skipAssert(assert, 6);
16302       }
16303     });
16304
16305     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
16306       assert.expect(1);
16307
16308       var array = [1, 2, 3];
16309       assert.deepEqual(func(array, prop(array, ['0', '2'])), { '1': 2 });
16310     });
16311   });
16312
16313   /*--------------------------------------------------------------------------*/
16314
16315   QUnit.module('lodash.once');
16316
16317   (function() {
16318     QUnit.test('should invoke `func` once', function(assert) {
16319       assert.expect(2);
16320
16321       var count = 0,
16322           once = _.once(function() { return ++count; });
16323
16324       once();
16325       assert.strictEqual(once(), 1);
16326       assert.strictEqual(count, 1);
16327     });
16328
16329     QUnit.test('should ignore recursive calls', function(assert) {
16330       assert.expect(2);
16331
16332       var count = 0;
16333
16334       var once = _.once(function() {
16335         once();
16336         return ++count;
16337       });
16338
16339       assert.strictEqual(once(), 1);
16340       assert.strictEqual(count, 1);
16341     });
16342
16343     QUnit.test('should not throw more than once', function(assert) {
16344       assert.expect(2);
16345
16346       var pass = true;
16347
16348       var once = _.once(function() {
16349         throw new Error;
16350       });
16351
16352       assert.raises(once);
16353
16354       try {
16355         once();
16356       } catch (e) {
16357         pass = false;
16358       }
16359       assert.ok(pass);
16360     });
16361   }());
16362
16363   /*--------------------------------------------------------------------------*/
16364
16365   QUnit.module('lodash.over');
16366
16367   (function() {
16368     QUnit.test('should create a function that invokes `iteratees`', function(assert) {
16369       assert.expect(1);
16370
16371       var over = _.over(Math.max, Math.min);
16372       assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
16373     });
16374
16375     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16376       assert.expect(1);
16377
16378       var over = _.over(undefined, null);
16379       assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
16380     });
16381
16382     QUnit.test('should work with `_.property` shorthands', function(assert) {
16383       assert.expect(1);
16384
16385       var over = _.over('b', 'a');
16386       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
16387     });
16388
16389     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16390       assert.expect(1);
16391
16392       var over = _.over({ 'b': 1 }, { 'a': 1 });
16393       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
16394     });
16395
16396     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16397       assert.expect(2);
16398
16399       var over = _.over(['b', 2], [['a', 2]]);
16400
16401       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
16402       assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
16403     });
16404
16405     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16406       assert.expect(4);
16407
16408       var over = _.over(['a', 1]);
16409
16410       assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
16411       assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
16412
16413       over = _.over([['a', 1]]);
16414
16415       assert.deepEqual(over({ 'a': 1 }), [true]);
16416       assert.deepEqual(over({ 'a': 2 }), [false]);
16417     });
16418
16419     QUnit.test('should provide arguments to predicates', function(assert) {
16420       assert.expect(1);
16421
16422       var over = _.over(function() {
16423         return slice.call(arguments);
16424       });
16425
16426       assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
16427     });
16428
16429     QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
16430       assert.expect(1);
16431
16432       var over = _.over(function() { return this.b; }, function() { return this.a; }),
16433           object = { 'over': over, 'a': 1, 'b': 2 };
16434
16435       assert.deepEqual(object.over(), [2, 1]);
16436     });
16437   }());
16438
16439   /*--------------------------------------------------------------------------*/
16440
16441   QUnit.module('lodash.overEvery');
16442
16443   (function() {
16444     QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
16445       assert.expect(1);
16446
16447       var over = _.overEvery(alwaysTrue, alwaysOne, alwaysA);
16448       assert.strictEqual(over(), true);
16449     });
16450
16451     QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
16452       assert.expect(2);
16453
16454       var count = 0,
16455           countFalse = function() { count++; return false; },
16456           countTrue = function() { count++; return true; },
16457           over = _.overEvery(countTrue, countFalse, countTrue);
16458
16459       assert.strictEqual(over(), false);
16460       assert.strictEqual(count, 2);
16461     });
16462
16463     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16464       assert.expect(2);
16465
16466       var over = _.overEvery(undefined, null);
16467
16468       assert.strictEqual(over(true), true);
16469       assert.strictEqual(over(false), false);
16470     });
16471
16472     QUnit.test('should work with `_.property` shorthands', function(assert) {
16473       assert.expect(2);
16474
16475       var over = _.overEvery('b', 'a');
16476
16477       assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
16478       assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
16479     });
16480
16481     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16482       assert.expect(2);
16483
16484       var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
16485
16486       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16487       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16488     });
16489
16490     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16491       assert.expect(2);
16492
16493       var over = _.overEvery(['b', 2], [['a', 1]]);
16494
16495       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16496       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16497     });
16498
16499     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16500       assert.expect(5);
16501
16502       var over = _.overEvery(['a', 1]);
16503
16504       assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
16505       assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
16506       assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
16507
16508       over = _.overEvery([['a', 1]]);
16509
16510       assert.strictEqual(over({ 'a': 1 }), true);
16511       assert.strictEqual(over({ 'a': 2 }), false);
16512     });
16513
16514     QUnit.test('should flatten `predicates`', function(assert) {
16515       assert.expect(1);
16516
16517       var over = _.overEvery(alwaysTrue, [alwaysFalse]);
16518       assert.strictEqual(over(), false);
16519     });
16520
16521     QUnit.test('should provide arguments to predicates', function(assert) {
16522       assert.expect(1);
16523
16524       var args;
16525
16526       var over = _.overEvery(function() {
16527         args = slice.call(arguments);
16528       });
16529
16530       over('a', 'b', 'c');
16531       assert.deepEqual(args, ['a', 'b', 'c']);
16532     });
16533
16534     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16535       assert.expect(2);
16536
16537       var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
16538           object = { 'over': over, 'a': 1, 'b': 2 };
16539
16540       assert.strictEqual(object.over(), true);
16541
16542       object.a = 0;
16543       assert.strictEqual(object.over(), false);
16544     });
16545   }());
16546
16547   /*--------------------------------------------------------------------------*/
16548
16549   QUnit.module('lodash.overSome');
16550
16551   (function() {
16552     QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
16553       assert.expect(2);
16554
16555       var over = _.overSome(alwaysFalse, alwaysOne, alwaysEmptyString);
16556       assert.strictEqual(over(), true);
16557
16558       over = _.overSome(alwaysNull, alwaysA, alwaysZero);
16559       assert.strictEqual(over(), true);
16560     });
16561
16562     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
16563       assert.expect(2);
16564
16565       var count = 0,
16566           countFalse = function() { count++; return false; },
16567           countTrue = function() { count++; return true; },
16568           over = _.overSome(countFalse, countTrue, countFalse);
16569
16570       assert.strictEqual(over(), true);
16571       assert.strictEqual(count, 2);
16572     });
16573
16574     QUnit.test('should return `false` if all predicates return falsey', function(assert) {
16575       assert.expect(2);
16576
16577       var over = _.overSome(alwaysFalse, alwaysFalse, alwaysFalse);
16578       assert.strictEqual(over(), false);
16579
16580       over = _.overSome(alwaysNull, alwaysZero, alwaysEmptyString);
16581       assert.strictEqual(over(), false);
16582     });
16583
16584     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16585       assert.expect(2);
16586
16587       var over = _.overSome(undefined, null);
16588
16589       assert.strictEqual(over(true), true);
16590       assert.strictEqual(over(false), false);
16591     });
16592
16593     QUnit.test('should work with `_.property` shorthands', function(assert) {
16594       assert.expect(2);
16595
16596       var over = _.overSome('b', 'a');
16597
16598       assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
16599       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16600     });
16601
16602     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16603       assert.expect(2);
16604
16605       var over = _.overSome({ 'b': 2 }, { 'a': 1 });
16606
16607       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16608       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16609     });
16610
16611     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16612       assert.expect(2);
16613
16614       var over = _.overSome(['a', 1], [['b', 2]]);
16615
16616       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16617       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16618     });
16619
16620     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16621       assert.expect(5);
16622
16623       var over = _.overSome(['a', 1]);
16624
16625       assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
16626       assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
16627       assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
16628
16629       over = _.overSome([['a', 1]]);
16630
16631       assert.strictEqual(over({ 'a': 1 }), true);
16632       assert.strictEqual(over({ 'a': 2 }), false);
16633     });
16634
16635     QUnit.test('should flatten `predicates`', function(assert) {
16636       assert.expect(1);
16637
16638       var over = _.overSome(alwaysFalse, [alwaysTrue]);
16639       assert.strictEqual(over(), true);
16640     });
16641
16642     QUnit.test('should provide arguments to predicates', function(assert) {
16643       assert.expect(1);
16644
16645       var args;
16646
16647       var over = _.overSome(function() {
16648         args = slice.call(arguments);
16649       });
16650
16651       over('a', 'b', 'c');
16652       assert.deepEqual(args, ['a', 'b', 'c']);
16653     });
16654
16655     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16656       assert.expect(2);
16657
16658       var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
16659           object = { 'over': over, 'a': 1, 'b': 2 };
16660
16661       assert.strictEqual(object.over(), true);
16662
16663       object.a = object.b = 0;
16664       assert.strictEqual(object.over(), false);
16665     });
16666   }());
16667
16668   /*--------------------------------------------------------------------------*/
16669
16670   QUnit.module('lodash.pad');
16671
16672   (function() {
16673     var string = 'abc';
16674
16675     QUnit.test('should pad a string to a given length', function(assert) {
16676       assert.expect(1);
16677
16678       var values = [, undefined],
16679           expected = lodashStable.map(values, lodashStable.constant(' abc  '));
16680
16681       var actual = lodashStable.map(values, function(value, index) {
16682         return index ? _.pad(string, 6, value) : _.pad(string, 6);
16683       });
16684
16685       assert.deepEqual(actual, expected);
16686     });
16687
16688     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16689       assert.expect(2);
16690
16691       assert.strictEqual(_.pad(string, 8), '  abc   ');
16692       assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
16693     });
16694
16695     QUnit.test('should coerce `string` to a string', function(assert) {
16696       assert.expect(1);
16697
16698       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16699           expected = lodashStable.map(values, alwaysTrue);
16700
16701       var actual = lodashStable.map(values, function(value) {
16702         return _.pad(value, 6) === ' abc  ';
16703       });
16704
16705       assert.deepEqual(actual, expected);
16706     });
16707   }());
16708
16709   /*--------------------------------------------------------------------------*/
16710
16711   QUnit.module('lodash.padEnd');
16712
16713   (function() {
16714     var string = 'abc';
16715
16716     QUnit.test('should pad a string to a given length', function(assert) {
16717       assert.expect(1);
16718
16719       var values = [, undefined],
16720           expected = lodashStable.map(values, lodashStable.constant('abc   '));
16721
16722       var actual = lodashStable.map(values, function(value, index) {
16723         return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
16724       });
16725
16726       assert.deepEqual(actual, expected);
16727     });
16728
16729     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16730       assert.expect(1);
16731
16732       assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
16733     });
16734
16735     QUnit.test('should coerce `string` to a string', function(assert) {
16736       assert.expect(1);
16737
16738       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16739           expected = lodashStable.map(values, alwaysTrue);
16740
16741       var actual = lodashStable.map(values, function(value) {
16742         return _.padEnd(value, 6) === 'abc   ';
16743       });
16744
16745       assert.deepEqual(actual, expected);
16746     });
16747   }());
16748
16749   /*--------------------------------------------------------------------------*/
16750
16751   QUnit.module('lodash.padStart');
16752
16753   (function() {
16754     var string = 'abc';
16755
16756     QUnit.test('should pad a string to a given length', function(assert) {
16757       assert.expect(1);
16758
16759       var values = [, undefined],
16760           expected = lodashStable.map(values, lodashStable.constant('   abc'));
16761
16762       var actual = lodashStable.map(values, function(value, index) {
16763         return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
16764       });
16765
16766       assert.deepEqual(actual, expected);
16767     });
16768
16769     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16770       assert.expect(1);
16771
16772       assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
16773     });
16774
16775     QUnit.test('should coerce `string` to a string', function(assert) {
16776       assert.expect(1);
16777
16778       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16779           expected = lodashStable.map(values, alwaysTrue);
16780
16781       var actual = lodashStable.map(values, function(value) {
16782         return _.padStart(value, 6) === '   abc';
16783       });
16784
16785       assert.deepEqual(actual, expected);
16786     });
16787   }());
16788
16789   /*--------------------------------------------------------------------------*/
16790
16791   QUnit.module('pad methods');
16792
16793   lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
16794     var func = _[methodName],
16795         isPad = methodName == 'pad',
16796         isStart = methodName == 'padStart',
16797         string = 'abc';
16798
16799     QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
16800       assert.expect(2);
16801
16802       assert.strictEqual(func(string, 2), string);
16803       assert.strictEqual(func(string, 3), string);
16804     });
16805
16806     QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
16807       assert.expect(2);
16808
16809       lodashStable.each([0, -2], function(length) {
16810         assert.strictEqual(func(string, length), string);
16811       });
16812     });
16813
16814     QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
16815       assert.expect(2);
16816
16817       lodashStable.each(['', '4'], function(length) {
16818         var actual = length ? (isStart ? ' abc' : 'abc ') : string;
16819         assert.strictEqual(func(string, length), actual);
16820       });
16821     });
16822
16823     QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
16824       assert.expect(6);
16825
16826       lodashStable.each([undefined, '_-'], function(chars) {
16827         var expected = chars ? (isPad ? '__' : chars) : '  ';
16828         assert.strictEqual(func(null, 2, chars), expected);
16829         assert.strictEqual(func(undefined, 2, chars), expected);
16830         assert.strictEqual(func('', 2, chars), expected);
16831       });
16832     });
16833
16834     QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
16835       assert.expect(1);
16836
16837       var values = ['', Object('')],
16838           expected = lodashStable.map(values, lodashStable.constant(string));
16839
16840       var actual = lodashStable.map(values, function(value) {
16841         return _.pad(string, 6, value);
16842       });
16843
16844       assert.deepEqual(actual, expected);
16845     });
16846   });
16847
16848   /*--------------------------------------------------------------------------*/
16849
16850   QUnit.module('lodash.parseInt');
16851
16852   (function() {
16853     QUnit.test('should accept a `radix` argument', function(assert) {
16854       assert.expect(1);
16855
16856       var expected = lodashStable.range(2, 37);
16857
16858       var actual = lodashStable.map(expected, function(radix) {
16859         return _.parseInt('10', radix);
16860       });
16861
16862       assert.deepEqual(actual, expected);
16863     });
16864
16865     QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
16866       assert.expect(4);
16867
16868       assert.strictEqual(_.parseInt('10'), 10);
16869       assert.strictEqual(_.parseInt('10', 0), 10);
16870       assert.strictEqual(_.parseInt('10', 10), 10);
16871       assert.strictEqual(_.parseInt('10', undefined), 10);
16872     });
16873
16874     QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
16875       assert.expect(8);
16876
16877       lodashStable.each(['0x20', '0X20'], function(string) {
16878         assert.strictEqual(_.parseInt(string), 32);
16879         assert.strictEqual(_.parseInt(string, 0), 32);
16880         assert.strictEqual(_.parseInt(string, 16), 32);
16881         assert.strictEqual(_.parseInt(string, undefined), 32);
16882       });
16883     });
16884
16885     QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
16886       assert.expect(2);
16887
16888       assert.strictEqual(_.parseInt('08'), 8);
16889       assert.strictEqual(_.parseInt('08', 10), 8);
16890     });
16891
16892     QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
16893       assert.expect(2);
16894
16895       var expected = [8, 8, 10, 10, 32, 32, 32, 32];
16896
16897       lodashStable.times(2, function(index) {
16898         var actual = [],
16899             func = (index ? (lodashBizarro || {}) : _).parseInt;
16900
16901         if (func) {
16902           lodashStable.times(2, function(otherIndex) {
16903             var string = otherIndex ? '10' : '08';
16904             actual.push(
16905               func(whitespace + string, 10),
16906               func(whitespace + string)
16907             );
16908           });
16909
16910           lodashStable.each(['0x20', '0X20'], function(string) {
16911             actual.push(
16912               func(whitespace + string),
16913               func(whitespace + string, 16)
16914             );
16915           });
16916
16917           assert.deepEqual(actual, expected);
16918         }
16919         else {
16920           skipAssert(assert);
16921         }
16922       });
16923     });
16924
16925     QUnit.test('should coerce `radix` to a number', function(assert) {
16926       assert.expect(2);
16927
16928       var object = { 'valueOf': alwaysZero };
16929       assert.strictEqual(_.parseInt('08', object), 8);
16930       assert.strictEqual(_.parseInt('0x20', object), 32);
16931     });
16932
16933     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
16934       assert.expect(2);
16935
16936       var strings = lodashStable.map(['6', '08', '10'], Object),
16937           actual = lodashStable.map(strings, _.parseInt);
16938
16939       assert.deepEqual(actual, [6, 8, 10]);
16940
16941       actual = lodashStable.map('123', _.parseInt);
16942       assert.deepEqual(actual, [1, 2, 3]);
16943     });
16944   }());
16945
16946   /*--------------------------------------------------------------------------*/
16947
16948   QUnit.module('partial methods');
16949
16950   lodashStable.each(['partial', 'partialRight'], function(methodName) {
16951     var func = _[methodName],
16952         isPartial = methodName == 'partial',
16953         ph = func.placeholder;
16954
16955     QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
16956       assert.expect(1);
16957
16958       var par = func(identity, 'a');
16959       assert.strictEqual(par(), 'a');
16960     });
16961
16962     QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
16963       assert.expect(1);
16964
16965       var fn = function(a, b) { return [a, b]; },
16966           par = func(fn, 'a'),
16967           expected = isPartial ? ['a', 'b'] : ['b', 'a'];
16968
16969       assert.deepEqual(par('b'), expected);
16970     });
16971
16972     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
16973       assert.expect(1);
16974
16975       var fn = function() { return arguments.length; },
16976           par = func(fn);
16977
16978       assert.strictEqual(par(), 0);
16979     });
16980
16981     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
16982       assert.expect(1);
16983
16984       var par = func(identity);
16985       assert.strictEqual(par('a'), 'a');
16986     });
16987
16988     QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
16989       assert.expect(4);
16990
16991       var fn = function() { return slice.call(arguments); },
16992           par = func(fn, ph, 'b', ph);
16993
16994       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
16995       assert.deepEqual(par('a'), ['a', 'b', undefined]);
16996       assert.deepEqual(par(), [undefined, 'b', undefined]);
16997
16998       if (isPartial) {
16999         assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
17000       } else {
17001         par = func(fn, ph, 'c', ph);
17002         assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
17003       }
17004     });
17005
17006     QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
17007       assert.expect(1);
17008
17009       if (!isModularize) {
17010         var _ph = _.placeholder = {},
17011             fn = function() { return slice.call(arguments); },
17012             par = func(fn, _ph, 'b', ph),
17013             expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
17014
17015         assert.deepEqual(par('a', 'c'), expected);
17016         delete _.placeholder;
17017       }
17018       else {
17019         skipAssert(assert);
17020       }
17021     });
17022
17023     QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
17024       assert.expect(1);
17025
17026       var fn = function(a, b, c) {},
17027           par = func(fn, 'a');
17028
17029       assert.strictEqual(par.length, 0);
17030     });
17031
17032     QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
17033       assert.expect(2);
17034
17035       function Foo(value) {
17036         return value && object;
17037       }
17038
17039       var object = {},
17040           par = func(Foo);
17041
17042       assert.ok(new par instanceof Foo);
17043       assert.strictEqual(new par(true), object);
17044     });
17045
17046     QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
17047       assert.expect(3);
17048
17049       function greet(greeting, name) {
17050         return greeting + ' ' + name;
17051       }
17052
17053       var par1 = func(greet, 'hi'),
17054           par2 = func(par1, 'barney'),
17055           par3 = func(par1, 'pebbles');
17056
17057       assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
17058       assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
17059       assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
17060     });
17061
17062     QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
17063       assert.expect(2);
17064
17065       var fn = function(a, b, c) { return a + b + c; },
17066           curried = _.curry(func(fn, 1), 2);
17067
17068       assert.strictEqual(curried(2, 3), 6);
17069       assert.strictEqual(curried(2)(3), 6);
17070     });
17071
17072     QUnit.test('should work with placeholders and curried functions', function(assert) {
17073       assert.expect(1);
17074
17075       var fn = function() { return slice.call(arguments); },
17076           curried = _.curry(fn),
17077           par = func(curried, ph, 'b', ph, 'd');
17078
17079       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
17080     });
17081   });
17082
17083   /*--------------------------------------------------------------------------*/
17084
17085   QUnit.module('lodash.partialRight');
17086
17087   (function() {
17088     QUnit.test('should work as a deep `_.defaults`', function(assert) {
17089       assert.expect(1);
17090
17091       var object = { 'a': { 'b': 1 } },
17092           source = { 'a': { 'b': 2, 'c': 3 } },
17093           expected = { 'a': { 'b': 1, 'c': 3 } };
17094
17095       var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
17096         return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
17097       });
17098
17099       assert.deepEqual(defaultsDeep(object, source), expected);
17100     });
17101   }());
17102
17103   /*--------------------------------------------------------------------------*/
17104
17105   QUnit.module('methods using `createWrapper`');
17106
17107   (function() {
17108     function fn() {
17109       return slice.call(arguments);
17110     }
17111
17112     var ph1 = _.bind.placeholder,
17113         ph2 = _.bindKey.placeholder,
17114         ph3 = _.partial.placeholder,
17115         ph4 = _.partialRight.placeholder;
17116
17117     QUnit.test('should work with combinations of partial functions', function(assert) {
17118       assert.expect(1);
17119
17120       var a = _.partial(fn),
17121           b = _.partialRight(a, 3),
17122           c = _.partial(b, 1);
17123
17124       assert.deepEqual(c(2), [1, 2, 3]);
17125     });
17126
17127     QUnit.test('should work with combinations of bound and partial functions', function(assert) {
17128       assert.expect(3);
17129
17130       var fn = function() {
17131         var result = [this.a];
17132         push.apply(result, arguments);
17133         return result;
17134       };
17135
17136       var expected = [1, 2, 3, 4],
17137           object = { 'a': 1, 'fn': fn };
17138
17139       var a = _.bindKey(object, 'fn'),
17140           b = _.partialRight(a, 4),
17141           c = _.partial(b, 2);
17142
17143       assert.deepEqual(c(3), expected);
17144
17145       a = _.bind(fn, object);
17146       b = _.partialRight(a, 4);
17147       c = _.partial(b, 2);
17148
17149       assert.deepEqual(c(3), expected);
17150
17151       a = _.partial(fn, 2);
17152       b = _.bind(a, object);
17153       c = _.partialRight(b, 4);
17154
17155       assert.deepEqual(c(3), expected);
17156     });
17157
17158     QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
17159       assert.expect(2);
17160
17161       function Foo(a, b, c) {
17162         return b === 0 && object;
17163       }
17164
17165       var combo = _.partial(_.partialRight(Foo, 3), 1),
17166           object = {};
17167
17168       assert.ok(new combo(2) instanceof Foo);
17169       assert.strictEqual(new combo(0), object);
17170     });
17171
17172     QUnit.test('should work with combinations of functions with placeholders', function(assert) {
17173       assert.expect(3);
17174
17175       var expected = [1, 2, 3, 4, 5, 6],
17176           object = { 'fn': fn };
17177
17178       var a = _.bindKey(object, 'fn', ph2, 2),
17179           b = _.partialRight(a, ph4, 6),
17180           c = _.partial(b, 1, ph3, 4);
17181
17182       assert.deepEqual(c(3, 5), expected);
17183
17184       a = _.bind(fn, object, ph1, 2);
17185       b = _.partialRight(a, ph4, 6);
17186       c = _.partial(b, 1, ph3, 4);
17187
17188       assert.deepEqual(c(3, 5), expected);
17189
17190       a = _.partial(fn, ph3, 2);
17191       b = _.bind(a, object, 1, ph1, 4);
17192       c = _.partialRight(b, ph4, 6);
17193
17194       assert.deepEqual(c(3, 5), expected);
17195     });
17196
17197     QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
17198       assert.expect(3);
17199
17200       var expected = [1, 2, 3, 4],
17201           object = { 'fn': fn };
17202
17203       var a = _.bindKey(object, 'fn', ph2, 2),
17204           b = _.partialRight(a, ph4, 4),
17205           c = _.partial(b, ph3, 3);
17206
17207       assert.deepEqual(c(1), expected);
17208
17209       a = _.bind(fn, object, ph1, 2);
17210       b = _.partialRight(a, ph4, 4);
17211       c = _.partial(b, ph3, 3);
17212
17213       assert.deepEqual(c(1), expected);
17214
17215       a = _.partial(fn, ph3, 2);
17216       b = _.bind(a, object, ph1, 3);
17217       c = _.partialRight(b, ph4, 4);
17218
17219       assert.deepEqual(c(1), expected);
17220     });
17221
17222     QUnit.test('should work with recursively bound functions', function(assert) {
17223       assert.expect(1);
17224
17225       var fn = function() {
17226         return this.a;
17227       };
17228
17229       var a = _.bind(fn, { 'a': 1 }),
17230           b = _.bind(a,  { 'a': 2 }),
17231           c = _.bind(b,  { 'a': 3 });
17232
17233       assert.strictEqual(c(), 1);
17234     });
17235
17236     QUnit.test('should work when hot', function(assert) {
17237       assert.expect(12);
17238
17239       lodashStable.times(2, function(index) {
17240         var fn = function() {
17241           var result = [this];
17242           push.apply(result, arguments);
17243           return result;
17244         };
17245
17246         var object = {},
17247             bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17248             expected = [object, 1, 2, 3];
17249
17250         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17251           var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17252           return index ? bound2(3) : bound2(1, 2, 3);
17253         }));
17254
17255         assert.deepEqual(actual, expected);
17256
17257         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17258           var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17259               bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17260
17261           return index ? bound2(3) : bound2(1, 2, 3);
17262         }));
17263
17264         assert.deepEqual(actual, expected);
17265       });
17266
17267       lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
17268         var fn = function(a, b, c) { return [a, b, c]; },
17269             curried = _[methodName](fn),
17270             expected = index ? [3, 2, 1] :  [1, 2, 3];
17271
17272         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17273           return curried(1)(2)(3);
17274         }));
17275
17276         assert.deepEqual(actual, expected);
17277
17278         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17279           var curried = _[methodName](fn);
17280           return curried(1)(2)(3);
17281         }));
17282
17283         assert.deepEqual(actual, expected);
17284       });
17285
17286       lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
17287         var func = _[methodName],
17288             fn = function() { return slice.call(arguments); },
17289             par1 = func(fn, 1),
17290             expected = index ? [3, 2, 1] : [1, 2, 3];
17291
17292         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17293           var par2 = func(par1, 2);
17294           return par2(3);
17295         }));
17296
17297         assert.deepEqual(actual, expected);
17298
17299         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17300           var par1 = func(fn, 1),
17301               par2 = func(par1, 2);
17302
17303           return par2(3);
17304         }));
17305
17306         assert.deepEqual(actual, expected);
17307       });
17308     });
17309   }());
17310
17311   /*--------------------------------------------------------------------------*/
17312
17313   QUnit.module('lodash.partition');
17314
17315   (function() {
17316     var array = [1, 0, 1];
17317
17318     QUnit.test('should split elements into two groups by `predicate`', function(assert) {
17319       assert.expect(3);
17320
17321       assert.deepEqual(_.partition([], identity), [[], []]);
17322       assert.deepEqual(_.partition(array, alwaysTrue), [array, []]);
17323       assert.deepEqual(_.partition(array, alwaysFalse), [[], array]);
17324     });
17325
17326     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17327       assert.expect(1);
17328
17329       var values = [, null, undefined],
17330           expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
17331
17332       var actual = lodashStable.map(values, function(value, index) {
17333         return index ? _.partition(array, value) : _.partition(array);
17334       });
17335
17336       assert.deepEqual(actual, expected);
17337     });
17338
17339     QUnit.test('should work with `_.property` shorthands', function(assert) {
17340       assert.expect(1);
17341
17342       var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
17343           actual = _.partition(objects, 'a');
17344
17345       assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
17346     });
17347
17348     QUnit.test('should work with a number for `predicate`', function(assert) {
17349       assert.expect(2);
17350
17351       var array = [
17352         [1, 0],
17353         [0, 1],
17354         [1, 0]
17355       ];
17356
17357       assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
17358       assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
17359     });
17360
17361     QUnit.test('should work with an object for `collection`', function(assert) {
17362       assert.expect(1);
17363
17364       var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
17365       assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
17366     });
17367   }());
17368
17369   /*--------------------------------------------------------------------------*/
17370
17371   QUnit.module('lodash.pick');
17372
17373   (function() {
17374     var args = arguments,
17375         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17376
17377     QUnit.test('should flatten `props`', function(assert) {
17378       assert.expect(2);
17379
17380       assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
17381       assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
17382     });
17383
17384     QUnit.test('should work with a primitive `object` argument', function(assert) {
17385       assert.expect(1);
17386
17387       assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
17388     });
17389
17390     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
17391       assert.expect(2);
17392
17393       lodashStable.each([null, undefined], function(value) {
17394         assert.deepEqual(_.pick(value, 'valueOf'), {});
17395       });
17396     });
17397
17398     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
17399       assert.expect(1);
17400
17401       assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
17402     });
17403
17404     QUnit.test('should coerce property names to strings', function(assert) {
17405       assert.expect(1);
17406
17407       assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
17408     });
17409   }('a', 'c'));
17410
17411   /*--------------------------------------------------------------------------*/
17412
17413   QUnit.module('lodash.pickBy');
17414
17415   (function() {
17416     QUnit.test('should work with a predicate argument', function(assert) {
17417       assert.expect(1);
17418
17419       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17420
17421       var actual = _.pickBy(object, function(n) {
17422         return n == 1 || n == 3;
17423       });
17424
17425       assert.deepEqual(actual, { 'a': 1, 'c': 3 });
17426     });
17427   }());
17428
17429   /*--------------------------------------------------------------------------*/
17430
17431   QUnit.module('pick methods');
17432
17433   lodashStable.each(['pick', 'pickBy'], function(methodName) {
17434     var expected = { 'a': 1, 'c': 3 },
17435         func = _[methodName],
17436         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17437         prop = lodashStable.nthArg(1);
17438
17439     if (methodName == 'pickBy') {
17440       prop = function(object, props) {
17441         props = lodashStable.castArray(props);
17442         return function(value) {
17443           return lodashStable.some(props, function(key) {
17444             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
17445             return object[key] === value;
17446           });
17447         };
17448       };
17449     }
17450     QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
17451       assert.expect(2);
17452
17453       assert.deepEqual(func(object, prop(object, 'a')), { 'a': 1 });
17454       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
17455     });
17456
17457     QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
17458       assert.expect(1);
17459
17460       function Foo() {}
17461       Foo.prototype = object;
17462
17463       var foo = new Foo;
17464       assert.deepEqual(func(foo, prop(foo, ['a', 'c'])), expected);
17465     });
17466
17467     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
17468       assert.expect(1);
17469
17470       var object = { '-0': 'a', '0': 'b' },
17471           props = [-0, Object(-0), 0, Object(0)],
17472           expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
17473
17474       var actual = lodashStable.map(props, function(key) {
17475         return func(object, prop(object, key));
17476       });
17477
17478       assert.deepEqual(actual, expected);
17479     });
17480
17481     QUnit.test('`_.' + methodName + '` should pick symbol properties', function(assert) {
17482       assert.expect(2);
17483
17484       function Foo() {
17485         this[symbol] = 1;
17486       }
17487
17488       if (Symbol) {
17489         var symbol2 = Symbol('b');
17490         Foo.prototype[symbol2] = 2;
17491
17492         var foo = new Foo,
17493             actual = func(foo, prop(foo, [symbol, symbol2]));
17494
17495         assert.strictEqual(actual[symbol], 1);
17496         assert.strictEqual(actual[symbol2], 2);
17497       }
17498       else {
17499         skipAssert(assert, 2);
17500       }
17501     });
17502
17503     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
17504       assert.expect(1);
17505
17506       var array = [1, 2, 3];
17507       assert.deepEqual(func(array, prop(array, '1')), { '1': 2 });
17508     });
17509   });
17510
17511   /*--------------------------------------------------------------------------*/
17512
17513   QUnit.module('lodash.property');
17514
17515   (function() {
17516     QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
17517       assert.expect(4);
17518
17519       var object = { 'a': 1 };
17520
17521       lodashStable.each(['a', ['a']], function(path) {
17522         var prop = _.property(path);
17523         assert.strictEqual(prop.length, 1);
17524         assert.strictEqual(prop(object), 1);
17525       });
17526     });
17527
17528     QUnit.test('should pluck deep property values', function(assert) {
17529       assert.expect(2);
17530
17531       var object = { 'a': { 'b': 2 } };
17532
17533       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17534         var prop = _.property(path);
17535         assert.strictEqual(prop(object), 2);
17536       });
17537     });
17538
17539     QUnit.test('should pluck inherited property values', function(assert) {
17540       assert.expect(2);
17541
17542       function Foo() {}
17543       Foo.prototype.a = 1;
17544
17545       lodashStable.each(['a', ['a']], function(path) {
17546         var prop = _.property(path);
17547         assert.strictEqual(prop(new Foo), 1);
17548       });
17549     });
17550
17551     QUnit.test('should work with a non-string `path`', function(assert) {
17552       assert.expect(2);
17553
17554       var array = [1, 2, 3];
17555
17556       lodashStable.each([1, [1]], function(path) {
17557         var prop = _.property(path);
17558         assert.strictEqual(prop(array), 2);
17559       });
17560     });
17561
17562     QUnit.test('should preserve the sign of `0`', function(assert) {
17563       assert.expect(1);
17564
17565       var object = { '-0': 'a', '0': 'b' },
17566           props = [-0, Object(-0), 0, Object(0)];
17567
17568       var actual = lodashStable.map(props, function(key) {
17569         var prop = _.property(key);
17570         return prop(object);
17571       });
17572
17573       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17574     });
17575
17576     QUnit.test('should coerce key to a string', function(assert) {
17577       assert.expect(1);
17578
17579       function fn() {}
17580       fn.toString = lodashStable.constant('fn');
17581
17582       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
17583           values = [null, undefined, fn, {}];
17584
17585       var actual = lodashStable.transform(objects, function(result, object, index) {
17586         var key = values[index];
17587         lodashStable.each([key, [key]], function(path) {
17588           var prop = _.property(key);
17589           result.push(prop(object));
17590         });
17591       });
17592
17593       assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
17594     });
17595
17596     QUnit.test('should pluck a key over a path', function(assert) {
17597       assert.expect(2);
17598
17599       var object = { 'a.b': 1, 'a': { 'b': 2 } };
17600
17601       lodashStable.each(['a.b', ['a.b']], function(path) {
17602         var prop = _.property(path);
17603         assert.strictEqual(prop(object), 1);
17604       });
17605     });
17606
17607     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17608       assert.expect(2);
17609
17610       var values = [, null, undefined],
17611           expected = lodashStable.map(values, noop);
17612
17613       lodashStable.each(['constructor', ['constructor']], function(path) {
17614         var prop = _.property(path);
17615
17616         var actual = lodashStable.map(values, function(value, index) {
17617           return index ? prop(value) : prop();
17618         });
17619
17620         assert.deepEqual(actual, expected);
17621       });
17622     });
17623
17624     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
17625       assert.expect(2);
17626
17627       var values = [, null, undefined],
17628           expected = lodashStable.map(values, noop);
17629
17630       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17631         var prop = _.property(path);
17632
17633         var actual = lodashStable.map(values, function(value, index) {
17634           return index ? prop(value) : prop();
17635         });
17636
17637         assert.deepEqual(actual, expected);
17638       });
17639     });
17640
17641     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17642       assert.expect(4);
17643
17644       var object = {};
17645
17646       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17647         var prop = _.property(path);
17648         assert.strictEqual(prop(object), undefined);
17649       });
17650     });
17651   }());
17652
17653   /*--------------------------------------------------------------------------*/
17654
17655   QUnit.module('lodash.propertyOf');
17656
17657   (function() {
17658     QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
17659       assert.expect(3);
17660
17661       var object = { 'a': 1 },
17662           propOf = _.propertyOf(object);
17663
17664       assert.strictEqual(propOf.length, 1);
17665       lodashStable.each(['a', ['a']], function(path) {
17666         assert.strictEqual(propOf(path), 1);
17667       });
17668     });
17669
17670     QUnit.test('should pluck deep property values', function(assert) {
17671       assert.expect(2);
17672
17673       var object = { 'a': { 'b': 2 } },
17674           propOf = _.propertyOf(object);
17675
17676       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17677         assert.strictEqual(propOf(path), 2);
17678       });
17679     });
17680
17681     QUnit.test('should pluck inherited property values', function(assert) {
17682       assert.expect(2);
17683
17684       function Foo() {
17685         this.a = 1;
17686       }
17687       Foo.prototype.b = 2;
17688
17689       var propOf = _.propertyOf(new Foo);
17690
17691       lodashStable.each(['b', ['b']], function(path) {
17692         assert.strictEqual(propOf(path), 2);
17693       });
17694     });
17695
17696     QUnit.test('should work with a non-string `path`', function(assert) {
17697       assert.expect(2);
17698
17699       var array = [1, 2, 3],
17700           propOf = _.propertyOf(array);
17701
17702       lodashStable.each([1, [1]], function(path) {
17703         assert.strictEqual(propOf(path), 2);
17704       });
17705     });
17706
17707     QUnit.test('should preserve the sign of `0`', function(assert) {
17708       assert.expect(1);
17709
17710       var object = { '-0': 'a', '0': 'b' },
17711           props = [-0, Object(-0), 0, Object(0)];
17712
17713       var actual = lodashStable.map(props, function(key) {
17714         var propOf = _.propertyOf(object);
17715         return propOf(key);
17716       });
17717
17718       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17719     });
17720
17721     QUnit.test('should coerce key to a string', function(assert) {
17722       assert.expect(1);
17723
17724       function fn() {}
17725       fn.toString = lodashStable.constant('fn');
17726
17727       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
17728           values = [null, undefined, fn, {}];
17729
17730       var actual = lodashStable.transform(objects, function(result, object, index) {
17731         var key = values[index];
17732         lodashStable.each([key, [key]], function(path) {
17733           var propOf = _.propertyOf(object);
17734           result.push(propOf(key));
17735         });
17736       });
17737
17738       assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
17739     });
17740
17741     QUnit.test('should pluck a key over a path', function(assert) {
17742       assert.expect(2);
17743
17744       var object = { 'a.b': 1, 'a': { 'b': 2 } },
17745           propOf = _.propertyOf(object);
17746
17747       lodashStable.each(['a.b', ['a.b']], function(path) {
17748         assert.strictEqual(propOf(path), 1);
17749       });
17750     });
17751
17752     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17753       assert.expect(2);
17754
17755       var values = [, null, undefined],
17756           expected = lodashStable.map(values, noop);
17757
17758       lodashStable.each(['constructor', ['constructor']], function(path) {
17759         var actual = lodashStable.map(values, function(value, index) {
17760           var propOf = index ? _.propertyOf(value) : _.propertyOf();
17761           return propOf(path);
17762         });
17763
17764         assert.deepEqual(actual, expected);
17765       });
17766     });
17767
17768     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
17769       assert.expect(2);
17770
17771       var values = [, null, undefined],
17772           expected = lodashStable.map(values, noop);
17773
17774       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17775         var actual = lodashStable.map(values, function(value, index) {
17776           var propOf = index ? _.propertyOf(value) : _.propertyOf();
17777           return propOf(path);
17778         });
17779
17780         assert.deepEqual(actual, expected);
17781       });
17782     });
17783
17784     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17785       assert.expect(4);
17786
17787       var propOf = _.propertyOf({});
17788
17789       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17790         assert.strictEqual(propOf(path), undefined);
17791       });
17792     });
17793   }());
17794
17795   /*--------------------------------------------------------------------------*/
17796
17797   QUnit.module('lodash.pullAllBy');
17798
17799   (function() {
17800     QUnit.test('should accept an `iteratee` argument', function(assert) {
17801       assert.expect(1);
17802
17803       var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
17804
17805       var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
17806         return object.x;
17807       });
17808
17809       assert.deepEqual(actual, [{ 'x': 2 }]);
17810     });
17811
17812     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
17813       assert.expect(1);
17814
17815       var args,
17816           array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
17817
17818       _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
17819         args || (args = slice.call(arguments));
17820       });
17821
17822       assert.deepEqual(args, [{ 'x': 1 }]);
17823     });
17824   }());
17825
17826   /*--------------------------------------------------------------------------*/
17827
17828   QUnit.module('lodash.pullAllWith');
17829
17830   (function() {
17831     QUnit.test('should work with a `comparator` argument', function(assert) {
17832       assert.expect(1);
17833
17834       var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
17835           expected = [objects[0], objects[2]],
17836           actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
17837
17838       assert.deepEqual(actual, expected);
17839     });
17840   }());
17841
17842   /*--------------------------------------------------------------------------*/
17843
17844   QUnit.module('pull methods');
17845
17846   lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
17847     var func = _[methodName],
17848         isPull = methodName == 'pull';
17849
17850     function pull(array, values) {
17851       return isPull
17852         ? func.apply(undefined, [array].concat(values))
17853         : func(array, values);
17854     }
17855
17856     QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
17857       assert.expect(2);
17858
17859       var array = [1, 2, 3],
17860           actual = pull(array, [1, 3]);
17861
17862       assert.deepEqual(array, [2]);
17863       assert.ok(actual === array);
17864     });
17865
17866     QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
17867       assert.expect(2);
17868
17869       var array = [1, 2, 3, 4];
17870       delete array[1];
17871       delete array[3];
17872
17873       pull(array, [1]);
17874       assert.notOk('0' in array);
17875       assert.notOk('2' in array);
17876     });
17877
17878     QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
17879       assert.expect(1);
17880
17881       var array = [1, 2, 3];
17882       delete array[1];
17883
17884       pull(array, [undefined]);
17885       assert.deepEqual(array, [1, 3]);
17886     });
17887
17888     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
17889       assert.expect(1);
17890
17891       var array = [1, NaN, 3, NaN];
17892
17893       pull(array, [NaN]);
17894       assert.deepEqual(array, [1, 3]);
17895     });
17896   });
17897
17898   /*--------------------------------------------------------------------------*/
17899
17900   QUnit.module('lodash.pullAt');
17901
17902   (function() {
17903     QUnit.test('should modify the array and return removed elements', function(assert) {
17904       assert.expect(2);
17905
17906       var array = [1, 2, 3],
17907           actual = _.pullAt(array, [0, 1]);
17908
17909       assert.deepEqual(array, [3]);
17910       assert.deepEqual(actual, [1, 2]);
17911     });
17912
17913     QUnit.test('should work with unsorted indexes', function(assert) {
17914       assert.expect(2);
17915
17916       var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
17917           actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
17918
17919       assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
17920       assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
17921     });
17922
17923     QUnit.test('should work with repeated indexes', function(assert) {
17924       assert.expect(2);
17925
17926       var array = [1, 2, 3, 4],
17927           actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
17928
17929       assert.deepEqual(array, [4]);
17930       assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
17931     });
17932
17933     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
17934       assert.expect(2);
17935
17936       var array = ['a', 'b', 'c'],
17937           actual = _.pullAt(array, [2, 4, 0]);
17938
17939       assert.deepEqual(array, ['b']);
17940       assert.deepEqual(actual, ['c', undefined, 'a']);
17941     });
17942
17943     QUnit.test('should flatten `indexes`', function(assert) {
17944       assert.expect(4);
17945
17946       var array = ['a', 'b', 'c'];
17947       assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
17948       assert.deepEqual(array, ['b']);
17949
17950       array = ['a', 'b', 'c', 'd'];
17951       assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
17952       assert.deepEqual(array, ['b']);
17953     });
17954
17955     QUnit.test('should return an empty array when no indexes are given', function(assert) {
17956       assert.expect(4);
17957
17958       var array = ['a', 'b', 'c'],
17959           actual = _.pullAt(array);
17960
17961       assert.deepEqual(array, ['a', 'b', 'c']);
17962       assert.deepEqual(actual, []);
17963
17964       actual = _.pullAt(array, [], []);
17965
17966       assert.deepEqual(array, ['a', 'b', 'c']);
17967       assert.deepEqual(actual, []);
17968     });
17969
17970     QUnit.test('should work with non-index paths', function(assert) {
17971       assert.expect(2);
17972
17973       var values = lodashStable.reject(empties, function(value) {
17974         return (value === 0) || lodashStable.isArray(value);
17975       }).concat(-1, 1.1);
17976
17977       var array = lodashStable.transform(values, function(result, value) {
17978         result[value] = 1;
17979       }, []);
17980
17981       var expected = lodashStable.map(values, alwaysOne),
17982           actual = _.pullAt(array, values);
17983
17984       assert.deepEqual(actual, expected);
17985
17986       expected = lodashStable.map(values, noop),
17987       actual = lodashStable.at(array, values);
17988
17989       assert.deepEqual(actual, expected);
17990     });
17991
17992     QUnit.test('should preserve the sign of `0`', function(assert) {
17993       assert.expect(1);
17994
17995       var props = [-0, Object(-0), 0, Object(0)];
17996
17997       var actual = lodashStable.map(props, function(key) {
17998         var array = [-1];
17999         array['-0'] = -2;
18000         return _.pullAt(array, key);
18001       });
18002
18003       assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
18004     });
18005
18006     QUnit.test('should work with deep paths', function(assert) {
18007       assert.expect(3);
18008
18009       var array = [];
18010       array.a = { 'b': 2 };
18011
18012       var actual = _.pullAt(array, 'a.b');
18013
18014       assert.deepEqual(actual, [2]);
18015       assert.deepEqual(array.a, {});
18016
18017       try {
18018         actual = _.pullAt(array, 'a.b.c');
18019       } catch (e) {}
18020
18021       assert.deepEqual(actual, [undefined]);
18022     });
18023
18024     QUnit.test('should work with a falsey `array` argument when keys are given', function(assert) {
18025       assert.expect(1);
18026
18027       var values = falsey.slice(),
18028           expected = lodashStable.map(values, lodashStable.constant(Array(4)));
18029
18030       var actual = lodashStable.map(values, function(array) {
18031         try {
18032           return _.pullAt(array, 0, 1, 'pop', 'push');
18033         } catch (e) {}
18034       });
18035
18036       assert.deepEqual(actual, expected);
18037     });
18038   }());
18039
18040   /*--------------------------------------------------------------------------*/
18041
18042   QUnit.module('lodash.random');
18043
18044   (function() {
18045     var array = Array(1000);
18046
18047     QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
18048       assert.expect(1);
18049
18050       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18051         return _.random();
18052       })).sort();
18053
18054       assert.deepEqual(actual, [0, 1]);
18055     });
18056
18057     QUnit.test('should support a `min` and `max` argument', function(assert) {
18058       assert.expect(1);
18059
18060       var min = 5,
18061           max = 10;
18062
18063       assert.ok(_.some(array, function() {
18064         var result = _.random(min, max);
18065         return result >= min && result <= max;
18066       }));
18067     });
18068
18069     QUnit.test('should support not providing a `max` argument', function(assert) {
18070       assert.expect(1);
18071
18072       var min = 0,
18073           max = 5;
18074
18075       assert.ok(_.some(array, function() {
18076         var result = _.random(max);
18077         return result >= min && result <= max;
18078       }));
18079     });
18080
18081     QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
18082       assert.expect(1);
18083
18084       var min = 4,
18085           max = 2,
18086           expected = [2, 3, 4];
18087
18088       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18089         return _.random(min, max);
18090       })).sort();
18091
18092       assert.deepEqual(actual, expected);
18093     });
18094
18095     QUnit.test('should support large integer values', function(assert) {
18096       assert.expect(2);
18097
18098       var min = Math.pow(2, 31),
18099           max = Math.pow(2, 62);
18100
18101       assert.ok(lodashStable.every(array, function() {
18102         var result = _.random(min, max);
18103         return result >= min && result <= max;
18104       }));
18105
18106       assert.ok(_.some(array, function() {
18107         return _.random(MAX_INTEGER) > 0;
18108       }));
18109     });
18110
18111     QUnit.test('should coerce arguments to finite numbers', function(assert) {
18112       assert.expect(2);
18113
18114       assert.strictEqual(_.random('1', '1'), 1);
18115       assert.strictEqual(_.random(NaN, NaN), 0);
18116     });
18117
18118     QUnit.test('should support floats', function(assert) {
18119       assert.expect(2);
18120
18121       var min = 1.5,
18122           max = 1.6,
18123           actual = _.random(min, max);
18124
18125       assert.ok(actual % 1);
18126       assert.ok(actual >= min && actual <= max);
18127     });
18128
18129     QUnit.test('should support providing a `floating` argument', function(assert) {
18130       assert.expect(3);
18131
18132       var actual = _.random(true);
18133       assert.ok(actual % 1 && actual >= 0 && actual <= 1);
18134
18135       actual = _.random(2, true);
18136       assert.ok(actual % 1 && actual >= 0 && actual <= 2);
18137
18138       actual = _.random(2, 4, true);
18139       assert.ok(actual % 1 && actual >= 2 && actual <= 4);
18140     });
18141
18142     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18143       assert.expect(1);
18144
18145       var array = [1, 2, 3],
18146           expected = lodashStable.map(array, alwaysTrue),
18147           randoms = lodashStable.map(array, _.random);
18148
18149       var actual = lodashStable.map(randoms, function(result, index) {
18150         return result >= 0 && result <= array[index] && (result % 1) == 0;
18151       });
18152
18153       assert.deepEqual(actual, expected);
18154     });
18155   }());
18156
18157   /*--------------------------------------------------------------------------*/
18158
18159   QUnit.module('range methods');
18160
18161   lodashStable.each(['range', 'rangeRight'], function(methodName) {
18162     var func = _[methodName],
18163         isRange = methodName == 'range';
18164
18165     function resolve(range) {
18166       return isRange ? range : range.reverse();
18167     }
18168
18169     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
18170       assert.expect(2);
18171
18172       assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
18173       assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
18174     });
18175
18176     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
18177       assert.expect(2);
18178
18179       assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
18180       assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
18181     });
18182
18183     QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
18184       assert.expect(3);
18185
18186       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18187       assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
18188       assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
18189     });
18190
18191     QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
18192       assert.expect(1);
18193
18194       assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
18195     });
18196
18197     QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
18198       assert.expect(1);
18199
18200       assert.deepEqual(func(1, 5, 20), [1]);
18201     });
18202
18203     QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
18204       assert.expect(2);
18205
18206       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18207       assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
18208     });
18209
18210     QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
18211       assert.expect(1);
18212
18213       var actual = func(-0, 1);
18214       assert.strictEqual(1 / actual[0], -Infinity);
18215     });
18216
18217     QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
18218       assert.expect(13);
18219
18220       lodashStable.each(falsey, function(value, index) {
18221         if (index) {
18222           assert.deepEqual(func(value), []);
18223           assert.deepEqual(func(value, 1), [0]);
18224         } else {
18225           assert.deepEqual(func(), []);
18226         }
18227       });
18228     });
18229
18230     QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
18231       assert.expect(1);
18232
18233       var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
18234       assert.deepEqual(actual, [[0], [0], [0], [], []]);
18235     });
18236
18237     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
18238       assert.expect(2);
18239
18240       var array = [1, 2, 3],
18241           object = { 'a': 1, 'b': 2, 'c': 3 },
18242           expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
18243
18244       lodashStable.each([array, object], function(collection) {
18245         var actual = lodashStable.map(collection, func);
18246         assert.deepEqual(actual, expected);
18247       });
18248     });
18249   });
18250
18251   /*--------------------------------------------------------------------------*/
18252
18253   QUnit.module('lodash.rearg');
18254
18255   (function() {
18256     function fn() {
18257       return slice.call(arguments);
18258     }
18259
18260     QUnit.test('should reorder arguments provided to `func`', function(assert) {
18261       assert.expect(1);
18262
18263       var rearged = _.rearg(fn, [2, 0, 1]);
18264       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18265     });
18266
18267     QUnit.test('should work with repeated indexes', function(assert) {
18268       assert.expect(1);
18269
18270       var rearged = _.rearg(fn, [1, 1, 1]);
18271       assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
18272     });
18273
18274     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18275       assert.expect(1);
18276
18277       var rearged = _.rearg(fn, [1, 4]);
18278       assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
18279     });
18280
18281     QUnit.test('should use `undefined` for non-index values', function(assert) {
18282       assert.expect(1);
18283
18284       var values = lodashStable.reject(empties, function(value) {
18285         return (value === 0) || lodashStable.isArray(value);
18286       }).concat(-1, 1.1);
18287
18288       var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
18289
18290       var actual = lodashStable.map(values, function(value) {
18291         var rearged = _.rearg(fn, [value]);
18292         return rearged('a', 'b', 'c');
18293       });
18294
18295       assert.deepEqual(actual, expected);
18296     });
18297
18298     QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
18299       assert.expect(2);
18300
18301       var rearged = _.rearg(fn);
18302       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18303
18304       rearged = _.rearg(fn, [], []);
18305       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18306     });
18307
18308     QUnit.test('should accept multiple index arguments', function(assert) {
18309       assert.expect(1);
18310
18311       var rearged = _.rearg(fn, 2, 0, 1);
18312       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18313     });
18314
18315     QUnit.test('should accept multiple arrays of indexes', function(assert) {
18316       assert.expect(1);
18317
18318       var rearged = _.rearg(fn, [2], [0, 1]);
18319       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18320     });
18321
18322     QUnit.test('should work with fewer indexes than arguments', function(assert) {
18323       assert.expect(1);
18324
18325       var rearged = _.rearg(fn, [1, 0]);
18326       assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
18327     });
18328
18329     QUnit.test('should work on functions that have been rearged', function(assert) {
18330       assert.expect(1);
18331
18332       var rearged1 = _.rearg(fn, 2, 1, 0),
18333           rearged2 = _.rearg(rearged1, 1, 0, 2);
18334
18335       assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
18336     });
18337   }());
18338
18339   /*--------------------------------------------------------------------------*/
18340
18341   QUnit.module('lodash.reduce');
18342
18343   (function() {
18344     var array = [1, 2, 3];
18345
18346     QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
18347       assert.expect(1);
18348
18349       assert.strictEqual(_.reduce(array), 1);
18350     });
18351
18352     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18353       assert.expect(2);
18354
18355       var args;
18356
18357       _.reduce(array, function() {
18358         args || (args = slice.call(arguments));
18359       }, 0);
18360
18361       assert.deepEqual(args, [0, 1, 0, array]);
18362
18363       args = undefined;
18364       _.reduce(array, function() {
18365         args || (args = slice.call(arguments));
18366       });
18367
18368       assert.deepEqual(args, [1, 2, 1, array]);
18369     });
18370
18371     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18372       assert.expect(2);
18373
18374       var args,
18375           object = { 'a': 1, 'b': 2 },
18376           firstKey = _.head(_.keys(object));
18377
18378       var expected = firstKey == 'a'
18379         ? [0, 1, 'a', object]
18380         : [0, 2, 'b', object];
18381
18382       _.reduce(object, function() {
18383         args || (args = slice.call(arguments));
18384       }, 0);
18385
18386       assert.deepEqual(args, expected);
18387
18388       args = undefined;
18389       expected = firstKey == 'a'
18390         ? [1, 2, 'b', object]
18391         : [2, 1, 'a', object];
18392
18393       _.reduce(object, function() {
18394         args || (args = slice.call(arguments));
18395       });
18396
18397       assert.deepEqual(args, expected);
18398     });
18399   }());
18400
18401   /*--------------------------------------------------------------------------*/
18402
18403   QUnit.module('lodash.reduceRight');
18404
18405   (function() {
18406     var array = [1, 2, 3];
18407
18408     QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
18409       assert.expect(1);
18410
18411       assert.strictEqual(_.reduceRight(array), 3);
18412     });
18413
18414     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18415       assert.expect(2);
18416
18417       var args;
18418
18419       _.reduceRight(array, function() {
18420         args || (args = slice.call(arguments));
18421       }, 0);
18422
18423       assert.deepEqual(args, [0, 3, 2, array]);
18424
18425       args = undefined;
18426       _.reduceRight(array, function() {
18427         args || (args = slice.call(arguments));
18428       });
18429
18430       assert.deepEqual(args, [3, 2, 1, array]);
18431     });
18432
18433     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18434       assert.expect(2);
18435
18436       var args,
18437           object = { 'a': 1, 'b': 2 },
18438           isFIFO = lodashStable.keys(object)[0] == 'a';
18439
18440       var expected = isFIFO
18441         ? [0, 2, 'b', object]
18442         : [0, 1, 'a', object];
18443
18444       _.reduceRight(object, function() {
18445         args || (args = slice.call(arguments));
18446       }, 0);
18447
18448       assert.deepEqual(args, expected);
18449
18450       args = undefined;
18451       expected = isFIFO
18452         ? [2, 1, 'a', object]
18453         : [1, 2, 'b', object];
18454
18455       _.reduceRight(object, function() {
18456         args || (args = slice.call(arguments));
18457       });
18458
18459       assert.deepEqual(args, expected);
18460     });
18461   }());
18462
18463   /*--------------------------------------------------------------------------*/
18464
18465   QUnit.module('reduce methods');
18466
18467   lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
18468     var func = _[methodName],
18469         array = [1, 2, 3],
18470         isReduce = methodName == 'reduce';
18471
18472     QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
18473       assert.expect(1);
18474
18475       var actual = func(['a', 'b', 'c'], function(accumulator, value) {
18476         return accumulator + value;
18477       }, '');
18478
18479       assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
18480     });
18481
18482     QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
18483       assert.expect(1);
18484
18485       var actual = [],
18486           expected = lodashStable.map(empties, noop);
18487
18488       lodashStable.each(empties, function(value) {
18489         try {
18490           actual.push(func(value, noop));
18491         } catch (e) {}
18492       });
18493
18494       assert.deepEqual(actual, expected);
18495     });
18496
18497     QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
18498       assert.expect(1);
18499
18500       var expected = lodashStable.map(empties, lodashStable.constant('x'));
18501
18502       var actual = lodashStable.map(empties, function(value) {
18503         try {
18504           return func(value, noop, 'x');
18505         } catch (e) {}
18506       });
18507
18508       assert.deepEqual(actual, expected);
18509     });
18510
18511     QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
18512       assert.expect(1);
18513
18514       var actual = func([], noop, undefined);
18515       assert.strictEqual(actual, undefined);
18516     });
18517
18518     QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
18519       assert.expect(2);
18520
18521       var array = [],
18522           object = { '0': 1, 'length': 0 };
18523
18524       if ('__proto__' in array) {
18525         array.__proto__ = object;
18526         assert.strictEqual(func(array, noop), undefined);
18527       }
18528       else {
18529         skipAssert(assert);
18530       }
18531       assert.strictEqual(func(object, noop), undefined);
18532     });
18533
18534     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
18535       assert.expect(1);
18536
18537       if (!isNpm) {
18538         assert.strictEqual(_(array)[methodName](add), 6);
18539       }
18540       else {
18541         skipAssert(assert);
18542       }
18543     });
18544
18545     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
18546       assert.expect(1);
18547
18548       if (!isNpm) {
18549         assert.ok(_(array).chain()[methodName](add) instanceof _);
18550       }
18551       else {
18552         skipAssert(assert);
18553       }
18554     });
18555   });
18556
18557   /*--------------------------------------------------------------------------*/
18558
18559   QUnit.module('lodash.reject');
18560
18561   (function() {
18562     var array = [1, 2, 3];
18563
18564     QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
18565       assert.expect(1);
18566
18567       assert.deepEqual(_.reject(array, isEven), [1, 3]);
18568     });
18569   }());
18570
18571   /*--------------------------------------------------------------------------*/
18572
18573   QUnit.module('filter methods');
18574
18575   lodashStable.each(['filter', 'reject'], function(methodName) {
18576     var array = [1, 2, 3, 4],
18577         func = _[methodName],
18578         isFilter = methodName == 'filter',
18579         objects = [{ 'a': 0 }, { 'a': 1 }];
18580
18581     QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
18582       assert.expect(1);
18583
18584       var actual = func([0], function(value, index, array) {
18585         array[index] = 1;
18586         return isFilter;
18587       });
18588
18589       assert.deepEqual(actual, [0]);
18590     });
18591
18592     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
18593       assert.expect(1);
18594
18595       assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
18596     });
18597
18598     QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
18599       assert.expect(1);
18600
18601       assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
18602     });
18603
18604     QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
18605       assert.expect(2);
18606
18607       if (!isNpm) {
18608         var wrapped = _(array);
18609
18610         var actual = wrapped[methodName](function(n) {
18611           return n < 3;
18612         });
18613
18614         assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
18615
18616         actual = wrapped[methodName](function(n) {
18617           return n > 2;
18618         });
18619
18620         assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
18621       }
18622       else {
18623         skipAssert(assert, 2);
18624       }
18625     });
18626
18627     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
18628       assert.expect(2);
18629
18630       if (!isNpm) {
18631         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18632             predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
18633             actual = _(array).slice(1).map(square)[methodName](predicate).value();
18634
18635         assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
18636
18637         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
18638           return ['key' + index, index];
18639         }));
18640
18641         actual = _(object).mapValues(square)[methodName](predicate).value();
18642         assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
18643       }
18644       else {
18645         skipAssert(assert, 2);
18646       }
18647     });
18648
18649     QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
18650       assert.expect(5);
18651
18652       if (!isNpm) {
18653         var args,
18654             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18655             expected = [1, 0, lodashStable.map(array.slice(1), square)];
18656
18657         _(array).slice(1)[methodName](function(value, index, array) {
18658           args || (args = slice.call(arguments));
18659         }).value();
18660
18661         assert.deepEqual(args, [1, 0, array.slice(1)]);
18662
18663         args = undefined;
18664         _(array).slice(1).map(square)[methodName](function(value, index, array) {
18665           args || (args = slice.call(arguments));
18666         }).value();
18667
18668         assert.deepEqual(args, expected);
18669
18670         args = undefined;
18671         _(array).slice(1).map(square)[methodName](function(value, index) {
18672           args || (args = slice.call(arguments));
18673         }).value();
18674
18675         assert.deepEqual(args, expected);
18676
18677         args = undefined;
18678         _(array).slice(1).map(square)[methodName](function(value) {
18679           args || (args = slice.call(arguments));
18680         }).value();
18681
18682         assert.deepEqual(args, [1]);
18683
18684         args = undefined;
18685         _(array).slice(1).map(square)[methodName](function() {
18686           args || (args = slice.call(arguments));
18687         }).value();
18688
18689         assert.deepEqual(args, expected);
18690       }
18691       else {
18692         skipAssert(assert, 5);
18693       }
18694     });
18695   });
18696
18697   /*--------------------------------------------------------------------------*/
18698
18699   QUnit.module('lodash.remove');
18700
18701   (function() {
18702     QUnit.test('should modify the array and return removed elements', function(assert) {
18703       assert.expect(2);
18704
18705       var array = [1, 2, 3, 4];
18706
18707       var actual = _.remove(array, function(n) {
18708         return n % 2 == 0;
18709       });
18710
18711       assert.deepEqual(array, [1, 3]);
18712       assert.deepEqual(actual, [2, 4]);
18713     });
18714
18715     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
18716       assert.expect(1);
18717
18718       var argsList = [],
18719           array = [1, 2, 3],
18720           clone = array.slice();
18721
18722       _.remove(array, function(n, index) {
18723         var args = slice.call(arguments);
18724         args[2] = args[2].slice();
18725         argsList.push(args);
18726         return isEven(index);
18727       });
18728
18729       assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
18730     });
18731
18732     QUnit.test('should work with `_.matches` shorthands', function(assert) {
18733       assert.expect(1);
18734
18735       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
18736       _.remove(objects, { 'a': 1 });
18737       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
18738     });
18739
18740     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
18741       assert.expect(1);
18742
18743       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
18744       _.remove(objects, ['a', 1]);
18745       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
18746     });
18747
18748     QUnit.test('should work with `_.property` shorthands', function(assert) {
18749       assert.expect(1);
18750
18751       var objects = [{ 'a': 0 }, { 'a': 1 }];
18752       _.remove(objects, 'a');
18753       assert.deepEqual(objects, [{ 'a': 0 }]);
18754     });
18755
18756     QUnit.test('should preserve holes in arrays', function(assert) {
18757       assert.expect(2);
18758
18759       var array = [1, 2, 3, 4];
18760       delete array[1];
18761       delete array[3];
18762
18763       _.remove(array, function(n) {
18764         return n === 1;
18765       });
18766
18767       assert.notOk('0' in array);
18768       assert.notOk('2' in array);
18769     });
18770
18771     QUnit.test('should treat holes as `undefined`', function(assert) {
18772       assert.expect(1);
18773
18774       var array = [1, 2, 3];
18775       delete array[1];
18776
18777       _.remove(array, function(n) {
18778         return n == null;
18779       });
18780
18781       assert.deepEqual(array, [1, 3]);
18782     });
18783
18784     QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
18785       assert.expect(1);
18786
18787       var array = [1, 2, 3];
18788
18789       _.remove(array, function(n, index) {
18790         return isEven(index);
18791       });
18792
18793       assert.deepEqual(array, [2]);
18794     });
18795   }());
18796
18797   /*--------------------------------------------------------------------------*/
18798
18799   QUnit.module('lodash.repeat');
18800
18801   (function() {
18802     var string = 'abc';
18803
18804     QUnit.test('should repeat a string `n` times', function(assert) {
18805       assert.expect(2);
18806
18807       assert.strictEqual(_.repeat('*', 3), '***');
18808       assert.strictEqual(_.repeat(string, 2), 'abcabc');
18809     });
18810
18811     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
18812       assert.expect(1);
18813
18814       var expected = lodashStable.map(falsey, function(value) {
18815         return value === undefined ? string : '';
18816       });
18817
18818       var actual = lodashStable.map(falsey, function(n, index) {
18819         return index ? _.repeat(string, n) : _.repeat(string);
18820       });
18821
18822       assert.deepEqual(actual, expected);
18823     });
18824
18825     QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
18826       assert.expect(2);
18827
18828       assert.strictEqual(_.repeat(string, 0), '');
18829       assert.strictEqual(_.repeat(string, -2), '');
18830     });
18831
18832     QUnit.test('should coerce `n` to an integer', function(assert) {
18833       assert.expect(3);
18834
18835       assert.strictEqual(_.repeat(string, '2'), 'abcabc');
18836       assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
18837       assert.strictEqual(_.repeat('*', { 'valueOf': alwaysThree }), '***');
18838     });
18839
18840     QUnit.test('should coerce `string` to a string', function(assert) {
18841       assert.expect(2);
18842
18843       assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
18844       assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
18845     });
18846
18847     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18848       assert.expect(1);
18849
18850       var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
18851       assert.deepEqual(actual, ['a', 'b', 'c']);
18852     });
18853   }());
18854
18855   /*--------------------------------------------------------------------------*/
18856
18857   QUnit.module('lodash.replace');
18858
18859   (function() {
18860     QUnit.test('should replace the matched pattern', function(assert) {
18861       assert.expect(2);
18862
18863       var string = 'abcde';
18864       assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
18865       assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
18866     });
18867   }());
18868
18869   /*--------------------------------------------------------------------------*/
18870
18871   QUnit.module('lodash.result');
18872
18873   (function() {
18874     var object = { 'a': 1, 'b': alwaysB };
18875
18876     QUnit.test('should invoke function values', function(assert) {
18877       assert.expect(1);
18878
18879       assert.strictEqual(_.result(object, 'b'), 'b');
18880     });
18881
18882     QUnit.test('should invoke default function values', function(assert) {
18883       assert.expect(1);
18884
18885       var actual = _.result(object, 'c', object.b);
18886       assert.strictEqual(actual, 'b');
18887     });
18888
18889     QUnit.test('should invoke nested function values', function(assert) {
18890       assert.expect(2);
18891
18892       var value = { 'a': lodashStable.constant({ 'b': alwaysB }) };
18893
18894       lodashStable.each(['a.b', ['a', 'b']], function(path) {
18895         assert.strictEqual(_.result(value, path), 'b');
18896       });
18897     });
18898
18899     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
18900       assert.expect(2);
18901
18902       var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
18903
18904       lodashStable.each(['a.b', ['a', 'b']], function(path) {
18905         assert.strictEqual(_.result(value, path), 1);
18906       });
18907     });
18908   }());
18909
18910   /*--------------------------------------------------------------------------*/
18911
18912   QUnit.module('lodash.get and lodash.result');
18913
18914   lodashStable.each(['get', 'result'], function(methodName) {
18915     var func = _[methodName];
18916
18917     QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
18918       assert.expect(2);
18919
18920       var object = { 'a': 1 };
18921
18922       lodashStable.each(['a', ['a']], function(path) {
18923         assert.strictEqual(func(object, path), 1);
18924       });
18925     });
18926
18927     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
18928       assert.expect(1);
18929
18930       var object = { '-0': 'a', '0': 'b' },
18931           props = [-0, Object(-0), 0, Object(0)];
18932
18933       var actual = lodashStable.map(props, function(key) {
18934         return func(object, key);
18935       });
18936
18937       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
18938     });
18939
18940     QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
18941       assert.expect(1);
18942
18943       if (Symbol) {
18944         var object = {};
18945         object[symbol] = 1;
18946
18947         assert.strictEqual(func(object, symbol), 1);
18948       }
18949       else {
18950         skipAssert(assert);
18951       }
18952     });
18953
18954     QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
18955       assert.expect(2);
18956
18957       var object = { 'a': { 'b': 2 } };
18958
18959       lodashStable.each(['a.b', ['a', 'b']], function(path) {
18960         assert.strictEqual(func(object, path), 2);
18961       });
18962     });
18963
18964     QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
18965       assert.expect(2);
18966
18967       var object = { 'a.b': 1, 'a': { 'b': 2 } };
18968
18969       lodashStable.each(['a.b', ['a.b']], function(path) {
18970         assert.strictEqual(func(object, path), 1);
18971       });
18972     });
18973
18974     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
18975       assert.expect(1);
18976
18977       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
18978       assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
18979     });
18980
18981     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
18982       assert.expect(1);
18983
18984       var object = { 'a': 1 };
18985       assert.strictEqual(func(object, 'a[]'), 1);
18986     });
18987
18988     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
18989       assert.expect(4);
18990
18991       lodashStable.each([['', ''], [[], ['']]], function(pair) {
18992         assert.strictEqual(func({}, pair[0]), undefined);
18993         assert.strictEqual(func({ '': 3 }, pair[1]), 3);
18994       });
18995     });
18996
18997     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
18998       assert.expect(2);
18999
19000       var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
19001
19002       var paths = [
19003         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19004         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19005       ];
19006
19007       lodashStable.each(paths, function(path) {
19008         assert.strictEqual(func(object, path), 8);
19009       });
19010     });
19011
19012     QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
19013       assert.expect(4);
19014
19015       lodashStable.each(['constructor', ['constructor']], function(path) {
19016         assert.strictEqual(func(null, path), undefined);
19017         assert.strictEqual(func(undefined, path), undefined);
19018       });
19019     });
19020
19021     QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
19022       assert.expect(2);
19023
19024       var values = [null, undefined],
19025           expected = lodashStable.map(values, noop),
19026           paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
19027
19028       lodashStable.each(paths, function(path) {
19029         var actual = lodashStable.map(values, function(value) {
19030           return func(value, path);
19031         });
19032
19033         assert.deepEqual(actual, expected);
19034       });
19035     });
19036
19037     QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
19038       assert.expect(2);
19039
19040       var object = { 'a': [, null] };
19041
19042       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19043         assert.strictEqual(func(object, path), undefined);
19044       });
19045     });
19046
19047     QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
19048       assert.expect(2);
19049
19050       var object = { 'a': { 'b': null } };
19051
19052       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19053         assert.strictEqual(func(object, path), null);
19054       });
19055     });
19056
19057     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19058       assert.expect(2);
19059
19060       var paths = ['a.b', ['a', 'b']];
19061
19062       lodashStable.each(paths, function(path) {
19063         numberProto.a = { 'b': 2 };
19064         assert.strictEqual(func(0, path), 2);
19065         delete numberProto.a;
19066       });
19067     });
19068
19069     QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
19070       assert.expect(1);
19071
19072       var object = { 'a': {} },
19073           values = empties.concat(true, new Date, 1, /x/, 'a');
19074
19075       var expected = lodashStable.transform(values, function(result, value) {
19076         result.push(value, value, value, value);
19077       });
19078
19079       var actual = lodashStable.transform(values, function(result, value) {
19080         lodashStable.each(['a.b', ['a', 'b']], function(path) {
19081           result.push(
19082             func(object, path, value),
19083             func(null, path, value)
19084           );
19085         });
19086       });
19087
19088       assert.deepEqual(actual, expected);
19089     });
19090
19091     QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
19092       assert.expect(1);
19093
19094       assert.strictEqual(func({}, [], 'a'), 'a');
19095     });
19096   });
19097
19098   /*--------------------------------------------------------------------------*/
19099
19100   QUnit.module('lodash.rest');
19101
19102   (function() {
19103     function fn(a, b, c) {
19104       return slice.call(arguments);
19105     }
19106
19107     QUnit.test('should apply a rest parameter to `func`', function(assert) {
19108       assert.expect(1);
19109
19110       var rest = _.rest(fn);
19111       assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
19112     });
19113
19114     QUnit.test('should work with `start`', function(assert) {
19115       assert.expect(1);
19116
19117       var rest = _.rest(fn, 1);
19118       assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
19119     });
19120
19121     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
19122       assert.expect(1);
19123
19124       var values = [-1, NaN, 'a'],
19125           expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
19126
19127       var actual = lodashStable.map(values, function(value) {
19128         var rest = _.rest(fn, value);
19129         return rest(1, 2, 3, 4);
19130       });
19131
19132       assert.deepEqual(actual, expected);
19133     });
19134
19135     QUnit.test('should coerce `start` to an integer', function(assert) {
19136       assert.expect(1);
19137
19138       var rest = _.rest(fn, 1.6);
19139       assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
19140     });
19141
19142     QUnit.test('should use an empty array when `start` is not reached', function(assert) {
19143       assert.expect(1);
19144
19145       var rest = _.rest(fn);
19146       assert.deepEqual(rest(1), [1, undefined, []]);
19147     });
19148
19149     QUnit.test('should work on functions with more than three parameters', function(assert) {
19150       assert.expect(1);
19151
19152       var rest = _.rest(function(a, b, c, d) {
19153         return slice.call(arguments);
19154       });
19155
19156       assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
19157     });
19158   }());
19159
19160   /*--------------------------------------------------------------------------*/
19161
19162   QUnit.module('lodash.reverse');
19163
19164   (function() {
19165     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
19166         smallArray = [0, 1, 2, null];
19167
19168     QUnit.test('should reverse `array`', function(assert) {
19169       assert.expect(2);
19170
19171       var array = [1, 2, 3],
19172           actual = _.reverse(array);
19173
19174       assert.deepEqual(array, [3, 2, 1]);
19175       assert.strictEqual(actual, array);
19176     });
19177
19178     QUnit.test('should return the wrapped reversed `array`', function(assert) {
19179       assert.expect(6);
19180
19181       if (!isNpm) {
19182         lodashStable.times(2, function(index) {
19183           var array = (index ? largeArray : smallArray).slice(),
19184               clone = array.slice(),
19185               wrapped = _(array).reverse(),
19186               actual = wrapped.value();
19187
19188           assert.ok(wrapped instanceof _);
19189           assert.strictEqual(actual, array);
19190           assert.deepEqual(actual, clone.slice().reverse());
19191         });
19192       }
19193       else {
19194         skipAssert(assert, 6);
19195       }
19196     });
19197
19198     QUnit.test('should work in a lazy sequence', function(assert) {
19199       assert.expect(4);
19200
19201       if (!isNpm) {
19202         lodashStable.times(2, function(index) {
19203           var array = (index ? largeArray : smallArray).slice(),
19204               expected = array.slice(),
19205               actual = _(array).slice(1).reverse().value();
19206
19207           assert.deepEqual(actual, expected.slice(1).reverse());
19208           assert.deepEqual(array, expected);
19209         });
19210       }
19211       else {
19212         skipAssert(assert, 4);
19213       }
19214     });
19215
19216     QUnit.test('should be lazy when in a lazy sequence', function(assert) {
19217       assert.expect(3);
19218
19219       if (!isNpm) {
19220         var spy = {
19221           'toString': function() {
19222             throw new Error('spy was revealed');
19223           }
19224         };
19225
19226         var array = largeArray.concat(spy),
19227             expected = array.slice();
19228
19229         try {
19230           var wrapped = _(array).slice(1).map(String).reverse(),
19231               actual = wrapped.last();
19232         } catch (e) {}
19233
19234         assert.ok(wrapped instanceof _);
19235         assert.strictEqual(actual, '1');
19236         assert.deepEqual(array, expected);
19237       }
19238       else {
19239         skipAssert(assert, 3);
19240       }
19241     });
19242
19243     QUnit.test('should work in a hybrid sequence', function(assert) {
19244       assert.expect(8);
19245
19246       if (!isNpm) {
19247         lodashStable.times(2, function(index) {
19248           var clone = (index ? largeArray : smallArray).slice();
19249
19250           lodashStable.each(['map', 'filter'], function(methodName) {
19251             var array = clone.slice(),
19252                 expected = clone.slice(1, -1).reverse(),
19253                 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
19254
19255             assert.deepEqual(actual, expected);
19256
19257             array = clone.slice();
19258             actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
19259
19260             assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
19261           });
19262         });
19263       }
19264       else {
19265         skipAssert(assert, 8);
19266       }
19267     });
19268
19269     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
19270       assert.expect(6);
19271
19272       if (!isNpm) {
19273         lodashStable.times(2, function(index) {
19274           var array = (index ? largeArray : smallArray).slice(),
19275               expected = array.slice().reverse(),
19276               wrapped = _(array).chain().reverse().head();
19277
19278           assert.ok(wrapped instanceof _);
19279           assert.strictEqual(wrapped.value(), _.head(expected));
19280           assert.deepEqual(array, expected);
19281         });
19282       }
19283       else {
19284         skipAssert(assert, 6);
19285       }
19286     });
19287   }());
19288
19289   /*--------------------------------------------------------------------------*/
19290
19291   QUnit.module('round methods');
19292
19293   lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
19294     var func = _[methodName],
19295         isCeil = methodName == 'ceil',
19296         isFloor = methodName == 'floor';
19297
19298     QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
19299       assert.expect(1);
19300
19301       var actual = func(4.006);
19302       assert.strictEqual(actual, isCeil ? 5 : 4);
19303     });
19304
19305     QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
19306       assert.expect(1);
19307
19308       var actual = func(4.006, 0);
19309       assert.strictEqual(actual, isCeil ? 5 : 4);
19310     });
19311
19312     QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
19313       assert.expect(2);
19314
19315       var actual = func(4.016, 2);
19316       assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
19317
19318       actual = func(4.1, 2);
19319       assert.strictEqual(actual, 4.1);
19320     });
19321
19322     QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
19323       assert.expect(1);
19324
19325       var actual = func(4160, -2);
19326       assert.strictEqual(actual, isFloor ? 4100 : 4200);
19327     });
19328
19329     QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
19330       assert.expect(3);
19331
19332       var actual = func(4.006, NaN);
19333       assert.strictEqual(actual, isCeil ? 5 : 4);
19334
19335       var expected = isFloor ? 4.01 : 4.02;
19336
19337       actual = func(4.016, 2.6);
19338       assert.strictEqual(actual, expected);
19339
19340       actual = func(4.016, '+2');
19341       assert.strictEqual(actual, expected);
19342     });
19343
19344     QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
19345       assert.expect(3);
19346
19347       var actual = func(5e1, 2);
19348       assert.deepEqual(actual, 50);
19349
19350       actual = func('5e', 1);
19351       assert.deepEqual(actual, NaN);
19352
19353       actual = func('5e1e1', 1);
19354       assert.deepEqual(actual, NaN);
19355     });
19356
19357     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19358       assert.expect(1);
19359
19360       var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
19361           expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
19362
19363       var actual = lodashStable.map(values, function(args) {
19364         return 1 / func.apply(undefined, args);
19365       });
19366
19367       assert.deepEqual(actual, expected);
19368     });
19369   });
19370
19371   /*--------------------------------------------------------------------------*/
19372
19373   QUnit.module('lodash.runInContext');
19374
19375   (function() {
19376     QUnit.test('should not require a fully populated `context` object', function(assert) {
19377       assert.expect(1);
19378
19379       if (!isModularize) {
19380         var lodash = _.runInContext({
19381           'setTimeout': function(callback) {
19382             callback();
19383           }
19384         });
19385
19386         var pass = false;
19387         lodash.delay(function() { pass = true; }, 32);
19388         assert.ok(pass);
19389       }
19390       else {
19391         skipAssert(assert);
19392       }
19393     });
19394
19395     QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
19396       assert.expect(3);
19397
19398       if (!isModularize) {
19399         lodashStable.times(2, _.uniqueId);
19400
19401         var oldId = Number(_.uniqueId()),
19402             lodash = _.runInContext();
19403
19404         assert.ok(_.uniqueId() > oldId);
19405
19406         var id = lodash.uniqueId();
19407         assert.strictEqual(id, '1');
19408         assert.ok(id < oldId);
19409       }
19410       else {
19411         skipAssert(assert, 3);
19412       }
19413     });
19414   }());
19415
19416   /*--------------------------------------------------------------------------*/
19417
19418   QUnit.module('lodash.sample');
19419
19420   (function() {
19421     var array = [1, 2, 3];
19422
19423     QUnit.test('should return a random element', function(assert) {
19424       assert.expect(1);
19425
19426       var actual = _.sample(array);
19427       assert.ok(lodashStable.includes(array, actual));
19428     });
19429
19430     QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
19431       assert.expect(1);
19432
19433       var expected = lodashStable.map(empties, noop);
19434
19435       var actual = lodashStable.transform(empties, function(result, value) {
19436         try {
19437           result.push(_.sample(value));
19438         } catch (e) {}
19439       });
19440
19441       assert.deepEqual(actual, expected);
19442     });
19443
19444     QUnit.test('should sample an object', function(assert) {
19445       assert.expect(1);
19446
19447       var object = { 'a': 1, 'b': 2, 'c': 3 },
19448           actual = _.sample(object);
19449
19450       assert.ok(lodashStable.includes(array, actual));
19451     });
19452   }());
19453
19454   /*--------------------------------------------------------------------------*/
19455
19456   QUnit.module('lodash.sampleSize');
19457
19458   (function() {
19459     var array = [1, 2, 3];
19460
19461     QUnit.test('should return an array of random elements', function(assert) {
19462       assert.expect(2);
19463
19464       var actual = _.sampleSize(array, 2);
19465
19466       assert.strictEqual(actual.length, 2);
19467       assert.deepEqual(lodashStable.difference(actual, array), []);
19468     });
19469
19470     QUnit.test('should contain elements of the collection', function(assert) {
19471       assert.expect(1);
19472
19473       var actual = _.sampleSize(array, array.length).sort();
19474
19475       assert.deepEqual(actual, array);
19476     });
19477
19478     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
19479       assert.expect(1);
19480
19481       var expected = lodashStable.map(falsey, function(value) {
19482         return value === undefined ? ['a'] : [];
19483       });
19484
19485       var actual = lodashStable.map(falsey, function(size, index) {
19486         return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
19487       });
19488
19489       assert.deepEqual(actual, expected);
19490     });
19491
19492     QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
19493       assert.expect(3);
19494
19495       lodashStable.each([0, -1, -Infinity], function(n) {
19496         assert.deepEqual(_.sampleSize(array, n), []);
19497       });
19498     });
19499
19500     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
19501       assert.expect(4);
19502
19503       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19504         var actual = _.sampleSize(array, n).sort();
19505         assert.deepEqual(actual, array);
19506       });
19507     });
19508
19509     QUnit.test('should coerce `n` to an integer', function(assert) {
19510       assert.expect(1);
19511
19512       var actual = _.sampleSize(array, 1.6);
19513       assert.strictEqual(actual.length, 1);
19514     });
19515
19516     QUnit.test('should return an empty array for empty collections', function(assert) {
19517       assert.expect(1);
19518
19519       var expected = lodashStable.map(empties, alwaysEmptyArray);
19520
19521       var actual = lodashStable.transform(empties, function(result, value) {
19522         try {
19523           result.push(_.sampleSize(value, 1));
19524         } catch (e) {}
19525       });
19526
19527       assert.deepEqual(actual, expected);
19528     });
19529
19530     QUnit.test('should sample an object', function(assert) {
19531       assert.expect(2);
19532
19533       var object = { 'a': 1, 'b': 2, 'c': 3 },
19534           actual = _.sampleSize(object, 2);
19535
19536       assert.strictEqual(actual.length, 2);
19537       assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
19538     });
19539
19540     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19541       assert.expect(1);
19542
19543       var actual = lodashStable.map([['a']], _.sampleSize);
19544       assert.deepEqual(actual, [['a']]);
19545     });
19546   }());
19547
19548   /*--------------------------------------------------------------------------*/
19549
19550   QUnit.module('lodash.setWith');
19551
19552   (function() {
19553     QUnit.test('should work with a `customizer` callback', function(assert) {
19554       assert.expect(1);
19555
19556       var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
19557         return lodashStable.isObject(value) ? undefined : {};
19558       });
19559
19560       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
19561     });
19562
19563     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
19564       assert.expect(1);
19565
19566       var actual = _.setWith({}, 'a[0].b.c', 4, noop);
19567       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
19568     });
19569   }());
19570
19571   /*--------------------------------------------------------------------------*/
19572
19573   QUnit.module('set methods');
19574
19575   lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
19576     var func = _[methodName],
19577         isUpdate = methodName == 'update' || methodName == 'updateWith';
19578
19579     var oldValue = 1,
19580         value = 2,
19581         updater = isUpdate ? lodashStable.constant(value) : value;
19582
19583     QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
19584       assert.expect(4);
19585
19586       lodashStable.each(['a', ['a']], function(path) {
19587         var object = { 'a': oldValue },
19588             actual = func(object, path, updater);
19589
19590         assert.strictEqual(actual, object);
19591         assert.strictEqual(object.a, value);
19592       });
19593     });
19594
19595     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19596       assert.expect(1);
19597
19598       var props = [-0, Object(-0), 0, Object(0)],
19599           expected = lodashStable.map(props, lodashStable.constant(value));
19600
19601       var actual = lodashStable.map(props, function(key) {
19602         var object = { '-0': 'a', '0': 'b' };
19603         func(object, key, updater);
19604         return object[lodashStable.toString(key)];
19605       });
19606
19607       assert.deepEqual(actual, expected);
19608     });
19609
19610     QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
19611       assert.expect(2);
19612
19613       if (Symbol) {
19614         var object = {};
19615         object[symbol] = 1;
19616
19617         assert.strictEqual(_.unset(object, symbol), true);
19618         assert.notOk(symbol in object);
19619       }
19620       else {
19621         skipAssert(assert, 2);
19622       }
19623     });
19624
19625     QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
19626       assert.expect(4);
19627
19628       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19629         var object = { 'a': { 'b': oldValue } },
19630             actual = func(object, path, updater);
19631
19632         assert.strictEqual(actual, object);
19633         assert.strictEqual(object.a.b, value);
19634       });
19635     });
19636
19637     QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
19638       assert.expect(4);
19639
19640       lodashStable.each(['a.b', ['a.b']], function(path) {
19641         var object = { 'a.b': oldValue },
19642             actual = func(object, path, updater);
19643
19644         assert.strictEqual(actual, object);
19645         assert.deepEqual(object, { 'a.b': value });
19646       });
19647     });
19648
19649     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
19650       assert.expect(1);
19651
19652       var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
19653
19654       func(object, ['a', 'b', 'c'], updater);
19655       assert.strictEqual(object.a.b.c, value);
19656     });
19657
19658     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
19659       assert.expect(1);
19660
19661       var object = {};
19662
19663       func(object, 'a[]', updater);
19664       assert.deepEqual(object, { 'a': value });
19665     });
19666
19667     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
19668       assert.expect(4);
19669
19670       lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
19671         var object = {};
19672
19673         func(object, pair[0], updater);
19674         assert.deepEqual(object, index ? {} : { '': value });
19675
19676         func(object, pair[1], updater);
19677         assert.deepEqual(object, { '': value });
19678       });
19679     });
19680
19681     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
19682       assert.expect(2);
19683
19684       var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
19685
19686       var paths = [
19687         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19688         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19689       ];
19690
19691       lodashStable.each(paths, function(path) {
19692         func(object, path, updater);
19693         assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
19694         object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
19695       });
19696     });
19697
19698     QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
19699       assert.expect(6);
19700
19701       var object = {};
19702
19703       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19704         var actual = func(object, path, updater);
19705
19706         assert.strictEqual(actual, object);
19707         assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
19708         assert.notOk('0' in object.a);
19709
19710         delete object.a;
19711       });
19712     });
19713
19714     QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
19715       assert.expect(1);
19716
19717       var values = [null, undefined],
19718           expected = [[null, null], [undefined, undefined]];
19719
19720       var actual = lodashStable.map(values, function(value) {
19721         try {
19722           return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
19723         } catch (e) {
19724           return e.message;
19725         }
19726       });
19727
19728       assert.deepEqual(actual, expected);
19729     });
19730
19731     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19732       assert.expect(4);
19733
19734       var object = { 'a': '' },
19735           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
19736
19737       lodashStable.each(paths, function(path) {
19738         func(0, path, updater);
19739         assert.strictEqual(0..a, value);
19740         delete numberProto.a;
19741       });
19742
19743       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
19744         func(object, path, updater);
19745         assert.strictEqual(stringProto.replace.b, value);
19746         delete stringProto.replace.b;
19747       });
19748     });
19749
19750     QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
19751       'use strict';
19752
19753       assert.expect(2);
19754
19755       lodashStable.each(['a', 'a.a.a'], function(path) {
19756         numberProto.a = oldValue;
19757         try {
19758           func(0, path, updater);
19759           assert.strictEqual(0..a, oldValue);
19760         } catch (e) {
19761           assert.ok(false, e.message);
19762         }
19763       });
19764
19765       delete numberProto.a;
19766     });
19767
19768     QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
19769       assert.expect(1);
19770
19771       var object = {};
19772
19773       func(object, ['1a', '2b', '3c'], updater);
19774       assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
19775     });
19776
19777     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
19778       assert.expect(4);
19779
19780       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
19781         if (defineProperty) {
19782           var object = {},
19783               pass = true,
19784               updater = isUpdate ? lodashStable.constant(value) : value;
19785
19786           defineProperty(object, 'a', {
19787             'enumerable': true,
19788             'configurable': true,
19789             'get': lodashStable.constant(value),
19790             'set': function() { pass = false; }
19791           });
19792
19793           func(object, 'a', updater);
19794           assert.ok(pass);
19795         }
19796         else {
19797           skipAssert(assert);
19798         }
19799       });
19800     });
19801   });
19802
19803   /*--------------------------------------------------------------------------*/
19804
19805   QUnit.module('lodash.shuffle');
19806
19807   (function() {
19808     var array = [1, 2, 3],
19809         object = { 'a': 1, 'b': 2, 'c': 3 };
19810
19811     QUnit.test('should return a new array', function(assert) {
19812       assert.expect(1);
19813
19814       assert.notStrictEqual(_.shuffle(array), array);
19815     });
19816
19817     QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
19818       assert.expect(2);
19819
19820       assert.deepEqual(_.shuffle(array).sort(), array);
19821       assert.deepEqual(_.shuffle(object).sort(), array);
19822     });
19823
19824     QUnit.test('should shuffle small collections', function(assert) {
19825       assert.expect(1);
19826
19827       var actual = lodashStable.times(1000, function(assert) {
19828         return _.shuffle([1, 2]);
19829       });
19830
19831       assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
19832     });
19833
19834     QUnit.test('should treat number values for `collection` as empty', function(assert) {
19835       assert.expect(1);
19836
19837       assert.deepEqual(_.shuffle(1), []);
19838     });
19839   }());
19840
19841   /*--------------------------------------------------------------------------*/
19842
19843   QUnit.module('lodash.size');
19844
19845   (function() {
19846     var args = arguments,
19847         array = [1, 2, 3];
19848
19849     QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
19850       assert.expect(1);
19851
19852       assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
19853     });
19854
19855     QUnit.test('should return the length of an array', function(assert) {
19856       assert.expect(1);
19857
19858       assert.strictEqual(_.size(array), 3);
19859     });
19860
19861     QUnit.test('should accept a falsey `object` argument', function(assert) {
19862       assert.expect(1);
19863
19864       var expected = lodashStable.map(falsey, alwaysZero);
19865
19866       var actual = lodashStable.map(falsey, function(object, index) {
19867         try {
19868           return index ? _.size(object) : _.size();
19869         } catch (e) {}
19870       });
19871
19872       assert.deepEqual(actual, expected);
19873     });
19874
19875     QUnit.test('should work with `arguments` objects', function(assert) {
19876       assert.expect(1);
19877
19878       assert.strictEqual(_.size(args), 3);
19879     });
19880
19881     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
19882       assert.expect(1);
19883
19884       function Foo(elements) {
19885         push.apply(this, elements);
19886       }
19887       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
19888
19889       assert.strictEqual(_.size(new Foo(array)), 3);
19890     });
19891
19892     QUnit.test('should work with maps', function(assert) {
19893       assert.expect(2);
19894
19895       if (Map) {
19896         lodashStable.each([new Map, realm.map], function(map) {
19897           map.set('a', 1);
19898           map.set('b', 2);
19899           assert.strictEqual(_.size(map), 2);
19900           map.clear();
19901         });
19902       }
19903       else {
19904         skipAssert(assert, 2);
19905       }
19906     });
19907
19908     QUnit.test('should work with sets', function(assert) {
19909       assert.expect(2);
19910
19911       if (Set) {
19912         lodashStable.each([new Set, realm.set], function(set) {
19913           set.add(1);
19914           set.add(2);
19915           assert.strictEqual(_.size(set), 2);
19916           set.clear();
19917         });
19918       }
19919       else {
19920         skipAssert(assert, 2);
19921       }
19922     });
19923
19924     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
19925       assert.expect(1);
19926
19927       assert.strictEqual(_.size({ 'length': -1 }), 1);
19928     });
19929
19930     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
19931       assert.expect(1);
19932
19933       assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
19934     });
19935
19936     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
19937       assert.expect(1);
19938
19939       assert.strictEqual(_.size({ 'length': '0' }), 1);
19940     });
19941   }(1, 2, 3));
19942
19943   /*--------------------------------------------------------------------------*/
19944
19945   QUnit.module('lodash.slice');
19946
19947   (function() {
19948     var array = [1, 2, 3];
19949
19950     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
19951       assert.expect(2);
19952
19953       var actual = _.slice(array);
19954       assert.deepEqual(actual, array);
19955       assert.notStrictEqual(actual, array);
19956     });
19957
19958     QUnit.test('should work with a positive `start`', function(assert) {
19959       assert.expect(2);
19960
19961       assert.deepEqual(_.slice(array, 1), [2, 3]);
19962       assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
19963     });
19964
19965     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
19966       assert.expect(4);
19967
19968       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
19969         assert.deepEqual(_.slice(array, start), []);
19970       });
19971     });
19972
19973     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
19974       assert.expect(1);
19975
19976       var expected = lodashStable.map(falsey, lodashStable.constant(array));
19977
19978       var actual = lodashStable.map(falsey, function(start) {
19979         return _.slice(array, start);
19980       });
19981
19982       assert.deepEqual(actual, expected);
19983     });
19984
19985     QUnit.test('should work with a negative `start`', function(assert) {
19986       assert.expect(1);
19987
19988       assert.deepEqual(_.slice(array, -1), [3]);
19989     });
19990
19991     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
19992       assert.expect(3);
19993
19994       lodashStable.each([-3, -4, -Infinity], function(start) {
19995         assert.deepEqual(_.slice(array, start), array);
19996       });
19997     });
19998
19999     QUnit.test('should work with `start` >= `end`', function(assert) {
20000       assert.expect(2);
20001
20002       lodashStable.each([2, 3], function(start) {
20003         assert.deepEqual(_.slice(array, start, 2), []);
20004       });
20005     });
20006
20007     QUnit.test('should work with a positive `end`', function(assert) {
20008       assert.expect(1);
20009
20010       assert.deepEqual(_.slice(array, 0, 1), [1]);
20011     });
20012
20013     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
20014       assert.expect(4);
20015
20016       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
20017         assert.deepEqual(_.slice(array, 0, end), array);
20018       });
20019     });
20020
20021     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
20022       assert.expect(1);
20023
20024       var expected = lodashStable.map(falsey, function(value) {
20025         return value === undefined ? array : [];
20026       });
20027
20028       var actual = lodashStable.map(falsey, function(end, index) {
20029         return index ? _.slice(array, 0, end) : _.slice(array, 0);
20030       });
20031
20032       assert.deepEqual(actual, expected);
20033     });
20034
20035     QUnit.test('should work with a negative `end`', function(assert) {
20036       assert.expect(1);
20037
20038       assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
20039     });
20040
20041     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
20042       assert.expect(3);
20043
20044       lodashStable.each([-3, -4, -Infinity], function(end) {
20045         assert.deepEqual(_.slice(array, 0, end), []);
20046       });
20047     });
20048
20049     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
20050       assert.expect(1);
20051
20052       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
20053
20054       var actual = lodashStable.map(positions, function(pos) {
20055         return _.slice.apply(_, [array].concat(pos));
20056       });
20057
20058       assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
20059     });
20060
20061     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20062       assert.expect(2);
20063
20064       var array = [[1], [2, 3]],
20065           actual = lodashStable.map(array, _.slice);
20066
20067       assert.deepEqual(actual, array);
20068       assert.notStrictEqual(actual, array);
20069     });
20070
20071     QUnit.test('should work in a lazy sequence', function(assert) {
20072       assert.expect(38);
20073
20074       if (!isNpm) {
20075         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
20076             length = array.length,
20077             wrapped = _(array);
20078
20079         lodashStable.each(['map', 'filter'], function(methodName) {
20080           assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
20081           assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
20082           assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
20083           assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
20084
20085           assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
20086           assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
20087           assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
20088           assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
20089
20090           assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
20091           assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
20092           assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
20093
20094           assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
20095           assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
20096
20097           assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
20098           assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
20099           assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
20100           assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
20101           assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
20102           assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
20103         });
20104       }
20105       else {
20106         skipAssert(assert, 38);
20107       }
20108     });
20109   }());
20110
20111   /*--------------------------------------------------------------------------*/
20112
20113   QUnit.module('lodash.some');
20114
20115   (function() {
20116     QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
20117       assert.expect(2);
20118
20119       assert.strictEqual(_.some([false, 1, ''], identity), true);
20120       assert.strictEqual(_.some([null, 'a', 0], identity), true);
20121     });
20122
20123     QUnit.test('should return `false` for empty collections', function(assert) {
20124       assert.expect(1);
20125
20126       var expected = lodashStable.map(empties, alwaysFalse);
20127
20128       var actual = lodashStable.map(empties, function(value) {
20129         try {
20130           return _.some(value, identity);
20131         } catch (e) {}
20132       });
20133
20134       assert.deepEqual(actual, expected);
20135     });
20136
20137     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
20138       assert.expect(2);
20139
20140       var count = 0;
20141
20142       assert.strictEqual(_.some([null, true, null], function(value) {
20143         count++;
20144         return value;
20145       }), true);
20146
20147       assert.strictEqual(count, 2);
20148     });
20149
20150     QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
20151       assert.expect(2);
20152
20153       assert.strictEqual(_.some([false, false, false], identity), false);
20154       assert.strictEqual(_.some([null, 0, ''], identity), false);
20155     });
20156
20157     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
20158       assert.expect(2);
20159
20160       var values = [, null, undefined],
20161           expected = lodashStable.map(values, alwaysFalse);
20162
20163       var actual = lodashStable.map(values, function(value, index) {
20164         var array = [0, 0];
20165         return index ? _.some(array, value) : _.some(array);
20166       });
20167
20168       assert.deepEqual(actual, expected);
20169
20170       expected = lodashStable.map(values, alwaysTrue);
20171       actual = lodashStable.map(values, function(value, index) {
20172         var array = [0, 1];
20173         return index ? _.some(array, value) : _.some(array);
20174       });
20175
20176       assert.deepEqual(actual, expected);
20177     });
20178
20179     QUnit.test('should work with `_.property` shorthands', function(assert) {
20180       assert.expect(2);
20181
20182       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
20183       assert.strictEqual(_.some(objects, 'a'), false);
20184       assert.strictEqual(_.some(objects, 'b'), true);
20185     });
20186
20187     QUnit.test('should work with `_.matches` shorthands', function(assert) {
20188       assert.expect(2);
20189
20190       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
20191       assert.strictEqual(_.some(objects, { 'a': 0 }), true);
20192       assert.strictEqual(_.some(objects, { 'b': 2 }), false);
20193     });
20194
20195     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20196       assert.expect(1);
20197
20198       var actual = lodashStable.map([[1]], _.some);
20199       assert.deepEqual(actual, [true]);
20200     });
20201   }());
20202
20203   /*--------------------------------------------------------------------------*/
20204
20205   QUnit.module('lodash.sortBy');
20206
20207   (function() {
20208     var objects = [
20209       { 'a': 'x', 'b': 3 },
20210       { 'a': 'y', 'b': 4 },
20211       { 'a': 'x', 'b': 1 },
20212       { 'a': 'y', 'b': 2 }
20213     ];
20214
20215     QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
20216       assert.expect(1);
20217
20218       var actual = lodashStable.map(_.sortBy(objects, function(object) {
20219         return object.b;
20220       }), 'b');
20221
20222       assert.deepEqual(actual, [1, 2, 3, 4]);
20223     });
20224
20225     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20226       assert.expect(1);
20227
20228       var array = [3, 2, 1],
20229           values = [, null, undefined],
20230           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
20231
20232       var actual = lodashStable.map(values, function(value, index) {
20233         return index ? _.sortBy(array, value) : _.sortBy(array);
20234       });
20235
20236       assert.deepEqual(actual, expected);
20237     });
20238
20239     QUnit.test('should work with `_.property` shorthands', function(assert) {
20240       assert.expect(1);
20241
20242       var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
20243       assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
20244     });
20245
20246     QUnit.test('should work with an object for `collection`', function(assert) {
20247       assert.expect(1);
20248
20249       var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
20250       assert.deepEqual(actual, [3, 1, 2]);
20251     });
20252
20253     QUnit.test('should move symbol, `null`, `undefined`, and `NaN` values to the end', function(assert) {
20254       assert.expect(2);
20255
20256       var symbol1 = Symbol ? Symbol('a') : null,
20257           symbol2 = Symbol ? Symbol('b') : null,
20258           array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
20259           expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20260
20261       assert.deepEqual(_.sortBy(array), expected);
20262
20263       array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
20264       expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20265
20266       assert.deepEqual(_.sortBy(array), expected);
20267     });
20268
20269     QUnit.test('should treat number values for `collection` as empty', function(assert) {
20270       assert.expect(1);
20271
20272       assert.deepEqual(_.sortBy(1), []);
20273     });
20274
20275     QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
20276       assert.expect(1);
20277
20278       var actual = _.sortBy(objects, function(object) {
20279         var result = [object.a, object.b];
20280         result.toString = function() { return String(this[0]); };
20281         return result;
20282       });
20283
20284       assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
20285     });
20286
20287     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20288       assert.expect(1);
20289
20290       var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
20291       assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
20292     });
20293   }());
20294
20295   /*--------------------------------------------------------------------------*/
20296
20297   QUnit.module('sortBy methods');
20298
20299   lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
20300     var func = _[methodName];
20301
20302     function Pair(a, b, c) {
20303       this.a = a;
20304       this.b = b;
20305       this.c = c;
20306     }
20307
20308     var objects = [
20309       { 'a': 'x', 'b': 3 },
20310       { 'a': 'y', 'b': 4 },
20311       { 'a': 'x', 'b': 1 },
20312       { 'a': 'y', 'b': 2 }
20313     ];
20314
20315     var stableArray = [
20316       new Pair(1, 1, 1), new Pair(1, 2, 1),
20317       new Pair(1, 1, 1), new Pair(1, 2, 1),
20318       new Pair(1, 3, 1), new Pair(1, 4, 1),
20319       new Pair(1, 5, 1), new Pair(1, 6, 1),
20320       new Pair(2, 1, 2), new Pair(2, 2, 2),
20321       new Pair(2, 3, 2), new Pair(2, 4, 2),
20322       new Pair(2, 5, 2), new Pair(2, 6, 2),
20323       new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
20324       new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
20325       new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
20326     ];
20327
20328     var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
20329
20330     QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
20331       assert.expect(1);
20332
20333       var actual = func(objects, ['a', 'b']);
20334       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20335     });
20336
20337     QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
20338       assert.expect(1);
20339
20340       var actual = func(objects, ['a', function(object) { return object.b; }]);
20341       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20342     });
20343
20344     QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
20345       assert.expect(2);
20346
20347       lodashStable.each([stableArray, stableObject], function(value, index) {
20348         var actual = func(value, ['a', 'c']);
20349         assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
20350       });
20351     });
20352
20353     QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
20354       assert.expect(1);
20355
20356       try {
20357         var actual = func(objects.concat(null, undefined), ['a', 'b']);
20358       } catch (e) {}
20359
20360       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
20361     });
20362
20363     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
20364       assert.expect(3);
20365
20366       var objects = [
20367         { 'a': 'x', '0': 3 },
20368         { 'a': 'y', '0': 4 },
20369         { 'a': 'x', '0': 1 },
20370         { 'a': 'y', '0': 2 }
20371       ];
20372
20373       var funcs = [func, lodashStable.partialRight(func, 'bogus')];
20374
20375       lodashStable.each(['a', 0, [0]], function(props, index) {
20376         var expected = lodashStable.map(funcs, lodashStable.constant(
20377           index
20378             ? [objects[2], objects[3], objects[0], objects[1]]
20379             : [objects[0], objects[2], objects[1], objects[3]]
20380         ));
20381
20382         var actual = lodashStable.map(funcs, function(func) {
20383           return lodashStable.reduce([props], func, objects);
20384         });
20385
20386         assert.deepEqual(actual, expected);
20387       });
20388     });
20389   });
20390
20391   /*--------------------------------------------------------------------------*/
20392
20393   QUnit.module('sortedIndex methods');
20394
20395   lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
20396     var func = _[methodName],
20397         isSortedIndex = methodName == 'sortedIndex';
20398
20399     QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
20400       assert.expect(1);
20401
20402       var array = [30, 50],
20403           values = [30, 40, 50],
20404           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20405
20406       var actual = lodashStable.map(values, function(value) {
20407         return func(array, value);
20408       });
20409
20410       assert.deepEqual(actual, expected);
20411     });
20412
20413     QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
20414       assert.expect(1);
20415
20416       var array = ['a', 'c'],
20417           values = ['a', 'b', 'c'],
20418           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20419
20420       var actual = lodashStable.map(values, function(value) {
20421         return func(array, value);
20422       });
20423
20424       assert.deepEqual(actual, expected);
20425     });
20426
20427     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
20428       assert.expect(1);
20429
20430       var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
20431
20432       var actual = lodashStable.map(falsey, function(array) {
20433         return [func(array, 1), func(array, undefined), func(array, NaN)];
20434       });
20435
20436       assert.deepEqual(actual, expected);
20437     });
20438
20439     QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
20440       assert.expect(12);
20441
20442       var symbol1 = Symbol ? Symbol('a') : null,
20443           symbol2 = Symbol ? Symbol('b') : null,
20444           expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
20445
20446       lodashStable.each([
20447         [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
20448         ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
20449       ], function(array) {
20450         assert.deepEqual(_.sortBy(array), expected);
20451         assert.strictEqual(func(expected, 3), 2);
20452         assert.strictEqual(func(expected, symbol1), (isSortedIndex ? 3 : (Symbol ? 5 : 6)));
20453         assert.strictEqual(func(expected, null), (isSortedIndex ? (Symbol ? 5 : 3) : 6));
20454         assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
20455         assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
20456       });
20457     });
20458   });
20459
20460   /*--------------------------------------------------------------------------*/
20461
20462   QUnit.module('sortedIndexBy methods');
20463
20464   lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
20465     var func = _[methodName],
20466         isSortedIndexBy = methodName == 'sortedIndexBy';
20467
20468     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
20469       assert.expect(1);
20470
20471       var args;
20472
20473       func([30, 50], 40, function(assert) {
20474         args || (args = slice.call(arguments));
20475       });
20476
20477       assert.deepEqual(args, [40]);
20478     });
20479
20480     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
20481       assert.expect(1);
20482
20483       var objects = [{ 'x': 30 }, { 'x': 50 }],
20484           actual = func(objects, { 'x': 40 }, 'x');
20485
20486       assert.strictEqual(actual, 1);
20487     });
20488
20489     QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
20490       assert.expect(12);
20491
20492       lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
20493         var array = [],
20494             values = [MAX_ARRAY_LENGTH, NaN, undefined];
20495
20496         array.length = length;
20497
20498         lodashStable.each(values, function(value) {
20499           var steps = 0;
20500
20501           var actual = func(array, value, function(value) {
20502             steps++;
20503             return value;
20504           });
20505
20506           var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
20507             ? 0
20508             : Math.min(length, MAX_ARRAY_INDEX);
20509
20510           // Avoid false fails in older Firefox.
20511           if (array.length == length) {
20512             assert.ok(steps == 32 || steps == 33);
20513             assert.strictEqual(actual, expected);
20514           }
20515           else {
20516             skipAssert(assert, 2);
20517           }
20518         });
20519       });
20520     });
20521   });
20522
20523   /*--------------------------------------------------------------------------*/
20524
20525   QUnit.module('sortedIndexOf methods');
20526
20527   lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
20528     var func = _[methodName],
20529         isSortedIndexOf = methodName == 'sortedIndexOf';
20530
20531     QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
20532       assert.expect(1);
20533
20534       var sorted = [4, 4, 5, 5, 6, 6];
20535       assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
20536     });
20537   });
20538
20539   /*--------------------------------------------------------------------------*/
20540
20541   QUnit.module('lodash.sortedUniq');
20542
20543   (function() {
20544     QUnit.test('should return unique values of a sorted array', function(assert) {
20545       assert.expect(3);
20546
20547       var expected = [1, 2, 3];
20548
20549       lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
20550         assert.deepEqual(_.sortedUniq(array), expected);
20551       });
20552     });
20553   }());
20554
20555   /*--------------------------------------------------------------------------*/
20556
20557   QUnit.module('lodash.split');
20558
20559   (function() {
20560     QUnit.test('should split a string by `separator`', function(assert) {
20561       assert.expect(3);
20562
20563       var string = 'abcde';
20564       assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
20565       assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
20566       assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
20567     });
20568
20569     QUnit.test('should return an array containing an empty string for empty values', function(assert) {
20570       assert.expect(1);
20571
20572       var values = [, null, undefined, ''],
20573           expected = lodashStable.map(values, lodashStable.constant(['']));
20574
20575       var actual = lodashStable.map(values, function(value, index) {
20576         return index ? _.split(value) : _.split();
20577       });
20578
20579       assert.deepEqual(actual, expected);
20580     });
20581
20582     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20583       assert.expect(1);
20584
20585       var strings = ['abc', 'def', 'ghi'],
20586           actual = lodashStable.map(strings, _.split);
20587
20588       assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
20589     });
20590
20591     QUnit.test('should allow mixed string and array prototype methods', function(assert) {
20592       assert.expect(1);
20593
20594       if (!isNpm) {
20595         var wrapped = _('abc');
20596         assert.strictEqual(wrapped.split('b').join(','), 'a,c');
20597       }
20598       else {
20599         skipAssert(assert);
20600       }
20601     });
20602   }());
20603
20604   /*--------------------------------------------------------------------------*/
20605
20606   QUnit.module('lodash.spread');
20607
20608   (function() {
20609     function fn(a, b, c) {
20610       return slice.call(arguments);
20611     }
20612
20613     QUnit.test('should spread arguments to `func`', function(assert) {
20614       assert.expect(1);
20615
20616       var spread = _.spread(fn);
20617       assert.deepEqual(spread([4, 2]), [4, 2]);
20618     });
20619
20620     QUnit.test('should accept a falsey `array` argument', function(assert) {
20621       assert.expect(1);
20622
20623       var spread = _.spread(alwaysTrue),
20624           expected = lodashStable.map(falsey, alwaysTrue);
20625
20626       var actual = lodashStable.map(falsey, function(array, index) {
20627         try {
20628           return index ? spread(array) : spread();
20629         } catch (e) {}
20630       });
20631
20632       assert.deepEqual(actual, expected);
20633     });
20634
20635     QUnit.test('should provide the correct `func` arguments', function(assert) {
20636       assert.expect(1);
20637
20638       var args;
20639
20640       var spread = _.spread(function() {
20641         args = slice.call(arguments);
20642       });
20643
20644       spread([4, 2], 'ignored');
20645       assert.deepEqual(args, [4, 2]);
20646     });
20647
20648     QUnit.test('should work with `start`', function(assert) {
20649       assert.expect(1);
20650
20651       var spread = _.spread(fn, 1);
20652       assert.deepEqual(spread(1, [2, 3, 4]), [1, 2, 3, 4]);
20653     });
20654
20655     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
20656       assert.expect(1);
20657
20658       var values = [-1, NaN, 'a'],
20659           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
20660
20661       var actual = lodashStable.map(values, function(value) {
20662         var spread = _.spread(fn, value);
20663         return spread([1, 2, 3, 4]);
20664       });
20665
20666       assert.deepEqual(actual, expected);
20667     });
20668
20669     QUnit.test('should coerce `start` to an integer', function(assert) {
20670       assert.expect(1);
20671
20672       var spread = _.spread(fn, 1.6);
20673       assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
20674     });
20675   }());
20676
20677   /*--------------------------------------------------------------------------*/
20678
20679   QUnit.module('lodash.startCase');
20680
20681   (function() {
20682     QUnit.test('should uppercase only the first character of each word', function(assert) {
20683       assert.expect(3);
20684
20685       assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
20686       assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
20687       assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
20688     });
20689   }());
20690
20691   /*--------------------------------------------------------------------------*/
20692
20693   QUnit.module('lodash.startsWith');
20694
20695   (function() {
20696     var string = 'abc';
20697
20698     QUnit.test('should return `true` if a string starts with `target`', function(assert) {
20699       assert.expect(1);
20700
20701       assert.strictEqual(_.startsWith(string, 'a'), true);
20702     });
20703
20704     QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
20705       assert.expect(1);
20706
20707       assert.strictEqual(_.startsWith(string, 'b'), false);
20708     });
20709
20710     QUnit.test('should work with a `position` argument', function(assert) {
20711       assert.expect(1);
20712
20713       assert.strictEqual(_.startsWith(string, 'b', 1), true);
20714     });
20715
20716     QUnit.test('should work with `position` >= `string.length`', function(assert) {
20717       assert.expect(4);
20718
20719       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
20720         assert.strictEqual(_.startsWith(string, 'a', position), false);
20721       });
20722     });
20723
20724     QUnit.test('should treat falsey `position` values as `0`', function(assert) {
20725       assert.expect(1);
20726
20727       var expected = lodashStable.map(falsey, alwaysTrue);
20728
20729       var actual = lodashStable.map(falsey, function(position) {
20730         return _.startsWith(string, 'a', position);
20731       });
20732
20733       assert.deepEqual(actual, expected);
20734     });
20735
20736     QUnit.test('should treat a negative `position` as `0`', function(assert) {
20737       assert.expect(6);
20738
20739       lodashStable.each([-1, -3, -Infinity], function(position) {
20740         assert.strictEqual(_.startsWith(string, 'a', position), true);
20741         assert.strictEqual(_.startsWith(string, 'b', position), false);
20742       });
20743     });
20744
20745     QUnit.test('should coerce `position` to an integer', function(assert) {
20746       assert.expect(1);
20747
20748       assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
20749     });
20750
20751     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
20752       assert.expect(1);
20753
20754       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
20755         return _.startsWith(string, '', position, true);
20756       }));
20757     });
20758   }());
20759
20760   /*--------------------------------------------------------------------------*/
20761
20762   QUnit.module('lodash.startsWith and lodash.endsWith');
20763
20764   lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
20765     var func = _[methodName],
20766         isStartsWith = methodName == 'startsWith';
20767
20768     var string = 'abc',
20769         chr = isStartsWith ? 'a' : 'c';
20770
20771     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
20772       assert.expect(2);
20773
20774       assert.strictEqual(func(Object(string), chr), true);
20775       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
20776     });
20777
20778     QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
20779       assert.expect(2);
20780
20781       assert.strictEqual(func(string, Object(chr)), true);
20782       assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
20783     });
20784
20785     QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
20786       assert.expect(2);
20787
20788       var position = isStartsWith ? 1 : 2;
20789       assert.strictEqual(func(string, 'b', Object(position)), true);
20790       assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
20791     });
20792   });
20793
20794   /*--------------------------------------------------------------------------*/
20795
20796   QUnit.module('lodash.subtract');
20797
20798   (function() {
20799     QUnit.test('should subtract two numbers', function(assert) {
20800       assert.expect(3);
20801
20802       assert.strictEqual(_.subtract(6, 4), 2);
20803       assert.strictEqual(_.subtract(-6, 4), -10);
20804       assert.strictEqual(_.subtract(-6, -4), -2);
20805     });
20806
20807     QUnit.test('should coerce arguments to numbers', function(assert) {
20808       assert.expect(2);
20809
20810       assert.strictEqual(_.subtract('6', '4'), 2);
20811       assert.deepEqual(_.subtract('x', 'y'), NaN);
20812     });
20813   }());
20814
20815   /*--------------------------------------------------------------------------*/
20816
20817   QUnit.module('math operator methods');
20818
20819   lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
20820     var func = _[methodName];
20821
20822     QUnit.test('`_.' + methodName + '` should return `0` when no arguments are given', function(assert) {
20823       assert.expect(1);
20824
20825       assert.strictEqual(func(), 0);
20826     });
20827
20828     QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
20829       assert.expect(3);
20830
20831       assert.strictEqual(func(6), 6);
20832       assert.strictEqual(func(6, undefined), 6);
20833       assert.strictEqual(func(undefined, 4), 4);
20834     });
20835
20836     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
20837       assert.expect(2);
20838
20839       var values = [0, '0', -0, '-0'],
20840           expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
20841
20842       lodashStable.times(2, function(index) {
20843         var actual = lodashStable.map(values, function(value) {
20844           var result = index ? func(undefined, value) : func(value);
20845           return [result, 1 / result];
20846         });
20847
20848         assert.deepEqual(actual, expected);
20849       });
20850     });
20851
20852     QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
20853       assert.expect(2);
20854
20855       assert.deepEqual(func(0, {}), NaN);
20856       assert.deepEqual(func({}, 0), NaN);
20857     });
20858
20859     QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
20860       assert.expect(2);
20861
20862       if (Symbol) {
20863         assert.deepEqual(func(0, symbol), NaN);
20864         assert.deepEqual(func(symbol, 0), NaN);
20865       }
20866       else {
20867         skipAssert(assert, 2);
20868       }
20869     });
20870
20871     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
20872       assert.expect(1);
20873
20874       if (!isNpm) {
20875         var actual = _(1)[methodName](2);
20876         assert.notOk(actual instanceof _);
20877       }
20878       else {
20879         skipAssert(assert);
20880       }
20881     });
20882
20883     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
20884       assert.expect(1);
20885
20886       if (!isNpm) {
20887         var actual = _(1).chain()[methodName](2);
20888         assert.ok(actual instanceof _);
20889       }
20890       else {
20891         skipAssert(assert);
20892       }
20893     });
20894   });
20895
20896   /*--------------------------------------------------------------------------*/
20897
20898   QUnit.module('lodash.sumBy');
20899
20900   (function() {
20901     var array = [6, 4, 2],
20902         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
20903
20904     QUnit.test('should work with an `iteratee` argument', function(assert) {
20905       assert.expect(1);
20906
20907       var actual = _.sumBy(objects, function(object) {
20908         return object.a;
20909       });
20910
20911       assert.deepEqual(actual, 6);
20912     });
20913
20914     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
20915       assert.expect(1);
20916
20917       var args;
20918
20919       _.sumBy(array, function() {
20920         args || (args = slice.call(arguments));
20921       });
20922
20923       assert.deepEqual(args, [6]);
20924     });
20925
20926     QUnit.test('should work with `_.property` shorthands', function(assert) {
20927       assert.expect(2);
20928
20929       var arrays = [[2], [3], [1]];
20930       assert.strictEqual(_.sumBy(arrays, 0), 6);
20931       assert.strictEqual(_.sumBy(objects, 'a'), 6);
20932     });
20933   }());
20934
20935   /*--------------------------------------------------------------------------*/
20936
20937   QUnit.module('sum methods');
20938
20939   lodashStable.each(['sum', 'sumBy'], function(methodName) {
20940     var array = [6, 4, 2],
20941         func = _[methodName];
20942
20943     QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
20944       assert.expect(1);
20945
20946       assert.strictEqual(func(array), 12);
20947     });
20948
20949     QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
20950       assert.expect(1);
20951
20952       var expected = lodashStable.map(empties, alwaysZero);
20953
20954       var actual = lodashStable.map(empties, function(value) {
20955         return func(value);
20956       });
20957
20958       assert.deepEqual(actual, expected);
20959     });
20960
20961     QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
20962       assert.expect(1);
20963
20964       assert.strictEqual(func([1, undefined]), 1);
20965     });
20966
20967     QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
20968       assert.expect(1);
20969
20970       assert.deepEqual(func([1, NaN]), NaN);
20971     });
20972
20973     QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
20974       assert.expect(1);
20975
20976       assert.strictEqual(func(['1', '2']), '12');
20977     });
20978   });
20979
20980   /*--------------------------------------------------------------------------*/
20981
20982   QUnit.module('lodash.tail');
20983
20984   (function() {
20985     var array = [1, 2, 3];
20986
20987     QUnit.test('should accept a falsey `array` argument', function(assert) {
20988       assert.expect(1);
20989
20990       var expected = lodashStable.map(falsey, alwaysEmptyArray);
20991
20992       var actual = lodashStable.map(falsey, function(array, index) {
20993         try {
20994           return index ? _.tail(array) : _.tail();
20995         } catch (e) {}
20996       });
20997
20998       assert.deepEqual(actual, expected);
20999     });
21000
21001     QUnit.test('should exclude the first element', function(assert) {
21002       assert.expect(1);
21003
21004       assert.deepEqual(_.tail(array), [2, 3]);
21005     });
21006
21007     QUnit.test('should return an empty when querying empty arrays', function(assert) {
21008       assert.expect(1);
21009
21010       assert.deepEqual(_.tail([]), []);
21011     });
21012
21013     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21014       assert.expect(1);
21015
21016       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21017           actual = lodashStable.map(array, _.tail);
21018
21019       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
21020     });
21021
21022     QUnit.test('should work in a lazy sequence', function(assert) {
21023       assert.expect(4);
21024
21025       if (!isNpm) {
21026         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21027             values = [];
21028
21029         var actual = _(array).tail().filter(function(value) {
21030           values.push(value);
21031           return false;
21032         })
21033         .value();
21034
21035         assert.deepEqual(actual, []);
21036         assert.deepEqual(values, array.slice(1));
21037
21038         values = [];
21039
21040         actual = _(array).filter(function(value) {
21041           values.push(value);
21042           return isEven(value);
21043         })
21044         .tail()
21045         .value();
21046
21047         assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
21048         assert.deepEqual(values, array);
21049       }
21050       else {
21051         skipAssert(assert, 4);
21052       }
21053     });
21054
21055     QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
21056       assert.expect(4);
21057
21058       if (!isNpm) {
21059         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21060             iteratee = function() { pass = false; },
21061             pass = true,
21062             actual = _(array).slice(0, 1).tail().map(iteratee).value();
21063
21064         assert.ok(pass);
21065         assert.deepEqual(actual, []);
21066
21067         pass = true;
21068         actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
21069
21070         assert.ok(pass);
21071         assert.deepEqual(actual, []);
21072       }
21073       else {
21074         skipAssert(assert, 4);
21075       }
21076     });
21077   }());
21078
21079   /*--------------------------------------------------------------------------*/
21080
21081   QUnit.module('lodash.take');
21082
21083   (function() {
21084     var array = [1, 2, 3];
21085
21086     QUnit.test('should take the first two elements', function(assert) {
21087       assert.expect(1);
21088
21089       assert.deepEqual(_.take(array, 2), [1, 2]);
21090     });
21091
21092     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21093       assert.expect(1);
21094
21095       var expected = lodashStable.map(falsey, function(value) {
21096         return value === undefined ? [1] : [];
21097       });
21098
21099       var actual = lodashStable.map(falsey, function(n) {
21100         return _.take(array, n);
21101       });
21102
21103       assert.deepEqual(actual, expected);
21104     });
21105
21106     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21107       assert.expect(3);
21108
21109       lodashStable.each([0, -1, -Infinity], function(n) {
21110         assert.deepEqual(_.take(array, n), []);
21111       });
21112     });
21113
21114     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
21115       assert.expect(4);
21116
21117       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21118         assert.deepEqual(_.take(array, n), array);
21119       });
21120     });
21121
21122     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21123       assert.expect(1);
21124
21125       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21126           actual = lodashStable.map(array, _.take);
21127
21128       assert.deepEqual(actual, [[1], [4], [7]]);
21129     });
21130
21131     QUnit.test('should work in a lazy sequence', function(assert) {
21132       assert.expect(6);
21133
21134       if (!isNpm) {
21135         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
21136             predicate = function(value) { values.push(value); return isEven(value); },
21137             values = [],
21138             actual = _(array).take(2).take().value();
21139
21140         assert.deepEqual(actual, _.take(_.take(array, 2)));
21141
21142         actual = _(array).filter(predicate).take(2).take().value();
21143         assert.deepEqual(values, [1, 2]);
21144         assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
21145
21146         actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
21147         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
21148
21149         values = [];
21150
21151         actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
21152         assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
21153         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
21154       }
21155       else {
21156         skipAssert(assert, 6);
21157       }
21158     });
21159   }());
21160
21161   /*--------------------------------------------------------------------------*/
21162
21163   QUnit.module('lodash.takeRight');
21164
21165   (function() {
21166     var array = [1, 2, 3];
21167
21168     QUnit.test('should take the last two elements', function(assert) {
21169       assert.expect(1);
21170
21171       assert.deepEqual(_.takeRight(array, 2), [2, 3]);
21172     });
21173
21174     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21175       assert.expect(1);
21176
21177       var expected = lodashStable.map(falsey, function(value) {
21178         return value === undefined ? [3] : [];
21179       });
21180
21181       var actual = lodashStable.map(falsey, function(n) {
21182         return _.takeRight(array, n);
21183       });
21184
21185       assert.deepEqual(actual, expected);
21186     });
21187
21188     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21189       assert.expect(3);
21190
21191       lodashStable.each([0, -1, -Infinity], function(n) {
21192         assert.deepEqual(_.takeRight(array, n), []);
21193       });
21194     });
21195
21196     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
21197       assert.expect(4);
21198
21199       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21200         assert.deepEqual(_.takeRight(array, n), array);
21201       });
21202     });
21203
21204     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21205       assert.expect(1);
21206
21207       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21208           actual = lodashStable.map(array, _.takeRight);
21209
21210       assert.deepEqual(actual, [[3], [6], [9]]);
21211     });
21212
21213     QUnit.test('should work in a lazy sequence', function(assert) {
21214       assert.expect(6);
21215
21216       if (!isNpm) {
21217         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21218             predicate = function(value) { values.push(value); return isEven(value); },
21219             values = [],
21220             actual = _(array).takeRight(2).takeRight().value();
21221
21222         assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
21223
21224         actual = _(array).filter(predicate).takeRight(2).takeRight().value();
21225         assert.deepEqual(values, array);
21226         assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
21227
21228         actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
21229         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
21230
21231         values = [];
21232
21233         actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
21234         assert.deepEqual(values, array);
21235         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
21236       }
21237       else {
21238         skipAssert(assert, 6);
21239       }
21240     });
21241   }());
21242
21243   /*--------------------------------------------------------------------------*/
21244
21245   QUnit.module('lodash.takeRightWhile');
21246
21247   (function() {
21248     var array = [1, 2, 3, 4];
21249
21250     var objects = [
21251       { 'a': 0, 'b': 0 },
21252       { 'a': 1, 'b': 1 },
21253       { 'a': 2, 'b': 2 }
21254     ];
21255
21256     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21257       assert.expect(1);
21258
21259       var actual = _.takeRightWhile(array, function(n) {
21260         return n > 2;
21261       });
21262
21263       assert.deepEqual(actual, [3, 4]);
21264     });
21265
21266     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21267       assert.expect(1);
21268
21269       var args;
21270
21271       _.takeRightWhile(array, function() {
21272         args = slice.call(arguments);
21273       });
21274
21275       assert.deepEqual(args, [4, 3, array]);
21276     });
21277
21278     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21279       assert.expect(1);
21280
21281       assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
21282     });
21283
21284     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21285       assert.expect(1);
21286
21287       assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
21288     });
21289
21290     QUnit.test('should work with `_.property` shorthands', function(assert) {
21291       assert.expect(1);
21292
21293       assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
21294     });
21295
21296     QUnit.test('should work in a lazy sequence', function(assert) {
21297       assert.expect(3);
21298
21299       if (!isNpm) {
21300         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21301             predicate = function(n) { return n > 2; },
21302             expected = _.takeRightWhile(array, predicate),
21303             wrapped = _(array).takeRightWhile(predicate);
21304
21305         assert.deepEqual(wrapped.value(), expected);
21306         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21307         assert.strictEqual(wrapped.last(), _.last(expected));
21308       }
21309       else {
21310         skipAssert(assert, 3);
21311       }
21312     });
21313
21314     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21315       assert.expect(5);
21316
21317       if (!isNpm) {
21318         var args,
21319             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21320             expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
21321
21322         _(array).slice(1).takeRightWhile(function(value, index, array) {
21323           args = slice.call(arguments);
21324         }).value();
21325
21326         assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
21327
21328         _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
21329           args = slice.call(arguments);
21330         }).value();
21331
21332         assert.deepEqual(args, expected);
21333
21334         _(array).slice(1).map(square).takeRightWhile(function(value, index) {
21335           args = slice.call(arguments);
21336         }).value();
21337
21338         assert.deepEqual(args, expected);
21339
21340         _(array).slice(1).map(square).takeRightWhile(function(index) {
21341           args = slice.call(arguments);
21342         }).value();
21343
21344         assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
21345
21346         _(array).slice(1).map(square).takeRightWhile(function() {
21347           args = slice.call(arguments);
21348         }).value();
21349
21350         assert.deepEqual(args, expected);
21351       }
21352       else {
21353         skipAssert(assert, 5);
21354       }
21355     });
21356   }());
21357
21358   /*--------------------------------------------------------------------------*/
21359
21360   QUnit.module('lodash.takeWhile');
21361
21362   (function() {
21363     var array = [1, 2, 3, 4];
21364
21365     var objects = [
21366       { 'a': 2, 'b': 2 },
21367       { 'a': 1, 'b': 1 },
21368       { 'a': 0, 'b': 0 }
21369     ];
21370
21371     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21372       assert.expect(1);
21373
21374       var actual = _.takeWhile(array, function(n) {
21375         return n < 3;
21376       });
21377
21378       assert.deepEqual(actual, [1, 2]);
21379     });
21380
21381     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21382       assert.expect(1);
21383
21384       var args;
21385
21386       _.takeWhile(array, function() {
21387         args = slice.call(arguments);
21388       });
21389
21390       assert.deepEqual(args, [1, 0, array]);
21391     });
21392
21393     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21394       assert.expect(1);
21395
21396       assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
21397     });
21398
21399     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21400       assert.expect(1);
21401
21402       assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
21403     });
21404     QUnit.test('should work with `_.property` shorthands', function(assert) {
21405       assert.expect(1);
21406
21407       assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
21408     });
21409
21410     QUnit.test('should work in a lazy sequence', function(assert) {
21411       assert.expect(3);
21412
21413       if (!isNpm) {
21414         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21415             predicate = function(n) { return n < 3; },
21416             expected = _.takeWhile(array, predicate),
21417             wrapped = _(array).takeWhile(predicate);
21418
21419         assert.deepEqual(wrapped.value(), expected);
21420         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21421         assert.strictEqual(wrapped.last(), _.last(expected));
21422       }
21423       else {
21424         skipAssert(assert, 3);
21425       }
21426     });
21427
21428     QUnit.test('should work in a lazy sequence with `take`', function(assert) {
21429       assert.expect(1);
21430
21431       if (!isNpm) {
21432         var array = lodashStable.range(LARGE_ARRAY_SIZE);
21433
21434         var actual = _(array)
21435           .takeWhile(function(n) { return n < 4; })
21436           .take(2)
21437           .takeWhile(function(n) { return n == 0; })
21438           .value();
21439
21440         assert.deepEqual(actual, [0]);
21441       }
21442       else {
21443         skipAssert(assert);
21444       }
21445     });
21446
21447     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21448       assert.expect(5);
21449
21450       if (!isNpm) {
21451         var args,
21452             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21453             expected = [1, 0, lodashStable.map(array.slice(1), square)];
21454
21455         _(array).slice(1).takeWhile(function(value, index, array) {
21456           args = slice.call(arguments);
21457         }).value();
21458
21459         assert.deepEqual(args, [1, 0, array.slice(1)]);
21460
21461         _(array).slice(1).map(square).takeWhile(function(value, index, array) {
21462           args = slice.call(arguments);
21463         }).value();
21464
21465         assert.deepEqual(args, expected);
21466
21467         _(array).slice(1).map(square).takeWhile(function(value, index) {
21468           args = slice.call(arguments);
21469         }).value();
21470
21471         assert.deepEqual(args, expected);
21472
21473         _(array).slice(1).map(square).takeWhile(function(value) {
21474           args = slice.call(arguments);
21475         }).value();
21476
21477         assert.deepEqual(args, [1]);
21478
21479         _(array).slice(1).map(square).takeWhile(function() {
21480           args = slice.call(arguments);
21481         }).value();
21482
21483         assert.deepEqual(args, expected);
21484       }
21485       else {
21486         skipAssert(assert, 5);
21487       }
21488     });
21489   }());
21490
21491   /*--------------------------------------------------------------------------*/
21492
21493   QUnit.module('lodash.tap');
21494
21495   (function() {
21496     QUnit.test('should intercept and return the given value', function(assert) {
21497       assert.expect(2);
21498
21499       if (!isNpm) {
21500         var intercepted,
21501             array = [1, 2, 3];
21502
21503         var actual = _.tap(array, function(value) {
21504           intercepted = value;
21505         });
21506
21507         assert.strictEqual(actual, array);
21508         assert.strictEqual(intercepted, array);
21509       }
21510       else {
21511         skipAssert(assert, 2);
21512       }
21513     });
21514
21515     QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
21516       assert.expect(2);
21517
21518       if (!isNpm) {
21519         var intercepted,
21520             array = [1, 2, 3];
21521
21522         var wrapped = _(array).tap(function(value) {
21523           intercepted = value;
21524           value.pop();
21525         });
21526
21527         assert.ok(wrapped instanceof _);
21528
21529         wrapped.value();
21530         assert.strictEqual(intercepted, array);
21531       }
21532       else {
21533         skipAssert(assert, 2);
21534       }
21535     });
21536   }());
21537
21538   /*--------------------------------------------------------------------------*/
21539
21540   QUnit.module('lodash.template');
21541
21542   (function() {
21543     QUnit.test('should escape values in "escape" delimiters', function(assert) {
21544       assert.expect(1);
21545
21546       var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
21547           expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
21548           data = { 'value': '&<>"\'`\/' };
21549
21550       var actual = lodashStable.map(strings, function(string) {
21551         return _.template(string)(data);
21552       });
21553
21554       assert.deepEqual(actual, expected);
21555     });
21556
21557     QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
21558       assert.expect(1);
21559
21560       var compiled = _.template('<%= typeof __e %>');
21561       assert.strictEqual(compiled({}), 'undefined');
21562     });
21563
21564     QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
21565       assert.expect(1);
21566
21567       var compiled = _.template(
21568         '<ul><%\
21569         for (var key in collection) {\
21570           %><li><%= collection[key] %></li><%\
21571         } %></ul>'
21572       );
21573
21574       var data = { 'collection': { 'a': 'A', 'b': 'B' } },
21575           actual = compiled(data);
21576
21577       assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
21578     });
21579
21580     QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
21581       assert.expect(1);
21582
21583       var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
21584           data = { 'value': true };
21585
21586       assert.strictEqual(compiled(data), 'yap');
21587     });
21588
21589     QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
21590       assert.expect(1);
21591
21592       var compiled = _.template('<% var b = a; %><%= b.value %>'),
21593           data = { 'a': { 'value': 1 } };
21594
21595       assert.strictEqual(compiled(data), '1');
21596     });
21597
21598     QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
21599       assert.expect(1);
21600
21601       var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
21602           expected = lodashStable.map(strings, lodashStable.constant('ABC')),
21603           data = { 'a': 'A' };
21604
21605       var actual = lodashStable.map(strings, function(string) {
21606         return _.template(string)(data);
21607       });
21608
21609       assert.deepEqual(actual, expected);
21610     });
21611
21612     QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
21613       assert.expect(1);
21614
21615       var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
21616           data = { 'a': true };
21617
21618       assert.strictEqual(compiled(data), 'a="A"');
21619     });
21620
21621     QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
21622       assert.expect(1);
21623
21624       var compiled = _.template('<%= value ? value : "b" %>'),
21625           data = { 'value': 'a' };
21626
21627       assert.strictEqual(compiled(data), 'a');
21628     });
21629
21630     QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
21631       assert.expect(1);
21632
21633       var compiled = _.template('<%= typeof Math.abs %>');
21634
21635       try {
21636         var actual = compiled();
21637       } catch (e) {}
21638
21639       assert.strictEqual(actual, 'function');
21640     });
21641
21642     QUnit.test('should support complex "interpolate" delimiters', function(assert) {
21643       assert.expect(22);
21644
21645       lodashStable.forOwn({
21646         '<%= a + b %>': '3',
21647         '<%= b - a %>': '1',
21648         '<%= a = b %>': '2',
21649         '<%= !a %>': 'false',
21650         '<%= ~a %>': '-2',
21651         '<%= a * b %>': '2',
21652         '<%= a / b %>': '0.5',
21653         '<%= a % b %>': '1',
21654         '<%= a >> b %>': '0',
21655         '<%= a << b %>': '4',
21656         '<%= a & b %>': '0',
21657         '<%= a ^ b %>': '3',
21658         '<%= a | b %>': '3',
21659         '<%= {}.toString.call(0) %>': numberTag,
21660         '<%= a.toFixed(2) %>': '1.00',
21661         '<%= obj["a"] %>': '1',
21662         '<%= delete a %>': 'true',
21663         '<%= "a" in obj %>': 'true',
21664         '<%= obj instanceof Object %>': 'true',
21665         '<%= new Boolean %>': 'false',
21666         '<%= typeof a %>': 'number',
21667         '<%= void a %>': ''
21668       },
21669       function(value, key) {
21670         var compiled = _.template(key),
21671             data = { 'a': 1, 'b': 2 };
21672
21673         assert.strictEqual(compiled(data), value, key);
21674       });
21675     });
21676
21677     QUnit.test('should support ES6 template delimiters', function(assert) {
21678       assert.expect(2);
21679
21680       var data = { 'value': 2 };
21681       assert.strictEqual(_.template('1${value}3')(data), '123');
21682       assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
21683     });
21684
21685     QUnit.test('should support the "imports" option', function(assert) {
21686       assert.expect(1);
21687
21688       var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
21689       assert.strictEqual(compiled({}), '1');
21690     });
21691
21692     QUnit.test('should support the "variable" options', function(assert) {
21693       assert.expect(1);
21694
21695       var compiled = _.template(
21696         '<% _.each( data.a, function( value ) { %>' +
21697             '<%= value.valueOf() %>' +
21698         '<% }) %>', { 'variable': 'data' }
21699       );
21700
21701       var data = { 'a': [1, 2, 3] };
21702
21703       try {
21704         assert.strictEqual(compiled(data), '123');
21705       } catch (e) {
21706         assert.ok(false, e.message);
21707       }
21708     });
21709
21710     QUnit.test('should support custom delimiters', function(assert) {
21711       assert.expect(2);
21712
21713       lodashStable.times(2, function(index) {
21714         var settingsClone = lodashStable.clone(_.templateSettings);
21715
21716         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
21717           'escape': /\{\{-([\s\S]+?)\}\}/g,
21718           'evaluate': /\{\{([\s\S]+?)\}\}/g,
21719           'interpolate': /\{\{=([\s\S]+?)\}\}/g
21720         });
21721
21722         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
21723             compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
21724             data = { 'collection': ['a & A', 'b & B'] };
21725
21726         assert.strictEqual(compiled(data), expected);
21727         lodashStable.assign(_.templateSettings, settingsClone);
21728       });
21729     });
21730
21731     QUnit.test('should support custom delimiters containing special characters', function(assert) {
21732       assert.expect(2);
21733
21734       lodashStable.times(2, function(index) {
21735         var settingsClone = lodashStable.clone(_.templateSettings);
21736
21737         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
21738           'escape': /<\?-([\s\S]+?)\?>/g,
21739           'evaluate': /<\?([\s\S]+?)\?>/g,
21740           'interpolate': /<\?=([\s\S]+?)\?>/g
21741         });
21742
21743         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
21744             compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
21745             data = { 'collection': ['a & A', 'b & B'] };
21746
21747         assert.strictEqual(compiled(data), expected);
21748         lodashStable.assign(_.templateSettings, settingsClone);
21749       });
21750     });
21751
21752     QUnit.test('should use a `with` statement by default', function(assert) {
21753       assert.expect(1);
21754
21755       var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
21756           actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
21757
21758       assert.strictEqual(actual, '1b012');
21759     });
21760
21761     QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
21762       assert.expect(1);
21763
21764       var lodash = _.templateSettings.imports._,
21765           settingsClone = lodashStable.clone(lodash.templateSettings);
21766
21767       lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
21768         'interpolate': /\{\{=([\s\S]+?)\}\}/g
21769       });
21770
21771       var compiled = _.template('{{= a }}');
21772       assert.strictEqual(compiled({ 'a': 1 }), '1');
21773
21774       if (settingsClone) {
21775         lodashStable.assign(lodash.templateSettings, settingsClone);
21776       } else {
21777         delete lodash.templateSettings;
21778       }
21779     });
21780
21781     QUnit.test('should fallback to `_.templateSettings`', function(assert) {
21782       assert.expect(1);
21783
21784       var lodash = _.templateSettings.imports._,
21785           delimiter = _.templateSettings.interpolate;
21786
21787       _.templateSettings.imports._ = { 'escape': lodashStable.escape };
21788       _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
21789
21790       var compiled = _.template('{{= a }}');
21791       assert.strictEqual(compiled({ 'a': 1 }), '1');
21792
21793       _.templateSettings.imports._ = lodash;
21794       _.templateSettings.interpolate = delimiter;
21795     });
21796
21797     QUnit.test('should ignore `null` delimiters', function(assert) {
21798       assert.expect(3);
21799
21800       var delimiter = {
21801         'escape': /\{\{-([\s\S]+?)\}\}/g,
21802         'evaluate': /\{\{([\s\S]+?)\}\}/g,
21803         'interpolate': /\{\{=([\s\S]+?)\}\}/g
21804       };
21805
21806       lodashStable.forOwn({
21807         'escape': '{{- a }}',
21808         'evaluate': '{{ print(a) }}',
21809         'interpolate': '{{= a }}'
21810       },
21811       function(value, key) {
21812         var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
21813         settings[key] = delimiter[key];
21814
21815         var expected = '1 <%- a %> <% print(a) %> <%= a %>',
21816             compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
21817             data = { 'a': 1 };
21818
21819         assert.strictEqual(compiled(data), expected);
21820       });
21821     });
21822
21823     QUnit.test('should work without delimiters', function(assert) {
21824       assert.expect(1);
21825
21826       var expected = 'abc';
21827       assert.strictEqual(_.template(expected)({}), expected);
21828     });
21829
21830     QUnit.test('should work with `this` references', function(assert) {
21831       assert.expect(2);
21832
21833       var compiled = _.template('a<%= this.String("b") %>c');
21834       assert.strictEqual(compiled(), 'abc');
21835
21836       var object = { 'b': 'B' };
21837       object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
21838       assert.strictEqual(object.compiled(), 'ABC');
21839     });
21840
21841     QUnit.test('should work with backslashes', function(assert) {
21842       assert.expect(1);
21843
21844       var compiled = _.template('<%= a %> \\b'),
21845           data = { 'a': 'A' };
21846
21847       assert.strictEqual(compiled(data), 'A \\b');
21848     });
21849
21850     QUnit.test('should work with escaped characters in string literals', function(assert) {
21851       assert.expect(2);
21852
21853       var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
21854       assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
21855
21856       var data = { 'a': 'A' };
21857       compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
21858       assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
21859     });
21860
21861     QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
21862       assert.expect(1);
21863
21864       var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
21865       assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
21866     });
21867
21868     QUnit.test('should work with statements containing quotes', function(assert) {
21869       assert.expect(1);
21870
21871       var compiled = _.template("<%\
21872         if (a == 'A' || a == \"a\") {\
21873           %>'a',\"A\"<%\
21874         } %>"
21875       );
21876
21877       var data = { 'a': 'A' };
21878       assert.strictEqual(compiled(data), "'a',\"A\"");
21879     });
21880
21881     QUnit.test('should work with templates containing newlines and comments', function(assert) {
21882       assert.expect(1);
21883
21884       var compiled = _.template('<%\n\
21885         // A code comment.\n\
21886         if (value) { value += 3; }\n\
21887         %><p><%= value %></p>'
21888       );
21889
21890       assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
21891     });
21892
21893     QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
21894       assert.expect(1);
21895
21896       var compiled = _.template(''),
21897           pass = true;
21898
21899       /*@cc_on @*/
21900       try {
21901         compiled();
21902       } catch (e) {
21903         pass = false;
21904       }
21905       assert.ok(pass);
21906     });
21907
21908     QUnit.test('should tokenize delimiters', function(assert) {
21909       assert.expect(1);
21910
21911       var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
21912           data = { 'type': 1 };
21913
21914       assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
21915     });
21916
21917     QUnit.test('should evaluate delimiters once', function(assert) {
21918       assert.expect(1);
21919
21920       var actual = [],
21921           compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
21922           data = { 'func': function(value) { actual.push(value); } };
21923
21924       compiled(data);
21925       assert.deepEqual(actual, ['a', 'b', 'c']);
21926     });
21927
21928     QUnit.test('should match delimiters before escaping text', function(assert) {
21929       assert.expect(1);
21930
21931       var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
21932       assert.strictEqual(compiled(), '<<\n a \n>>');
21933     });
21934
21935     QUnit.test('should resolve nullish values to an empty string', function(assert) {
21936       assert.expect(3);
21937
21938       var compiled = _.template('<%= a %><%- a %>'),
21939           data = { 'a': null };
21940
21941       assert.strictEqual(compiled(data), '');
21942
21943       data = { 'a': undefined };
21944       assert.strictEqual(compiled(data), '');
21945
21946       data = { 'a': {} };
21947       compiled = _.template('<%= a.b %><%- a.b %>');
21948       assert.strictEqual(compiled(data), '');
21949     });
21950
21951     QUnit.test('should return an empty string for empty values', function(assert) {
21952       assert.expect(1);
21953
21954       var values = [, null, undefined, ''],
21955           expected = lodashStable.map(values, alwaysEmptyString),
21956           data = { 'a': 1 };
21957
21958       var actual = lodashStable.map(values, function(value, index) {
21959         var compiled = index ? _.template(value) : _.template();
21960         return compiled(data);
21961       });
21962
21963       assert.deepEqual(actual, expected);
21964     });
21965
21966     QUnit.test('should parse delimiters without newlines', function(assert) {
21967       assert.expect(1);
21968
21969       var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
21970           compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
21971           data = { 'value': true };
21972
21973       assert.strictEqual(compiled(data), expected);
21974     });
21975
21976     QUnit.test('should support recursive calls', function(assert) {
21977       assert.expect(1);
21978
21979       var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
21980           data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
21981
21982       assert.strictEqual(compiled(data), 'AB');
21983     });
21984
21985     QUnit.test('should coerce `text` argument to a string', function(assert) {
21986       assert.expect(1);
21987
21988       var object = { 'toString': lodashStable.constant('<%= a %>') },
21989           data = { 'a': 1 };
21990
21991       assert.strictEqual(_.template(object)(data), '1');
21992     });
21993
21994     QUnit.test('should not modify the `options` object', function(assert) {
21995       assert.expect(1);
21996
21997       var options = {};
21998       _.template('', options);
21999       assert.deepEqual(options, {});
22000     });
22001
22002     QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
22003       assert.expect(2);
22004
22005       var data = { 'a': 1 };
22006
22007       assert.notOk('a' in _.templateSettings);
22008       _.template('', {}, data);
22009       assert.notOk('a' in _.templateSettings);
22010
22011       delete _.templateSettings.a;
22012     });
22013
22014     QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
22015       assert.expect(2);
22016
22017       var pass = true;
22018
22019       try {
22020         _.template('')(1);
22021       } catch (e) {
22022         pass = false;
22023       }
22024       assert.ok(pass, '`data` value');
22025
22026       pass = true;
22027
22028       try {
22029         _.template('', 1)(1);
22030       } catch (e) {
22031         pass = false;
22032       }
22033       assert.ok(pass, '`options` value');
22034     });
22035
22036     QUnit.test('should expose the source on compiled templates', function(assert) {
22037       assert.expect(1);
22038
22039       var compiled = _.template('x'),
22040           values = [String(compiled), compiled.source],
22041           expected = lodashStable.map(values, alwaysTrue);
22042
22043       var actual = lodashStable.map(values, function(value) {
22044         return lodashStable.includes(value, '__p');
22045       });
22046
22047       assert.deepEqual(actual, expected);
22048     });
22049
22050     QUnit.test('should expose the source on SyntaxErrors', function(assert) {
22051       assert.expect(1);
22052
22053       try {
22054         _.template('<% if x %>');
22055       } catch (e) {
22056         var source = e.source;
22057       }
22058       assert.ok(lodashStable.includes(source, '__p'));
22059     });
22060
22061     QUnit.test('should not include sourceURLs in the source', function(assert) {
22062       assert.expect(1);
22063
22064       var options = { 'sourceURL': '/a/b/c' },
22065           compiled = _.template('x', options),
22066           values = [compiled.source, undefined];
22067
22068       try {
22069         _.template('<% if x %>', options);
22070       } catch (e) {
22071         values[1] = e.source;
22072       }
22073       var expected = lodashStable.map(values, alwaysFalse);
22074
22075       var actual = lodashStable.map(values, function(value) {
22076         return lodashStable.includes(value, 'sourceURL');
22077       });
22078
22079       assert.deepEqual(actual, expected);
22080     });
22081
22082     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22083       assert.expect(1);
22084
22085       var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
22086           compiles = lodashStable.map(array, _.template),
22087           data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
22088
22089       var actual = lodashStable.map(compiles, function(compiled) {
22090         return compiled(data);
22091       });
22092
22093       assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
22094     });
22095   }());
22096
22097   /*--------------------------------------------------------------------------*/
22098
22099   QUnit.module('lodash.truncate');
22100
22101   (function() {
22102     var string = 'hi-diddly-ho there, neighborino';
22103
22104     QUnit.test('should use a default `length` of `30`', function(assert) {
22105       assert.expect(1);
22106
22107       assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
22108     });
22109
22110     QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
22111       assert.expect(2);
22112
22113       assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
22114       assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
22115     });
22116
22117     QUnit.test('should truncate string the given length', function(assert) {
22118       assert.expect(1);
22119
22120       assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
22121     });
22122
22123     QUnit.test('should support a `omission` option', function(assert) {
22124       assert.expect(1);
22125
22126       assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
22127     });
22128
22129     QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
22130       assert.expect(2);
22131
22132       assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
22133       assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
22134     });
22135
22136     QUnit.test('should support a `length` option', function(assert) {
22137       assert.expect(1);
22138
22139       assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
22140     });
22141
22142     QUnit.test('should support a `separator` option', function(assert) {
22143       assert.expect(3);
22144
22145       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
22146       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
22147       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
22148     });
22149
22150     QUnit.test('should treat negative `length` as `0`', function(assert) {
22151       assert.expect(2);
22152
22153       lodashStable.each([0, -2], function(length) {
22154         assert.strictEqual(_.truncate(string, { 'length': length }), '...');
22155       });
22156     });
22157
22158     QUnit.test('should coerce `length` to an integer', function(assert) {
22159       assert.expect(4);
22160
22161       lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
22162         var actual = index > 1 ? 'h...' : '...';
22163         assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
22164       });
22165     });
22166
22167     QUnit.test('should coerce `string` to a string', function(assert) {
22168       assert.expect(2);
22169
22170       assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
22171       assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
22172     });
22173
22174     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22175       assert.expect(1);
22176
22177       var actual = lodashStable.map([string, string, string], _.truncate),
22178           truncated = 'hi-diddly-ho there, neighbo...';
22179
22180       assert.deepEqual(actual, [truncated, truncated, truncated]);
22181     });
22182   }());
22183
22184   /*--------------------------------------------------------------------------*/
22185
22186   QUnit.module('lodash.throttle');
22187
22188   (function() {
22189     QUnit.test('should throttle a function', function(assert) {
22190       assert.expect(2);
22191
22192       var done = assert.async();
22193
22194       var callCount = 0,
22195           throttled = _.throttle(function() { callCount++; }, 32);
22196
22197       throttled();
22198       throttled();
22199       throttled();
22200
22201       var lastCount = callCount;
22202       assert.ok(callCount > 0);
22203
22204       setTimeout(function() {
22205         assert.ok(callCount > lastCount);
22206         done();
22207       }, 64);
22208     });
22209
22210     QUnit.test('subsequent calls should return the result of the first call', function(assert) {
22211       assert.expect(5);
22212
22213       var done = assert.async();
22214
22215       var throttled = _.throttle(identity, 32),
22216           result = [throttled('a'), throttled('b')];
22217
22218       assert.deepEqual(result, ['a', 'a']);
22219
22220       setTimeout(function() {
22221         var result = [throttled('x'), throttled('y')];
22222         assert.notEqual(result[0], 'a');
22223         assert.notStrictEqual(result[0], undefined);
22224
22225         assert.notEqual(result[1], 'y');
22226         assert.notStrictEqual(result[1], undefined);
22227         done();
22228       }, 64);
22229     });
22230
22231     QUnit.test('should clear timeout when `func` is called', function(assert) {
22232       assert.expect(1);
22233
22234       var done = assert.async();
22235
22236       if (!isModularize) {
22237         var callCount = 0,
22238             dateCount = 0;
22239
22240         var getTime = function() {
22241           return ++dateCount == 5
22242             ? Infinity
22243             : +new Date;
22244         };
22245
22246         var lodash = _.runInContext(lodashStable.assign({}, root, {
22247           'Date': lodashStable.assign(function() {
22248             return { 'getTime': getTime };
22249           }, {
22250             'now': Date.now
22251           })
22252         }));
22253
22254         var throttled = lodash.throttle(function() { callCount++; }, 32);
22255
22256         throttled();
22257         throttled();
22258
22259         setTimeout(function() {
22260           assert.strictEqual(callCount, 2);
22261           done();
22262         }, 64);
22263       }
22264       else {
22265         skipAssert(assert);
22266         done();
22267       }
22268     });
22269
22270     QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
22271       assert.expect(2);
22272
22273       var done = assert.async();
22274
22275       var callCount = 0,
22276           throttled = _.throttle(function() { callCount++; }, 32);
22277
22278       throttled();
22279       assert.strictEqual(callCount, 1);
22280
22281       setTimeout(function() {
22282         assert.strictEqual(callCount, 1);
22283         done();
22284       }, 64);
22285     });
22286
22287     lodashStable.times(2, function(index) {
22288       QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
22289         assert.expect(1);
22290
22291         var done = assert.async();
22292
22293         var callCount = 0,
22294             limit = (argv || isPhantom) ? 1000 : 320,
22295             options = index ? { 'leading': false } : {},
22296             throttled = _.throttle(function() { callCount++; }, 32, options);
22297
22298         var start = +new Date;
22299         while ((new Date - start) < limit) {
22300           throttled();
22301         }
22302         var actual = callCount > 1;
22303         setTimeout(function() {
22304           assert.ok(actual);
22305           done();
22306         }, 1);
22307       });
22308     });
22309
22310     QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
22311       assert.expect(3);
22312
22313       var done = assert.async();
22314
22315       var callCount = 0;
22316
22317       var throttled = _.throttle(function() {
22318         callCount++;
22319       }, 128, { 'leading': false });
22320
22321       throttled();
22322
22323       setTimeout(function() {
22324         assert.strictEqual(callCount, 1);
22325         throttled();
22326       }, 192);
22327
22328       setTimeout(function() {
22329         assert.strictEqual(callCount, 1);
22330       }, 254);
22331
22332       setTimeout(function() {
22333         assert.strictEqual(callCount, 2);
22334         done();
22335       }, 384);
22336     });
22337
22338     QUnit.test('should apply default options', function(assert) {
22339       assert.expect(2);
22340
22341       var done = assert.async();
22342
22343       var callCount = 0,
22344           throttled = _.throttle(function() { callCount++; }, 32, {});
22345
22346       throttled();
22347       throttled();
22348       assert.strictEqual(callCount, 1);
22349
22350       setTimeout(function() {
22351         assert.strictEqual(callCount, 2);
22352         done();
22353       }, 128);
22354     });
22355
22356     QUnit.test('should support a `leading` option', function(assert) {
22357       assert.expect(2);
22358
22359       var withLeading = _.throttle(identity, 32, { 'leading': true });
22360       assert.strictEqual(withLeading('a'), 'a');
22361
22362       var withoutLeading = _.throttle(identity, 32, { 'leading': false });
22363       assert.strictEqual(withoutLeading('a'), undefined);
22364     });
22365
22366     QUnit.test('should support a `trailing` option', function(assert) {
22367       assert.expect(6);
22368
22369       var done = assert.async();
22370
22371       var withCount = 0,
22372           withoutCount = 0;
22373
22374       var withTrailing = _.throttle(function(value) {
22375         withCount++;
22376         return value;
22377       }, 64, { 'trailing': true });
22378
22379       var withoutTrailing = _.throttle(function(value) {
22380         withoutCount++;
22381         return value;
22382       }, 64, { 'trailing': false });
22383
22384       assert.strictEqual(withTrailing('a'), 'a');
22385       assert.strictEqual(withTrailing('b'), 'a');
22386
22387       assert.strictEqual(withoutTrailing('a'), 'a');
22388       assert.strictEqual(withoutTrailing('b'), 'a');
22389
22390       setTimeout(function() {
22391         assert.strictEqual(withCount, 2);
22392         assert.strictEqual(withoutCount, 1);
22393         done();
22394       }, 256);
22395     });
22396
22397     QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
22398       assert.expect(1);
22399
22400       var done = assert.async();
22401
22402       var callCount = 0;
22403
22404       var throttled = _.throttle(function() {
22405         callCount++;
22406       }, 64, { 'trailing': false });
22407
22408       throttled();
22409       throttled();
22410
22411       setTimeout(function() {
22412         throttled();
22413         throttled();
22414       }, 96);
22415
22416       setTimeout(function() {
22417         assert.ok(callCount > 1);
22418         done();
22419       }, 192);
22420     });
22421   }());
22422
22423   /*--------------------------------------------------------------------------*/
22424
22425   QUnit.module('lodash.debounce and lodash.throttle');
22426
22427   lodashStable.each(['debounce', 'throttle'], function(methodName) {
22428     var func = _[methodName],
22429         isDebounce = methodName == 'debounce';
22430
22431     QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
22432       assert.expect(1);
22433
22434       var pass = true;
22435
22436       try {
22437         func(noop, 32, 1);
22438       } catch (e) {
22439         pass = false;
22440       }
22441       assert.ok(pass);
22442     });
22443
22444     QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
22445       assert.expect(1);
22446
22447       var done = assert.async();
22448
22449       var callCount = 0,
22450           funced = func(function() { callCount++; });
22451
22452       funced();
22453
22454       setTimeout(function() {
22455         funced();
22456         assert.strictEqual(callCount, isDebounce ? 1 : 2);
22457         done();
22458       }, 32);
22459     });
22460
22461     QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
22462       assert.expect(1);
22463
22464       var done = assert.async();
22465
22466       var actual = [],
22467           object = { 'funced': func(function() { actual.push(this); }, 32) },
22468           expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
22469
22470       object.funced();
22471       if (!isDebounce) {
22472         object.funced();
22473       }
22474       setTimeout(function() {
22475         assert.deepEqual(actual, expected);
22476         done();
22477       }, 64);
22478     });
22479
22480     QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
22481       assert.expect(2);
22482
22483       var done = assert.async();
22484
22485       var actual = [],
22486           args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
22487           expected = args.slice(),
22488           queue = args.slice();
22489
22490       var funced = func(function() {
22491         var current = [this];
22492         push.apply(current, arguments);
22493         actual.push(current);
22494
22495         var next = queue.shift();
22496         if (next) {
22497           funced.call(next[0], next[1]);
22498         }
22499       }, 32);
22500
22501       var next = queue.shift();
22502       funced.call(next[0], next[1]);
22503       assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
22504
22505       setTimeout(function() {
22506         assert.deepEqual(actual, expected.slice(0, actual.length));
22507         done();
22508       }, 256);
22509     });
22510
22511     QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
22512       assert.expect(1);
22513
22514       var done = assert.async();
22515
22516       if (!isModularize) {
22517         var callCount = 0,
22518             dateCount = 0;
22519
22520         var getTime = function() {
22521           return ++dateCount === 4
22522             ? +new Date(2012, 3, 23, 23, 27, 18)
22523             : +new Date;
22524         };
22525
22526         var lodash = _.runInContext(lodashStable.assign({}, root, {
22527           'Date': lodashStable.assign(function() {
22528             return { 'getTime': getTime, 'valueOf': getTime };
22529           }, {
22530             'now': Date.now
22531           })
22532         }));
22533
22534         var funced = lodash[methodName](function() {
22535           callCount++;
22536         }, 32);
22537
22538         funced();
22539
22540         setTimeout(function() {
22541           funced();
22542           assert.strictEqual(callCount, isDebounce ? 1 : 2);
22543           done();
22544         }, 64);
22545       }
22546       else {
22547         skipAssert(assert);
22548         done();
22549       }
22550     });
22551
22552     QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
22553       assert.expect(1);
22554
22555       var done = assert.async();
22556
22557       var callCount = 0;
22558
22559       var funced = func(function() {
22560         callCount++;
22561       }, 32, { 'leading': false });
22562
22563       funced();
22564       funced.cancel();
22565
22566       setTimeout(function() {
22567         assert.strictEqual(callCount, 0);
22568         done();
22569       }, 64);
22570     });
22571
22572     QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
22573       assert.expect(3);
22574
22575       var done = assert.async();
22576
22577       var callCount = 0;
22578
22579       var funced = func(function() {
22580         return ++callCount;
22581       }, 32, { 'leading': true });
22582
22583       assert.strictEqual(funced(), 1);
22584       funced.cancel();
22585
22586       assert.strictEqual(funced(), 2);
22587       funced();
22588
22589       setTimeout(function() {
22590         assert.strictEqual(callCount, 3);
22591         done();
22592       }, 64);
22593     });
22594
22595     QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
22596       assert.expect(2);
22597
22598       var done = assert.async();
22599
22600       var callCount = 0;
22601
22602       var funced = func(function() {
22603         return ++callCount;
22604       }, 32, { 'leading': false });
22605
22606       funced();
22607       assert.strictEqual(funced.flush(), 1);
22608
22609       setTimeout(function() {
22610         assert.strictEqual(callCount, 1);
22611         done();
22612       }, 64);
22613     });
22614
22615     QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
22616       assert.expect(2);
22617
22618       var done = assert.async();
22619
22620       var callCount = 0,
22621           funced = func(function() { callCount++; }, 32);
22622
22623       funced.cancel();
22624       assert.strictEqual(funced.flush(), undefined);
22625
22626       setTimeout(function() {
22627         assert.strictEqual(callCount, 0);
22628         done();
22629       }, 64);
22630     });
22631   });
22632
22633   /*--------------------------------------------------------------------------*/
22634
22635   QUnit.module('lodash.times');
22636
22637   (function() {
22638     QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
22639       assert.expect(3);
22640
22641       lodashStable.each([-Infinity, NaN, Infinity], function(n) {
22642         assert.deepEqual(_.times(n), []);
22643       });
22644     });
22645
22646     QUnit.test('should coerce `n` to an integer', function(assert) {
22647       assert.expect(1);
22648
22649       var actual = _.times(2.6, _.indentify);
22650       assert.deepEqual(actual, [0, 1]);
22651     });
22652
22653     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
22654       assert.expect(1);
22655
22656       var args;
22657
22658       _.times(1, function(assert) {
22659         args || (args = slice.call(arguments));
22660       });
22661
22662       assert.deepEqual(args, [0]);
22663     });
22664
22665     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
22666       assert.expect(1);
22667
22668       var values = [, null, undefined],
22669           expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
22670
22671       var actual = lodashStable.map(values, function(value, index) {
22672         return index ? _.times(3, value) : _.times(3);
22673       });
22674
22675       assert.deepEqual(actual, expected);
22676     });
22677
22678     QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
22679       assert.expect(1);
22680
22681       assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
22682     });
22683
22684     QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
22685       assert.expect(1);
22686
22687       var values = falsey.concat(-1, -Infinity),
22688           expected = lodashStable.map(values, alwaysEmptyArray);
22689
22690       var actual = lodashStable.map(values, function(value, index) {
22691         return index ? _.times(value) : _.times();
22692       });
22693
22694       assert.deepEqual(actual, expected);
22695     });
22696
22697     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
22698       assert.expect(1);
22699
22700       if (!isNpm) {
22701         assert.deepEqual(_(3).times(), [0, 1, 2]);
22702       }
22703       else {
22704         skipAssert(assert);
22705       }
22706     });
22707
22708     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
22709       assert.expect(1);
22710
22711       if (!isNpm) {
22712         assert.ok(_(3).chain().times() instanceof _);
22713       }
22714       else {
22715         skipAssert(assert);
22716       }
22717     });
22718   }());
22719
22720   /*--------------------------------------------------------------------------*/
22721
22722   QUnit.module('lodash.toArray');
22723
22724   (function() {
22725     QUnit.test('should convert objects to arrays', function(assert) {
22726       assert.expect(1);
22727
22728       assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
22729     });
22730
22731     QUnit.test('should convert strings to arrays', function(assert) {
22732       assert.expect(3);
22733
22734       assert.deepEqual(_.toArray(''), []);
22735       assert.deepEqual(_.toArray('ab'), ['a', 'b']);
22736       assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
22737     });
22738
22739     QUnit.test('should convert iterables to arrays', function(assert) {
22740       assert.expect(1);
22741
22742       if (!isNpm && Symbol && Symbol.iterator) {
22743         var object = { '0': 'a', 'length': 1 };
22744         object[Symbol.iterator] = arrayProto[Symbol.iterator];
22745
22746         assert.deepEqual(_.toArray(object), ['a']);
22747       }
22748       else {
22749         skipAssert(assert);
22750       }
22751     });
22752
22753     QUnit.test('should work in a lazy sequence', function(assert) {
22754       assert.expect(2);
22755
22756       if (!isNpm) {
22757         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
22758             actual = _(array).slice(1).map(String).toArray().value();
22759
22760         assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
22761
22762         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
22763           return ['key' + index, index];
22764         }));
22765
22766         actual = _(object).toArray().slice(1).map(String).value();
22767         assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
22768       }
22769       else {
22770         skipAssert(assert, 2);
22771       }
22772     });
22773   }());
22774
22775   /*--------------------------------------------------------------------------*/
22776
22777   QUnit.module('lodash.toLower');
22778
22779   (function() {
22780     QUnit.test('should convert whole string to lower case', function(assert) {
22781       assert.expect(3);
22782
22783       assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
22784       assert.deepEqual(_.toLower('fooBar'), 'foobar');
22785       assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
22786     });
22787   }());
22788
22789   /*--------------------------------------------------------------------------*/
22790
22791   QUnit.module('lodash.toUpper');
22792
22793   (function() {
22794     QUnit.test('should convert whole string to upper case', function(assert) {
22795       assert.expect(3);
22796
22797       assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
22798       assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
22799       assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
22800     });
22801   }());
22802
22803   /*--------------------------------------------------------------------------*/
22804
22805   QUnit.module('lodash.slice and lodash.toArray');
22806
22807   lodashStable.each(['slice', 'toArray'], function(methodName) {
22808     var args = (function() { return arguments; }(1, 2, 3)),
22809         array = [1, 2, 3],
22810         func = _[methodName];
22811
22812     QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
22813       assert.expect(3);
22814
22815       var sparse = Array(3);
22816       sparse[1] = 2;
22817
22818       var actual = func(sparse);
22819
22820       assert.ok('0' in actual);
22821       assert.ok('2' in actual);
22822       assert.deepEqual(actual, sparse);
22823     });
22824
22825     QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
22826       assert.expect(2);
22827
22828       var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
22829       assert.deepEqual(func(object), ['a', 'b', 'c']);
22830       assert.deepEqual(func(args), array);
22831     });
22832
22833     QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
22834       assert.expect(2);
22835
22836       var actual = func(array);
22837       assert.deepEqual(actual, array);
22838       assert.notStrictEqual(actual, array);
22839     });
22840
22841     QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
22842       assert.expect(1);
22843
22844       if (document) {
22845         try {
22846           var actual = func(document.getElementsByTagName('body'));
22847         } catch (e) {}
22848
22849         assert.deepEqual(actual, [body]);
22850       }
22851       else {
22852         skipAssert(assert);
22853       }
22854     });
22855   });
22856
22857   /*--------------------------------------------------------------------------*/
22858
22859   QUnit.module('toInteger methods');
22860
22861   lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
22862     var func = _[methodName],
22863         isSafe = methodName == 'toSafeInteger';
22864
22865     QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
22866       assert.expect(6);
22867
22868       assert.strictEqual(func(-5.6), -5);
22869       assert.strictEqual(func('5.6'), 5);
22870       assert.strictEqual(func(), 0);
22871       assert.strictEqual(func(NaN), 0);
22872
22873       var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
22874       assert.strictEqual(func(Infinity), expected);
22875       assert.strictEqual(func(-Infinity), -expected);
22876     });
22877
22878     QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
22879       assert.expect(1);
22880
22881       assert.strictEqual(1 / func(-0), -Infinity);
22882     });
22883   });
22884
22885   /*--------------------------------------------------------------------------*/
22886
22887   QUnit.module('lodash.toLength');
22888
22889   (function() {
22890     QUnit.test('should return a valid length', function(assert) {
22891       assert.expect(4);
22892
22893       assert.strictEqual(_.toLength(-1), 0);
22894       assert.strictEqual(_.toLength('1'), 1);
22895       assert.strictEqual(_.toLength(1.1), 1);
22896       assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
22897     });
22898
22899     QUnit.test('should return `value` if a valid length', function(assert) {
22900       assert.expect(3);
22901
22902       assert.strictEqual(_.toLength(0), 0);
22903       assert.strictEqual(_.toLength(3), 3);
22904       assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
22905     });
22906
22907     QUnit.test('should convert `-0` to `0`', function(assert) {
22908       assert.expect(1);
22909
22910       assert.strictEqual(1 / _.toLength(-0), Infinity);
22911     });
22912   }());
22913
22914   /*--------------------------------------------------------------------------*/
22915
22916   QUnit.module('number coercion methods');
22917
22918   lodashStable.each(['toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
22919     var func = _[methodName];
22920
22921     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
22922       assert.expect(2);
22923
22924       var values = [0, '0', -0, '-0'],
22925           expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
22926
22927       lodashStable.times(2, function(index) {
22928         var others = lodashStable.map(values, index ? Object : identity);
22929
22930         var actual = lodashStable.map(others, function(value) {
22931           var result = func(value);
22932           return [result, 1 / result];
22933         });
22934
22935         assert.deepEqual(actual, expected);
22936       });
22937     });
22938   });
22939
22940   lodashStable.each(['toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
22941     var func = _[methodName],
22942         isToLength = methodName == 'toLength',
22943         isToNumber = methodName == 'toNumber',
22944         isToSafeInteger = methodName == 'toSafeInteger';
22945
22946     function negative(string) {
22947       return '-' + string;
22948     }
22949
22950     function pad(string) {
22951       return whitespace + string + whitespace;
22952     }
22953
22954     function positive(string) {
22955       return '+' + string;
22956     }
22957
22958     QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
22959       assert.expect(1);
22960
22961       var values = [0, 1, NaN];
22962
22963       var expected = lodashStable.map(values, function(value) {
22964         return (!isToNumber && value !== value) ? 0 : value;
22965       });
22966
22967       var actual = lodashStable.map(values, func);
22968
22969       assert.deepEqual(actual, expected);
22970     });
22971
22972     QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
22973       assert.expect(1);
22974
22975       var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
22976
22977       var expected = lodashStable.map(values, function(value) {
22978         if (!isToNumber) {
22979           if (value == 1.2) {
22980             value = 1;
22981           }
22982           else if (value == Infinity) {
22983             value = MAX_INTEGER;
22984           }
22985           else if (value !== value) {
22986             value = 0;
22987           }
22988           if (isToLength || isToSafeInteger) {
22989             value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
22990           }
22991         }
22992         var neg = isToLength ? 0 : -value;
22993         return [value, value, neg, neg];
22994       });
22995
22996       var actual = lodashStable.map(values, function(value) {
22997         return [func(value), func(Object(value)), func(-value), func(Object(-value))];
22998       });
22999
23000       assert.deepEqual(actual, expected);
23001     });
23002
23003     QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
23004       assert.expect(1);
23005
23006       var transforms = [identity, pad, positive, negative];
23007
23008       var values = [
23009         '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
23010         '1e+308', '1e308', '1E+308', '1E308',
23011         '5e-324', '5E-324',
23012         'Infinity', 'NaN'
23013       ];
23014
23015       var expected = lodashStable.map(values, function(value) {
23016         var n = +value;
23017         if (!isToNumber) {
23018           if (n == 1.234567890) {
23019             n = 1;
23020           }
23021           else if (n == Infinity) {
23022             n = MAX_INTEGER;
23023           }
23024           else if (n == Number.MIN_VALUE || n !== n) {
23025             n = 0;
23026           }
23027           if (isToLength || isToSafeInteger) {
23028             n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23029           }
23030         }
23031         var neg = isToLength ? 0 : -n;
23032         return [n, n, n, n, n, n, neg, neg];
23033       });
23034
23035       var actual = lodashStable.map(values, function(value) {
23036         return lodashStable.flatMap(transforms, function(mod) {
23037           return [func(mod(value)), func(Object(mod(value)))];
23038         });
23039       });
23040
23041       assert.deepEqual(actual, expected);
23042     });
23043
23044     QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
23045       assert.expect(1);
23046
23047       var numbers = [42, 5349, 1715004],
23048           transforms = [identity, pad],
23049           values = ['0b101010', '0o12345', '0x1a2b3c'];
23050
23051       var expected = lodashStable.map(numbers, function(n) {
23052         return lodashStable.times(8, lodashStable.constant(n));
23053       });
23054
23055       var actual = lodashStable.map(values, function(value) {
23056         var upper = value.toUpperCase();
23057         return lodashStable.flatMap(transforms, function(mod) {
23058           return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
23059         });
23060       });
23061
23062       assert.deepEqual(actual, expected);
23063     });
23064
23065     QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23066       assert.expect(1);
23067
23068       var transforms = [identity, pad, positive, negative],
23069           values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
23070
23071       var expected = lodashStable.map(values, function(n) {
23072         return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
23073       });
23074
23075       var actual = lodashStable.map(values, function(value) {
23076         return lodashStable.flatMap(transforms, function(mod) {
23077           return [func(mod(value)), func(Object(mod(value)))];
23078         });
23079       });
23080
23081       assert.deepEqual(actual, expected);
23082     });
23083
23084     QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23085       assert.expect(1);
23086
23087       if (Symbol) {
23088         var object1 = Object(symbol),
23089             object2 = Object(symbol),
23090             values = [symbol, object1, object2],
23091             expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
23092
23093         object2.valueOf = undefined;
23094         var actual = lodashStable.map(values, func);
23095
23096         assert.deepEqual(actual, expected);
23097       }
23098       else {
23099         skipAssert(assert);
23100       }
23101     });
23102
23103     QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
23104       assert.expect(1);
23105
23106       var values = falsey.concat(whitespace);
23107
23108       var expected = lodashStable.map(values, function(value) {
23109         return (isToNumber && value !== whitespace) ? Number(value) : 0;
23110       });
23111
23112       var actual = lodashStable.map(values, function(value, index) {
23113         return index ? func(value) : func();
23114       });
23115
23116       assert.deepEqual(actual, expected);
23117     });
23118
23119     QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
23120       assert.expect(1);
23121
23122       var values = [
23123         {},
23124         [],
23125         [1],
23126         [1, 2],
23127         { 'valueOf': '1.1' },
23128         { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
23129         { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
23130         { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
23131         { 'valueOf': lodashStable.constant('-0x1a2b3c') },
23132         { 'toString': lodashStable.constant('-0x1a2b3c') },
23133         { 'valueOf': lodashStable.constant('0o12345') },
23134         { 'toString': lodashStable.constant('0o12345') },
23135         { 'valueOf': lodashStable.constant('0b101010') },
23136         { 'toString': lodashStable.constant('0b101010') }
23137       ];
23138
23139       var expected = [
23140         NaN,   0,   1,   NaN,
23141         NaN,  2.2,  1.1, 1.1,
23142         NaN,  NaN,
23143         5349, 5349,
23144         42,   42
23145       ];
23146
23147       if (!isToNumber) {
23148         expected = [
23149           0, 0, 1, 0,
23150           0, 2, 1, 1,
23151           0, 0,
23152           5349, 5349,
23153           42, 42
23154         ];
23155       }
23156       var actual = lodashStable.map(values, func);
23157
23158       assert.deepEqual(actual, expected);
23159     });
23160   });
23161
23162   /*--------------------------------------------------------------------------*/
23163
23164   QUnit.module('lodash.toPairs');
23165
23166   (function() {
23167     QUnit.test('should be aliased', function(assert) {
23168       assert.expect(1);
23169
23170       assert.strictEqual(_.entries, _.toPairs);
23171     });
23172   }());
23173
23174   /*--------------------------------------------------------------------------*/
23175
23176   QUnit.module('lodash.toPairsIn');
23177
23178   (function() {
23179     QUnit.test('should be aliased', function(assert) {
23180       assert.expect(1);
23181
23182       assert.strictEqual(_.entriesIn, _.toPairsIn);
23183     });
23184   }());
23185
23186   /*--------------------------------------------------------------------------*/
23187
23188   QUnit.module('toPairs methods');
23189
23190   lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
23191     var func = _[methodName],
23192         isToPairs = methodName == 'toPairs';
23193
23194     QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
23195       assert.expect(1);
23196
23197       var object = { 'a': 1, 'b': 2 },
23198           actual = lodashStable.sortBy(func(object), 0);
23199
23200       assert.deepEqual(actual, [['a', 1], ['b', 2]]);
23201     });
23202
23203     QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
23204       assert.expect(1);
23205
23206       var object = { '0': 'a', '1': 'b', 'length': 2 },
23207           actual = lodashStable.sortBy(func(object), 0);
23208
23209       assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
23210     });
23211
23212     QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
23213       assert.expect(1);
23214
23215       function Foo() {
23216         this.a = 1;
23217       }
23218       Foo.prototype.b = 2;
23219
23220       var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
23221           actual = lodashStable.sortBy(func(new Foo), 0);
23222
23223       assert.deepEqual(actual, expected);
23224     });
23225
23226     QUnit.test('`_.' + methodName + '` should work with strings', function(assert) {
23227       assert.expect(2);
23228
23229       lodashStable.each(['xo', Object('xo')], function(string) {
23230         var actual = lodashStable.sortBy(func(string), 0);
23231         assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
23232       });
23233     });
23234   });
23235
23236   /*--------------------------------------------------------------------------*/
23237
23238   QUnit.module('lodash.toPath');
23239
23240   (function() {
23241     QUnit.test('should convert a string to a path', function(assert) {
23242       assert.expect(2);
23243
23244       assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
23245       assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
23246     });
23247
23248     QUnit.test('should coerce array elements to strings', function(assert) {
23249       assert.expect(4);
23250
23251       var array = ['a', 'b', 'c'];
23252
23253       lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
23254         var actual = _.toPath(value);
23255         assert.deepEqual(actual, array);
23256         assert.notStrictEqual(actual, array);
23257       });
23258     });
23259
23260     QUnit.test('should a new path array', function(assert) {
23261       assert.expect(1);
23262
23263       assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
23264     });
23265
23266     QUnit.test('should not coerce symbols to strings', function(assert) {
23267       assert.expect(4);
23268
23269       if (Symbol) {
23270         var object = Object(symbol);
23271         lodashStable.each([symbol, object, [symbol], [object]], function(value) {
23272           var actual = _.toPath(value);
23273           assert.ok(lodashStable.isSymbol(actual[0]));
23274         });
23275       }
23276       else {
23277         skipAssert(assert, 4);
23278       }
23279     });
23280
23281     QUnit.test('should handle complex paths', function(assert) {
23282       assert.expect(1);
23283
23284       var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
23285       assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
23286     });
23287
23288     QUnit.test('should ignore consecutive brackets and dots', function(assert) {
23289       assert.expect(4);
23290
23291       var expected = ['a'];
23292       assert.deepEqual(_.toPath('a.'), expected);
23293       assert.deepEqual(_.toPath('a[]'), expected);
23294
23295       expected = ['a', 'b'];
23296       assert.deepEqual(_.toPath('a..b'), expected);
23297       assert.deepEqual(_.toPath('a[][]b'), expected);
23298     });
23299   }());
23300
23301   /*--------------------------------------------------------------------------*/
23302
23303   QUnit.module('lodash.toPlainObject');
23304
23305   (function() {
23306     var args = arguments;
23307
23308     QUnit.test('should flatten inherited string keyed properties', function(assert) {
23309       assert.expect(1);
23310
23311       function Foo() {
23312         this.b = 2;
23313       }
23314       Foo.prototype.c = 3;
23315
23316       var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
23317       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
23318     });
23319
23320     QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
23321       assert.expect(1);
23322
23323       var actual = _.toPlainObject(args),
23324           expected = { '0': 1, '1': 2, '2': 3 };
23325
23326       assert.deepEqual(actual, expected);
23327     });
23328
23329     QUnit.test('should convert arrays to plain objects', function(assert) {
23330       assert.expect(1);
23331
23332       var actual = _.toPlainObject(['a', 'b', 'c']),
23333           expected = { '0': 'a', '1': 'b', '2': 'c' };
23334
23335       assert.deepEqual(actual, expected);
23336     });
23337   }(1, 2, 3));
23338
23339   /*--------------------------------------------------------------------------*/
23340
23341   QUnit.module('lodash.toString');
23342
23343   (function() {
23344     QUnit.test('should treat nullish values as empty strings', function(assert) {
23345       assert.expect(1);
23346
23347       var values = [, null, undefined],
23348           expected = lodashStable.map(values, alwaysEmptyString);
23349
23350       var actual = lodashStable.map(values, function(value, index) {
23351         return index ? _.toString(value) : _.toString();
23352       });
23353
23354       assert.deepEqual(actual, expected);
23355     });
23356
23357     QUnit.test('should preserve the sign of `0`', function(assert) {
23358       assert.expect(1);
23359
23360       var values = [-0, Object(-0), 0, Object(0)],
23361           expected = ['-0', '-0', '0', '0'],
23362           actual = lodashStable.map(values, _.toString);
23363
23364       assert.deepEqual(actual, expected);
23365     });
23366
23367     QUnit.test('should not error on symbols', function(assert) {
23368       assert.expect(1);
23369
23370       if (Symbol) {
23371         try {
23372           assert.strictEqual(_.toString(symbol), 'Symbol(a)');
23373         } catch (e) {
23374           assert.ok(false, e.message);
23375         }
23376       }
23377       else {
23378         skipAssert(assert);
23379       }
23380     });
23381
23382     QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
23383       assert.expect(1);
23384
23385       if (!isNpm) {
23386         var wrapped = _([1, 2, 3]);
23387         assert.strictEqual(wrapped.toString(), '1,2,3');
23388       }
23389       else {
23390         skipAssert(assert);
23391       }
23392     });
23393   }());
23394
23395   /*--------------------------------------------------------------------------*/
23396
23397   QUnit.module('lodash.transform');
23398
23399   (function() {
23400     function Foo() {
23401       this.a = 1;
23402       this.b = 2;
23403       this.c = 3;
23404     }
23405
23406     QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
23407       assert.expect(4);
23408
23409       var accumulators = [, null, undefined],
23410           object = new Foo,
23411           expected = lodashStable.map(accumulators, alwaysTrue);
23412
23413       var iteratee = function(result, value, key) {
23414         result[key] = square(value);
23415       };
23416
23417       var mapper = function(accumulator, index) {
23418         return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
23419       };
23420
23421       var results = lodashStable.map(accumulators, mapper);
23422
23423       var actual = lodashStable.map(results, function(result) {
23424         return result instanceof Foo;
23425       });
23426
23427       assert.deepEqual(actual, expected);
23428
23429       expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
23430       actual = lodashStable.map(results, lodashStable.toPlainObject);
23431
23432       assert.deepEqual(actual, expected);
23433
23434       object = { 'a': 1, 'b': 2, 'c': 3 };
23435       actual = lodashStable.map(accumulators, mapper);
23436
23437       assert.deepEqual(actual, expected);
23438
23439       object = [1, 2, 3];
23440       expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
23441       actual = lodashStable.map(accumulators, mapper);
23442
23443       assert.deepEqual(actual, expected);
23444     });
23445
23446     QUnit.test('should create regular arrays from typed arrays', function(assert) {
23447       assert.expect(1);
23448
23449       var expected = lodashStable.map(typedArrays, alwaysTrue);
23450
23451       var actual = lodashStable.map(typedArrays, function(type) {
23452         var Ctor = root[type],
23453             array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
23454
23455         return lodashStable.isArray(_.transform(array, noop));
23456       });
23457
23458       assert.deepEqual(actual, expected);
23459     });
23460
23461     QUnit.test('should support an `accumulator` value', function(assert) {
23462       assert.expect(6);
23463
23464       var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
23465           expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
23466
23467       var actual = lodashStable.map(values, function(value) {
23468         return _.transform(value, function(result, value) {
23469           result.push(square(value));
23470         }, []);
23471       });
23472
23473       assert.deepEqual(actual, expected);
23474
23475       var object = { 'a': 1, 'b': 4, 'c': 9 },
23476       expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
23477
23478       actual = lodashStable.map(values, function(value) {
23479         return _.transform(value, function(result, value, key) {
23480           result[key] = square(value);
23481         }, {});
23482       });
23483
23484       assert.deepEqual(actual, expected);
23485
23486       lodashStable.each([[], {}], function(accumulator) {
23487         var actual = lodashStable.map(values, function(value) {
23488           return _.transform(value, noop, accumulator);
23489         });
23490
23491         assert.ok(lodashStable.every(actual, function(result) {
23492           return result === accumulator;
23493         }));
23494
23495         assert.strictEqual(_.transform(null, null, accumulator), accumulator);
23496       });
23497     });
23498
23499     QUnit.test('should treat sparse arrays as dense', function(assert) {
23500       assert.expect(1);
23501
23502       var actual = _.transform(Array(1), function(result, value, index) {
23503         result[index] = String(value);
23504       });
23505
23506       assert.deepEqual(actual, ['undefined']);
23507     });
23508
23509     QUnit.test('should work without an `iteratee` argument', function(assert) {
23510       assert.expect(1);
23511
23512       assert.ok(_.transform(new Foo) instanceof Foo);
23513     });
23514
23515     QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
23516       assert.expect(2);
23517
23518       var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
23519           values = [false, true, 0, 1, NaN, '', 'a'],
23520           expected = lodashStable.map(values, alwaysEmptyObject);
23521
23522       var results = lodashStable.map(values, function(value) {
23523         return _.transform(value);
23524       });
23525
23526       assert.deepEqual(results, expected);
23527
23528       expected = lodashStable.map(values, alwaysFalse);
23529
23530       var actual = lodashStable.map(results, function(value, index) {
23531         return value instanceof Ctors[index];
23532       });
23533
23534       assert.deepEqual(actual, expected);
23535     });
23536
23537     QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
23538       assert.expect(1);
23539
23540       Foo.prototype.constructor = null;
23541       assert.notOk(_.transform(new Foo) instanceof Foo);
23542       Foo.prototype.constructor = Foo;
23543     });
23544
23545     QUnit.test('should create an empty object when given a falsey `object` argument', function(assert) {
23546       assert.expect(1);
23547
23548       var expected = lodashStable.map(falsey, alwaysEmptyObject);
23549
23550       var actual = lodashStable.map(falsey, function(object, index) {
23551         return index ? _.transform(object) : _.transform();
23552       });
23553
23554       assert.deepEqual(actual, expected);
23555     });
23556
23557     lodashStable.each({
23558       'array': [1, 2, 3],
23559       'object': { 'a': 1, 'b': 2, 'c': 3 }
23560     },
23561     function(object, key) {
23562       QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
23563         assert.expect(2);
23564
23565         var args;
23566
23567         _.transform(object, function() {
23568           args || (args = slice.call(arguments));
23569         });
23570
23571         var first = args[0];
23572         if (key == 'array') {
23573           assert.ok(first !== object && lodashStable.isArray(first));
23574           assert.deepEqual(args, [first, 1, 0, object]);
23575         } else {
23576           assert.ok(first !== object && lodashStable.isPlainObject(first));
23577           assert.deepEqual(args, [first, 1, 'a', object]);
23578         }
23579       });
23580     });
23581
23582     QUnit.test('should create an object from the same realm as `object`', function(assert) {
23583       assert.expect(1);
23584
23585       var objects = lodashStable.filter(realm, function(value) {
23586         return lodashStable.isObject(value) && !lodashStable.isElement(value);
23587       });
23588
23589       var expected = lodashStable.map(objects, alwaysTrue);
23590
23591       var actual = lodashStable.map(objects, function(object) {
23592         var Ctor = object.constructor,
23593             result = _.transform(object);
23594
23595         if (result === object) {
23596           return false;
23597         }
23598         if (lodashStable.isTypedArray(object)) {
23599           return result instanceof Array;
23600         }
23601         return result instanceof Ctor || !(new Ctor instanceof Ctor);
23602       });
23603
23604       assert.deepEqual(actual, expected);
23605     });
23606   }());
23607
23608   /*--------------------------------------------------------------------------*/
23609
23610   QUnit.module('trim methods');
23611
23612   lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
23613     var func = _[methodName],
23614         parts = [];
23615
23616     if (index != 2) {
23617       parts.push('leading');
23618     }
23619     if (index != 1) {
23620       parts.push('trailing');
23621     }
23622     parts = parts.join(' and ');
23623
23624     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
23625       assert.expect(1);
23626
23627       var string = whitespace + 'a b c' + whitespace,
23628           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23629
23630       assert.strictEqual(func(string), expected);
23631     });
23632
23633     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
23634       assert.expect(1);
23635
23636       var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
23637           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23638
23639       assert.strictEqual(func(object), expected);
23640     });
23641
23642     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
23643       assert.expect(1);
23644
23645       var string = '-_-a-b-c-_-',
23646           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
23647
23648       assert.strictEqual(func(string, '_-'), expected);
23649     });
23650
23651     QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
23652       assert.expect(1);
23653
23654       var object = { 'toString': lodashStable.constant('_-') },
23655           string = '-_-a-b-c-_-',
23656           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
23657
23658       assert.strictEqual(func(string, object), expected);
23659     });
23660
23661     QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
23662       assert.expect(6);
23663
23664       lodashStable.each([null, '_-'], function(chars) {
23665         assert.strictEqual(func(null, chars), '');
23666         assert.strictEqual(func(undefined, chars), '');
23667         assert.strictEqual(func('', chars), '');
23668       });
23669     });
23670
23671     QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
23672       assert.expect(2);
23673
23674       var string = whitespace + 'a b c' + whitespace,
23675           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23676
23677       assert.strictEqual(func(string, undefined), expected);
23678       assert.strictEqual(func(string, ''), string);
23679     });
23680
23681     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
23682       assert.expect(1);
23683
23684       var string = Object(whitespace + 'a b c' + whitespace),
23685           trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
23686           actual = lodashStable.map([string, string, string], func);
23687
23688       assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
23689     });
23690
23691     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
23692       assert.expect(1);
23693
23694       if (!isNpm) {
23695         var string = whitespace + 'a b c' + whitespace,
23696             expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23697
23698         assert.strictEqual(_(string)[methodName](), expected);
23699       }
23700       else {
23701         skipAssert(assert);
23702       }
23703     });
23704
23705     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
23706       assert.expect(1);
23707
23708       if (!isNpm) {
23709         var string = whitespace + 'a b c' + whitespace;
23710         assert.ok(_(string).chain()[methodName]() instanceof _);
23711       }
23712       else {
23713         skipAssert(assert);
23714       }
23715     });
23716   });
23717
23718   /*--------------------------------------------------------------------------*/
23719
23720   QUnit.module('uncommon symbols');
23721
23722   (function() {
23723     var flag = '\ud83c\uddfa\ud83c\uddf8',
23724         heart = '\u2764' + emojiVar,
23725         hearts = '\ud83d\udc95',
23726         comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
23727         hashKeycap = '#' + emojiVar + '\u20e3',
23728         leafs = '\ud83c\udf42',
23729         mic = '\ud83c\udf99',
23730         noMic = mic + '\u20e0',
23731         raisedHand = '\u270B' + emojiVar,
23732         rocket = '\ud83d\ude80',
23733         thumbsUp = '\ud83d\udc4d';
23734
23735     QUnit.test('should account for astral symbols', function(assert) {
23736       assert.expect(34);
23737
23738       var allHearts = _.repeat(hearts, 10),
23739           chars = hearts + comboGlyph,
23740           string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
23741           trimChars = comboGlyph + hearts,
23742           trimString = trimChars + string + trimChars;
23743
23744       assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
23745       assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
23746       assert.strictEqual(_.capitalize(rocket), rocket);
23747
23748       assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
23749       assert.strictEqual(_.padStart(string, 16), '   ' + string);
23750       assert.strictEqual(_.padEnd(string, 16), string + '   ');
23751
23752       assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
23753       assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
23754       assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
23755
23756       assert.strictEqual(_.size(string), 13);
23757       assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
23758       assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
23759       assert.deepEqual(_.split(string, undefined), [string]);
23760       assert.deepEqual(_.split(string, undefined, -1), [string]);
23761       assert.deepEqual(_.split(string, undefined, 0), []);
23762
23763       var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
23764
23765       assert.deepEqual(_.split(string, ''), expected);
23766       assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
23767       assert.deepEqual(_.toArray(string), expected);
23768
23769       assert.strictEqual(_.trim(trimString, chars), string);
23770       assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
23771       assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
23772
23773       assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
23774       assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
23775
23776       assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
23777       assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
23778       assert.deepEqual(_.toArray(noMic), [noMic]);
23779
23780       lodashStable.times(2, function(index) {
23781         var separator = index ? RegExp(hearts) : hearts,
23782             options = { 'length': 4, 'separator': separator },
23783             actual = _.truncate(string, options);
23784
23785         assert.strictEqual(actual, 'A...');
23786         assert.strictEqual(actual.length, 4);
23787
23788         actual = _.truncate(allHearts, options);
23789         assert.strictEqual(actual, hearts + '...');
23790         assert.strictEqual(actual.length, 5);
23791       });
23792     });
23793
23794     QUnit.test('should account for combining diacritical marks', function(assert) {
23795       assert.expect(1);
23796
23797       var values = lodashStable.map(comboMarks, function(mark) {
23798         return 'o' + mark;
23799       });
23800
23801       var expected = lodashStable.map(values, function(value) {
23802         return [1, [value], [value]];
23803       });
23804
23805       var actual = lodashStable.map(values, function(value) {
23806         return [_.size(value), _.toArray(value), _.words(value)];
23807       });
23808
23809       assert.deepEqual(actual, expected);
23810     });
23811
23812     QUnit.test('should account for fitzpatrick modifiers', function(assert) {
23813       assert.expect(1);
23814
23815       var values = lodashStable.map(fitzModifiers, function(modifier) {
23816         return thumbsUp + modifier;
23817       });
23818
23819       var expected = lodashStable.map(values, function(value) {
23820         return [1, [value], [value]];
23821       });
23822
23823       var actual = lodashStable.map(values, function(value) {
23824         return [_.size(value), _.toArray(value), _.words(value)];
23825       });
23826
23827       assert.deepEqual(actual, expected);
23828     });
23829
23830     QUnit.test('should account for regional symbols', function(assert) {
23831       assert.expect(6);
23832
23833       var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
23834           regionals = pair.join(' ');
23835
23836       assert.strictEqual(_.size(flag), 1);
23837       assert.strictEqual(_.size(regionals), 3);
23838
23839       assert.deepEqual(_.toArray(flag), [flag]);
23840       assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
23841
23842       assert.deepEqual(_.words(flag), [flag]);
23843       assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
23844     });
23845
23846     QUnit.test('should account for variation selectors', function(assert) {
23847       assert.expect(3);
23848
23849       assert.strictEqual(_.size(heart), 1);
23850       assert.deepEqual(_.toArray(heart), [heart]);
23851       assert.deepEqual(_.words(heart), [heart]);
23852     });
23853
23854     QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
23855       assert.expect(1);
23856
23857       var values = lodashStable.map(fitzModifiers, function(modifier) {
23858         return raisedHand + modifier;
23859       });
23860
23861       var expected = lodashStable.map(values, function(value) {
23862         return [1, [value], [value]];
23863       });
23864
23865       var actual = lodashStable.map(values, function(value) {
23866         return [_.size(value), _.toArray(value), _.words(value)];
23867       });
23868
23869       assert.deepEqual(actual, expected);
23870     });
23871
23872     QUnit.test('should match lone surrogates', function(assert) {
23873       assert.expect(3);
23874
23875       var pair = hearts.split(''),
23876           surrogates = pair[0] + ' ' + pair[1];
23877
23878       assert.strictEqual(_.size(surrogates), 3);
23879       assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
23880       assert.deepEqual(_.words(surrogates), []);
23881     });
23882
23883     QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
23884       assert.expect(1);
23885
23886       var string = fitzModifiers[0] + fitzModifiers[0];
23887       assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
23888     });
23889   }());
23890
23891   /*--------------------------------------------------------------------------*/
23892
23893   QUnit.module('lodash.unary');
23894
23895   (function() {
23896     function fn() {
23897       return slice.call(arguments);
23898     }
23899
23900     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
23901       assert.expect(1);
23902
23903       var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
23904       assert.deepEqual(actual, [6, 8, 10]);
23905     });
23906
23907     QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
23908       assert.expect(1);
23909
23910       var capped = _.unary(fn);
23911       assert.deepEqual(capped(), []);
23912     });
23913   }());
23914
23915   /*--------------------------------------------------------------------------*/
23916
23917   QUnit.module('lodash.unescape');
23918
23919   (function() {
23920     var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
23921         unescaped = '&<>"\'\/';
23922
23923     escaped += escaped;
23924     unescaped += unescaped;
23925
23926     QUnit.test('should unescape entities in order', function(assert) {
23927       assert.expect(1);
23928
23929       assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
23930     });
23931
23932     QUnit.test('should unescape the proper entities', function(assert) {
23933       assert.expect(1);
23934
23935       assert.strictEqual(_.unescape(escaped), unescaped);
23936     });
23937
23938     QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
23939       assert.expect(1);
23940
23941       assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
23942     });
23943
23944     QUnit.test('should handle strings with nothing to unescape', function(assert) {
23945       assert.expect(1);
23946
23947       assert.strictEqual(_.unescape('abc'), 'abc');
23948     });
23949
23950     QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
23951       assert.expect(1);
23952
23953       assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
23954     });
23955   }());
23956
23957   /*--------------------------------------------------------------------------*/
23958
23959   QUnit.module('lodash.unionBy');
23960
23961   (function() {
23962     QUnit.test('should accept an `iteratee` argument', function(assert) {
23963       assert.expect(2);
23964
23965       var actual = _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
23966       assert.deepEqual(actual, [2.1, 1.2, 4.3]);
23967
23968       actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
23969       assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
23970     });
23971
23972     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23973       assert.expect(1);
23974
23975       var args;
23976
23977       _.unionBy([2.1, 1.2], [4.3, 2.4], function() {
23978         args || (args = slice.call(arguments));
23979       });
23980
23981       assert.deepEqual(args, [2.1]);
23982     });
23983   }());
23984
23985   /*--------------------------------------------------------------------------*/
23986
23987   QUnit.module('lodash.unionWith');
23988
23989   (function() {
23990     QUnit.test('should work with a `comparator` argument', function(assert) {
23991       assert.expect(1);
23992
23993       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
23994           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
23995           actual = _.unionWith(objects, others, lodashStable.isEqual);
23996
23997       assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
23998     });
23999   }());
24000
24001   /*--------------------------------------------------------------------------*/
24002
24003   QUnit.module('union methods');
24004
24005   lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
24006     var args = (function() { return arguments; }(1, 2, 3)),
24007         func = _[methodName];
24008
24009     QUnit.test('`_.' + methodName + '` should return the union of the given arrays', function(assert) {
24010       assert.expect(1);
24011
24012       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
24013       assert.deepEqual(actual, [1, 3, 2, 5, 4]);
24014     });
24015
24016     QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
24017       assert.expect(1);
24018
24019       var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
24020       assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
24021     });
24022
24023     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24024       assert.expect(3);
24025
24026       var array = [0];
24027       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24028       assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
24029       assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
24030     });
24031   });
24032
24033   /*--------------------------------------------------------------------------*/
24034
24035   QUnit.module('lodash.uniq');
24036
24037   (function() {
24038     QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
24039       assert.expect(1);
24040
24041       var array = [[2, 1, 2], [1, 2, 1]],
24042           actual = lodashStable.map(array, lodashStable.uniq);
24043
24044       assert.deepEqual(actual, [[2, 1], [1, 2]]);
24045     });
24046   }());
24047
24048   /*--------------------------------------------------------------------------*/
24049
24050   QUnit.module('uniqBy methods');
24051
24052   lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
24053     var func = _[methodName],
24054         isSorted = methodName == 'sortedUniqBy',
24055         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24056
24057     if (isSorted) {
24058       objects = _.sortBy(objects, 'a');
24059     }
24060     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
24061       assert.expect(1);
24062
24063       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
24064
24065       var actual = func(objects, function(object) {
24066         return object.a;
24067       });
24068
24069       assert.deepEqual(actual, expected);
24070     });
24071
24072     QUnit.test('should work with large arrays', function(assert) {
24073       assert.expect(2);
24074
24075       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
24076         return [1, 2];
24077       });
24078
24079       var actual = func(largeArray, String);
24080
24081       assert.deepEqual(actual, [[1, 2]]);
24082       assert.strictEqual(actual[0], largeArray[0]);
24083     });
24084
24085     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
24086       assert.expect(1);
24087
24088       var args;
24089
24090       func(objects, function() {
24091         args || (args = slice.call(arguments));
24092       });
24093
24094       assert.deepEqual(args, [objects[0]]);
24095     });
24096
24097     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
24098       assert.expect(2);
24099
24100       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
24101           actual = func(objects, 'a');
24102
24103       assert.deepEqual(actual, expected);
24104
24105       var arrays = [[2], [3], [1], [2], [3], [1]];
24106       if (isSorted) {
24107         arrays = lodashStable.sortBy(arrays, 0);
24108       }
24109       expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
24110       actual = func(arrays, 0);
24111
24112       assert.deepEqual(actual, expected);
24113     });
24114
24115     lodashStable.each({
24116       'an array': [0, 'a'],
24117       'an object': { '0': 'a' },
24118       'a number': 0,
24119       'a string': '0'
24120     },
24121     function(iteratee, key) {
24122       QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
24123         assert.expect(1);
24124
24125         var actual = func([['a'], ['a'], ['b']], iteratee);
24126         assert.deepEqual(actual, [['a'], ['b']]);
24127       });
24128     });
24129   });
24130
24131   /*--------------------------------------------------------------------------*/
24132
24133   QUnit.module('lodash.uniqWith');
24134
24135   (function() {
24136     QUnit.test('should work with a `comparator` argument', function(assert) {
24137       assert.expect(1);
24138
24139       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }],
24140           actual = _.uniqWith(objects, lodashStable.isEqual);
24141
24142       assert.deepEqual(actual, [objects[0], objects[1]]);
24143     });
24144
24145     QUnit.test('should preserve the sign of `0`', function(assert) {
24146       assert.expect(1);
24147
24148       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24149         return isEven(index) ? -0 : 0;
24150       });
24151
24152       var arrays = [[-0, 0], largeArray],
24153           expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
24154
24155       var actual = lodashStable.map(arrays, function(array) {
24156         return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
24157       });
24158
24159       assert.deepEqual(actual, expected);
24160     });
24161   }());
24162
24163   /*--------------------------------------------------------------------------*/
24164
24165   QUnit.module('uniq methods');
24166
24167   lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
24168     var func = _[methodName],
24169         isSorted = /^sorted/.test(methodName),
24170         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24171
24172     if (isSorted) {
24173       objects = _.sortBy(objects, 'a');
24174     }
24175     else {
24176       QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
24177         assert.expect(1);
24178
24179         var array = [2, 3, 1, 2, 3, 1];
24180         assert.deepEqual(func(array), [2, 3, 1]);
24181       });
24182     }
24183     QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
24184       assert.expect(1);
24185
24186       var array = [1, 1, 2, 2, 3];
24187       assert.deepEqual(func(array), [1, 2, 3]);
24188     });
24189
24190     QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
24191       assert.expect(1);
24192
24193       assert.deepEqual(func(objects), objects);
24194     });
24195
24196     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
24197       assert.expect(1);
24198
24199       var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
24200       assert.deepEqual(actual, ['0']);
24201     });
24202
24203     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
24204       assert.expect(1);
24205
24206       assert.deepEqual(func([NaN, NaN]), [NaN]);
24207     });
24208
24209     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
24210       assert.expect(1);
24211
24212       var largeArray = [],
24213           expected = [0, {}, 'a'],
24214           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24215
24216       lodashStable.each(expected, function(value) {
24217         lodashStable.times(count, function() {
24218           largeArray.push(value);
24219         });
24220       });
24221
24222       assert.deepEqual(func(largeArray), expected);
24223     });
24224
24225     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
24226       assert.expect(1);
24227
24228       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24229         return isEven(index) ? -0 : 0;
24230       });
24231
24232       var actual = lodashStable.map(func(largeArray), lodashStable.toString);
24233       assert.deepEqual(actual, ['0']);
24234     });
24235
24236     QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
24237       assert.expect(1);
24238
24239       var largeArray = [],
24240           expected = [null, undefined, false, true, NaN],
24241           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24242
24243       lodashStable.each(expected, function(value) {
24244         lodashStable.times(count, function() {
24245           largeArray.push(value);
24246         });
24247       });
24248
24249       assert.deepEqual(func(largeArray), expected);
24250     });
24251
24252     QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
24253       assert.expect(1);
24254
24255       if (Symbol) {
24256         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
24257         assert.deepEqual(func(largeArray), largeArray);
24258       }
24259       else {
24260         skipAssert(assert);
24261       }
24262     });
24263
24264     QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
24265       assert.expect(1);
24266
24267       // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
24268       if (Symbol) {
24269         var expected = [
24270           Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
24271           Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
24272           Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
24273         ];
24274
24275         var largeArray = [],
24276             count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24277
24278         expected = lodashStable.map(expected, function(symbol) {
24279           return symbol || {};
24280         });
24281
24282         lodashStable.each(expected, function(value) {
24283           lodashStable.times(count, function() {
24284             largeArray.push(value);
24285           });
24286         });
24287
24288         assert.deepEqual(func(largeArray), expected);
24289       }
24290       else {
24291         skipAssert(assert);
24292       }
24293     });
24294
24295     QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
24296       assert.expect(1);
24297
24298       var largeArray = [],
24299           expected = ['2', 2, Object('2'), Object(2)],
24300           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24301
24302       lodashStable.each(expected, function(value) {
24303         lodashStable.times(count, function() {
24304           largeArray.push(value);
24305         });
24306       });
24307
24308       assert.deepEqual(func(largeArray), expected);
24309     });
24310   });
24311
24312   /*--------------------------------------------------------------------------*/
24313
24314   QUnit.module('lodash.uniqueId');
24315
24316   (function() {
24317     QUnit.test('should generate unique ids', function(assert) {
24318       assert.expect(1);
24319
24320       var actual = lodashStable.times(1000, function(assert) {
24321         return _.uniqueId();
24322       });
24323
24324       assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
24325     });
24326
24327     QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
24328       assert.expect(1);
24329
24330       assert.strictEqual(typeof _.uniqueId(), 'string');
24331     });
24332
24333     QUnit.test('should coerce the prefix argument to a string', function(assert) {
24334       assert.expect(1);
24335
24336       var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
24337       assert.ok(/3\d+,2\d+,1\d+/.test(actual));
24338     });
24339   }());
24340
24341   /*--------------------------------------------------------------------------*/
24342
24343   QUnit.module('lodash.unset');
24344
24345   (function() {
24346     QUnit.test('should unset property values', function(assert) {
24347       assert.expect(4);
24348
24349       lodashStable.each(['a', ['a']], function(path) {
24350         var object = { 'a': 1, 'c': 2 };
24351         assert.strictEqual(_.unset(object, path), true);
24352         assert.deepEqual(object, { 'c': 2 });
24353       });
24354     });
24355
24356     QUnit.test('should preserve the sign of `0`', function(assert) {
24357       assert.expect(1);
24358
24359       var props = [-0, Object(-0), 0, Object(0)],
24360           expected = lodashStable.map(props, lodashStable.constant([true, false]));
24361
24362       var actual = lodashStable.map(props, function(key) {
24363         var object = { '-0': 'a', '0': 'b' };
24364         return [_.unset(object, key), lodashStable.toString(key) in object];
24365       });
24366
24367       assert.deepEqual(actual, expected);
24368     });
24369
24370     QUnit.test('should unset symbol keyed property values', function(assert) {
24371       assert.expect(2);
24372
24373       if (Symbol) {
24374         var object = {};
24375         object[symbol] = 1;
24376
24377         assert.strictEqual(_.unset(object, symbol), true);
24378         assert.notOk(symbol in object);
24379       }
24380       else {
24381         skipAssert(assert, 2);
24382       }
24383     });
24384
24385     QUnit.test('should unset deep property values', function(assert) {
24386       assert.expect(4);
24387
24388       lodashStable.each(['a.b', ['a', 'b']], function(path) {
24389         var object = { 'a': { 'b': null } };
24390         assert.strictEqual(_.unset(object, path), true);
24391         assert.deepEqual(object, { 'a': {} });
24392       });
24393     });
24394
24395     QUnit.test('should handle complex paths', function(assert) {
24396       assert.expect(4);
24397
24398       var paths = [
24399         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
24400         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
24401       ];
24402
24403       lodashStable.each(paths, function(path) {
24404         var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
24405         assert.strictEqual(_.unset(object, path), true);
24406         assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
24407       });
24408     });
24409
24410     QUnit.test('should return `true` for nonexistent paths', function(assert) {
24411       assert.expect(5);
24412
24413       var object = { 'a': { 'b': { 'c': null } } };
24414
24415       lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
24416         assert.strictEqual(_.unset(object, path), true);
24417       });
24418
24419       assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
24420     });
24421
24422     QUnit.test('should not error when `object` is nullish', function(assert) {
24423       assert.expect(1);
24424
24425       var values = [null, undefined],
24426           expected = [[true, true], [true, true]];
24427
24428       var actual = lodashStable.map(values, function(value) {
24429         try {
24430           return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
24431         } catch (e) {
24432           return e.message;
24433         }
24434       });
24435
24436       assert.deepEqual(actual, expected);
24437     });
24438
24439     QUnit.test('should follow `path` over non-plain objects', function(assert) {
24440       assert.expect(8);
24441
24442       var object = { 'a': '' },
24443           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
24444
24445       lodashStable.each(paths, function(path) {
24446         numberProto.a = 1;
24447
24448         var actual = _.unset(0, path);
24449         assert.strictEqual(actual, true);
24450         assert.notOk('a' in numberProto);
24451
24452         delete numberProto.a;
24453       });
24454
24455       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
24456         stringProto.replace.b = 1;
24457
24458         var actual = _.unset(object, path);
24459         assert.strictEqual(actual, true);
24460         assert.notOk('a' in stringProto.replace);
24461
24462         delete stringProto.replace.b;
24463       });
24464     });
24465
24466     QUnit.test('should return `false` for non-configurable properties', function(assert) {
24467       assert.expect(1);
24468
24469       var object = {};
24470
24471       if (!isStrict && defineProperty) {
24472         defineProperty(object, 'a', {
24473           'configurable': false,
24474           'enumerable': true,
24475           'writable': true,
24476           'value': 1,
24477         });
24478         assert.strictEqual(_.unset(object, 'a'), false);
24479       }
24480       else {
24481         skipAssert(assert);
24482       }
24483     });
24484   }());
24485
24486   /*--------------------------------------------------------------------------*/
24487
24488   QUnit.module('lodash.unzipWith');
24489
24490   (function() {
24491     QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
24492       assert.expect(1);
24493
24494       var array = [[1, 4], [2, 5], [3, 6]];
24495
24496       var actual = _.unzipWith(array, function(a, b, c) {
24497         return a + b + c;
24498       });
24499
24500       assert.deepEqual(actual, [6, 15]);
24501     });
24502
24503     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24504       assert.expect(1);
24505
24506       var args;
24507
24508       _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
24509         args || (args = slice.call(arguments));
24510       });
24511
24512       assert.deepEqual(args, [1, 2]);
24513     });
24514
24515     QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
24516       assert.expect(1);
24517
24518       var array = [[1, 3], [2, 4]],
24519           values = [, null, undefined],
24520           expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
24521
24522       var actual = lodashStable.map(values, function(value, index) {
24523         return index ? _.unzipWith(array, value) : _.unzipWith(array);
24524       });
24525
24526       assert.deepEqual(actual, expected);
24527     });
24528   }());
24529
24530   /*--------------------------------------------------------------------------*/
24531
24532   QUnit.module('lodash.updateWith');
24533
24534   (function() {
24535     QUnit.test('should work with a `customizer` callback', function(assert) {
24536       assert.expect(1);
24537
24538       var actual = _.updateWith({ '0': {} }, '[0][1][2]', alwaysThree, function(value) {
24539         return lodashStable.isObject(value) ? undefined : {};
24540       });
24541
24542       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
24543     });
24544
24545     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
24546       assert.expect(1);
24547
24548       var actual = _.updateWith({}, 'a[0].b.c', alwaysFour, noop);
24549       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
24550     });
24551   }());
24552
24553   /*--------------------------------------------------------------------------*/
24554
24555   QUnit.module('update methods');
24556
24557   lodashStable.each(['update', 'updateWith'], function(methodName) {
24558     var func = _[methodName],
24559         oldValue = 1;
24560
24561     QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
24562       assert.expect(4);
24563
24564       var object = { 'a': [{ 'b': { 'c': oldValue } }] },
24565           expected = oldValue + 1;
24566
24567       lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
24568         func(object, path, function(n) {
24569           assert.strictEqual(n, oldValue);
24570           return ++n;
24571         });
24572
24573         assert.strictEqual(object.a[0].b.c, expected);
24574         object.a[0].b.c = oldValue;
24575       });
24576     });
24577   });
24578
24579   /*--------------------------------------------------------------------------*/
24580
24581   QUnit.module('lodash.upperCase');
24582
24583   (function() {
24584     QUnit.test('should uppercase as space-separated words', function(assert) {
24585       assert.expect(3);
24586
24587       assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
24588       assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
24589       assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
24590     });
24591   }());
24592
24593   /*--------------------------------------------------------------------------*/
24594
24595   QUnit.module('lodash.upperFirst');
24596
24597   (function() {
24598     QUnit.test('should uppercase only the first character', function(assert) {
24599       assert.expect(3);
24600
24601       assert.strictEqual(_.upperFirst('fred'), 'Fred');
24602       assert.strictEqual(_.upperFirst('Fred'), 'Fred');
24603       assert.strictEqual(_.upperFirst('FRED'), 'FRED');
24604     });
24605   }());
24606
24607   /*--------------------------------------------------------------------------*/
24608
24609   QUnit.module('values methods');
24610
24611   lodashStable.each(['values', 'valuesIn'], function(methodName) {
24612     var args = (function() { return arguments; }(1, 2, 3)),
24613         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
24614         func = _[methodName],
24615         isValues = methodName == 'values';
24616
24617     QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
24618       assert.expect(1);
24619
24620       var object = { 'a': 1, 'b': 2 },
24621           actual = func(object).sort();
24622
24623       assert.deepEqual(actual, [1, 2]);
24624     });
24625
24626     QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
24627       assert.expect(1);
24628
24629       var object = { '0': 'a', '1': 'b', 'length': 2 },
24630           actual = func(object).sort();
24631
24632       assert.deepEqual(actual, [2, 'a', 'b']);
24633     });
24634
24635     QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
24636       assert.expect(1);
24637
24638       function Foo() {
24639         this.a = 1;
24640       }
24641       Foo.prototype.b = 2;
24642
24643       var expected = isValues ? [1] : [1, 2],
24644           actual = func(new Foo).sort();
24645
24646       assert.deepEqual(actual, expected);
24647     });
24648
24649     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
24650       assert.expect(1);
24651
24652       var values = [args, strictArgs],
24653           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
24654
24655       var actual = lodashStable.map(values, function(value) {
24656         return func(value).sort();
24657       });
24658
24659       assert.deepEqual(actual, expected);
24660     });
24661   });
24662
24663   /*--------------------------------------------------------------------------*/
24664
24665   QUnit.module('lodash.without');
24666
24667   (function() {
24668     QUnit.test('should use strict equality to determine the values to reject', function(assert) {
24669       assert.expect(2);
24670
24671       var object1 = { 'a': 1 },
24672           object2 = { 'b': 2 },
24673           array = [object1, object2];
24674
24675       assert.deepEqual(_.without(array, { 'a': 1 }), array);
24676       assert.deepEqual(_.without(array, object1), [object2]);
24677     });
24678
24679     QUnit.test('should remove all occurrences of each value from an array', function(assert) {
24680       assert.expect(1);
24681
24682       var array = [1, 2, 3, 1, 2, 3];
24683       assert.deepEqual(_.without(array, 1, 2), [3, 3]);
24684     });
24685   }(1, 2, 3));
24686
24687   /*--------------------------------------------------------------------------*/
24688
24689   QUnit.module('lodash.words');
24690
24691   (function() {
24692     QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
24693       assert.expect(1);
24694
24695       var expected = lodashStable.map(burredLetters, function(letter) {
24696         return [letter];
24697       });
24698
24699       var actual = lodashStable.map(burredLetters, function(letter) {
24700         return _.words(letter);
24701       });
24702
24703       assert.deepEqual(actual, expected);
24704     });
24705
24706     QUnit.test('should not treat mathematical operators as words', function(assert) {
24707       assert.expect(1);
24708
24709       var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
24710           expected = lodashStable.map(operators, alwaysEmptyArray),
24711           actual = lodashStable.map(operators, _.words);
24712
24713       assert.deepEqual(actual, expected);
24714     });
24715
24716     QUnit.test('should not treat punctuation as words', function(assert) {
24717       assert.expect(1);
24718
24719       var marks = [
24720         '\u2012', '\u2013', '\u2014', '\u2015',
24721         '\u2024', '\u2025', '\u2026',
24722         '\u205d', '\u205e'
24723       ];
24724
24725       var expected = lodashStable.map(marks, alwaysEmptyArray),
24726           actual = lodashStable.map(marks, _.words);
24727
24728       assert.deepEqual(actual, expected);
24729     });
24730
24731     QUnit.test('should support a `pattern` argument', function(assert) {
24732       assert.expect(2);
24733
24734       assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
24735       assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
24736     });
24737
24738     QUnit.test('should work with compound words', function(assert) {
24739       assert.expect(12);
24740
24741       assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
24742       assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
24743       assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
24744       assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
24745       assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
24746       assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
24747       assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
24748       assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
24749       assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
24750       assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
24751       assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
24752       assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
24753     });
24754
24755     QUnit.test('should work with compound words containing diacritical marks', function(assert) {
24756       assert.expect(3);
24757
24758       assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
24759       assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
24760       assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
24761     });
24762
24763     QUnit.test('should work with contractions', function(assert) {
24764       assert.expect(2);
24765
24766       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
24767
24768       lodashStable.each(["'", '\u2019'], function(apos) {
24769         var actual = lodashStable.map(postfixes, function(postfix) {
24770           return _.words('a b' + apos + postfix +  ' c');
24771         });
24772
24773         var expected = lodashStable.map(postfixes, function(postfix) {
24774           return ['a', 'b' + apos + postfix, 'c'];
24775         });
24776
24777         assert.deepEqual(actual, expected);
24778       });
24779     });
24780
24781     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
24782       assert.expect(1);
24783
24784       var strings = lodashStable.map(['a', 'b', 'c'], Object),
24785           actual = lodashStable.map(strings, _.words);
24786
24787       assert.deepEqual(actual, [['a'], ['b'], ['c']]);
24788     });
24789   }());
24790
24791   /*--------------------------------------------------------------------------*/
24792
24793   QUnit.module('lodash.wrap');
24794
24795   (function() {
24796     QUnit.test('should create a wrapped function', function(assert) {
24797       assert.expect(1);
24798
24799       var p = _.wrap(_.escape, function(func, text) {
24800         return '<p>' + func(text) + '</p>';
24801       });
24802
24803       assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
24804     });
24805
24806     QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
24807       assert.expect(1);
24808
24809       var args;
24810
24811       var wrapped = _.wrap(noop, function() {
24812         args || (args = slice.call(arguments));
24813       });
24814
24815       wrapped(1, 2, 3);
24816       assert.deepEqual(args, [noop, 1, 2, 3]);
24817     });
24818
24819     QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
24820       assert.expect(1);
24821
24822       var values = [, null, undefined],
24823           expected = lodashStable.map(values, alwaysA);
24824
24825       var actual = lodashStable.map(values, function(value, index) {
24826         var wrapped = index ? _.wrap('a', value) : _.wrap('a');
24827         return wrapped('b', 'c');
24828       });
24829
24830       assert.deepEqual(actual, expected);
24831     });
24832
24833     QUnit.test('should not set a `this` binding', function(assert) {
24834       assert.expect(1);
24835
24836       var p = _.wrap(_.escape, function(func) {
24837         return '<p>' + func(this.text) + '</p>';
24838       });
24839
24840       var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
24841       assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
24842     });
24843   }());
24844
24845   /*--------------------------------------------------------------------------*/
24846
24847   QUnit.module('xor methods');
24848
24849   lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
24850     var args = (function() { return arguments; }(1, 2, 3)),
24851         func = _[methodName];
24852
24853     QUnit.test('`_.' + methodName + '` should return the symmetric difference of the given arrays', function(assert) {
24854       assert.expect(1);
24855
24856       var actual = func([1, 2, 5], [2, 3, 5], [3, 4, 5]);
24857       assert.deepEqual(actual, [1, 4, 5]);
24858     });
24859
24860     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
24861       assert.expect(2);
24862
24863       var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
24864       assert.deepEqual(actual, [1, 4, 5]);
24865
24866       actual = func([1, 1]);
24867       assert.deepEqual(actual, [1]);
24868     });
24869
24870     QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
24871       assert.expect(1);
24872
24873       var array = [1];
24874       assert.notStrictEqual(func(array), array);
24875     });
24876
24877     QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
24878       assert.expect(1);
24879
24880       var array = [0];
24881       assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
24882     });
24883
24884     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24885       assert.expect(3);
24886
24887       var array = [1, 2];
24888       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24889       assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
24890       assert.deepEqual(func(array, null, args, null), [3]);
24891     });
24892
24893     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
24894       assert.expect(1);
24895
24896       if (!isNpm) {
24897         var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
24898         assert.ok(wrapped instanceof _);
24899       }
24900       else {
24901         skipAssert(assert);
24902       }
24903     });
24904
24905     QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
24906       assert.expect(1);
24907
24908       if (!isNpm) {
24909         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
24910             wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
24911
24912         var actual = lodashStable.map(['head', 'last'], function(methodName) {
24913           return wrapped[methodName]();
24914         });
24915
24916         assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
24917       }
24918       else {
24919         skipAssert(assert);
24920       }
24921     });
24922   });
24923
24924   /*--------------------------------------------------------------------------*/
24925
24926   QUnit.module('lodash.xorBy');
24927
24928   (function() {
24929     QUnit.test('should accept an `iteratee` argument', function(assert) {
24930       assert.expect(2);
24931
24932       var actual = _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
24933       assert.deepEqual(actual, [1.2, 4.3]);
24934
24935       actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
24936       assert.deepEqual(actual, [{ 'x': 2 }]);
24937     });
24938
24939     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24940       assert.expect(1);
24941
24942       var args;
24943
24944       _.xorBy([2.1, 1.2], [4.3, 2.4], function() {
24945         args || (args = slice.call(arguments));
24946       });
24947
24948       assert.deepEqual(args, [4.3]);
24949     });
24950   }());
24951
24952   /*--------------------------------------------------------------------------*/
24953
24954   QUnit.module('lodash.xorWith');
24955
24956   (function() {
24957     QUnit.test('should work with a `comparator` argument', function(assert) {
24958       assert.expect(1);
24959
24960       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
24961           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
24962           actual = _.xorWith(objects, others, lodashStable.isEqual);
24963
24964       assert.deepEqual(actual, [objects[1], others[0]]);
24965     });
24966   }());
24967
24968   /*--------------------------------------------------------------------------*/
24969
24970   QUnit.module('zipObject methods');
24971
24972   lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
24973     var func = _[methodName],
24974         object = { 'barney': 36, 'fred': 40 },
24975         isDeep = methodName == 'zipObjectDeep';
24976
24977     QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
24978       assert.expect(1);
24979
24980       var actual = func(['barney', 'fred'], [36, 40]);
24981       assert.deepEqual(actual, object);
24982     });
24983
24984     QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
24985       assert.expect(1);
24986
24987       assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
24988     });
24989
24990     QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
24991       assert.expect(1);
24992
24993       assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
24994     });
24995
24996     QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
24997       assert.expect(2);
24998
24999       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
25000         var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
25001         assert.deepEqual(func([path], [1]), expected);
25002       });
25003     });
25004
25005     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
25006       assert.expect(1);
25007
25008       if (!isNpm) {
25009         var values = lodashStable.range(LARGE_ARRAY_SIZE),
25010             props = lodashStable.map(values, function(value) { return 'key' + value; }),
25011             actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
25012
25013         assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
25014       }
25015       else {
25016         skipAssert(assert);
25017       }
25018     });
25019   });
25020
25021   /*--------------------------------------------------------------------------*/
25022
25023   QUnit.module('lodash.zipWith');
25024
25025   (function() {
25026     QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
25027       assert.expect(2);
25028
25029       var array1 = [1, 2, 3],
25030           array2 = [4, 5, 6],
25031           array3 = [7, 8, 9];
25032
25033       var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
25034         return a + b + c;
25035       });
25036
25037       assert.deepEqual(actual, [12, 15, 18]);
25038
25039       var actual = _.zipWith(array1, [], function(a, b) {
25040         return a + (b || 0);
25041       });
25042
25043       assert.deepEqual(actual, [1, 2, 3]);
25044     });
25045
25046     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
25047       assert.expect(1);
25048
25049       var args;
25050
25051       _.zipWith([1, 2], [3, 4], [5, 6], function() {
25052         args || (args = slice.call(arguments));
25053       });
25054
25055       assert.deepEqual(args, [1, 3, 5]);
25056     });
25057
25058     QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
25059       assert.expect(1);
25060
25061       var array1 = [1, 2],
25062           array2 = [3, 4],
25063           values = [, null, undefined],
25064           expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
25065
25066       var actual = lodashStable.map(values, function(value, index) {
25067         return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
25068       });
25069
25070       assert.deepEqual(actual, expected);
25071     });
25072   }());
25073
25074   /*--------------------------------------------------------------------------*/
25075
25076   QUnit.module('lodash.unzip and lodash.zip');
25077
25078   lodashStable.each(['unzip', 'zip'], function(methodName, index) {
25079     var func = _[methodName];
25080     func = lodashStable.bind(index ? func.apply : func.call, func, null);
25081
25082     var object = {
25083       'an empty array': [
25084         [],
25085         []
25086       ],
25087       '0-tuples': [
25088         [[], []],
25089         []
25090       ],
25091       '2-tuples': [
25092         [['barney', 'fred'], [36, 40]],
25093         [['barney', 36], ['fred', 40]]
25094       ],
25095       '3-tuples': [
25096         [['barney', 'fred'], [36, 40], [false, true]],
25097         [['barney', 36, false], ['fred', 40, true]]
25098       ]
25099     };
25100
25101     lodashStable.forOwn(object, function(pair, key) {
25102       QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
25103         assert.expect(2);
25104
25105         var actual = func(pair[0]);
25106         assert.deepEqual(actual, pair[1]);
25107         assert.deepEqual(func(actual), actual.length ? pair[0] : []);
25108       });
25109     });
25110
25111     QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
25112       assert.expect(4);
25113
25114       var pair = [
25115         [['barney', 36], ['fred', 40, false]],
25116         [['barney', 'fred'], [36, 40], [undefined, false]]
25117       ];
25118
25119       var actual = func(pair[0]);
25120       assert.ok('0' in actual[2]);
25121       assert.deepEqual(actual, pair[1]);
25122
25123       actual = func(actual);
25124       assert.ok('2' in actual[0]);
25125       assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
25126     });
25127
25128     QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
25129       assert.expect(1);
25130
25131       var expected = lodashStable.map(falsey, alwaysEmptyArray);
25132
25133       var actual = lodashStable.map(falsey, function(value) {
25134         return func([value, value, value]);
25135       });
25136
25137       assert.deepEqual(actual, expected);
25138     });
25139
25140     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25141       assert.expect(1);
25142
25143       var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
25144       assert.deepEqual(func(array), [[1, 3], [2, 4]]);
25145     });
25146
25147     QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
25148       assert.expect(1);
25149
25150       var expected = [['barney', 'fred'], [36, 40]];
25151       assert.deepEqual(func(func(func(func(expected)))), expected);
25152     });
25153   });
25154
25155   /*--------------------------------------------------------------------------*/
25156
25157   QUnit.module('lodash(...).commit');
25158
25159   (function() {
25160     QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
25161       assert.expect(4);
25162
25163       if (!isNpm) {
25164         var array = [1],
25165             wrapped = _(array).push(2).push(3);
25166
25167         assert.deepEqual(array, [1]);
25168
25169         var otherWrapper = wrapped.commit();
25170         assert.ok(otherWrapper instanceof _);
25171         assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
25172         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25173       }
25174       else {
25175         skipAssert(assert, 4);
25176       }
25177     });
25178
25179     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
25180       assert.expect(2);
25181
25182       if (!isNpm) {
25183         var wrapped = _([1]).chain().commit().head();
25184         assert.ok(wrapped instanceof _);
25185         assert.strictEqual(wrapped.value(), 1);
25186       }
25187       else {
25188         skipAssert(assert, 2);
25189       }
25190     });
25191   }());
25192
25193   /*--------------------------------------------------------------------------*/
25194
25195   QUnit.module('lodash(...).next');
25196
25197   lodashStable.each([false, true], function(implict) {
25198     function chain(value) {
25199       return implict ? _(value) : _.chain(value);
25200     }
25201
25202     var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
25203
25204     QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
25205       assert.expect(3);
25206
25207       if (!isNpm) {
25208         var wrapped = chain([1, 2]);
25209
25210         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
25211         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
25212         assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
25213       }
25214       else {
25215         skipAssert(assert, 3);
25216       }
25217     });
25218
25219     QUnit.test('should act as an iterable ' + chainType, function(assert) {
25220       assert.expect(2);
25221
25222       if (!isNpm && Symbol && Symbol.iterator) {
25223         var array = [1, 2],
25224             wrapped = chain(array);
25225
25226         assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
25227         assert.deepEqual(_.toArray(wrapped), array);
25228       }
25229       else {
25230         skipAssert(assert, 2);
25231       }
25232     });
25233
25234     QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
25235       assert.expect(3);
25236
25237       if (!isNpm && Array.from) {
25238         var hearts = '\ud83d\udc95',
25239             values = [[1], { 'a': 1 }, hearts];
25240
25241         lodashStable.each(values, function(value) {
25242           var wrapped = chain(value);
25243           assert.deepEqual(Array.from(wrapped), _.toArray(value));
25244         });
25245       }
25246       else {
25247         skipAssert(assert, 3);
25248       }
25249     });
25250
25251     QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
25252       assert.expect(4);
25253
25254       if (!isNpm && Symbol && Symbol.iterator) {
25255         var array = [1, 2],
25256             wrapped = chain(array);
25257
25258         assert.deepEqual(_.toArray(wrapped), array);
25259         assert.deepEqual(_.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
25260
25261         var other = wrapped.filter();
25262         assert.deepEqual(_.toArray(other), array, 'reset for new chain segments');
25263         assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted');
25264       }
25265       else {
25266         skipAssert(assert, 4);
25267       }
25268     });
25269
25270     QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
25271       assert.expect(3);
25272
25273       if (!isNpm && Symbol && Symbol.iterator) {
25274         var array = lodashStable.range(LARGE_ARRAY_SIZE),
25275             predicate = function(value) { values.push(value); return isEven(value); },
25276             values = [],
25277             wrapped = chain(array);
25278
25279         assert.deepEqual(_.toArray(wrapped), array);
25280
25281         wrapped = wrapped.filter(predicate);
25282         assert.deepEqual(_.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
25283         assert.deepEqual(values, array, 'memoizes iterator values');
25284       }
25285       else {
25286         skipAssert(assert, 3);
25287       }
25288     });
25289   });
25290
25291   /*--------------------------------------------------------------------------*/
25292
25293   QUnit.module('lodash(...).plant');
25294
25295   (function() {
25296     QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
25297       assert.expect(2);
25298
25299       if (!isNpm) {
25300         var array1 = [5, null, 3, null, 1],
25301             array2 = [10, null, 8, null, 6],
25302             wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
25303             wrapped2 = wrapped1.plant(array2);
25304
25305         assert.deepEqual(wrapped2.value(), [36, 64]);
25306         assert.deepEqual(wrapped1.value(), [1, 9]);
25307       }
25308       else {
25309         skipAssert(assert, 2);
25310       }
25311     });
25312
25313     QUnit.test('should clone `chainAll` settings', function(assert) {
25314       assert.expect(1);
25315
25316       if (!isNpm) {
25317         var array1 = [2, 4],
25318             array2 = [6, 8],
25319             wrapped1 = _(array1).chain().map(square),
25320             wrapped2 = wrapped1.plant(array2);
25321
25322         assert.deepEqual(wrapped2.head().value(), 36);
25323       }
25324       else {
25325         skipAssert(assert);
25326       }
25327     });
25328
25329     QUnit.test('should reset iterator data on cloned sequences', function(assert) {
25330       assert.expect(3);
25331
25332       if (!isNpm && Symbol && Symbol.iterator) {
25333         var array1 = [2, 4],
25334             array2 = [6, 8],
25335             wrapped1 = _(array1).map(square);
25336
25337         assert.deepEqual(_.toArray(wrapped1), [4, 16]);
25338         assert.deepEqual(_.toArray(wrapped1), []);
25339
25340         var wrapped2 = wrapped1.plant(array2);
25341         assert.deepEqual(_.toArray(wrapped2), [36, 64]);
25342       }
25343       else {
25344         skipAssert(assert, 3);
25345       }
25346     });
25347   }());
25348
25349   /*--------------------------------------------------------------------------*/
25350
25351   QUnit.module('lodash(...).pop');
25352
25353   (function() {
25354     QUnit.test('should remove elements from the end of `array`', function(assert) {
25355       assert.expect(5);
25356
25357       if (!isNpm) {
25358         var array = [1, 2],
25359             wrapped = _(array);
25360
25361         assert.strictEqual(wrapped.pop(), 2);
25362         assert.deepEqual(wrapped.value(), [1]);
25363         assert.strictEqual(wrapped.pop(), 1);
25364
25365         var actual = wrapped.value();
25366         assert.deepEqual(actual, []);
25367         assert.strictEqual(actual, array);
25368       }
25369       else {
25370         skipAssert(assert, 5);
25371       }
25372     });
25373
25374     QUnit.test('should accept falsey arguments', function(assert) {
25375       assert.expect(1);
25376
25377       if (!isNpm) {
25378         var expected = lodashStable.map(falsey, alwaysTrue);
25379
25380         var actual = lodashStable.map(falsey, function(value, index) {
25381           try {
25382             var result = index ? _(value).pop() : _().pop();
25383             return result === undefined;
25384           } catch (e) {}
25385         });
25386
25387         assert.deepEqual(actual, expected);
25388       }
25389       else {
25390         skipAssert(assert);
25391       }
25392     });
25393   }());
25394
25395   /*--------------------------------------------------------------------------*/
25396
25397   QUnit.module('lodash(...).push');
25398
25399   (function() {
25400     QUnit.test('should append elements to `array`', function(assert) {
25401       assert.expect(2);
25402
25403       if (!isNpm) {
25404         var array = [1],
25405             wrapped = _(array).push(2, 3),
25406             actual = wrapped.value();
25407
25408         assert.strictEqual(actual, array);
25409         assert.deepEqual(actual, [1, 2, 3]);
25410       }
25411       else {
25412         skipAssert(assert, 2);
25413       }
25414     });
25415
25416     QUnit.test('should accept falsey arguments', function(assert) {
25417       assert.expect(1);
25418
25419       if (!isNpm) {
25420         var expected = lodashStable.map(falsey, alwaysTrue);
25421
25422         var actual = lodashStable.map(falsey, function(value, index) {
25423           try {
25424             var result = index ? _(value).push(1).value() : _().push(1).value();
25425             return lodashStable.eq(result, value);
25426           } catch (e) {}
25427         });
25428
25429         assert.deepEqual(actual, expected);
25430       }
25431       else {
25432         skipAssert(assert);
25433       }
25434     });
25435   }());
25436
25437   /*--------------------------------------------------------------------------*/
25438
25439   QUnit.module('lodash(...).shift');
25440
25441   (function() {
25442     QUnit.test('should remove elements from the front of `array`', function(assert) {
25443       assert.expect(5);
25444
25445       if (!isNpm) {
25446         var array = [1, 2],
25447             wrapped = _(array);
25448
25449         assert.strictEqual(wrapped.shift(), 1);
25450         assert.deepEqual(wrapped.value(), [2]);
25451         assert.strictEqual(wrapped.shift(), 2);
25452
25453         var actual = wrapped.value();
25454         assert.deepEqual(actual, []);
25455         assert.strictEqual(actual, array);
25456       }
25457       else {
25458         skipAssert(assert, 5);
25459       }
25460     });
25461
25462     QUnit.test('should accept falsey arguments', function(assert) {
25463       assert.expect(1);
25464
25465       if (!isNpm) {
25466         var expected = lodashStable.map(falsey, alwaysTrue);
25467
25468         var actual = lodashStable.map(falsey, function(value, index) {
25469           try {
25470             var result = index ? _(value).shift() : _().shift();
25471             return result === undefined;
25472           } catch (e) {}
25473         });
25474
25475         assert.deepEqual(actual, expected);
25476       }
25477       else {
25478         skipAssert(assert);
25479       }
25480     });
25481   }());
25482
25483   /*--------------------------------------------------------------------------*/
25484
25485   QUnit.module('lodash(...).sort');
25486
25487   (function() {
25488     QUnit.test('should return the wrapped sorted `array`', function(assert) {
25489       assert.expect(2);
25490
25491       if (!isNpm) {
25492         var array = [3, 1, 2],
25493             wrapped = _(array).sort(),
25494             actual = wrapped.value();
25495
25496         assert.strictEqual(actual, array);
25497         assert.deepEqual(actual, [1, 2, 3]);
25498       }
25499       else {
25500         skipAssert(assert, 2);
25501       }
25502     });
25503
25504     QUnit.test('should accept falsey arguments', function(assert) {
25505       assert.expect(1);
25506
25507       if (!isNpm) {
25508         var expected = lodashStable.map(falsey, alwaysTrue);
25509
25510         var actual = lodashStable.map(falsey, function(value, index) {
25511           try {
25512             var result = index ? _(value).sort().value() : _().sort().value();
25513             return lodashStable.eq(result, value);
25514           } catch (e) {}
25515         });
25516
25517         assert.deepEqual(actual, expected);
25518       }
25519       else {
25520         skipAssert(assert);
25521       }
25522     });
25523   }());
25524
25525   /*--------------------------------------------------------------------------*/
25526
25527   QUnit.module('lodash(...).splice');
25528
25529   (function() {
25530     QUnit.test('should support removing and inserting elements', function(assert) {
25531       assert.expect(5);
25532
25533       if (!isNpm) {
25534         var array = [1, 2],
25535             wrapped = _(array);
25536
25537         assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
25538         assert.deepEqual(wrapped.value(), [1, 3]);
25539         assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
25540
25541         var actual = wrapped.value();
25542         assert.deepEqual(actual, []);
25543         assert.strictEqual(actual, array);
25544       }
25545       else {
25546         skipAssert(assert, 5);
25547       }
25548     });
25549
25550     QUnit.test('should accept falsey arguments', function(assert) {
25551       assert.expect(1);
25552
25553       if (!isNpm) {
25554         var expected = lodashStable.map(falsey, alwaysTrue);
25555
25556         var actual = lodashStable.map(falsey, function(value, index) {
25557           try {
25558             var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
25559             return lodashStable.isEqual(result, []);
25560           } catch (e) {}
25561         });
25562
25563         assert.deepEqual(actual, expected);
25564       }
25565       else {
25566         skipAssert(assert);
25567       }
25568     });
25569   }());
25570
25571   /*--------------------------------------------------------------------------*/
25572
25573   QUnit.module('lodash(...).unshift');
25574
25575   (function() {
25576     QUnit.test('should prepend elements to `array`', function(assert) {
25577       assert.expect(2);
25578
25579       if (!isNpm) {
25580         var array = [3],
25581             wrapped = _(array).unshift(1, 2),
25582             actual = wrapped.value();
25583
25584         assert.strictEqual(actual, array);
25585         assert.deepEqual(actual, [1, 2, 3]);
25586       }
25587       else {
25588         skipAssert(assert, 2);
25589       }
25590     });
25591
25592     QUnit.test('should accept falsey arguments', function(assert) {
25593       assert.expect(1);
25594
25595       if (!isNpm) {
25596         var expected = lodashStable.map(falsey, alwaysTrue);
25597
25598         var actual = lodashStable.map(falsey, function(value, index) {
25599           try {
25600             var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
25601             return lodashStable.eq(result, value);
25602           } catch (e) {}
25603         });
25604
25605         assert.deepEqual(actual, expected);
25606       }
25607       else {
25608         skipAssert(assert);
25609       }
25610     });
25611   }());
25612
25613   /*--------------------------------------------------------------------------*/
25614
25615   QUnit.module('lodash(...).value');
25616
25617   (function() {
25618     QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
25619       assert.expect(4);
25620
25621       if (!isNpm) {
25622         var array = [1],
25623             wrapped = _(array).push(2).push(3);
25624
25625         assert.deepEqual(array, [1]);
25626         assert.deepEqual(wrapped.value(), [1, 2, 3]);
25627         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25628         assert.deepEqual(array, [1, 2, 3, 2, 3]);
25629       }
25630       else {
25631         skipAssert(assert, 4);
25632       }
25633     });
25634
25635     QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
25636       assert.expect(1);
25637
25638       if (!isNpm) {
25639         var wrapped = _(123);
25640         assert.strictEqual(Number(wrapped), 123);
25641       }
25642       else {
25643         skipAssert(assert);
25644       }
25645     });
25646
25647     QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
25648       assert.expect(1);
25649
25650       if (!isNpm && JSON) {
25651         var wrapped = _([1, 2, 3]);
25652         assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
25653       }
25654       else {
25655         skipAssert(assert);
25656       }
25657     });
25658
25659     QUnit.test('should be aliased', function(assert) {
25660       assert.expect(2);
25661
25662       if (!isNpm) {
25663         var expected = _.prototype.value;
25664         assert.strictEqual(_.prototype.toJSON, expected);
25665         assert.strictEqual(_.prototype.valueOf, expected);
25666       }
25667       else {
25668         skipAssert(assert, 2);
25669       }
25670     });
25671   }());
25672
25673   /*--------------------------------------------------------------------------*/
25674
25675   QUnit.module('lodash(...) methods that return the wrapped modified array');
25676
25677   (function() {
25678     var funcs = [
25679       'push',
25680       'reverse',
25681       'sort',
25682       'unshift'
25683     ];
25684
25685     lodashStable.each(funcs, function(methodName) {
25686       QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
25687         assert.expect(2);
25688
25689         if (!isNpm) {
25690           var array = [1, 2, 3],
25691               wrapped = _(array),
25692               actual = wrapped[methodName]();
25693
25694           assert.ok(actual instanceof _);
25695           assert.notStrictEqual(actual, wrapped);
25696         }
25697         else {
25698           skipAssert(assert, 2);
25699         }
25700       });
25701     });
25702   }());
25703
25704   /*--------------------------------------------------------------------------*/
25705
25706   QUnit.module('lodash(...) methods that return new wrapped values');
25707
25708   (function() {
25709     var funcs = [
25710       'castArray',
25711       'concat',
25712       'difference',
25713       'differenceBy',
25714       'differenceWith',
25715       'intersection',
25716       'intersectionBy',
25717       'intersectionWith',
25718       'pull',
25719       'pullAll',
25720       'pullAt',
25721       'sampleSize',
25722       'shuffle',
25723       'slice',
25724       'splice',
25725       'split',
25726       'toArray',
25727       'union',
25728       'unionBy',
25729       'unionWith',
25730       'uniq',
25731       'uniqBy',
25732       'uniqWith',
25733       'words',
25734       'xor',
25735       'xorBy',
25736       'xorWith'
25737     ];
25738
25739     lodashStable.each(funcs, function(methodName) {
25740       QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
25741         assert.expect(2);
25742
25743         if (!isNpm) {
25744           var value = methodName == 'split' ? 'abc' : [1, 2, 3],
25745               wrapped = _(value),
25746               actual = wrapped[methodName]();
25747
25748           assert.ok(actual instanceof _);
25749           assert.notStrictEqual(actual, wrapped);
25750         }
25751         else {
25752           skipAssert(assert, 2);
25753         }
25754       });
25755     });
25756   }());
25757
25758   /*--------------------------------------------------------------------------*/
25759
25760   QUnit.module('lodash(...) methods that return unwrapped values');
25761
25762   (function() {
25763     var funcs = [
25764       'add',
25765       'camelCase',
25766       'capitalize',
25767       'ceil',
25768       'clone',
25769       'deburr',
25770       'divide',
25771       'endsWith',
25772       'escape',
25773       'escapeRegExp',
25774       'every',
25775       'find',
25776       'floor',
25777       'has',
25778       'hasIn',
25779       'head',
25780       'includes',
25781       'isArguments',
25782       'isArray',
25783       'isArrayBuffer',
25784       'isArrayLike',
25785       'isBoolean',
25786       'isBuffer',
25787       'isDate',
25788       'isElement',
25789       'isEmpty',
25790       'isEqual',
25791       'isError',
25792       'isFinite',
25793       'isFunction',
25794       'isInteger',
25795       'isMap',
25796       'isNaN',
25797       'isNative',
25798       'isNil',
25799       'isNull',
25800       'isNumber',
25801       'isObject',
25802       'isObjectLike',
25803       'isPlainObject',
25804       'isRegExp',
25805       'isSafeInteger',
25806       'isSet',
25807       'isString',
25808       'isUndefined',
25809       'isWeakMap',
25810       'isWeakSet',
25811       'join',
25812       'kebabCase',
25813       'last',
25814       'lowerCase',
25815       'lowerFirst',
25816       'max',
25817       'maxBy',
25818       'min',
25819       'minBy',
25820       'multiply',
25821       'nth',
25822       'pad',
25823       'padEnd',
25824       'padStart',
25825       'parseInt',
25826       'pop',
25827       'random',
25828       'reduce',
25829       'reduceRight',
25830       'repeat',
25831       'replace',
25832       'round',
25833       'sample',
25834       'shift',
25835       'size',
25836       'snakeCase',
25837       'some',
25838       'startCase',
25839       'startsWith',
25840       'subtract',
25841       'sum',
25842       'toInteger',
25843       'toLower',
25844       'toNumber',
25845       'toSafeInteger',
25846       'toString',
25847       'toUpper',
25848       'trim',
25849       'trimEnd',
25850       'trimStart',
25851       'truncate',
25852       'unescape',
25853       'upperCase',
25854       'upperFirst'
25855     ];
25856
25857     lodashStable.each(funcs, function(methodName) {
25858       QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
25859         assert.expect(1);
25860
25861         if (!isNpm) {
25862           var actual = _()[methodName]();
25863           assert.notOk(actual instanceof _);
25864         }
25865         else {
25866           skipAssert(assert);
25867         }
25868       });
25869
25870       QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
25871         assert.expect(1);
25872
25873         if (!isNpm) {
25874           var actual = _().chain()[methodName]();
25875           assert.ok(actual instanceof _);
25876         }
25877         else {
25878           skipAssert(assert);
25879         }
25880       });
25881     });
25882   }());
25883
25884   /*--------------------------------------------------------------------------*/
25885
25886   QUnit.module('"Arrays" category methods');
25887
25888   (function() {
25889     var args = (function() { return arguments; }(1, null, [3], null, 5)),
25890         sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
25891         array = [1, 2, 3, 4, 5, 6];
25892
25893     QUnit.test('should work with `arguments` objects', function(assert) {
25894       assert.expect(30);
25895
25896       function message(methodName) {
25897         return '`_.' + methodName + '` should work with `arguments` objects';
25898       }
25899
25900       assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
25901       assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
25902
25903       assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
25904       assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
25905
25906       assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
25907       assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
25908       assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
25909       assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
25910       assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
25911       assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
25912       assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
25913       assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
25914       assert.deepEqual(_.head(args), 1, message('head'));
25915       assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
25916       assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
25917       assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
25918       assert.deepEqual(_.last(args), 5, message('last'));
25919       assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
25920       assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
25921       assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
25922       assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
25923       assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
25924       assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
25925       assert.deepEqual(_.take(args, 2), [1, null], message('take'));
25926       assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
25927       assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
25928       assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
25929       assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
25930       assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
25931       assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
25932     });
25933
25934     QUnit.test('should accept falsey primary arguments', function(assert) {
25935       assert.expect(4);
25936
25937       function message(methodName) {
25938         return '`_.' + methodName + '` should accept falsey primary arguments';
25939       }
25940
25941       assert.deepEqual(_.difference(null, array), [], message('difference'));
25942       assert.deepEqual(_.intersection(null, array), [], message('intersection'));
25943       assert.deepEqual(_.union(null, array), array, message('union'));
25944       assert.deepEqual(_.xor(null, array), array, message('xor'));
25945     });
25946
25947     QUnit.test('should accept falsey secondary arguments', function(assert) {
25948       assert.expect(3);
25949
25950       function message(methodName) {
25951         return '`_.' + methodName + '` should accept falsey secondary arguments';
25952       }
25953
25954       assert.deepEqual(_.difference(array, null), array, message('difference'));
25955       assert.deepEqual(_.intersection(array, null), [], message('intersection'));
25956       assert.deepEqual(_.union(array, null), array, message('union'));
25957     });
25958   }());
25959
25960   /*--------------------------------------------------------------------------*/
25961
25962   QUnit.module('"Strings" category methods');
25963
25964   (function() {
25965     var stringMethods = [
25966       'camelCase',
25967       'capitalize',
25968       'escape',
25969       'kebabCase',
25970       'lowerCase',
25971       'lowerFirst',
25972       'pad',
25973       'padEnd',
25974       'padStart',
25975       'repeat',
25976       'snakeCase',
25977       'toLower',
25978       'toUpper',
25979       'trim',
25980       'trimEnd',
25981       'trimStart',
25982       'truncate',
25983       'unescape',
25984       'upperCase',
25985       'upperFirst'
25986     ];
25987
25988     lodashStable.each(stringMethods, function(methodName) {
25989       var func = _[methodName];
25990
25991       QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
25992         assert.expect(1);
25993
25994         var values = [, null, undefined, ''],
25995             expected = lodashStable.map(values, alwaysEmptyString);
25996
25997         var actual = lodashStable.map(values, function(value, index) {
25998           return index ? func(value) : func();
25999         });
26000
26001         assert.deepEqual(actual, expected);
26002       });
26003     });
26004   }());
26005
26006   /*--------------------------------------------------------------------------*/
26007
26008   QUnit.module('lodash methods');
26009
26010   (function() {
26011     var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
26012       return lodashStable.startsWith(methodName, '_');
26013     });
26014
26015     var checkFuncs = [
26016       'after',
26017       'ary',
26018       'before',
26019       'bind',
26020       'curry',
26021       'curryRight',
26022       'debounce',
26023       'defer',
26024       'delay',
26025       'flip',
26026       'flow',
26027       'flowRight',
26028       'memoize',
26029       'negate',
26030       'once',
26031       'partial',
26032       'partialRight',
26033       'rearg',
26034       'rest',
26035       'spread',
26036       'throttle',
26037       'unary'
26038     ];
26039
26040     var noBinding = [
26041       'flip',
26042       'memoize',
26043       'negate',
26044       'once',
26045       'overArgs',
26046       'partial',
26047       'partialRight',
26048       'rearg',
26049       'rest',
26050       'spread'
26051     ];
26052
26053     var rejectFalsey = [
26054       'tap',
26055       'thru'
26056     ].concat(checkFuncs);
26057
26058     var returnArrays = [
26059       'at',
26060       'chunk',
26061       'compact',
26062       'difference',
26063       'drop',
26064       'filter',
26065       'flatten',
26066       'functions',
26067       'initial',
26068       'intersection',
26069       'invokeMap',
26070       'keys',
26071       'map',
26072       'orderBy',
26073       'pull',
26074       'pullAll',
26075       'pullAt',
26076       'range',
26077       'rangeRight',
26078       'reject',
26079       'remove',
26080       'shuffle',
26081       'sortBy',
26082       'tail',
26083       'take',
26084       'times',
26085       'toArray',
26086       'toPairs',
26087       'toPairsIn',
26088       'union',
26089       'uniq',
26090       'values',
26091       'without',
26092       'xor',
26093       'zip'
26094     ];
26095
26096     var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
26097
26098     QUnit.test('should accept falsey arguments', function(assert) {
26099       assert.expect(308);
26100
26101       var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
26102
26103       lodashStable.each(acceptFalsey, function(methodName) {
26104         var expected = emptyArrays,
26105             func = _[methodName],
26106             pass = true;
26107
26108         var actual = lodashStable.map(falsey, function(value, index) {
26109           try {
26110             return index ? func(value) : func();
26111           } catch (e) {
26112             pass = false;
26113           }
26114         });
26115
26116         if (methodName == 'noConflict') {
26117           root._ = oldDash;
26118         }
26119         else if (methodName == 'pull' || methodName == 'pullAll') {
26120           expected = falsey;
26121         }
26122         if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
26123           assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
26124         }
26125         assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
26126       });
26127
26128       // Skip tests for missing methods of modularized builds.
26129       lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
26130         if (!_[methodName]) {
26131           skipAssert(assert);
26132         }
26133       });
26134     });
26135
26136     QUnit.test('should return an array', function(assert) {
26137       assert.expect(70);
26138
26139       var array = [1, 2, 3];
26140
26141       lodashStable.each(returnArrays, function(methodName) {
26142         var actual,
26143             func = _[methodName];
26144
26145         switch (methodName) {
26146           case 'invokeMap':
26147             actual = func(array, 'toFixed');
26148             break;
26149           case 'sample':
26150             actual = func(array, 1);
26151             break;
26152           default:
26153             actual = func(array);
26154         }
26155         assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
26156
26157         var isPull = methodName == 'pull' || methodName == 'pullAll';
26158         assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
26159       });
26160     });
26161
26162     QUnit.test('should throw an error for falsey arguments', function(assert) {
26163       assert.expect(24);
26164
26165       lodashStable.each(rejectFalsey, function(methodName) {
26166         var expected = lodashStable.map(falsey, alwaysTrue),
26167             func = _[methodName];
26168
26169         var actual = lodashStable.map(falsey, function(value, index) {
26170           var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
26171
26172           try {
26173             index ? func(value) : func();
26174           } catch (e) {
26175             pass = !pass && (e instanceof TypeError) &&
26176               (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
26177           }
26178           return pass;
26179         });
26180
26181         assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
26182       });
26183     });
26184
26185     QUnit.test('should not set a `this` binding', function(assert) {
26186       assert.expect(30);
26187
26188       lodashStable.each(noBinding, function(methodName) {
26189         var fn = function() { return this.a; },
26190             func = _[methodName],
26191             isNegate = methodName == 'negate',
26192             object = { 'a': 1 },
26193             expected = isNegate ? false : 1;
26194
26195         var wrapper = func(_.bind(fn, object));
26196         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
26197
26198         wrapper = _.bind(func(fn), object);
26199         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
26200
26201         object.wrapper = func(fn);
26202         assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
26203       });
26204     });
26205
26206     QUnit.test('should not contain minified method names (test production builds)', function(assert) {
26207       assert.expect(1);
26208
26209       var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
26210       assert.ok(lodashStable.every(_.functions(_), function(methodName) {
26211         return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
26212       }));
26213     });
26214   }());
26215
26216   /*--------------------------------------------------------------------------*/
26217
26218   QUnit.config.asyncRetries = 10;
26219   QUnit.config.hidepassed = true;
26220
26221   if (!document) {
26222     QUnit.config.noglobals = true;
26223     QUnit.load();
26224   }
26225 }.call(this));