nexus site path corrected
[portal.git] / ecomp-portal-FE / client / 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   /** Stub functions. */
87   var stubA = function() { return 'a'; },
88       stubB = function() { return 'b'; },
89       stubC = function() { return 'c'; };
90
91   var stubTrue = function() { return true; },
92       stubFalse = function() { return false; };
93
94   var stubNaN = function() { return NaN; },
95       stubNull = function() { return null; };
96
97   var stubZero = function() { return 0; },
98       stubOne = function() { return 1; },
99       stubTwo = function() { return 2; },
100       stubThree = function() { return 3; },
101       stubFour = function() { return 4; };
102
103   var stubArray = function() { return []; },
104       stubObject = function() { return {}; },
105       stubString = 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) || 'default' in require(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   // Assign `setTimeout` to itself to avoid being flagged as a leak.
237   setProperty(root, 'setTimeout', setTimeout);
238
239   // Exit early if going to run tests in a PhantomJS web page.
240   if (phantom && isModularize) {
241     var page = require('webpage').create();
242
243     page.onCallback = function(details) {
244       var coverage = details.coverage;
245       if (coverage) {
246         var fs = require('fs'),
247             cwd = fs.workingDirectory,
248             sep = fs.separator;
249
250         fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
251       }
252       phantom.exit(details.failed ? 1 : 0);
253     };
254
255     page.onConsoleMessage = function(message) {
256       console.log(message);
257     };
258
259     page.onInitialized = function() {
260       page.evaluate(function() {
261         document.addEventListener('DOMContentLoaded', function() {
262           QUnit.done(function(details) {
263             details.coverage = window.__coverage__;
264             callPhantom(details);
265           });
266         });
267       });
268     };
269
270     page.open(filePath, function(status) {
271       if (status != 'success') {
272         console.log('PhantomJS failed to load page: ' + filePath);
273         phantom.exit(1);
274       }
275     });
276
277     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
278     return;
279   }
280
281   /*--------------------------------------------------------------------------*/
282
283   /** Used to test Web Workers. */
284   var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
285     (document && document.origin != 'null') && root.Worker;
286
287   /** Used to test host objects in IE. */
288   try {
289     var xml = new ActiveXObject('Microsoft.XMLDOM');
290   } catch (e) {}
291
292   /** Poison the free variable `root` in Node.js */
293   try {
294     defineProperty(global.root, 'root', {
295       'configurable': false,
296       'enumerable': false,
297       'get': function() { throw new ReferenceError; }
298     });
299   } catch (e) {}
300
301   /** Load QUnit and extras. */
302   var QUnit = root.QUnit || require('qunit-extras');
303
304   /** Load stable Lodash. */
305   var lodashStable = root.lodashStable;
306   if (!lodashStable) {
307     try {
308       lodashStable = interopRequire('../node_modules/lodash/lodash.js');
309     } catch (e) {
310       console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
311       return;
312     }
313     lodashStable = lodashStable.noConflict();
314   }
315
316   /** The `lodash` function to test. */
317   var _ = root._ || (root._ = interopRequire(filePath));
318
319   /** Used to test pseudo private map caches. */
320   var mapCaches = (function() {
321     var MapCache = _.memoize.Cache;
322     var result = {
323       'Hash': new MapCache().__data__.hash.constructor,
324       'MapCache': MapCache
325     };
326     _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() {
327       var stack = lodashStable.last(arguments);
328       result.ListCache = stack.__data__.constructor;
329       result.Stack = stack.constructor;
330     });
331     return result;
332   }());
333
334   /** Used to detect instrumented istanbul code coverage runs. */
335   var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
336     return /^(?:\$\$cov_\d+\$\$)$/.test(key);
337   })];
338
339   /** Used to test generator functions. */
340   var generator = lodashStable.attempt(function() {
341     return Function('return function*(){}');
342   });
343
344   /** Used to restore the `_` reference. */
345   var oldDash = root._;
346
347   /**
348    * Used to check for problems removing whitespace. For a whitespace reference,
349    * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
350    */
351   var whitespace = lodashStable.filter([
352     // Basic whitespace characters.
353     ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
354
355     // Line terminators.
356     '\n', '\r', '\u2028', '\u2029',
357
358     // Unicode category "Zs" space separators.
359     '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
360     '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
361   ],
362   function(chr) { return /\s/.exec(chr); })
363   .join('');
364
365   /**
366    * Creates a custom error object.
367    *
368    * @private
369    * @constructor
370    * @param {string} message The error message.
371    */
372   function CustomError(message) {
373     this.name = 'CustomError';
374     this.message = message;
375   }
376
377   CustomError.prototype = lodashStable.create(Error.prototype, {
378     'constructor': CustomError
379   });
380
381   /**
382    * Removes all own enumerable string keyed properties from a given object.
383    *
384    * @private
385    * @param {Object} object The object to empty.
386    */
387   function emptyObject(object) {
388     lodashStable.forOwn(object, function(value, key, object) {
389       delete object[key];
390     });
391   }
392
393   /**
394    * Extracts the unwrapped value from its wrapper.
395    *
396    * @private
397    * @param {Object} wrapper The wrapper to unwrap.
398    * @returns {*} Returns the unwrapped value.
399    */
400   function getUnwrappedValue(wrapper) {
401     var index = -1,
402         actions = wrapper.__actions__,
403         length = actions.length,
404         result = wrapper.__wrapped__;
405
406     while (++index < length) {
407       var args = [result],
408           action = actions[index];
409
410       push.apply(args, action.args);
411       result = action.func.apply(action.thisArg, args);
412     }
413     return result;
414   }
415
416   /**
417    * Loads the module of `id`. If the module has an `exports.default`, the
418    * exported default value is returned as the resolved module.
419    *
420    * @private
421    * @param {string} id The identifier of the module to resolve.
422    * @returns {*} Returns the resolved module.
423    */
424   function interopRequire(id) {
425     var result = require(id);
426     return 'default' in result ? result['default'] : result;
427   }
428
429   /**
430    * Sets a non-enumerable property value on `object`.
431    *
432    * Note: This function is used to avoid a bug in older versions of V8 where
433    * overwriting non-enumerable built-ins makes them enumerable.
434    * See https://code.google.com/p/v8/issues/detail?id=1623
435    *
436    * @private
437    * @param {Object} object The object modify.
438    * @param {string} key The name of the property to set.
439    * @param {*} value The property value.
440    */
441   function setProperty(object, key, value) {
442     try {
443       defineProperty(object, key, {
444         'configurable': true,
445         'enumerable': false,
446         'writable': true,
447         'value': value
448       });
449     } catch (e) {
450       object[key] = value;
451     }
452     return object;
453   }
454
455   /**
456    * Skips a given number of tests with a passing result.
457    *
458    * @private
459    * @param {Object} assert The QUnit assert object.
460    * @param {number} [count=1] The number of tests to skip.
461    */
462   function skipAssert(assert, count) {
463     count || (count = 1);
464     while (count--) {
465       assert.ok(true, 'test skipped');
466     }
467   }
468
469   /*--------------------------------------------------------------------------*/
470
471   // Add bizarro values.
472   (function() {
473     if (document || (typeof require != 'function')) {
474       return;
475     }
476     var nativeString = fnToString.call(toString),
477         reToString = /toString/g;
478
479     function createToString(funcName) {
480       return lodashStable.constant(nativeString.replace(reToString, funcName));
481     }
482
483     // Allow bypassing native checks.
484     setProperty(funcProto, 'toString', function wrapper() {
485       setProperty(funcProto, 'toString', fnToString);
486       var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
487       setProperty(funcProto, 'toString', wrapper);
488       return result;
489     });
490
491     // Add prototype extensions.
492     funcProto._method = noop;
493
494     // Set bad shims.
495     setProperty(Object, 'create', (function() {
496       function object() {}
497       return function(prototype) {
498         if (lodashStable.isObject(prototype)) {
499           object.prototype = prototype;
500           var result = new object;
501           object.prototype = undefined;
502         }
503         return result || {};
504       };
505     }()));
506
507     setProperty(Object, 'getOwnPropertySymbols', undefined);
508
509     var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
510     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
511       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
512     });
513
514     if (Buffer) {
515       defineProperty(root, 'Buffer', {
516         'configurable': true,
517         'enumerable': true,
518         'get': function get() {
519           var caller = get.caller,
520               name = caller ? caller.name : '';
521
522           if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
523             return Buffer;
524           }
525         }
526       });
527     }
528     if (Map) {
529       setProperty(root, 'Map', (function() {
530         var count = 0;
531         return function() {
532           if (count++) {
533             return new Map;
534           }
535           setProperty(root, 'Map', Map);
536           return {};
537         };
538       }()));
539
540       setProperty(root.Map, 'toString', createToString('Map'));
541     }
542     setProperty(root, 'Promise', noop);
543     setProperty(root, 'Set', noop);
544     setProperty(root, 'Symbol', undefined);
545     setProperty(root, 'WeakMap', noop);
546
547     // Fake `WinRTError`.
548     setProperty(root, 'WinRTError', Error);
549
550     // Clear cache so lodash can be reloaded.
551     emptyObject(require.cache);
552
553     // Load lodash and expose it to the bad extensions/shims.
554     lodashBizarro = interopRequire(filePath);
555     root._ = oldDash;
556
557     // Restore built-in methods.
558     setProperty(Object, 'create', create);
559     setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
560     setProperty(root, 'Buffer', Buffer);
561
562     if (getSymbols) {
563       Object.getOwnPropertySymbols = getSymbols;
564     } else {
565       delete Object.getOwnPropertySymbols;
566     }
567     if (Map) {
568       setProperty(root, 'Map', Map);
569     } else {
570       delete root.Map;
571     }
572     if (Promise) {
573       setProperty(root, 'Promise', Promise);
574     } else {
575       delete root.Promise;
576     }
577     if (Set) {
578       setProperty(root, 'Set', Set);
579     } else {
580       delete root.Set;
581     }
582     if (Symbol) {
583       setProperty(root, 'Symbol', Symbol);
584     } else {
585       delete root.Symbol;
586     }
587     if (WeakMap) {
588       setProperty(root, 'WeakMap', WeakMap);
589     } else {
590       delete root.WeakMap;
591     }
592     delete root.WinRTError;
593     delete funcProto._method;
594   }());
595
596   // Add other realm values from the `vm` module.
597   lodashStable.attempt(function() {
598     lodashStable.assign(realm, require('vm').runInNewContext([
599       '(function() {',
600       '  var noop = function() {},',
601       '      root = this;',
602       '',
603       '  var object = {',
604       "    'ArrayBuffer': root.ArrayBuffer,",
605       "    'arguments': (function() { return arguments; }(1, 2, 3)),",
606       "    'array': [1],",
607       "    'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
608       "    'boolean': Object(false),",
609       "    'date': new Date,",
610       "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
611       "    'function': noop,",
612       "    'map': root.Map ? new root.Map : undefined,",
613       "    'nan': NaN,",
614       "    'null': null,",
615       "    'number': Object(0),",
616       "    'object': { 'a': 1 },",
617       "    'promise': root.Promise ? Promise.resolve(1) : undefined,",
618       "    'regexp': /x/,",
619       "    'set': root.Set ? new root.Set : undefined,",
620       "    'string': Object('a'),",
621       "    'symbol': root.Symbol ? root.Symbol() : undefined,",
622       "    'undefined': undefined,",
623       "    'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
624       "    'weakSet': root.WeakSet ? new root.WeakSet : undefined",
625       '  };',
626       '',
627       "  ['" + arrayViews.join("', '") + "'].forEach(function(type) {",
628       '    var Ctor = root[type]',
629       '    object[type] = Ctor;',
630       '    object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
631       '  });',
632       '',
633       '  return object;',
634       '}())'
635     ].join('\n')));
636   });
637
638   // Add other realm values from an iframe.
639   lodashStable.attempt(function() {
640     _._realm = realm;
641
642     var iframe = document.createElement('iframe');
643     iframe.frameBorder = iframe.height = iframe.width = 0;
644     body.appendChild(iframe);
645
646     var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
647     idoc.write([
648       '<script>',
649       'var _ = parent._;',
650       '',
651       '  var noop = function() {},',
652       '      root = this;',
653       '',
654       'var object = {',
655       "  'ArrayBuffer': root.ArrayBuffer,",
656       "  'arguments': (function() { return arguments; }(1, 2, 3)),",
657       "  'array': [1],",
658       "  'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
659       "  'boolean': Object(false),",
660       "  'date': new Date,",
661       "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
662       "  'function': noop,",
663       "  'map': root.Map ? new root.Map : undefined,",
664       "  'nan': NaN,",
665       "  'null': null,",
666       "  'number': Object(0),",
667       "  'object': { 'a': 1 },",
668       "  'promise': root.Promise ? Promise.resolve(1) : undefined,",
669       "  'regexp': /x/,",
670       "  'set': root.Set ? new root.Set : undefined,",
671       "  'string': Object('a'),",
672       "  'symbol': root.Symbol ? root.Symbol() : undefined,",
673       "  'undefined': undefined,",
674       "  'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
675       "  'weakSet': root.WeakSet ? new root.WeakSet : undefined",
676       '};',
677       '',
678       "_.each(['" + arrayViews.join("', '") + "'], function(type) {",
679       '  var Ctor = root[type];',
680       '  object[type] = Ctor;',
681       '  object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
682       '});',
683       '',
684       '_.assign(_._realm, object);',
685       '<\/script>'
686     ].join('\n'));
687
688     idoc.close();
689     delete _._realm;
690   });
691
692   // Add a web worker.
693   lodashStable.attempt(function() {
694     var worker = new Worker('./asset/worker.js?t=' + (+new Date));
695     worker.addEventListener('message', function(e) {
696       _._VERSION = e.data || '';
697     }, false);
698
699     worker.postMessage(ui.buildPath);
700   });
701
702   // Expose internal modules for better code coverage.
703   lodashStable.attempt(function() {
704     var path = require('path'),
705         basePath = path.dirname(filePath);
706
707     if (isModularize && !(amd || isNpm)) {
708       lodashStable.each([
709         'baseEach',
710         'isIndex',
711         'isIterateeCall'
712       ], function(funcName) {
713         _['_' + funcName] = interopRequire(path.join(basePath, '_' + funcName));
714       });
715     }
716   });
717
718   /*--------------------------------------------------------------------------*/
719
720   if (params) {
721     console.log('Running lodash tests.');
722     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
723   }
724
725   QUnit.module(basename);
726
727   (function() {
728     QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
729       assert.expect(1);
730
731       if (amd) {
732         assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
733       }
734       else {
735         skipAssert(assert);
736       }
737     });
738
739     QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
740       assert.expect(1);
741
742       if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
743         assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
744       } else {
745         skipAssert(assert);
746       }
747     });
748
749     QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
750       assert.expect(1);
751
752       if (amd) {
753         assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
754       }
755       else {
756         skipAssert(assert);
757       }
758     });
759
760     QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
761       assert.expect(1);
762
763       var done = assert.async();
764
765       if (Worker) {
766         var limit = 30000 / QUnit.config.asyncRetries,
767             start = +new Date;
768
769         var attempt = function() {
770           var actual = _._VERSION;
771           if ((new Date - start) < limit && typeof actual != 'string') {
772             setTimeout(attempt, 16);
773             return;
774           }
775           assert.strictEqual(actual, _.VERSION);
776           done();
777         };
778
779         attempt();
780       }
781       else {
782         skipAssert(assert);
783         done();
784       }
785     });
786
787     QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
788       assert.expect(1);
789
790       if (lodashBizarro) {
791         assert.notOk('_method' in lodashBizarro);
792       }
793       else {
794         skipAssert(assert);
795       }
796     });
797
798     QUnit.test('should avoid non-native built-ins', function(assert) {
799       assert.expect(7);
800
801       function message(lodashMethod, nativeMethod) {
802         return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
803       }
804
805       function Foo() {
806         this.a = 1;
807       }
808       Foo.prototype.b = 2;
809
810       var object = { 'a': 1 },
811           otherObject = { 'b': 2 },
812           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
813
814       if (lodashBizarro) {
815         try {
816           var actual = lodashBizarro.keysIn(new Foo).sort();
817         } catch (e) {
818           actual = null;
819         }
820         var label = message('_.keysIn', 'Object#propertyIsEnumerable');
821         assert.deepEqual(actual, ['a', 'b'], label);
822
823         try {
824           var actual = lodashBizarro.isEmpty({});
825         } catch (e) {
826           actual = null;
827         }
828         var label = message('_.isEmpty', 'Object#propertyIsEnumerable');
829         assert.strictEqual(actual, true, label);
830
831         try {
832           actual = [
833             lodashBizarro.difference([object, otherObject], largeArray),
834             lodashBizarro.intersection(largeArray, [object]),
835             lodashBizarro.uniq(largeArray)
836           ];
837         } catch (e) {
838           actual = null;
839         }
840         label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
841         assert.deepEqual(actual, [[otherObject], [object], [object]], label);
842
843         try {
844           if (Symbol) {
845             object[symbol] = {};
846           }
847           actual = [
848             lodashBizarro.clone(object),
849             lodashBizarro.cloneDeep(object)
850           ];
851         } catch (e) {
852           actual = null;
853         }
854         label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
855         assert.deepEqual(actual, [object, object], label);
856
857         try {
858           var symObject = Object(symbol);
859
860           // Avoid symbol detection in Babel's `typeof` helper.
861           symObject.constructor = Object;
862
863           actual = [
864             Symbol ? lodashBizarro.clone(symObject) : { 'constructor': Object },
865             Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
866             Symbol ? lodashBizarro.toString(symObject) : ''
867           ];
868         } catch (e) {
869           actual = null;
870         }
871         label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
872         assert.deepEqual(actual, [{ 'constructor': Object }, false, ''], label);
873
874         try {
875           var map = new lodashBizarro.memoize.Cache;
876           actual = map.set('a', 1).get('a');
877         } catch (e) {
878           actual = null;
879         }
880         label = message('_.memoize.Cache', 'Map');
881         assert.deepEqual(actual, 1, label);
882
883         try {
884           map = new (Map || Object);
885           if (Symbol && Symbol.iterator) {
886             map[Symbol.iterator] = null;
887           }
888           actual = lodashBizarro.toArray(map);
889         } catch (e) {
890           actual = null;
891         }
892         label = message('_.toArray', 'Map');
893         assert.deepEqual(actual, [], label);
894       }
895       else {
896         skipAssert(assert, 7);
897       }
898     });
899   }());
900
901   /*--------------------------------------------------------------------------*/
902
903   QUnit.module('isIndex');
904
905   (function() {
906     var func = _._isIndex;
907
908     QUnit.test('should return `true` for indexes', function(assert) {
909       assert.expect(1);
910
911       if (func) {
912         var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
913             expected = lodashStable.map(values, stubTrue);
914
915         var actual = lodashStable.map(values, function(args) {
916           return func.apply(undefined, args);
917         });
918
919         assert.deepEqual(actual, expected);
920       }
921       else {
922         skipAssert(assert);
923       }
924     });
925
926     QUnit.test('should return `false` for non-indexes', function(assert) {
927       assert.expect(1);
928
929       if (func) {
930         var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
931             expected = lodashStable.map(values, stubFalse);
932
933         var actual = lodashStable.map(values, function(args) {
934           return func.apply(undefined, args);
935         });
936
937         assert.deepEqual(actual, expected);
938       }
939       else {
940         skipAssert(assert);
941       }
942     });
943   }());
944
945   /*--------------------------------------------------------------------------*/
946
947   QUnit.module('isIterateeCall');
948
949   (function() {
950     var array = [1],
951         func = _._isIterateeCall,
952         object =  { 'a': 1 };
953
954     QUnit.test('should return `true` for iteratee calls', function(assert) {
955       assert.expect(3);
956
957       function Foo() {}
958       Foo.prototype.a = 1;
959
960       if (func) {
961         assert.strictEqual(func(1, 0, array), true);
962         assert.strictEqual(func(1, 'a', object), true);
963         assert.strictEqual(func(1, 'a', new Foo), true);
964       }
965       else {
966         skipAssert(assert, 3);
967       }
968     });
969
970     QUnit.test('should return `false` for non-iteratee calls', function(assert) {
971       assert.expect(4);
972
973       if (func) {
974         assert.strictEqual(func(2, 0, array), false);
975         assert.strictEqual(func(1, 1.1, array), false);
976         assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
977         assert.strictEqual(func(1, 'b', object), false);
978       }
979       else {
980         skipAssert(assert, 4);
981       }
982     });
983
984     QUnit.test('should work with `NaN` values', function(assert) {
985       assert.expect(2);
986
987       if (func) {
988         assert.strictEqual(func(NaN, 0, [NaN]), true);
989         assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
990       }
991       else {
992         skipAssert(assert, 2);
993       }
994     });
995
996     QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
997       assert.expect(1);
998
999       if (func) {
1000         try {
1001           var actual = func(1, { 'toString': null }, [1]);
1002         } catch (e) {
1003           var message = e.message;
1004         }
1005         assert.strictEqual(actual, false, message || '');
1006       }
1007       else {
1008         skipAssert(assert);
1009       }
1010     });
1011   }());
1012
1013   /*--------------------------------------------------------------------------*/
1014
1015   QUnit.module('map caches');
1016
1017   (function() {
1018     var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || noop];
1019
1020     var pairs = lodashStable.map(keys, function(key, index) {
1021       var lastIndex = keys.length - 1;
1022       return [key, keys[lastIndex - index]];
1023     });
1024
1025     var largeStack = new mapCaches.Stack(pairs);
1026
1027     lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
1028       largeStack.set({}, {});
1029     });
1030
1031     var caches = {
1032       'hashes': new mapCaches.Hash(pairs),
1033       'list caches': new mapCaches.ListCache(pairs),
1034       'map caches': new mapCaches.MapCache(pairs),
1035       'stack caches': new mapCaches.Stack(pairs),
1036       'large stacks': largeStack
1037     };
1038
1039     lodashStable.forOwn(caches, function(cache, key) {
1040       QUnit.test('should implement a `Map` interface for ' + key, function(assert) {
1041         assert.expect(82);
1042
1043         lodashStable.each(keys, function(key, index) {
1044           var value = pairs[index][1];
1045
1046           assert.deepEqual(cache.get(key), value);
1047           assert.strictEqual(cache.has(key), true);
1048           assert.strictEqual(cache['delete'](key), true);
1049           assert.strictEqual(cache.has(key), false);
1050           assert.strictEqual(cache.get(key), undefined);
1051           assert.strictEqual(cache['delete'](key), false);
1052           assert.strictEqual(cache.set(key, value), cache);
1053           assert.strictEqual(cache.has(key), true);
1054         });
1055
1056         assert.strictEqual(cache.clear(), undefined);
1057         assert.ok(lodashStable.every(keys, function(key) {
1058           return !cache.has(key);
1059         }));
1060       });
1061     });
1062   }());
1063
1064   /*--------------------------------------------------------------------------*/
1065
1066   QUnit.module('lodash constructor');
1067
1068   (function() {
1069     var values = empties.concat(true, 1, 'a'),
1070         expected = lodashStable.map(values, stubTrue);
1071
1072     QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
1073       assert.expect(1);
1074
1075       if (!isNpm) {
1076         var actual = lodashStable.map(values, function(value) {
1077           return _(value) instanceof _;
1078         });
1079
1080         assert.deepEqual(actual, expected);
1081       }
1082       else {
1083         skipAssert(assert);
1084       }
1085     });
1086
1087     QUnit.test('should return the given `lodash` instances', function(assert) {
1088       assert.expect(1);
1089
1090       if (!isNpm) {
1091         var actual = lodashStable.map(values, function(value) {
1092           var wrapped = _(value);
1093           return _(wrapped) === wrapped;
1094         });
1095
1096         assert.deepEqual(actual, expected);
1097       }
1098       else {
1099         skipAssert(assert);
1100       }
1101     });
1102
1103     QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
1104       assert.expect(1);
1105
1106       if (!isNpm && lodashBizarro) {
1107         var actual = lodashStable.map(values, function(value) {
1108           var wrapped = _(lodashBizarro(value)),
1109               unwrapped = wrapped.value();
1110
1111           return wrapped instanceof _ &&
1112             ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
1113         });
1114
1115         assert.deepEqual(actual, expected);
1116       }
1117       else {
1118         skipAssert(assert);
1119       }
1120     });
1121   }());
1122
1123   /*--------------------------------------------------------------------------*/
1124
1125   QUnit.module('lodash.add');
1126
1127   (function() {
1128     QUnit.test('should add two numbers', function(assert) {
1129       assert.expect(3);
1130
1131       assert.strictEqual(_.add(6, 4), 10);
1132       assert.strictEqual(_.add(-6, 4), -2);
1133       assert.strictEqual(_.add(-6, -4), -10);
1134     });
1135
1136     QUnit.test('should not coerce arguments to numbers', function(assert) {
1137       assert.expect(2);
1138
1139       assert.strictEqual(_.add('6', '4'), '64');
1140       assert.strictEqual(_.add('x', 'y'), 'xy');
1141     });
1142   }());
1143
1144   /*--------------------------------------------------------------------------*/
1145
1146   QUnit.module('lodash.after');
1147
1148   (function() {
1149     function after(n, times) {
1150       var count = 0;
1151       lodashStable.times(times, _.after(n, function() { count++; }));
1152       return count;
1153     }
1154
1155     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1156       assert.expect(4);
1157
1158       assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1159       assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1160       assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1161       assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1162     });
1163
1164     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1165       assert.expect(1);
1166
1167       assert.strictEqual(after(NaN, 1), 1);
1168     });
1169
1170     QUnit.test('should not set a `this` binding', function(assert) {
1171       assert.expect(2);
1172
1173       var after = _.after(1, function(assert) { return ++this.count; }),
1174           object = { 'after': after, 'count': 0 };
1175
1176       object.after();
1177       assert.strictEqual(object.after(), 2);
1178       assert.strictEqual(object.count, 2);
1179     });
1180   }());
1181
1182   /*--------------------------------------------------------------------------*/
1183
1184   QUnit.module('lodash.ary');
1185
1186   (function() {
1187     function fn(a, b, c) {
1188       return slice.call(arguments);
1189     }
1190
1191     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1192       assert.expect(2);
1193
1194       var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1195       assert.deepEqual(actual, [6, 8, 10]);
1196
1197       var capped = _.ary(fn, 2);
1198       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1199     });
1200
1201     QUnit.test('should use `func.length` if `n` is not given', function(assert) {
1202       assert.expect(1);
1203
1204       var capped = _.ary(fn);
1205       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1206     });
1207
1208     QUnit.test('should treat a negative `n` as `0`', function(assert) {
1209       assert.expect(1);
1210
1211       var capped = _.ary(fn, -1);
1212
1213       try {
1214         var actual = capped('a');
1215       } catch (e) {}
1216
1217       assert.deepEqual(actual, []);
1218     });
1219
1220     QUnit.test('should coerce `n` to an integer', function(assert) {
1221       assert.expect(1);
1222
1223       var values = ['1', 1.6, 'xyz'],
1224           expected = [['a'], ['a'], []];
1225
1226       var actual = lodashStable.map(values, function(n) {
1227         var capped = _.ary(fn, n);
1228         return capped('a', 'b');
1229       });
1230
1231       assert.deepEqual(actual, expected);
1232     });
1233
1234     QUnit.test('should work when given less than the capped number of arguments', function(assert) {
1235       assert.expect(1);
1236
1237       var capped = _.ary(fn, 3);
1238       assert.deepEqual(capped('a'), ['a']);
1239     });
1240
1241     QUnit.test('should use the existing `ary` if smaller', function(assert) {
1242       assert.expect(1);
1243
1244       var capped = _.ary(_.ary(fn, 1), 2);
1245       assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1246     });
1247
1248     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1249       assert.expect(1);
1250
1251       var funcs = lodashStable.map([fn], _.ary),
1252           actual = funcs[0]('a', 'b', 'c');
1253
1254       assert.deepEqual(actual, ['a', 'b', 'c']);
1255     });
1256
1257     QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1258       assert.expect(2);
1259
1260       var array = ['a', 'b', 'c'],
1261           includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1262
1263       assert.strictEqual(includes('b')(array, 2), true);
1264
1265       if (!isNpm) {
1266         includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1267         assert.strictEqual(includes('b')(array, 2), true);
1268       }
1269       else {
1270         skipAssert(assert);
1271       }
1272     });
1273   }());
1274
1275   /*--------------------------------------------------------------------------*/
1276
1277   QUnit.module('lodash.assignIn');
1278
1279   (function() {
1280     QUnit.test('should be aliased', function(assert) {
1281       assert.expect(1);
1282
1283       assert.strictEqual(_.extend, _.assignIn);
1284     });
1285   }());
1286
1287   /*--------------------------------------------------------------------------*/
1288
1289   QUnit.module('lodash.assign and lodash.assignIn');
1290
1291   lodashStable.each(['assign', 'assignIn'], function(methodName) {
1292     var func = _[methodName];
1293
1294     QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1295       assert.expect(1);
1296
1297       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1298     });
1299
1300     QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1301       assert.expect(2);
1302
1303       var expected = { 'a': 1, 'b': 2, 'c': 3 };
1304       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1305       assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1306     });
1307
1308     QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1309       assert.expect(1);
1310
1311       var expected = { 'a': 3, 'b': 2, 'c': 1 };
1312       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1313     });
1314
1315     QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1316       assert.expect(1);
1317
1318       var expected = { 'a': null, 'b': undefined, 'c': null };
1319       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1320     });
1321
1322     QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1323       assert.expect(1);
1324
1325       var object = {};
1326
1327       var descriptor = {
1328         'configurable': true,
1329         'enumerable': true,
1330         'set': function() { throw new Error; }
1331       };
1332
1333       var source = {
1334         'a': 1,
1335         'b': undefined,
1336         'c': NaN,
1337         'd': undefined,
1338         'constructor': Object,
1339         'toString': lodashStable.constant('source')
1340       };
1341
1342       defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1343         'get': stubOne
1344       }));
1345
1346       defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1347         'get': noop
1348       }));
1349
1350       defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1351         'get': stubNaN
1352       }));
1353
1354       defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1355         'get': lodashStable.constant(Object)
1356       }));
1357
1358       try {
1359         var actual = func(object, source);
1360       } catch (e) {}
1361
1362       assert.deepEqual(actual, source);
1363     });
1364
1365     QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) {
1366       assert.expect(1);
1367
1368       var array = [1];
1369       array[2] = 3;
1370
1371       assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 });
1372     });
1373
1374     QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) {
1375       assert.expect(1);
1376
1377       function Foo() {}
1378       Foo.prototype.a = 1;
1379
1380       assert.deepEqual(func({}, Foo.prototype), { 'a': 1 });
1381     });
1382
1383     QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) {
1384       assert.expect(1);
1385
1386       assert.deepEqual(func({}, 'a'), { '0': 'a' });
1387     });
1388   });
1389
1390   /*--------------------------------------------------------------------------*/
1391
1392   QUnit.module('lodash.assignInWith');
1393
1394   (function() {
1395     QUnit.test('should be aliased', function(assert) {
1396       assert.expect(1);
1397
1398       assert.strictEqual(_.extendWith, _.assignInWith);
1399     });
1400   }());
1401
1402   /*--------------------------------------------------------------------------*/
1403
1404   QUnit.module('lodash.assignWith and lodash.assignInWith');
1405
1406   lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1407     var func = _[methodName];
1408
1409     QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1410       assert.expect(1);
1411
1412       var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1413         return a === undefined ? b : a;
1414       });
1415
1416       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1417     });
1418
1419     QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1420       assert.expect(1);
1421
1422       var expected = { 'a': undefined };
1423       assert.deepEqual(func({}, expected, noop), expected);
1424     });
1425   });
1426
1427   /*--------------------------------------------------------------------------*/
1428
1429   QUnit.module('lodash.at');
1430
1431   (function() {
1432     var args = arguments,
1433         array = ['a', 'b', 'c'],
1434         object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1435
1436     QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1437       assert.expect(1);
1438
1439       var actual = _.at(array, [0, 2]);
1440       assert.deepEqual(actual, ['a', 'c']);
1441     });
1442
1443     QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1444       assert.expect(1);
1445
1446       var actual = _.at(array, [2, 4, 0]);
1447       assert.deepEqual(actual, ['c', undefined, 'a']);
1448     });
1449
1450     QUnit.test('should work with non-index keys on array values', function(assert) {
1451       assert.expect(1);
1452
1453       var values = lodashStable.reject(empties, function(value) {
1454         return (value === 0) || lodashStable.isArray(value);
1455       }).concat(-1, 1.1);
1456
1457       var array = lodashStable.transform(values, function(result, value) {
1458         result[value] = 1;
1459       }, []);
1460
1461       var expected = lodashStable.map(values, stubOne),
1462           actual = _.at(array, values);
1463
1464       assert.deepEqual(actual, expected);
1465     });
1466
1467     QUnit.test('should return an empty array when no keys are given', function(assert) {
1468       assert.expect(2);
1469
1470       assert.deepEqual(_.at(array), []);
1471       assert.deepEqual(_.at(array, [], []), []);
1472     });
1473
1474     QUnit.test('should accept multiple key arguments', function(assert) {
1475       assert.expect(1);
1476
1477       var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1478       assert.deepEqual(actual, ['d', 'a', 'c']);
1479     });
1480
1481     QUnit.test('should work with a falsey `object` argument when keys are given', function(assert) {
1482       assert.expect(1);
1483
1484       var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1485
1486       var actual = lodashStable.map(falsey, function(object) {
1487         try {
1488           return _.at(object, 0, 1, 'pop', 'push');
1489         } catch (e) {}
1490       });
1491
1492       assert.deepEqual(actual, expected);
1493     });
1494
1495     QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1496       assert.expect(1);
1497
1498       var actual = _.at(args, [2, 0]);
1499       assert.deepEqual(actual, [3, 1]);
1500     });
1501
1502     QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1503       assert.expect(1);
1504
1505       var actual = _.at([1, 2, 3, 4, 5], args);
1506       assert.deepEqual(actual, [2, 3, 4]);
1507     });
1508
1509     QUnit.test('should work with an object for `object`', function(assert) {
1510       assert.expect(1);
1511
1512       var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1513       assert.deepEqual(actual, [3, 4]);
1514     });
1515
1516     QUnit.test('should pluck inherited property values', function(assert) {
1517       assert.expect(1);
1518
1519       function Foo() {
1520         this.a = 1;
1521       }
1522       Foo.prototype.b = 2;
1523
1524       var actual = _.at(new Foo, 'b');
1525       assert.deepEqual(actual, [2]);
1526     });
1527
1528     QUnit.test('should work in a lazy sequence', function(assert) {
1529       assert.expect(6);
1530
1531       if (!isNpm) {
1532         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1533             smallArray = array;
1534
1535         lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1536           lodashStable.times(2, function(index) {
1537             var array = index ? largeArray : smallArray,
1538                 wrapped = _(array).map(identity).at(paths);
1539
1540             assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1541           });
1542         });
1543       }
1544       else {
1545         skipAssert(assert, 6);
1546       }
1547     });
1548
1549     QUnit.test('should support shortcut fusion', function(assert) {
1550       assert.expect(8);
1551
1552       if (!isNpm) {
1553         var array = lodashStable.range(LARGE_ARRAY_SIZE),
1554             count = 0,
1555             iteratee = function(value) { count++; return square(value); },
1556             lastIndex = LARGE_ARRAY_SIZE - 1;
1557
1558         lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1559           count = 0;
1560           var actual = _(array).map(iteratee).at(n).value(),
1561               expected = index < 2 ? 1 : 0;
1562
1563           assert.strictEqual(count, expected);
1564
1565           expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1566           assert.deepEqual(actual, expected);
1567         });
1568       }
1569       else {
1570         skipAssert(assert, 8);
1571       }
1572     });
1573
1574     QUnit.test('work with an object for `object` when chaining', function(assert) {
1575       assert.expect(2);
1576
1577       if (!isNpm) {
1578         var paths = ['a[0].b.c', 'a[1]'],
1579             actual = _(object).map(identity).at(paths).value();
1580
1581         assert.deepEqual(actual, _.at(_.map(object, identity), paths));
1582
1583         var indexObject = { '0': 1 };
1584         actual = _(indexObject).at(0).value();
1585         assert.deepEqual(actual, _.at(indexObject, 0));
1586       }
1587       else {
1588         skipAssert(assert, 2);
1589       }
1590     });
1591   }(1, 2, 3));
1592
1593   /*--------------------------------------------------------------------------*/
1594
1595   QUnit.module('lodash.attempt');
1596
1597   (function() {
1598     QUnit.test('should return the result of `func`', function(assert) {
1599       assert.expect(1);
1600
1601       assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1602     });
1603
1604     QUnit.test('should provide additional arguments to `func`', function(assert) {
1605       assert.expect(1);
1606
1607       var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1608       assert.deepEqual(actual, [1, 2]);
1609     });
1610
1611     QUnit.test('should return the caught error', function(assert) {
1612       assert.expect(1);
1613
1614       var expected = lodashStable.map(errors, stubTrue);
1615
1616       var actual = lodashStable.map(errors, function(error) {
1617         return _.attempt(function() { throw error; }) === error;
1618       });
1619
1620       assert.deepEqual(actual, expected);
1621     });
1622
1623     QUnit.test('should coerce errors to error objects', function(assert) {
1624       assert.expect(1);
1625
1626       var actual = _.attempt(function() { throw 'x'; });
1627       assert.ok(lodashStable.isEqual(actual, Error('x')));
1628     });
1629
1630     QUnit.test('should preserve custom errors', function(assert) {
1631       assert.expect(1);
1632
1633       var actual = _.attempt(function() { throw new CustomError('x'); });
1634       assert.ok(actual instanceof CustomError);
1635     });
1636
1637     QUnit.test('should work with an error object from another realm', function(assert) {
1638       assert.expect(1);
1639
1640       if (realm.errors) {
1641         var expected = lodashStable.map(realm.errors, stubTrue);
1642
1643         var actual = lodashStable.map(realm.errors, function(error) {
1644           return _.attempt(function() { throw error; }) === error;
1645         });
1646
1647         assert.deepEqual(actual, expected);
1648       }
1649       else {
1650         skipAssert(assert);
1651       }
1652     });
1653
1654     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1655       assert.expect(1);
1656
1657       if (!isNpm) {
1658         assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1659       }
1660       else {
1661         skipAssert(assert);
1662       }
1663     });
1664
1665     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1666       assert.expect(1);
1667
1668       if (!isNpm) {
1669         assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1670       }
1671       else {
1672         skipAssert(assert);
1673       }
1674     });
1675   }());
1676
1677   /*--------------------------------------------------------------------------*/
1678
1679   QUnit.module('lodash.before');
1680
1681   (function() {
1682     function before(n, times) {
1683       var count = 0;
1684       lodashStable.times(times, _.before(n, function() { count++; }));
1685       return count;
1686     }
1687
1688     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1689       assert.expect(4);
1690
1691       assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1692       assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1693       assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1694       assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1695     });
1696
1697     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1698       assert.expect(1);
1699
1700       assert.strictEqual(before(NaN, 1), 0);
1701     });
1702
1703     QUnit.test('should not set a `this` binding', function(assert) {
1704       assert.expect(2);
1705
1706       var before = _.before(2, function(assert) { return ++this.count; }),
1707           object = { 'before': before, 'count': 0 };
1708
1709       object.before();
1710       assert.strictEqual(object.before(), 1);
1711       assert.strictEqual(object.count, 1);
1712     });
1713   }());
1714
1715   /*--------------------------------------------------------------------------*/
1716
1717   QUnit.module('lodash.bind');
1718
1719   (function() {
1720     function fn() {
1721       var result = [this];
1722       push.apply(result, arguments);
1723       return result;
1724     }
1725
1726     QUnit.test('should bind a function to an object', function(assert) {
1727       assert.expect(1);
1728
1729       var object = {},
1730           bound = _.bind(fn, object);
1731
1732       assert.deepEqual(bound('a'), [object, 'a']);
1733     });
1734
1735     QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
1736       assert.expect(1);
1737
1738       var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1739           expected = lodashStable.map(values, function(value) { return [value]; });
1740
1741       var actual = lodashStable.map(values, function(value) {
1742         try {
1743           var bound = _.bind(fn, value);
1744           return bound();
1745         } catch (e) {}
1746       });
1747
1748       assert.ok(lodashStable.every(actual, function(value, index) {
1749         return lodashStable.isEqual(value, expected[index]);
1750       }));
1751     });
1752
1753     QUnit.test('should bind a function to nullish values', function(assert) {
1754       assert.expect(6);
1755
1756       var bound = _.bind(fn, null),
1757           actual = bound('a');
1758
1759       assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1760       assert.strictEqual(actual[1], 'a');
1761
1762       lodashStable.times(2, function(index) {
1763         bound = index ? _.bind(fn, undefined) : _.bind(fn);
1764         actual = bound('b');
1765
1766         assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1767         assert.strictEqual(actual[1], 'b');
1768       });
1769     });
1770
1771     QUnit.test('should partially apply arguments ', function(assert) {
1772       assert.expect(4);
1773
1774       var object = {},
1775           bound = _.bind(fn, object, 'a');
1776
1777       assert.deepEqual(bound(), [object, 'a']);
1778
1779       bound = _.bind(fn, object, 'a');
1780       assert.deepEqual(bound('b'), [object, 'a', 'b']);
1781
1782       bound = _.bind(fn, object, 'a', 'b');
1783       assert.deepEqual(bound(), [object, 'a', 'b']);
1784       assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1785     });
1786
1787     QUnit.test('should support placeholders', function(assert) {
1788       assert.expect(4);
1789
1790       var object = {},
1791           ph = _.bind.placeholder,
1792           bound = _.bind(fn, object, ph, 'b', ph);
1793
1794       assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1795       assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1796       assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1797       assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1798     });
1799
1800     QUnit.test('should use `_.placeholder` when set', function(assert) {
1801       assert.expect(1);
1802
1803       if (!isModularize) {
1804         var _ph = _.placeholder = {},
1805             ph = _.bind.placeholder,
1806             object = {},
1807             bound = _.bind(fn, object, _ph, 'b', ph);
1808
1809         assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
1810         delete _.placeholder;
1811       }
1812       else {
1813         skipAssert(assert);
1814       }
1815     });
1816
1817     QUnit.test('should create a function with a `length` of `0`', function(assert) {
1818       assert.expect(2);
1819
1820       var fn = function(a, b, c) {},
1821           bound = _.bind(fn, {});
1822
1823       assert.strictEqual(bound.length, 0);
1824
1825       bound = _.bind(fn, {}, 1);
1826       assert.strictEqual(bound.length, 0);
1827     });
1828
1829     QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1830       assert.expect(3);
1831
1832       function Foo() {
1833         return this;
1834       }
1835
1836       var bound = _.bind(Foo, { 'a': 1 }),
1837           newBound = new bound;
1838
1839       assert.strictEqual(bound().a, 1);
1840       assert.strictEqual(newBound.a, undefined);
1841       assert.ok(newBound instanceof Foo);
1842     });
1843
1844     QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1845       assert.expect(1);
1846
1847       function Foo() {
1848         return this;
1849       }
1850
1851       function Bar() {}
1852
1853       var thisArg = { 'a': 1 },
1854           boundFoo = _.bind(Foo, thisArg),
1855           boundBar = _.bind(Bar, thisArg),
1856           count = 9,
1857           expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1858
1859       var actual = lodashStable.times(count, function(index) {
1860         try {
1861           switch (index) {
1862             case 0: return [new boundFoo().a, new boundBar().a];
1863             case 1: return [new boundFoo(1).a, new boundBar(1).a];
1864             case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1865             case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1866             case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1867             case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1868             case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1869             case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1870             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];
1871           }
1872         } catch (e) {}
1873       });
1874
1875       assert.deepEqual(actual, expected);
1876     });
1877
1878     QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1879       assert.expect(2);
1880
1881       function Foo(value) {
1882         return value && object;
1883       }
1884
1885       var bound = _.bind(Foo),
1886           object = {};
1887
1888       assert.ok(new bound instanceof Foo);
1889       assert.strictEqual(new bound(true), object);
1890     });
1891
1892     QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1893       assert.expect(1);
1894
1895       var object = {},
1896           bound = _.bind(fn, object, 'a');
1897
1898       assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1899     });
1900
1901     QUnit.test('should not rebind functions', function(assert) {
1902       assert.expect(3);
1903
1904       var object1 = {},
1905           object2 = {},
1906           object3 = {};
1907
1908       var bound1 = _.bind(fn, object1),
1909           bound2 = _.bind(bound1, object2, 'a'),
1910           bound3 = _.bind(bound1, object3, 'b');
1911
1912       assert.deepEqual(bound1(), [object1]);
1913       assert.deepEqual(bound2(), [object1, 'a']);
1914       assert.deepEqual(bound3(), [object1, 'b']);
1915     });
1916
1917     QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1918       assert.expect(2);
1919
1920       var Ctor = _.bind(Date, null),
1921           expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1922
1923       try {
1924         var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1925       } catch (e) {}
1926
1927       assert.deepEqual(actual, expected);
1928
1929       Ctor = _.bind(Date, null, 2012, 4, 23);
1930
1931       try {
1932         actual = new Ctor(0, 0, 0, 0);
1933       } catch (e) {}
1934
1935       assert.deepEqual(actual, expected);
1936     });
1937
1938     QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
1939       assert.expect(1);
1940
1941       var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
1942
1943       if (typeof createCtor == 'function') {
1944         var bound = _.bind(createCtor()),
1945             count = 8,
1946             expected = lodashStable.times(count, stubTrue);
1947
1948         var actual = lodashStable.times(count, function(index) {
1949           try {
1950             switch (index) {
1951               case 0: return !!(new bound);
1952               case 1: return !!(new bound(1));
1953               case 2: return !!(new bound(1, 2));
1954               case 3: return !!(new bound(1, 2, 3));
1955               case 4: return !!(new bound(1, 2, 3, 4));
1956               case 5: return !!(new bound(1, 2, 3, 4, 5));
1957               case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
1958               case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
1959             }
1960           } catch (e) {}
1961         });
1962
1963         assert.deepEqual(actual, expected);
1964       }
1965       else {
1966         skipAssert(assert);
1967       }
1968     });
1969
1970     QUnit.test('should return a wrapped value when chaining', function(assert) {
1971       assert.expect(2);
1972
1973       if (!isNpm) {
1974         var object = {},
1975             bound = _(fn).bind({}, 'a', 'b');
1976
1977         assert.ok(bound instanceof _);
1978
1979         var actual = bound.value()('c');
1980         assert.deepEqual(actual, [object, 'a', 'b', 'c']);
1981       }
1982       else {
1983         skipAssert(assert, 2);
1984       }
1985     });
1986   }());
1987
1988   /*--------------------------------------------------------------------------*/
1989
1990   QUnit.module('lodash.bindAll');
1991
1992   (function() {
1993     var args = arguments;
1994
1995     var source = {
1996       '_n0': -2,
1997       '_p0': -1,
1998       '_a': 1,
1999       '_b': 2,
2000       '_c': 3,
2001       '_d': 4,
2002       '-0': function() { return this._n0; },
2003       '0': function() { return this._p0; },
2004       'a': function() { return this._a; },
2005       'b': function() { return this._b; },
2006       'c': function() { return this._c; },
2007       'd': function() { return this._d; }
2008     };
2009
2010     QUnit.test('should accept individual method names', function(assert) {
2011       assert.expect(1);
2012
2013       var object = lodashStable.cloneDeep(source);
2014       _.bindAll(object, 'a', 'b');
2015
2016       var actual = lodashStable.map(['a', 'b', 'c'], function(key) {
2017         return object[key].call({});
2018       });
2019
2020       assert.deepEqual(actual, [1, 2, undefined]);
2021     });
2022
2023     QUnit.test('should accept arrays of method names', function(assert) {
2024       assert.expect(1);
2025
2026       var object = lodashStable.cloneDeep(source);
2027       _.bindAll(object, ['a', 'b'], ['c']);
2028
2029       var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) {
2030         return object[key].call({});
2031       });
2032
2033       assert.deepEqual(actual, [1, 2, 3, undefined]);
2034     });
2035
2036     QUnit.test('should preserve the sign of `0`', function(assert) {
2037       assert.expect(1);
2038
2039       var props = [-0, Object(-0), 0, Object(0)];
2040
2041       var actual = lodashStable.map(props, function(key) {
2042         var object = lodashStable.cloneDeep(source);
2043         _.bindAll(object, key);
2044         return object[lodashStable.toString(key)].call({});
2045       });
2046
2047       assert.deepEqual(actual, [-2, -2, -1, -1]);
2048     });
2049
2050     QUnit.test('should work with an array `object` argument', function(assert) {
2051       assert.expect(1);
2052
2053       var array = ['push', 'pop'];
2054       _.bindAll(array);
2055       assert.strictEqual(array.pop, arrayProto.pop);
2056     });
2057
2058     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
2059       assert.expect(1);
2060
2061       var object = lodashStable.cloneDeep(source);
2062       _.bindAll(object, args);
2063
2064       var actual = lodashStable.map(args, function(key) {
2065         return object[key].call({});
2066       });
2067
2068       assert.deepEqual(actual, [1]);
2069     });
2070   }('a'));
2071
2072   /*--------------------------------------------------------------------------*/
2073
2074   QUnit.module('lodash.bindKey');
2075
2076   (function() {
2077     QUnit.test('should work when the target function is overwritten', function(assert) {
2078       assert.expect(2);
2079
2080       var object = {
2081         'user': 'fred',
2082         'greet': function(greeting) {
2083           return this.user + ' says: ' + greeting;
2084         }
2085       };
2086
2087       var bound = _.bindKey(object, 'greet', 'hi');
2088       assert.strictEqual(bound(), 'fred says: hi');
2089
2090       object.greet = function(greeting) {
2091         return this.user + ' says: ' + greeting + '!';
2092       };
2093
2094       assert.strictEqual(bound(), 'fred says: hi!');
2095     });
2096
2097     QUnit.test('should support placeholders', function(assert) {
2098       assert.expect(4);
2099
2100       var object = {
2101         'fn': function() {
2102           return slice.call(arguments);
2103         }
2104       };
2105
2106       var ph = _.bindKey.placeholder,
2107           bound = _.bindKey(object, 'fn', ph, 'b', ph);
2108
2109       assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
2110       assert.deepEqual(bound('a'), ['a', 'b', undefined]);
2111       assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
2112       assert.deepEqual(bound(), [undefined, 'b', undefined]);
2113     });
2114
2115     QUnit.test('should use `_.placeholder` when set', function(assert) {
2116       assert.expect(1);
2117
2118       if (!isModularize) {
2119         var object = {
2120           'fn': function() {
2121             return slice.call(arguments);
2122           }
2123         };
2124
2125         var _ph = _.placeholder = {},
2126             ph = _.bindKey.placeholder,
2127             bound = _.bindKey(object, 'fn', _ph, 'b', ph);
2128
2129         assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
2130         delete _.placeholder;
2131       }
2132       else {
2133         skipAssert(assert);
2134       }
2135     });
2136
2137     QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
2138       assert.expect(2);
2139
2140       function Foo(value) {
2141         return value && object;
2142       }
2143
2144       var object = { 'Foo': Foo },
2145           bound = _.bindKey(object, 'Foo');
2146
2147       assert.ok(new bound instanceof Foo);
2148       assert.strictEqual(new bound(true), object);
2149     });
2150   }());
2151
2152   /*--------------------------------------------------------------------------*/
2153
2154   QUnit.module('case methods');
2155
2156   lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
2157     var methodName = caseName + 'Case',
2158         func = _[methodName];
2159
2160     var strings = [
2161       'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
2162       'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'
2163     ];
2164
2165     var converted = (function() {
2166       switch (caseName) {
2167         case 'camel': return 'fooBar';
2168         case 'kebab': return 'foo-bar';
2169         case 'lower': return 'foo bar';
2170         case 'snake': return 'foo_bar';
2171         case 'start': return 'Foo Bar';
2172         case 'upper': return 'FOO BAR';
2173       }
2174     }());
2175
2176     QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
2177       assert.expect(1);
2178
2179       var actual = lodashStable.map(strings, function(string) {
2180         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2181         return func(string) === expected;
2182       });
2183
2184       assert.deepEqual(actual, lodashStable.map(strings, stubTrue));
2185     });
2186
2187     QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
2188       assert.expect(1);
2189
2190       var actual = lodashStable.map(strings, function(string) {
2191         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2192         return func(func(string)) === expected;
2193       });
2194
2195       assert.deepEqual(actual, lodashStable.map(strings, stubTrue));
2196     });
2197
2198     QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
2199       assert.expect(1);
2200
2201       var actual = lodashStable.map(burredLetters, function(burred, index) {
2202         var letter = deburredLetters[index];
2203         if (caseName == 'start') {
2204           letter = lodashStable.capitalize(letter);
2205         } else if (caseName == 'upper') {
2206           letter = letter.toUpperCase();
2207         } else {
2208           letter = letter.toLowerCase();
2209         }
2210         return func(burred) === letter;
2211       });
2212
2213       assert.deepEqual(actual, lodashStable.map(burredLetters, stubTrue));
2214     });
2215
2216     QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) {
2217       assert.expect(2);
2218
2219       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
2220
2221       lodashStable.each(["'", '\u2019'], function(apos) {
2222         var actual = lodashStable.map(postfixes, function(postfix) {
2223           return func('a b' + apos + postfix +  ' c');
2224         });
2225
2226         var expected = lodashStable.map(postfixes, function(postfix) {
2227           switch (caseName) {
2228             case 'camel': return 'aB'  + postfix + 'C';
2229             case 'kebab': return 'a-b' + postfix + '-c';
2230             case 'lower': return 'a b' + postfix + ' c';
2231             case 'snake': return 'a_b' + postfix + '_c';
2232             case 'start': return 'A B' + postfix + ' C';
2233             case 'upper': return 'A B' + postfix.toUpperCase() + ' C';
2234           }
2235         });
2236
2237         assert.deepEqual(actual, expected);
2238       });
2239     });
2240
2241     QUnit.test('`_.' + methodName + '` should remove latin-1 mathematical operators', function(assert) {
2242       assert.expect(1);
2243
2244       var actual = lodashStable.map(['\xd7', '\xf7'], func);
2245       assert.deepEqual(actual, ['', '']);
2246     });
2247
2248     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2249       assert.expect(2);
2250
2251       var string = 'foo bar';
2252       assert.strictEqual(func(Object(string)), converted);
2253       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2254     });
2255
2256     QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2257       assert.expect(1);
2258
2259       if (!isNpm) {
2260         assert.strictEqual(_('foo bar')[methodName](), converted);
2261       }
2262       else {
2263         skipAssert(assert);
2264       }
2265     });
2266
2267     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2268       assert.expect(1);
2269
2270       if (!isNpm) {
2271         assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2272       }
2273       else {
2274         skipAssert(assert);
2275       }
2276     });
2277   });
2278
2279   (function() {
2280     QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2281       assert.expect(1);
2282
2283       var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase];
2284
2285       var actual = lodashStable.reduce(funcs, function(result, func) {
2286         return func(result);
2287       }, 'enable 6h format');
2288
2289       assert.strictEqual(actual, 'enable6HFormat');
2290     });
2291   }());
2292
2293   /*--------------------------------------------------------------------------*/
2294
2295   QUnit.module('lodash.camelCase');
2296
2297   (function() {
2298     QUnit.test('should work with numbers', function(assert) {
2299       assert.expect(6);
2300
2301       assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2302       assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
2303       assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
2304       assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2305       assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2306       assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2307     });
2308
2309     QUnit.test('should handle acronyms', function(assert) {
2310       assert.expect(6);
2311
2312       lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2313         assert.strictEqual(_.camelCase(string), 'safeHtml');
2314       });
2315
2316       lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2317         assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2318       });
2319
2320       lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2321         assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2322       });
2323     });
2324   }());
2325
2326   /*--------------------------------------------------------------------------*/
2327
2328   QUnit.module('lodash.capitalize');
2329
2330   (function() {
2331     QUnit.test('should capitalize the first character of a string', function(assert) {
2332       assert.expect(3);
2333
2334       assert.strictEqual(_.capitalize('fred'), 'Fred');
2335       assert.strictEqual(_.capitalize('Fred'), 'Fred');
2336       assert.strictEqual(_.capitalize(' fred'), ' fred');
2337     });
2338   }());
2339
2340   /*--------------------------------------------------------------------------*/
2341
2342   QUnit.module('lodash.castArray');
2343
2344   (function() {
2345     QUnit.test('should wrap non-array items in an array', function(assert) {
2346       assert.expect(1);
2347
2348       var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
2349           expected = lodashStable.map(values, function(value) { return [value]; }),
2350           actual = lodashStable.map(values, _.castArray);
2351
2352       assert.deepEqual(actual, expected);
2353     });
2354
2355     QUnit.test('should return array values by reference', function(assert) {
2356       assert.expect(1);
2357
2358       var array = [1];
2359       assert.strictEqual(_.castArray(array), array);
2360     });
2361
2362     QUnit.test('should return an empty array when no arguments are given', function(assert) {
2363       assert.expect(1);
2364
2365       assert.deepEqual(_.castArray(), []);
2366     });
2367   }());
2368
2369   /*--------------------------------------------------------------------------*/
2370
2371   QUnit.module('lodash.chain');
2372
2373   (function() {
2374     QUnit.test('should return a wrapped value', function(assert) {
2375       assert.expect(1);
2376
2377       if (!isNpm) {
2378         var actual = _.chain({ 'a': 0 });
2379         assert.ok(actual instanceof _);
2380       }
2381       else {
2382         skipAssert(assert);
2383       }
2384     });
2385
2386     QUnit.test('should return existing wrapped values', function(assert) {
2387       assert.expect(2);
2388
2389       if (!isNpm) {
2390         var wrapped = _({ 'a': 0 });
2391         assert.strictEqual(_.chain(wrapped), wrapped);
2392         assert.strictEqual(wrapped.chain(), wrapped);
2393       }
2394       else {
2395         skipAssert(assert, 2);
2396       }
2397     });
2398
2399     QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2400       assert.expect(6);
2401
2402       if (!isNpm) {
2403         var array = ['c', 'b', 'a'];
2404
2405         assert.ok(_.chain(array).head() instanceof _);
2406         assert.ok(_(array).chain().head() instanceof _);
2407
2408         assert.ok(_.chain(array).isArray() instanceof _);
2409         assert.ok(_(array).chain().isArray() instanceof _);
2410
2411         assert.ok(_.chain(array).sortBy().head() instanceof _);
2412         assert.ok(_(array).chain().sortBy().head() instanceof _);
2413       }
2414       else {
2415         skipAssert(assert, 6);
2416       }
2417     });
2418
2419     QUnit.test('should chain multiple methods', function(assert) {
2420       assert.expect(6);
2421
2422       if (!isNpm) {
2423         lodashStable.times(2, function(index) {
2424           var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2425               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 },
2426               wrapped = index ? _(array).chain() : _.chain(array);
2427
2428           var actual = wrapped
2429             .chain()
2430             .map(function(value) { return value.split(''); })
2431             .flatten()
2432             .reduce(function(object, chr) {
2433               object[chr] || (object[chr] = 0);
2434               object[chr]++;
2435               return object;
2436             }, {})
2437             .value();
2438
2439           assert.deepEqual(actual, expected);
2440
2441           array = [1, 2, 3, 4, 5, 6];
2442           wrapped = index ? _(array).chain() : _.chain(array);
2443           actual = wrapped
2444             .chain()
2445             .filter(function(n) { return n % 2 != 0; })
2446             .reject(function(n) { return n % 3 == 0; })
2447             .sortBy(function(n) { return -n; })
2448             .value();
2449
2450           assert.deepEqual(actual, [5, 1]);
2451
2452           array = [3, 4];
2453           wrapped = index ? _(array).chain() : _.chain(array);
2454           actual = wrapped
2455             .reverse()
2456             .concat([2, 1])
2457             .unshift(5)
2458             .tap(function(value) { value.pop(); })
2459             .map(square)
2460             .value();
2461
2462           assert.deepEqual(actual, [25, 16, 9, 4]);
2463         });
2464       }
2465       else {
2466         skipAssert(assert, 6);
2467       }
2468     });
2469   }());
2470
2471   /*--------------------------------------------------------------------------*/
2472
2473   QUnit.module('lodash.chunk');
2474
2475   (function() {
2476     var array = [0, 1, 2, 3, 4, 5];
2477
2478     QUnit.test('should return chunked arrays', function(assert) {
2479       assert.expect(1);
2480
2481       var actual = _.chunk(array, 3);
2482       assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2483     });
2484
2485     QUnit.test('should return the last chunk as remaining elements', function(assert) {
2486       assert.expect(1);
2487
2488       var actual = _.chunk(array, 4);
2489       assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2490     });
2491
2492     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
2493       assert.expect(1);
2494
2495       var expected = lodashStable.map(falsey, function(value) {
2496         return value === undefined ? [[0], [1], [2], [3], [4], [5]] : [];
2497       });
2498
2499       var actual = lodashStable.map(falsey, function(size, index) {
2500         return index ? _.chunk(array, size) : _.chunk(array);
2501       });
2502
2503       assert.deepEqual(actual, expected);
2504     });
2505
2506     QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2507       assert.expect(1);
2508
2509       var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity),
2510           expected = lodashStable.map(values, stubArray);
2511
2512       var actual = lodashStable.map(values, function(n) {
2513         return _.chunk(array, n);
2514       });
2515
2516       assert.deepEqual(actual, expected);
2517     });
2518
2519     QUnit.test('should coerce `size` to an integer', function(assert) {
2520       assert.expect(1);
2521
2522       assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2523     });
2524
2525     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
2526       assert.expect(1);
2527
2528       var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk);
2529       assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]);
2530     });
2531   }());
2532
2533   /*--------------------------------------------------------------------------*/
2534
2535   QUnit.module('lodash.clamp');
2536
2537   (function() {
2538     QUnit.test('should work with a `max` argument', function(assert) {
2539       assert.expect(2);
2540
2541       assert.strictEqual(_.clamp(5, 3), 3);
2542       assert.strictEqual(_.clamp(1, 3), 1);
2543     });
2544
2545     QUnit.test('should clamp negative numbers', function(assert) {
2546       assert.expect(3);
2547
2548       assert.strictEqual(_.clamp(-10, -5, 5), -5);
2549       assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2550       assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2551     });
2552
2553     QUnit.test('should clamp positive numbers', function(assert) {
2554       assert.expect(3);
2555
2556       assert.strictEqual(_.clamp(10, -5, 5), 5);
2557       assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2558       assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2559     });
2560
2561     QUnit.test('should not alter negative numbers in range', function(assert) {
2562       assert.expect(3);
2563
2564       assert.strictEqual(_.clamp(-4, -5, 5), -4);
2565       assert.strictEqual(_.clamp(-5, -5, 5), -5);
2566       assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2567     });
2568
2569     QUnit.test('should not alter positive numbers in range', function(assert) {
2570       assert.expect(3);
2571
2572       assert.strictEqual(_.clamp(4, -5, 5), 4);
2573       assert.strictEqual(_.clamp(5, -5, 5), 5);
2574       assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2575     });
2576
2577     QUnit.test('should not alter `0` in range', function(assert) {
2578       assert.expect(1);
2579
2580       assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2581     });
2582
2583     QUnit.test('should clamp to `0`', function(assert) {
2584       assert.expect(1);
2585
2586       assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2587     });
2588
2589     QUnit.test('should not alter `-0` in range', function(assert) {
2590       assert.expect(1);
2591
2592       assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2593     });
2594
2595     QUnit.test('should clamp to `-0`', function(assert) {
2596       assert.expect(1);
2597
2598       assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2599     });
2600
2601     QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2602       assert.expect(1);
2603
2604       assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2605     });
2606
2607     QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2608       assert.expect(2);
2609
2610       assert.deepEqual(_.clamp(1, -5, NaN), 0);
2611       assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2612     });
2613   }());
2614
2615   /*--------------------------------------------------------------------------*/
2616
2617   QUnit.module('clone methods');
2618
2619   (function() {
2620     function Foo() {
2621       this.a = 1;
2622     }
2623     Foo.prototype.b = 1;
2624     Foo.c = function() {};
2625
2626     if (Map) {
2627       var map = new Map;
2628       map.set('a', 1);
2629       map.set('b', 2);
2630     }
2631     if (Set) {
2632       var set = new Set;
2633       set.add(1);
2634       set.add(2);
2635     }
2636     var objects = {
2637       '`arguments` objects': arguments,
2638       'arrays': ['a', ''],
2639       'array-like objects': { '0': 'a', '1': '', 'length': 3 },
2640       'booleans': false,
2641       'boolean objects': Object(false),
2642       'date objects': new Date,
2643       'Foo instances': new Foo,
2644       'objects': { 'a': 0, 'b': 1, 'c': 2 },
2645       'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2646       'objects from another document': realm.object || {},
2647       'maps': map,
2648       'null values': null,
2649       'numbers': 0,
2650       'number objects': Object(0),
2651       'regexes': /a/gim,
2652       'sets': set,
2653       'strings': 'a',
2654       'string objects': Object('a'),
2655       'undefined values': undefined
2656     };
2657
2658     objects.arrays.length = 3;
2659
2660     var uncloneable = {
2661       'DOM elements': body,
2662       'functions': Foo,
2663       'generators': generator
2664     };
2665
2666     lodashStable.each(errors, function(error) {
2667       uncloneable[error.name + 's'] = error;
2668     });
2669
2670     QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2671       assert.expect(2);
2672
2673       var array = [{ 'a': 0 }, { 'b': 1 }],
2674           actual = _.clone(array);
2675
2676       assert.deepEqual(actual, array);
2677       assert.ok(actual !== array && actual[0] === array[0]);
2678     });
2679
2680     QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2681       assert.expect(1);
2682
2683       var object = {
2684         'foo': { 'b': { 'c': { 'd': {} } } },
2685         'bar': {}
2686       };
2687
2688       object.foo.b.c.d = object;
2689       object.bar.b = object.foo.b;
2690
2691       var actual = _.cloneDeep(object);
2692       assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2693     });
2694
2695     QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2696       assert.expect(2);
2697
2698       var cyclical = {};
2699       lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2700         cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2701       });
2702
2703       var clone = _.cloneDeep(cyclical),
2704           actual = clone['v' + LARGE_ARRAY_SIZE][0];
2705
2706       assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2707       assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2708     });
2709
2710     QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2711       assert.expect(1);
2712
2713       var actual;
2714
2715       _.cloneDeepWith({ 'a': 1 }, function() {
2716         actual = _.last(arguments);
2717       });
2718
2719       assert.ok(isNpm
2720         ? actual.constructor.name == 'Stack'
2721         : actual instanceof mapCaches.Stack
2722       );
2723     });
2724
2725     lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2726       var func = _[methodName],
2727           isDeep = methodName == 'cloneDeep';
2728
2729       lodashStable.forOwn(objects, function(object, key) {
2730         QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
2731           assert.expect(2);
2732
2733           var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
2734               actual = func(object);
2735
2736           assert.ok(isEqual(actual, object));
2737
2738           if (lodashStable.isObject(object)) {
2739             assert.notStrictEqual(actual, object);
2740           } else {
2741             assert.strictEqual(actual, object);
2742           }
2743         });
2744       });
2745
2746       QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2747         assert.expect(2);
2748
2749         if (ArrayBuffer) {
2750           var actual = func(arrayBuffer);
2751           assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
2752           assert.notStrictEqual(actual, arrayBuffer);
2753         }
2754         else {
2755           skipAssert(assert, 2);
2756         }
2757       });
2758
2759       QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
2760         assert.expect(4);
2761
2762         if (Buffer) {
2763           var buffer = new Buffer([1, 2]),
2764               actual = func(buffer);
2765
2766           assert.strictEqual(actual.byteLength, buffer.byteLength);
2767           assert.strictEqual(actual.inspect(), buffer.inspect());
2768           assert.notStrictEqual(actual, buffer);
2769
2770           buffer[0] = 2;
2771           assert.strictEqual(actual[0], isDeep ? 2 : 1);
2772         }
2773         else {
2774           skipAssert(assert, 4);
2775         }
2776       });
2777
2778       QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2779         assert.expect(2);
2780
2781         var array = /c/.exec('abcde'),
2782             actual = func(array);
2783
2784         assert.strictEqual(actual.index, 2);
2785         assert.strictEqual(actual.input, 'abcde');
2786       });
2787
2788       QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2789         assert.expect(1);
2790
2791         var regexp = /c/g;
2792         regexp.exec('abcde');
2793
2794         assert.strictEqual(func(regexp).lastIndex, 3);
2795       });
2796
2797       QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
2798         assert.expect(1);
2799
2800         var values = lodashStable.map([false, true, 1, 'a'], function(value) {
2801           var object = Object(value);
2802           object.a = 1;
2803           return object;
2804         });
2805
2806         var expected = lodashStable.map(values, stubTrue);
2807
2808         var actual = lodashStable.map(values, function(value) {
2809           return func(value).a === 1;
2810         });
2811
2812         assert.deepEqual(actual, expected);
2813       });
2814
2815       QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
2816         assert.expect(2);
2817
2818         var actual = func(Foo.prototype);
2819
2820         assert.notOk(actual instanceof Foo);
2821         assert.deepEqual(actual, { 'b': 1 });
2822       });
2823
2824       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
2825         assert.expect(1);
2826
2827         assert.ok(func(new Foo) instanceof Foo);
2828       });
2829
2830       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
2831         assert.expect(1);
2832
2833         Foo.prototype.constructor = Object;
2834         assert.ok(func(new Foo) instanceof Foo);
2835         Foo.prototype.constructor = Foo;
2836       });
2837
2838       QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2839         assert.expect(1);
2840
2841         Foo.prototype.constructor = null;
2842         assert.notOk(func(new Foo) instanceof Foo);
2843         Foo.prototype.constructor = Foo;
2844       });
2845
2846       QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2847         assert.expect(2);
2848
2849         var object = {
2850           'constructor': objectProto.constructor,
2851           'hasOwnProperty': objectProto.hasOwnProperty,
2852           'isPrototypeOf': objectProto.isPrototypeOf,
2853           'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2854           'toLocaleString': objectProto.toLocaleString,
2855           'toString': objectProto.toString,
2856           'valueOf': objectProto.valueOf
2857         };
2858
2859         var actual = func(object);
2860
2861         assert.deepEqual(actual, object);
2862         assert.notStrictEqual(actual, object);
2863       });
2864
2865       QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2866         assert.expect(3);
2867
2868         function Foo() {
2869           this[symbol] = { 'c': 1 };
2870         }
2871
2872         if (Symbol) {
2873           var symbol2 = Symbol('b');
2874           Foo.prototype[symbol2] = 2;
2875
2876           var object = { 'a': { 'b': new Foo } };
2877           object[symbol] = { 'b': 1 };
2878
2879           var actual = func(object);
2880
2881           assert.deepEqual(getSymbols(actual.a.b), [symbol]);
2882
2883           if (isDeep) {
2884             assert.deepEqual(actual[symbol], object[symbol]);
2885             assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]);
2886           }
2887           else {
2888             assert.strictEqual(actual[symbol], object[symbol]);
2889             assert.strictEqual(actual.a, object.a);
2890           }
2891         }
2892         else {
2893           skipAssert(assert, 3);
2894         }
2895       });
2896
2897       QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2898         assert.expect(4);
2899
2900         if (Symbol) {
2901           assert.strictEqual(func(symbol), symbol);
2902
2903           var object = Object(symbol),
2904               actual = func(object);
2905
2906           assert.strictEqual(typeof actual, 'object');
2907           assert.strictEqual(typeof actual.valueOf(), 'symbol');
2908           assert.notStrictEqual(actual, object);
2909         }
2910         else {
2911           skipAssert(assert, 4);
2912         }
2913       });
2914
2915       QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2916         assert.expect(1);
2917
2918         if (Symbol) {
2919           assert.strictEqual(func(symbol), symbol);
2920         }
2921         else {
2922           skipAssert(assert);
2923         }
2924       });
2925
2926       QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2927         assert.expect(1);
2928
2929         if (document) {
2930           var element = document.createElement('div');
2931
2932           try {
2933             assert.deepEqual(func(element), {});
2934           } catch (e) {
2935             assert.ok(false, e.message);
2936           }
2937         }
2938         else {
2939           skipAssert(assert);
2940         }
2941       });
2942
2943       QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
2944         assert.expect(1);
2945
2946         var props = [];
2947
2948         var objects = lodashStable.transform(_, function(result, value, key) {
2949           if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
2950               !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
2951               !lodashStable.isFunction(value)) {
2952             props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
2953             result.push(value);
2954           }
2955         }, []);
2956
2957         var expected = lodashStable.map(objects, stubTrue);
2958
2959         var actual = lodashStable.map(objects, function(object) {
2960           var Ctor = object.constructor,
2961               result = func(object);
2962
2963           return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
2964         });
2965
2966         assert.deepEqual(actual, expected, props.join(', '));
2967       });
2968
2969       QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
2970         assert.expect(2);
2971
2972         var expected = [{ 'a': [0] }, { 'b': [1] }],
2973             actual = lodashStable.map(expected, func);
2974
2975         assert.deepEqual(actual, expected);
2976
2977         if (isDeep) {
2978           assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
2979         } else {
2980           assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
2981         }
2982       });
2983
2984       QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
2985         assert.expect(2);
2986
2987         if (!isNpm) {
2988           var object = objects.objects,
2989               actual = _(object)[methodName]();
2990
2991           assert.deepEqual(actual, object);
2992           assert.notStrictEqual(actual, object);
2993         }
2994         else {
2995           skipAssert(assert, 2);
2996         }
2997       });
2998
2999       lodashStable.each(arrayViews, function(type) {
3000         QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) {
3001           assert.expect(10);
3002
3003           var Ctor = root[type];
3004
3005           lodashStable.times(2, function(index) {
3006             if (Ctor) {
3007               var buffer = new ArrayBuffer(24),
3008                   view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
3009                   actual = func(view);
3010
3011               assert.deepEqual(actual, view);
3012               assert.notStrictEqual(actual, view);
3013               assert.strictEqual(actual.buffer === view.buffer, !isDeep);
3014               assert.strictEqual(actual.byteOffset, view.byteOffset);
3015               assert.strictEqual(actual.length, view.length);
3016             }
3017             else {
3018               skipAssert(assert, 5);
3019             }
3020           });
3021         });
3022       });
3023
3024       lodashStable.forOwn(uncloneable, function(value, key) {
3025         QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
3026           assert.expect(3);
3027
3028           if (value) {
3029             var object = { 'a': value, 'b': { 'c': value } },
3030                 actual = func(object),
3031                 expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
3032
3033             assert.deepEqual(actual, object);
3034             assert.notStrictEqual(actual, object);
3035             assert.deepEqual(func(value), expected);
3036           }
3037           else {
3038             skipAssert(assert, 3);
3039           }
3040         });
3041       });
3042     });
3043
3044     lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
3045       var func = _[methodName],
3046           isDeep = methodName == 'cloneDeepWith';
3047
3048       QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
3049         assert.expect(1);
3050
3051         var argsList = [],
3052             object = new Foo;
3053
3054         func(object, function() {
3055           var length = arguments.length,
3056               args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
3057
3058           argsList.push(args);
3059         });
3060
3061         assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]);
3062       });
3063
3064       QUnit.test('`_.' + methodName + '` should handle cloning when `customizer` returns `undefined`', function(assert) {
3065         assert.expect(1);
3066
3067         var actual = func({ 'a': { 'b': 'c' } }, noop);
3068         assert.deepEqual(actual, { 'a': { 'b': 'c' } });
3069       });
3070
3071       lodashStable.forOwn(uncloneable, function(value, key) {
3072         QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
3073           assert.expect(3);
3074
3075           var customizer = function(value) {
3076             return lodashStable.isPlainObject(value) ? undefined : value;
3077           };
3078
3079           var actual = func(value, customizer);
3080           assert.strictEqual(actual, value);
3081
3082           var object = { 'a': value, 'b': { 'c': value } };
3083           actual = func(object, customizer);
3084
3085           assert.deepEqual(actual, object);
3086           assert.notStrictEqual(actual, object);
3087         });
3088       });
3089     });
3090   }(1, 2, 3));
3091
3092   /*--------------------------------------------------------------------------*/
3093
3094   QUnit.module('lodash.compact');
3095
3096   (function() {
3097     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
3098
3099     QUnit.test('should filter falsey values', function(assert) {
3100       assert.expect(1);
3101
3102       var array = ['0', '1', '2'];
3103       assert.deepEqual(_.compact(falsey.concat(array)), array);
3104     });
3105
3106     QUnit.test('should work when in-between lazy operators', function(assert) {
3107       assert.expect(2);
3108
3109       if (!isNpm) {
3110         var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
3111         assert.deepEqual(actual, []);
3112
3113         actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
3114         assert.deepEqual(actual, [true, 1, 'a']);
3115       }
3116       else {
3117         skipAssert(assert, 2);
3118       }
3119     });
3120
3121     QUnit.test('should work in a lazy sequence', function(assert) {
3122       assert.expect(1);
3123
3124       if (!isNpm) {
3125         var actual = _(largeArray).slice(1).compact().reverse().take().value();
3126         assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
3127       }
3128       else {
3129         skipAssert(assert);
3130       }
3131     });
3132
3133     QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
3134       assert.expect(1);
3135
3136       if (!isModularize) {
3137         var iteratee = _.iteratee,
3138             pass = false;
3139
3140         _.iteratee = identity;
3141
3142         try {
3143           var actual = _(largeArray).slice(1).compact().value();
3144           pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
3145         } catch (e) {console.log(e);}
3146
3147         assert.ok(pass);
3148         _.iteratee = iteratee;
3149       }
3150       else {
3151         skipAssert(assert);
3152       }
3153     });
3154   }());
3155
3156   /*--------------------------------------------------------------------------*/
3157
3158   QUnit.module('lodash.concat');
3159
3160   (function() {
3161     QUnit.test('should shallow clone `array`', function(assert) {
3162       assert.expect(2);
3163
3164       var array = [1, 2, 3],
3165           actual = _.concat(array);
3166
3167       assert.deepEqual(actual, array);
3168       assert.notStrictEqual(actual, array);
3169     });
3170
3171     QUnit.test('should concat arrays and values', function(assert) {
3172       assert.expect(2);
3173
3174       var array = [1],
3175           actual = _.concat(array, 2, [3], [[4]]);
3176
3177       assert.deepEqual(actual, [1, 2, 3, [4]]);
3178       assert.deepEqual(array, [1]);
3179     });
3180
3181     QUnit.test('should cast non-array `array` values to arrays', function(assert) {
3182       assert.expect(2);
3183
3184       var values = [, null, undefined, false, true, 1, NaN, 'a'];
3185
3186       var expected = lodashStable.map(values, function(value, index) {
3187         return index ? [value] : [];
3188       });
3189
3190       var actual = lodashStable.map(values, function(value, index) {
3191         return index ? _.concat(value) : _.concat();
3192       });
3193
3194       assert.deepEqual(actual, expected);
3195
3196       expected = lodashStable.map(values, function(value) {
3197         return [value, 2, [3]];
3198       });
3199
3200       actual = lodashStable.map(values, function(value) {
3201         return _.concat(value, [2], [[3]]);
3202       });
3203
3204       assert.deepEqual(actual, expected);
3205     });
3206
3207     QUnit.test('should treat sparse arrays as dense', function(assert) {
3208       assert.expect(3);
3209
3210       var expected = [],
3211           actual = _.concat(Array(1), Array(1));
3212
3213       expected.push(undefined, undefined);
3214
3215       assert.ok('0'in actual);
3216       assert.ok('1' in actual);
3217       assert.deepEqual(actual, expected);
3218     });
3219
3220     QUnit.test('should return a new wrapped array', function(assert) {
3221       assert.expect(2);
3222
3223       if (!isNpm) {
3224         var array = [1],
3225             wrapped = _(array).concat([2, 3]),
3226             actual = wrapped.value();
3227
3228         assert.deepEqual(array, [1]);
3229         assert.deepEqual(actual, [1, 2, 3]);
3230       }
3231       else {
3232         skipAssert(assert, 2);
3233       }
3234     });
3235   }());
3236
3237   /*--------------------------------------------------------------------------*/
3238
3239   QUnit.module('lodash.cond');
3240
3241   (function() {
3242     QUnit.test('should create a conditional function', function(assert) {
3243       assert.expect(3);
3244
3245       var cond = _.cond([
3246         [lodashStable.matches({ 'a': 1 }),     stubA],
3247         [lodashStable.matchesProperty('b', 1), stubB],
3248         [lodashStable.property('c'),           stubC]
3249       ]);
3250
3251       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3252       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3253       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3254     });
3255
3256     QUnit.test('should provide arguments to functions', function(assert) {
3257       assert.expect(2);
3258
3259       var args1,
3260           args2,
3261           expected = ['a', 'b', 'c'];
3262
3263       var cond = _.cond([[
3264         function() { args1 || (args1 = slice.call(arguments)); return true; },
3265         function() { args2 || (args2 = slice.call(arguments)); }
3266       ]]);
3267
3268       cond('a', 'b', 'c');
3269
3270       assert.deepEqual(args1, expected);
3271       assert.deepEqual(args2, expected);
3272     });
3273
3274     QUnit.test('should work with predicate shorthands', function(assert) {
3275       assert.expect(3);
3276
3277       var cond = _.cond([
3278         [{ 'a': 1 }, stubA],
3279         [['b', 1],   stubB],
3280         ['c',        stubC]
3281       ]);
3282
3283       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3284       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3285       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3286     });
3287
3288     QUnit.test('should return `undefined` when no condition is met', function(assert) {
3289       assert.expect(1);
3290
3291       var cond = _.cond([[stubFalse, stubA]]);
3292       assert.strictEqual(cond({ 'a': 1 }), undefined);
3293     });
3294
3295     QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
3296       assert.expect(2);
3297
3298       lodashStable.each([false, true], function(value) {
3299         assert.raises(function() { _.cond([[stubTrue, value]])(); }, TypeError);
3300       });
3301     });
3302
3303     QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
3304       assert.expect(1);
3305
3306       var cond = _.cond([
3307         [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
3308       ]);
3309
3310       var object = { 'cond': cond, 'a': 1, 'b': 2 };
3311       assert.strictEqual(object.cond('a', 'b'), 2);
3312     });
3313   }());
3314
3315   /*--------------------------------------------------------------------------*/
3316
3317   QUnit.module('lodash.conforms');
3318
3319   (function() {
3320     var objects = [
3321       { 'a': 1, 'b': 8 },
3322       { 'a': 2, 'b': 4 },
3323       { 'a': 3, 'b': 16 }
3324     ];
3325
3326     QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
3327       assert.expect(2);
3328
3329       var conforms = _.conforms({
3330         'b': function(value) { return value > 4; }
3331       });
3332
3333       var actual = lodashStable.filter(objects, conforms);
3334       assert.deepEqual(actual, [objects[0], objects[2]]);
3335
3336       conforms = _.conforms({
3337         'b': function(value) { return value > 8; },
3338         'a': function(value) { return value > 1; }
3339       });
3340
3341       actual = lodashStable.filter(objects, conforms);
3342       assert.deepEqual(actual, [objects[2]]);
3343     });
3344
3345     QUnit.test('should not match by inherited `source` properties', function(assert) {
3346       assert.expect(1);
3347
3348       function Foo() {
3349         this.a = function(value) {
3350           return value > 1;
3351         };
3352       }
3353       Foo.prototype.b = function(value) {
3354         return value > 8;
3355       };
3356
3357       var conforms = _.conforms(new Foo),
3358           actual = lodashStable.filter(objects, conforms);
3359
3360       assert.deepEqual(actual, [objects[1], objects[2]]);
3361     });
3362
3363     QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
3364       assert.expect(2);
3365
3366       var count = 0;
3367
3368       var conforms = _.conforms({
3369         'a': function() { count++; return true; }
3370       });
3371
3372       assert.strictEqual(conforms({}), false);
3373       assert.strictEqual(count, 0);
3374     });
3375
3376     QUnit.test('should work with a function for `object`', function(assert) {
3377       assert.expect(2);
3378
3379       function Foo() {}
3380       Foo.a = 1;
3381
3382       function Bar() {}
3383       Bar.a = 2;
3384
3385       var conforms = _.conforms({
3386         'a': function(value) { return value > 1; }
3387       });
3388
3389       assert.strictEqual(conforms(Foo), false);
3390       assert.strictEqual(conforms(Bar), true);
3391     });
3392
3393     QUnit.test('should work with a function for `source`', function(assert) {
3394       assert.expect(1);
3395
3396       function Foo() {}
3397       Foo.a = function(value) { return value > 1; };
3398
3399       var objects = [{ 'a': 1 }, { 'a': 2 }],
3400           actual = lodashStable.filter(objects, _.conforms(Foo));
3401
3402       assert.deepEqual(actual, [objects[1]]);
3403     });
3404
3405     QUnit.test('should work with a non-plain `object`', function(assert) {
3406       assert.expect(1);
3407
3408       function Foo() {
3409         this.a = 1;
3410       }
3411       Foo.prototype.b = 2;
3412
3413       var conforms = _.conforms({
3414         'b': function(value) { return value > 1; }
3415       });
3416
3417       assert.strictEqual(conforms(new Foo), true);
3418     });
3419
3420     QUnit.test('should return `false` when `object` is nullish', function(assert) {
3421       assert.expect(1);
3422
3423       var values = [, null, undefined],
3424           expected = lodashStable.map(values, stubFalse);
3425
3426       var conforms = _.conforms({
3427         'a': function(value) { return value > 1; }
3428       });
3429
3430       var actual = lodashStable.map(values, function(value, index) {
3431         try {
3432           return index ? conforms(value) : conforms();
3433         } catch (e) {}
3434       });
3435
3436       assert.deepEqual(actual, expected);
3437     });
3438
3439     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3440       assert.expect(1);
3441
3442       var values = [, null, undefined],
3443           expected = lodashStable.map(values, stubTrue),
3444           conforms = _.conforms({});
3445
3446       var actual = lodashStable.map(values, function(value, index) {
3447         try {
3448           return index ? conforms(value) : conforms();
3449         } catch (e) {}
3450       });
3451
3452       assert.deepEqual(actual, expected);
3453     });
3454
3455     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
3456       assert.expect(1);
3457
3458       var object = { 'a': 1 },
3459           expected = lodashStable.map(empties, stubTrue);
3460
3461       var actual = lodashStable.map(empties, function(value) {
3462         var conforms = _.conforms(value);
3463         return conforms(object);
3464       });
3465
3466       assert.deepEqual(actual, expected);
3467     });
3468
3469     QUnit.test('should not change behavior if `source` is modified', function(assert) {
3470       assert.expect(2);
3471
3472       var source = {
3473         'a': function(value) { return value > 1; }
3474       };
3475
3476       var object = { 'a': 2 },
3477           conforms = _.conforms(source);
3478
3479       assert.strictEqual(conforms(object), true);
3480
3481       source.a = function(value) { return value < 2; };
3482       assert.strictEqual(conforms(object), true);
3483     });
3484   }());
3485
3486   /*--------------------------------------------------------------------------*/
3487
3488   QUnit.module('lodash.constant');
3489
3490   (function() {
3491     QUnit.test('should create a function that returns `value`', function(assert) {
3492       assert.expect(1);
3493
3494       var object = { 'a': 1 },
3495           values = Array(2).concat(empties, true, 1, 'a'),
3496           constant = _.constant(object);
3497
3498       var results = lodashStable.map(values, function(value, index) {
3499         if (index < 2) {
3500           return index ? constant.call({}) : constant();
3501         }
3502         return constant(value);
3503       });
3504
3505       assert.ok(lodashStable.every(results, function(result) {
3506         return result === object;
3507       }));
3508     });
3509
3510     QUnit.test('should work with falsey values', function(assert) {
3511       assert.expect(1);
3512
3513       var expected = lodashStable.map(falsey, stubTrue);
3514
3515       var actual = lodashStable.map(falsey, function(value, index) {
3516         var constant = index ? _.constant(value) : _.constant(),
3517             result = constant();
3518
3519         return (result === value) || (result !== result && value !== value);
3520       });
3521
3522       assert.deepEqual(actual, expected);
3523     });
3524
3525     QUnit.test('should return a wrapped value when chaining', function(assert) {
3526       assert.expect(1);
3527
3528       if (!isNpm) {
3529         var wrapped = _(true).constant();
3530         assert.ok(wrapped instanceof _);
3531       }
3532       else {
3533         skipAssert(assert);
3534       }
3535     });
3536   }());
3537
3538   /*--------------------------------------------------------------------------*/
3539
3540   QUnit.module('lodash.countBy');
3541
3542   (function() {
3543     var array = [6.1, 4.2, 6.3];
3544
3545     QUnit.test('should transform keys by `iteratee`', function(assert) {
3546       assert.expect(1);
3547
3548       var actual = _.countBy(array, Math.floor);
3549       assert.deepEqual(actual, { '4': 1, '6': 2 });
3550     });
3551
3552     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3553       assert.expect(1);
3554
3555       var array = [4, 6, 6],
3556           values = [, null, undefined],
3557           expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
3558
3559       var actual = lodashStable.map(values, function(value, index) {
3560         return index ? _.countBy(array, value) : _.countBy(array);
3561       });
3562
3563       assert.deepEqual(actual, expected);
3564     });
3565
3566     QUnit.test('should work with `_.property` shorthands', function(assert) {
3567       assert.expect(1);
3568
3569       var actual = _.countBy(['one', 'two', 'three'], 'length');
3570       assert.deepEqual(actual, { '3': 2, '5': 1 });
3571     });
3572
3573     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3574       assert.expect(2);
3575
3576       var actual = _.countBy(array, function(n) {
3577         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
3578       });
3579
3580       assert.deepEqual(actual.constructor, 1);
3581       assert.deepEqual(actual.hasOwnProperty, 2);
3582     });
3583
3584     QUnit.test('should work with a number for `iteratee`', function(assert) {
3585       assert.expect(2);
3586
3587       var array = [
3588         [1, 'a'],
3589         [2, 'a'],
3590         [2, 'b']
3591       ];
3592
3593       assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3594       assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3595     });
3596
3597     QUnit.test('should work with an object for `collection`', function(assert) {
3598       assert.expect(1);
3599
3600       var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
3601       assert.deepEqual(actual, { '4': 1, '6': 2 });
3602     });
3603
3604     QUnit.test('should work in a lazy sequence', function(assert) {
3605       assert.expect(1);
3606
3607       if (!isNpm) {
3608         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3609           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3610           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3611         );
3612
3613         var actual = _(array).countBy().map(square).filter(isEven).take().value();
3614
3615         assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3616       }
3617       else {
3618         skipAssert(assert);
3619       }
3620     });
3621   }());
3622
3623   /*--------------------------------------------------------------------------*/
3624
3625   QUnit.module('lodash.create');
3626
3627   (function() {
3628     function Shape() {
3629       this.x = 0;
3630       this.y = 0;
3631     }
3632
3633     function Circle() {
3634       Shape.call(this);
3635     }
3636
3637     QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3638       assert.expect(3);
3639
3640       Circle.prototype = _.create(Shape.prototype);
3641       Circle.prototype.constructor = Circle;
3642
3643       var actual = new Circle;
3644
3645       assert.ok(actual instanceof Circle);
3646       assert.ok(actual instanceof Shape);
3647       assert.notStrictEqual(Circle.prototype, Shape.prototype);
3648     });
3649
3650     QUnit.test('should assign `properties` to the created object', function(assert) {
3651       assert.expect(3);
3652
3653       var expected = { 'constructor': Circle, 'radius': 0 };
3654       Circle.prototype = _.create(Shape.prototype, expected);
3655
3656       var actual = new Circle;
3657
3658       assert.ok(actual instanceof Circle);
3659       assert.ok(actual instanceof Shape);
3660       assert.deepEqual(Circle.prototype, expected);
3661     });
3662
3663     QUnit.test('should assign own properties', function(assert) {
3664       assert.expect(1);
3665
3666       function Foo() {
3667         this.a = 1;
3668         this.c = 3;
3669       }
3670       Foo.prototype.b = 2;
3671
3672       assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3673     });
3674
3675     QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
3676       assert.expect(1);
3677
3678       function Foo() {
3679         this.a = 1;
3680       }
3681       var object = _.create(new Foo, { 'a': 1 });
3682       assert.deepEqual(lodashStable.keys(object), ['a']);
3683     });
3684
3685     QUnit.test('should accept a falsey `prototype` argument', function(assert) {
3686       assert.expect(1);
3687
3688       var expected = lodashStable.map(falsey, stubObject);
3689
3690       var actual = lodashStable.map(falsey, function(prototype, index) {
3691         return index ? _.create(prototype) : _.create();
3692       });
3693
3694       assert.deepEqual(actual, expected);
3695     });
3696
3697     QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
3698       assert.expect(1);
3699
3700       var expected = lodashStable.map(primitives, stubTrue);
3701
3702       var actual = lodashStable.map(primitives, function(value, index) {
3703         return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3704       });
3705
3706       assert.deepEqual(actual, expected);
3707     });
3708
3709     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3710       assert.expect(1);
3711
3712       var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3713           expected = lodashStable.map(array, stubTrue),
3714           objects = lodashStable.map(array, _.create);
3715
3716       var actual = lodashStable.map(objects, function(object) {
3717         return object.a === 1 && !_.keys(object).length;
3718       });
3719
3720       assert.deepEqual(actual, expected);
3721     });
3722   }());
3723
3724   /*--------------------------------------------------------------------------*/
3725
3726   QUnit.module('lodash.curry');
3727
3728   (function() {
3729     function fn(a, b, c, d) {
3730       return slice.call(arguments);
3731     }
3732
3733     QUnit.test('should curry based on the number of arguments given', function(assert) {
3734       assert.expect(3);
3735
3736       var curried = _.curry(fn),
3737           expected = [1, 2, 3, 4];
3738
3739       assert.deepEqual(curried(1)(2)(3)(4), expected);
3740       assert.deepEqual(curried(1, 2)(3, 4), expected);
3741       assert.deepEqual(curried(1, 2, 3, 4), expected);
3742     });
3743
3744     QUnit.test('should allow specifying `arity`', function(assert) {
3745       assert.expect(3);
3746
3747       var curried = _.curry(fn, 3),
3748           expected = [1, 2, 3];
3749
3750       assert.deepEqual(curried(1)(2, 3), expected);
3751       assert.deepEqual(curried(1, 2)(3), expected);
3752       assert.deepEqual(curried(1, 2, 3), expected);
3753     });
3754
3755     QUnit.test('should coerce `arity` to an integer', function(assert) {
3756       assert.expect(2);
3757
3758       var values = ['0', 0.6, 'xyz'],
3759           expected = lodashStable.map(values, stubArray);
3760
3761       var actual = lodashStable.map(values, function(arity) {
3762         return _.curry(fn, arity)();
3763       });
3764
3765       assert.deepEqual(actual, expected);
3766       assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3767     });
3768
3769     QUnit.test('should support placeholders', function(assert) {
3770       assert.expect(4);
3771
3772       var curried = _.curry(fn),
3773           ph = curried.placeholder;
3774
3775       assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3776       assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3777       assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3778       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3779     });
3780
3781     QUnit.test('should persist placeholders', function(assert) {
3782       assert.expect(1);
3783
3784       var curried = _.curry(fn),
3785           ph = curried.placeholder,
3786           actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
3787
3788       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3789     });
3790
3791     QUnit.test('should use `_.placeholder` when set', function(assert) {
3792       assert.expect(1);
3793
3794       if (!isModularize) {
3795         var curried = _.curry(fn),
3796             _ph = _.placeholder = {},
3797             ph = curried.placeholder;
3798
3799         assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
3800         delete _.placeholder;
3801       }
3802       else {
3803         skipAssert(assert);
3804       }
3805     });
3806
3807     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3808       assert.expect(3);
3809
3810       var curried = _.curry(fn, 3);
3811       assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3812       assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3813       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3814     });
3815
3816     QUnit.test('should create a function with a `length` of `0`', function(assert) {
3817       assert.expect(6);
3818
3819       lodashStable.times(2, function(index) {
3820         var curried = index ? _.curry(fn, 4) : _.curry(fn);
3821         assert.strictEqual(curried.length, 0);
3822         assert.strictEqual(curried(1).length, 0);
3823         assert.strictEqual(curried(1, 2).length, 0);
3824       });
3825     });
3826
3827     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3828       assert.expect(2);
3829
3830       function Foo(value) {
3831         return value && object;
3832       }
3833
3834       var curried = _.curry(Foo),
3835           object = {};
3836
3837       assert.ok(new curried(false) instanceof Foo);
3838       assert.strictEqual(new curried(true), object);
3839     });
3840
3841     QUnit.test('should not set a `this` binding', function(assert) {
3842       assert.expect(9);
3843
3844       var fn = function(a, b, c) {
3845         var value = this || {};
3846         return [value[a], value[b], value[c]];
3847       };
3848
3849       var object = { 'a': 1, 'b': 2, 'c': 3 },
3850           expected = [1, 2, 3];
3851
3852       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3853       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3854       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3855
3856       assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3857       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3858       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3859
3860       object.curried = _.curry(fn);
3861       assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3862       assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3863       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3864     });
3865
3866     QUnit.test('should work with partialed methods', function(assert) {
3867       assert.expect(2);
3868
3869       var curried = _.curry(fn),
3870           expected = [1, 2, 3, 4];
3871
3872       var a = _.partial(curried, 1),
3873           b = _.bind(a, null, 2),
3874           c = _.partialRight(b, 4),
3875           d = _.partialRight(b(3), 4);
3876
3877       assert.deepEqual(c(3), expected);
3878       assert.deepEqual(d(), expected);
3879     });
3880   }());
3881
3882   /*--------------------------------------------------------------------------*/
3883
3884   QUnit.module('lodash.curryRight');
3885
3886   (function() {
3887     function fn(a, b, c, d) {
3888       return slice.call(arguments);
3889     }
3890
3891     QUnit.test('should curry based on the number of arguments given', function(assert) {
3892       assert.expect(3);
3893
3894       var curried = _.curryRight(fn),
3895           expected = [1, 2, 3, 4];
3896
3897       assert.deepEqual(curried(4)(3)(2)(1), expected);
3898       assert.deepEqual(curried(3, 4)(1, 2), expected);
3899       assert.deepEqual(curried(1, 2, 3, 4), expected);
3900     });
3901
3902     QUnit.test('should allow specifying `arity`', function(assert) {
3903       assert.expect(3);
3904
3905       var curried = _.curryRight(fn, 3),
3906           expected = [1, 2, 3];
3907
3908       assert.deepEqual(curried(3)(1, 2), expected);
3909       assert.deepEqual(curried(2, 3)(1), expected);
3910       assert.deepEqual(curried(1, 2, 3), expected);
3911     });
3912
3913     QUnit.test('should coerce `arity` to an integer', function(assert) {
3914       assert.expect(2);
3915
3916       var values = ['0', 0.6, 'xyz'],
3917           expected = lodashStable.map(values, stubArray);
3918
3919       var actual = lodashStable.map(values, function(arity) {
3920         return _.curryRight(fn, arity)();
3921       });
3922
3923       assert.deepEqual(actual, expected);
3924       assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
3925     });
3926
3927     QUnit.test('should support placeholders', function(assert) {
3928       assert.expect(4);
3929
3930       var curried = _.curryRight(fn),
3931           expected = [1, 2, 3, 4],
3932           ph = curried.placeholder;
3933
3934       assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
3935       assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
3936       assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
3937       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
3938     });
3939
3940     QUnit.test('should persist placeholders', function(assert) {
3941       assert.expect(1);
3942
3943       var curried = _.curryRight(fn),
3944           ph = curried.placeholder,
3945           actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
3946
3947       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3948     });
3949
3950     QUnit.test('should use `_.placeholder` when set', function(assert) {
3951       assert.expect(1);
3952
3953       if (!isModularize) {
3954         var curried = _.curryRight(fn),
3955             _ph = _.placeholder = {},
3956             ph = curried.placeholder;
3957
3958         assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
3959         delete _.placeholder;
3960       }
3961       else {
3962         skipAssert(assert);
3963       }
3964     });
3965
3966     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3967       assert.expect(3);
3968
3969       var curried = _.curryRight(fn, 3);
3970       assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
3971       assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
3972       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3973     });
3974
3975     QUnit.test('should create a function with a `length` of `0`', function(assert) {
3976       assert.expect(6);
3977
3978       lodashStable.times(2, function(index) {
3979         var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
3980         assert.strictEqual(curried.length, 0);
3981         assert.strictEqual(curried(4).length, 0);
3982         assert.strictEqual(curried(3, 4).length, 0);
3983       });
3984     });
3985
3986     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3987       assert.expect(2);
3988
3989       function Foo(value) {
3990         return value && object;
3991       }
3992
3993       var curried = _.curryRight(Foo),
3994           object = {};
3995
3996       assert.ok(new curried(false) instanceof Foo);
3997       assert.strictEqual(new curried(true), object);
3998     });
3999
4000     QUnit.test('should not set a `this` binding', function(assert) {
4001       assert.expect(9);
4002
4003       var fn = function(a, b, c) {
4004         var value = this || {};
4005         return [value[a], value[b], value[c]];
4006       };
4007
4008       var object = { 'a': 1, 'b': 2, 'c': 3 },
4009           expected = [1, 2, 3];
4010
4011       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
4012       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
4013       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
4014
4015       assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
4016       assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
4017       assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
4018
4019       object.curried = _.curryRight(fn);
4020       assert.deepEqual(object.curried('c')('b')('a'), Array(3));
4021       assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
4022       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
4023     });
4024
4025     QUnit.test('should work with partialed methods', function(assert) {
4026       assert.expect(2);
4027
4028       var curried = _.curryRight(fn),
4029           expected = [1, 2, 3, 4];
4030
4031       var a = _.partialRight(curried, 4),
4032           b = _.partialRight(a, 3),
4033           c = _.bind(b, null, 1),
4034           d = _.partial(b(2), 1);
4035
4036       assert.deepEqual(c(2), expected);
4037       assert.deepEqual(d(), expected);
4038     });
4039   }());
4040
4041   /*--------------------------------------------------------------------------*/
4042
4043   QUnit.module('curry methods');
4044
4045   lodashStable.each(['curry', 'curryRight'], function(methodName) {
4046     var func = _[methodName],
4047         fn = function(a, b) { return slice.call(arguments); },
4048         isCurry = methodName == 'curry';
4049
4050     QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
4051       assert.expect(1);
4052
4053       function run(a, b) {
4054         return a + b;
4055       }
4056
4057       var curried = func(run);
4058
4059       try {
4060         var actual = curried(1)(2);
4061       } catch (e) {}
4062
4063       assert.strictEqual(actual, 3);
4064     });
4065
4066     QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
4067       assert.expect(1);
4068
4069       var curried = _.curry(function hasOwnProperty(a, b, c) {
4070         return [a, b, c];
4071       });
4072
4073       var expected = [1, 2, 3];
4074
4075       assert.deepEqual(curried(1)(2)(3), expected);
4076     });
4077
4078     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
4079       assert.expect(2);
4080
4081       var array = [fn, fn, fn],
4082           object = { 'a': fn, 'b': fn, 'c': fn };
4083
4084       lodashStable.each([array, object], function(collection) {
4085         var curries = lodashStable.map(collection, func),
4086             expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
4087
4088         var actual = lodashStable.map(curries, function(curried) {
4089           return curried('a')('b');
4090         });
4091
4092         assert.deepEqual(actual, expected);
4093       });
4094     });
4095   });
4096
4097   /*--------------------------------------------------------------------------*/
4098
4099   QUnit.module('lodash.debounce');
4100
4101   (function() {
4102     QUnit.test('should debounce a function', function(assert) {
4103       assert.expect(6);
4104
4105       var done = assert.async();
4106
4107       var callCount = 0;
4108
4109       var debounced = _.debounce(function(value) {
4110         ++callCount;
4111         return value;
4112       }, 32);
4113
4114       var results = [debounced('a'), debounced('b'), debounced('c')];
4115       assert.deepEqual(results, [undefined, undefined, undefined]);
4116       assert.strictEqual(callCount, 0);
4117
4118       setTimeout(function() {
4119         assert.strictEqual(callCount, 1);
4120
4121         var results = [debounced('d'), debounced('e'), debounced('f')];
4122         assert.deepEqual(results, ['c', 'c', 'c']);
4123         assert.strictEqual(callCount, 1);
4124       }, 128);
4125
4126       setTimeout(function() {
4127         assert.strictEqual(callCount, 2);
4128         done();
4129       }, 256);
4130     });
4131
4132     QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
4133       assert.expect(2);
4134
4135       var done = assert.async();
4136
4137       var debounced = _.debounce(identity, 32);
4138       debounced('a');
4139
4140       setTimeout(function() {
4141         assert.notEqual(debounced('b'), 'b');
4142       }, 64);
4143
4144       setTimeout(function() {
4145         assert.notEqual(debounced('c'), 'c');
4146         done();
4147       }, 128);
4148     });
4149
4150     QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) {
4151       assert.expect(2);
4152
4153       var done = assert.async();
4154
4155       var callCount = 0,
4156           debounced = _.debounce(function() { ++callCount; }, 0);
4157
4158       debounced();
4159       debounced();
4160       assert.strictEqual(callCount, 0);
4161
4162       setTimeout(function() {
4163         assert.strictEqual(callCount, 1);
4164         done();
4165       }, 5);
4166     });
4167
4168     QUnit.test('should apply default options', function(assert) {
4169       assert.expect(2);
4170
4171       var done = assert.async();
4172
4173       var callCount = 0,
4174           debounced = _.debounce(function() { callCount++; }, 32, {});
4175
4176       debounced();
4177       assert.strictEqual(callCount, 0);
4178
4179       setTimeout(function() {
4180         assert.strictEqual(callCount, 1);
4181         done();
4182       }, 64);
4183     });
4184
4185     QUnit.test('should support a `leading` option', function(assert) {
4186       assert.expect(4);
4187
4188       var done = assert.async();
4189
4190       var callCounts = [0, 0];
4191
4192       var withLeading = _.debounce(function() {
4193         callCounts[0]++;
4194       }, 32, { 'leading': true });
4195
4196       var withLeadingAndTrailing = _.debounce(function() {
4197         callCounts[1]++;
4198       }, 32, { 'leading': true });
4199
4200       withLeading();
4201       assert.strictEqual(callCounts[0], 1);
4202
4203       withLeadingAndTrailing();
4204       withLeadingAndTrailing();
4205       assert.strictEqual(callCounts[1], 1);
4206
4207       setTimeout(function() {
4208         assert.deepEqual(callCounts, [1, 2]);
4209
4210         withLeading();
4211         assert.strictEqual(callCounts[0], 2);
4212
4213         done();
4214       }, 64);
4215     });
4216
4217     QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) {
4218       assert.expect(2);
4219
4220       var done = assert.async();
4221
4222       var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
4223           results = [debounced('a'), debounced('b')];
4224
4225       assert.deepEqual(results, ['a', 'a']);
4226
4227       setTimeout(function() {
4228         var results = [debounced('c'), debounced('d')];
4229         assert.deepEqual(results, ['c', 'c']);
4230         done();
4231       }, 64);
4232     });
4233
4234     QUnit.test('should support a `trailing` option', function(assert) {
4235       assert.expect(4);
4236
4237       var done = assert.async();
4238
4239       var withCount = 0,
4240           withoutCount = 0;
4241
4242       var withTrailing = _.debounce(function() {
4243         withCount++;
4244       }, 32, { 'trailing': true });
4245
4246       var withoutTrailing = _.debounce(function() {
4247         withoutCount++;
4248       }, 32, { 'trailing': false });
4249
4250       withTrailing();
4251       assert.strictEqual(withCount, 0);
4252
4253       withoutTrailing();
4254       assert.strictEqual(withoutCount, 0);
4255
4256       setTimeout(function() {
4257         assert.strictEqual(withCount, 1);
4258         assert.strictEqual(withoutCount, 0);
4259         done();
4260       }, 64);
4261     });
4262
4263     QUnit.test('should support a `maxWait` option', function(assert) {
4264       assert.expect(4);
4265
4266       var done = assert.async();
4267
4268       var callCount = 0;
4269
4270       var debounced = _.debounce(function(value) {
4271         ++callCount;
4272         return value;
4273       }, 32, { 'maxWait': 64 });
4274
4275       debounced();
4276       debounced();
4277       assert.strictEqual(callCount, 0);
4278
4279       setTimeout(function() {
4280         assert.strictEqual(callCount, 1);
4281         debounced();
4282         debounced();
4283         assert.strictEqual(callCount, 1);
4284       }, 128);
4285
4286       setTimeout(function() {
4287         assert.strictEqual(callCount, 2);
4288         done();
4289       }, 256);
4290     });
4291
4292     QUnit.test('should support `maxWait` in a tight loop', function(assert) {
4293       assert.expect(1);
4294
4295       var done = assert.async();
4296
4297       var limit = (argv || isPhantom) ? 1000 : 320,
4298           withCount = 0,
4299           withoutCount = 0;
4300
4301       var withMaxWait = _.debounce(function() {
4302         withCount++;
4303       }, 64, { 'maxWait': 128 });
4304
4305       var withoutMaxWait = _.debounce(function() {
4306         withoutCount++;
4307       }, 96);
4308
4309       var start = +new Date;
4310       while ((new Date - start) < limit) {
4311         withMaxWait();
4312         withoutMaxWait();
4313       }
4314       var actual = [Boolean(withoutCount), Boolean(withCount)];
4315       setTimeout(function() {
4316         assert.deepEqual(actual, [false, true]);
4317         done();
4318       }, 1);
4319     });
4320
4321     QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) {
4322       assert.expect(1);
4323
4324       var done = assert.async();
4325
4326       var callCount = 0;
4327
4328       var debounced = _.debounce(function() {
4329         ++callCount;
4330       }, 64, { 'maxWait': 64 });
4331
4332       debounced();
4333
4334       lodashStable.times(20, function(index) {
4335         setTimeout(debounced, 54 + index);
4336       });
4337
4338       setTimeout(function() {
4339         assert.strictEqual(callCount, 2);
4340         done();
4341       }, 160);
4342     });
4343
4344     QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
4345       assert.expect(2);
4346
4347       var done = assert.async();
4348
4349       var callCount = 0;
4350
4351       var debounced = _.debounce(function() {
4352         callCount++;
4353       }, 32, { 'maxWait': 64 });
4354
4355       debounced();
4356
4357       setTimeout(function() {
4358         debounced();
4359         assert.strictEqual(callCount, 1);
4360       }, 128);
4361
4362       setTimeout(function() {
4363         assert.strictEqual(callCount, 2);
4364         done();
4365       }, 192);
4366     });
4367
4368     QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) {
4369       assert.expect(2);
4370
4371       var done = assert.async();
4372
4373       var actual,
4374           callCount = 0,
4375           object = {};
4376
4377       var debounced = _.debounce(function(value) {
4378         actual = [this];
4379         push.apply(actual, arguments);
4380         return ++callCount != 2;
4381       }, 32, { 'leading': true, 'maxWait': 64 });
4382
4383       while (true) {
4384         if (!debounced.call(object, 'a')) {
4385           break;
4386         }
4387       }
4388       setTimeout(function() {
4389         assert.strictEqual(callCount, 2);
4390         assert.deepEqual(actual, [object, 'a']);
4391         done();
4392       }, 64);
4393     });
4394   }());
4395
4396   /*--------------------------------------------------------------------------*/
4397
4398   QUnit.module('lodash.deburr');
4399
4400   (function() {
4401     QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
4402       assert.expect(1);
4403
4404       var actual = lodashStable.map(burredLetters, _.deburr);
4405       assert.deepEqual(actual, deburredLetters);
4406     });
4407
4408     QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
4409       assert.expect(1);
4410
4411       var operators = ['\xd7', '\xf7'],
4412           actual = lodashStable.map(operators, _.deburr);
4413
4414       assert.deepEqual(actual, operators);
4415     });
4416
4417     QUnit.test('should deburr combining diacritical marks', function(assert) {
4418       assert.expect(1);
4419
4420       var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
4421
4422       var actual = lodashStable.map(comboMarks, function(chr) {
4423         return _.deburr('e' + chr + 'i');
4424       });
4425
4426       assert.deepEqual(actual, expected);
4427     });
4428   }());
4429
4430   /*--------------------------------------------------------------------------*/
4431
4432   QUnit.module('lodash.defaults');
4433
4434   (function() {
4435     QUnit.test('should assign source properties if missing on `object`', function(assert) {
4436       assert.expect(1);
4437
4438       assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
4439     });
4440
4441     QUnit.test('should accept multiple sources', function(assert) {
4442       assert.expect(2);
4443
4444       var expected = { 'a': 1, 'b': 2, 'c': 3 };
4445       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
4446       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
4447     });
4448
4449     QUnit.test('should not overwrite `null` values', function(assert) {
4450       assert.expect(1);
4451
4452       var actual = _.defaults({ 'a': null }, { 'a': 1 });
4453       assert.strictEqual(actual.a, null);
4454     });
4455
4456     QUnit.test('should overwrite `undefined` values', function(assert) {
4457       assert.expect(1);
4458
4459       var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
4460       assert.strictEqual(actual.a, 1);
4461     });
4462
4463     QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
4464       assert.expect(2);
4465
4466       var object = {
4467         'constructor': objectProto.constructor,
4468         'hasOwnProperty': objectProto.hasOwnProperty,
4469         'isPrototypeOf': objectProto.isPrototypeOf,
4470         'propertyIsEnumerable': objectProto.propertyIsEnumerable,
4471         'toLocaleString': objectProto.toLocaleString,
4472         'toString': objectProto.toString,
4473         'valueOf': objectProto.valueOf
4474       };
4475
4476       var source = {
4477         'constructor': 1,
4478         'hasOwnProperty': 2,
4479         'isPrototypeOf': 3,
4480         'propertyIsEnumerable': 4,
4481         'toLocaleString': 5,
4482         'toString': 6,
4483         'valueOf': 7
4484       };
4485
4486       assert.deepEqual(_.defaults({}, source), source);
4487       assert.deepEqual(_.defaults({}, object, source), object);
4488     });
4489   }());
4490
4491   /*--------------------------------------------------------------------------*/
4492
4493   QUnit.module('lodash.defaultsDeep');
4494
4495   (function() {
4496     QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
4497       assert.expect(1);
4498
4499       var object = { 'a': { 'b': 2 }, 'd': 4 },
4500           source = { 'a': { 'b': 3, 'c': 3 }, 'e': 5 },
4501           expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
4502
4503       assert.deepEqual(_.defaultsDeep(object, source), expected);
4504     });
4505
4506     QUnit.test('should accept multiple sources', function(assert) {
4507       assert.expect(2);
4508
4509       var source1 = { 'a': { 'b': 3 } },
4510           source2 = { 'a': { 'c': 3 } },
4511           source3 = { 'a': { 'b': 3, 'c': 3 } },
4512           source4 = { 'a': { 'c': 4 } },
4513           expected = { 'a': { 'b': 2, 'c': 3 } };
4514
4515       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
4516       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
4517     });
4518
4519     QUnit.test('should not overwrite `null` values', function(assert) {
4520       assert.expect(1);
4521
4522       var object = { 'a': { 'b': null } },
4523           source = { 'a': { 'b': 2 } },
4524           actual = _.defaultsDeep(object, source);
4525
4526       assert.strictEqual(actual.a.b, null);
4527     });
4528
4529     QUnit.test('should not overwrite regexp values', function(assert) {
4530       assert.expect(1);
4531
4532       var object = { 'a': { 'b': /x/ } },
4533           source = { 'a': { 'b': /y/ } },
4534           actual = _.defaultsDeep(object, source);
4535
4536       assert.deepEqual(actual.a.b, /x/);
4537     });
4538
4539     QUnit.test('should not convert function properties to objects', function(assert) {
4540       assert.expect(2);
4541
4542       var actual = _.defaultsDeep({}, { 'a': noop });
4543       assert.strictEqual(actual.a, noop);
4544
4545       actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
4546       assert.strictEqual(actual.a.b, noop);
4547     });
4548
4549     QUnit.test('should overwrite `undefined` values', function(assert) {
4550       assert.expect(1);
4551
4552       var object = { 'a': { 'b': undefined } },
4553           source = { 'a': { 'b': 2 } },
4554           actual = _.defaultsDeep(object, source);
4555
4556       assert.strictEqual(actual.a.b, 2);
4557     });
4558
4559     QUnit.test('should merge sources containing circular references', function(assert) {
4560       assert.expect(2);
4561
4562       var object = {
4563         'foo': { 'b': { 'c': { 'd': {} } } },
4564         'bar': { 'a': 2 }
4565       };
4566
4567       var source = {
4568         'foo': { 'b': { 'c': { 'd': {} } } },
4569         'bar': {}
4570       };
4571
4572       object.foo.b.c.d = object;
4573       source.foo.b.c.d = source;
4574       source.bar.b = source.foo.b;
4575
4576       var actual = _.defaultsDeep(object, source);
4577
4578       assert.strictEqual(actual.bar.b, actual.foo.b);
4579       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
4580     });
4581
4582     QUnit.test('should not modify sources', function(assert) {
4583       assert.expect(3);
4584
4585       var source1 = { 'a': 1, 'b': { 'c': 2 } },
4586           source2 = { 'b': { 'c': 3, 'd': 3 } },
4587           actual = _.defaultsDeep({}, source1, source2);
4588
4589       assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4590       assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4591       assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4592     });
4593
4594     QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4595       assert.expect(1);
4596
4597       var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4598       assert.deepEqual(actual, { 'a': ['abc'] });
4599     });
4600   }());
4601
4602   /*--------------------------------------------------------------------------*/
4603
4604   QUnit.module('lodash.defer');
4605
4606   (function() {
4607     QUnit.test('should defer `func` execution', function(assert) {
4608       assert.expect(1);
4609
4610       var done = assert.async();
4611
4612       var pass = false;
4613       _.defer(function() { pass = true; });
4614
4615       setTimeout(function() {
4616         assert.ok(pass);
4617         done();
4618       }, 32);
4619     });
4620
4621     QUnit.test('should provide additional arguments to `func`', function(assert) {
4622       assert.expect(1);
4623
4624       var done = assert.async();
4625
4626       var args;
4627
4628       _.defer(function() {
4629         args = slice.call(arguments);
4630       }, 1, 2);
4631
4632       setTimeout(function() {
4633         assert.deepEqual(args, [1, 2]);
4634         done();
4635       }, 32);
4636     });
4637
4638     QUnit.test('should be cancelable', function(assert) {
4639       assert.expect(1);
4640
4641       var done = assert.async();
4642
4643       var pass = true,
4644           timerId = _.defer(function() { pass = false; });
4645
4646       clearTimeout(timerId);
4647
4648       setTimeout(function() {
4649         assert.ok(pass);
4650         done();
4651       }, 32);
4652     });
4653   }());
4654
4655   /*--------------------------------------------------------------------------*/
4656
4657   QUnit.module('lodash.delay');
4658
4659   (function() {
4660     QUnit.test('should delay `func` execution', function(assert) {
4661       assert.expect(2);
4662
4663       var done = assert.async();
4664
4665       var pass = false;
4666       _.delay(function() { pass = true; }, 32);
4667
4668       setTimeout(function() {
4669         assert.notOk(pass);
4670       }, 1);
4671
4672       setTimeout(function() {
4673         assert.ok(pass);
4674         done();
4675       }, 64);
4676     });
4677
4678     QUnit.test('should provide additional arguments to `func`', function(assert) {
4679       assert.expect(1);
4680
4681       var done = assert.async();
4682
4683       var args;
4684
4685       _.delay(function() {
4686         args = slice.call(arguments);
4687       }, 32, 1, 2);
4688
4689       setTimeout(function() {
4690         assert.deepEqual(args, [1, 2]);
4691         done();
4692       }, 64);
4693     });
4694
4695     QUnit.test('should use a default `wait` of `0`', function(assert) {
4696       assert.expect(2);
4697
4698       var done = assert.async();
4699
4700       var pass = false;
4701       _.delay(function() { pass = true; });
4702
4703       assert.notOk(pass);
4704
4705       setTimeout(function() {
4706         assert.ok(pass);
4707         done();
4708       }, 0);
4709     });
4710
4711     QUnit.test('should be cancelable', function(assert) {
4712       assert.expect(1);
4713
4714       var done = assert.async();
4715
4716       var pass = true,
4717           timerId = _.delay(function() { pass = false; }, 32);
4718
4719       clearTimeout(timerId);
4720
4721       setTimeout(function() {
4722         assert.ok(pass);
4723         done();
4724       }, 64);
4725     });
4726
4727     QUnit.test('should work with mocked `setTimeout`', function(assert) {
4728       assert.expect(1);
4729
4730       if (!isPhantom) {
4731         var pass = false,
4732             setTimeout = root.setTimeout;
4733
4734         setProperty(root, 'setTimeout', function(func) { func(); });
4735         _.delay(function() { pass = true; }, 32);
4736         setProperty(root, 'setTimeout', setTimeout);
4737
4738         assert.ok(pass);
4739       }
4740       else {
4741         skipAssert(assert);
4742       }
4743     });
4744   }());
4745
4746   /*--------------------------------------------------------------------------*/
4747
4748   QUnit.module('difference methods');
4749
4750   lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4751     var args = (function() { return arguments; }(1, 2, 3)),
4752         func = _[methodName];
4753
4754     QUnit.test('`_.' + methodName + '` should return the difference of two arrays', function(assert) {
4755       assert.expect(1);
4756
4757       var actual = func([2, 1], [2, 3]);
4758       assert.deepEqual(actual, [1]);
4759     });
4760
4761     QUnit.test('`_.' + methodName + '` should return the difference of multiple arrays', function(assert) {
4762       assert.expect(1);
4763
4764       var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
4765       assert.deepEqual(actual, [1]);
4766     });
4767
4768     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
4769       assert.expect(2);
4770
4771       var array = [-0, 0];
4772
4773       var actual = lodashStable.map(array, function(value) {
4774         return func(array, [value]);
4775       });
4776
4777       assert.deepEqual(actual, [[], []]);
4778
4779       actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
4780       assert.deepEqual(actual, ['0']);
4781     });
4782
4783     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4784       assert.expect(1);
4785
4786       assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4787     });
4788
4789     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4790       assert.expect(1);
4791
4792       var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4793           array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4794           a = {},
4795           b = {},
4796           c = {};
4797
4798       array1.push(a, b, c);
4799       array2.push(b, c, a);
4800
4801       assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4802     });
4803
4804     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
4805       assert.expect(2);
4806
4807       var array = [-0, 0];
4808
4809       var actual = lodashStable.map(array, function(value) {
4810         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
4811         return func(array, largeArray);
4812       });
4813
4814       assert.deepEqual(actual, [[], []]);
4815
4816       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne);
4817       actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
4818       assert.deepEqual(actual, ['0']);
4819     });
4820
4821     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4822       assert.expect(1);
4823
4824       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
4825       assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4826     });
4827
4828     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4829       assert.expect(1);
4830
4831       var object1 = {},
4832           object2 = {},
4833           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4834
4835       assert.deepEqual(func([object1, object2], largeArray), [object2]);
4836     });
4837
4838     QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4839       assert.expect(3);
4840
4841       var array = [1, null, 3];
4842
4843       assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4844       assert.deepEqual(func(null, array, 1), []);
4845       assert.deepEqual(func(array, args, null), [null]);
4846     });
4847   });
4848
4849   /*--------------------------------------------------------------------------*/
4850
4851   QUnit.module('lodash.differenceBy');
4852
4853   (function() {
4854     QUnit.test('should accept an `iteratee` argument', function(assert) {
4855       assert.expect(2);
4856
4857       var actual = _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
4858       assert.deepEqual(actual, [1.2]);
4859
4860       actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4861       assert.deepEqual(actual, [{ 'x': 2 }]);
4862     });
4863
4864     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
4865       assert.expect(1);
4866
4867       var args;
4868
4869       _.differenceBy([2.1, 1.2], [2.3, 3.4], function() {
4870         args || (args = slice.call(arguments));
4871       });
4872
4873       assert.deepEqual(args, [2.3]);
4874     });
4875   }());
4876
4877   /*--------------------------------------------------------------------------*/
4878
4879   QUnit.module('lodash.differenceWith');
4880
4881   (function() {
4882     QUnit.test('should work with a `comparator` argument', function(assert) {
4883       assert.expect(1);
4884
4885       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
4886           actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
4887
4888       assert.deepEqual(actual, [objects[1]]);
4889     });
4890
4891     QUnit.test('should preserve the sign of `0`', function(assert) {
4892       assert.expect(1);
4893
4894       var array = [-0, 1],
4895           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne),
4896           others = [[1], largeArray],
4897           expected = lodashStable.map(others, lodashStable.constant(['-0']));
4898
4899       var actual = lodashStable.map(others, function(other) {
4900         return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
4901       });
4902
4903       assert.deepEqual(actual, expected);
4904     });
4905   }());
4906
4907   /*--------------------------------------------------------------------------*/
4908
4909   QUnit.module('lodash.divide');
4910
4911   (function() {
4912     QUnit.test('should divide two numbers', function(assert) {
4913       assert.expect(3);
4914
4915       assert.strictEqual(_.divide(6, 4), 1.5);
4916       assert.strictEqual(_.divide(-6, 4), -1.5);
4917       assert.strictEqual(_.divide(-6, -4), 1.5);
4918     });
4919
4920     QUnit.test('should coerce arguments to numbers', function(assert) {
4921       assert.expect(2);
4922
4923       assert.strictEqual(_.divide('6', '4'), 1.5);
4924       assert.deepEqual(_.divide('x', 'y'), NaN);
4925     });
4926   }());
4927
4928   /*--------------------------------------------------------------------------*/
4929
4930   QUnit.module('lodash.drop');
4931
4932   (function() {
4933     var array = [1, 2, 3];
4934
4935     QUnit.test('should drop the first two elements', function(assert) {
4936       assert.expect(1);
4937
4938       assert.deepEqual(_.drop(array, 2), [3]);
4939     });
4940
4941     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4942       assert.expect(1);
4943
4944       var expected = lodashStable.map(falsey, function(value) {
4945         return value === undefined ? [2, 3] : array;
4946       });
4947
4948       var actual = lodashStable.map(falsey, function(n) {
4949         return _.drop(array, n);
4950       });
4951
4952       assert.deepEqual(actual, expected);
4953     });
4954
4955     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4956       assert.expect(3);
4957
4958       lodashStable.each([0, -1, -Infinity], function(n) {
4959         assert.deepEqual(_.drop(array, n), array);
4960       });
4961     });
4962
4963     QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
4964       assert.expect(4);
4965
4966       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4967         assert.deepEqual(_.drop(array, n), []);
4968       });
4969     });
4970
4971     QUnit.test('should coerce `n` to an integer', function(assert) {
4972       assert.expect(1);
4973
4974       assert.deepEqual(_.drop(array, 1.6), [2, 3]);
4975     });
4976
4977     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4978       assert.expect(1);
4979
4980       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4981           actual = lodashStable.map(array, _.drop);
4982
4983       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
4984     });
4985
4986     QUnit.test('should work in a lazy sequence', function(assert) {
4987       assert.expect(6);
4988
4989       if (!isNpm) {
4990         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4991             predicate = function(value) { values.push(value); return isEven(value); },
4992             values = [],
4993             actual = _(array).drop(2).drop().value();
4994
4995         assert.deepEqual(actual, array.slice(3));
4996
4997         actual = _(array).filter(predicate).drop(2).drop().value();
4998         assert.deepEqual(values, array);
4999         assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
5000
5001         actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
5002         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
5003
5004         values = [];
5005
5006         actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
5007         assert.deepEqual(values, array.slice(1));
5008         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
5009       }
5010       else {
5011         skipAssert(assert, 6);
5012       }
5013     });
5014   }());
5015
5016   /*--------------------------------------------------------------------------*/
5017
5018   QUnit.module('lodash.dropRight');
5019
5020   (function() {
5021     var array = [1, 2, 3];
5022
5023     QUnit.test('should drop the last two elements', function(assert) {
5024       assert.expect(1);
5025
5026       assert.deepEqual(_.dropRight(array, 2), [1]);
5027     });
5028
5029     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
5030       assert.expect(1);
5031
5032       var expected = lodashStable.map(falsey, function(value) {
5033         return value === undefined ? [1, 2] : array;
5034       });
5035
5036       var actual = lodashStable.map(falsey, function(n) {
5037         return _.dropRight(array, n);
5038       });
5039
5040       assert.deepEqual(actual, expected);
5041     });
5042
5043     QUnit.test('should return all elements when `n` < `1`', function(assert) {
5044       assert.expect(3);
5045
5046       lodashStable.each([0, -1, -Infinity], function(n) {
5047         assert.deepEqual(_.dropRight(array, n), array);
5048       });
5049     });
5050
5051     QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
5052       assert.expect(4);
5053
5054       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5055         assert.deepEqual(_.dropRight(array, n), []);
5056       });
5057     });
5058
5059     QUnit.test('should coerce `n` to an integer', function(assert) {
5060       assert.expect(1);
5061
5062       assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
5063     });
5064
5065     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5066       assert.expect(1);
5067
5068       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5069           actual = lodashStable.map(array, _.dropRight);
5070
5071       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
5072     });
5073
5074     QUnit.test('should work in a lazy sequence', function(assert) {
5075       assert.expect(6);
5076
5077       if (!isNpm) {
5078         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5079             predicate = function(value) { values.push(value); return isEven(value); },
5080             values = [],
5081             actual = _(array).dropRight(2).dropRight().value();
5082
5083         assert.deepEqual(actual, array.slice(0, -3));
5084
5085         actual = _(array).filter(predicate).dropRight(2).dropRight().value();
5086         assert.deepEqual(values, array);
5087         assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
5088
5089         actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
5090         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
5091
5092         values = [];
5093
5094         actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
5095         assert.deepEqual(values, array.slice(0, -1));
5096         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
5097       }
5098       else {
5099         skipAssert(assert, 6);
5100       }
5101     });
5102   }());
5103
5104   /*--------------------------------------------------------------------------*/
5105
5106   QUnit.module('lodash.dropRightWhile');
5107
5108   (function() {
5109     var array = [1, 2, 3, 4];
5110
5111     var objects = [
5112       { 'a': 0, 'b': 0 },
5113       { 'a': 1, 'b': 1 },
5114       { 'a': 2, 'b': 2 }
5115     ];
5116
5117     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5118       assert.expect(1);
5119
5120       var actual = _.dropRightWhile(array, function(n) {
5121         return n > 2;
5122       });
5123
5124       assert.deepEqual(actual, [1, 2]);
5125     });
5126
5127     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5128       assert.expect(1);
5129
5130       var args;
5131
5132       _.dropRightWhile(array, function() {
5133         args = slice.call(arguments);
5134       });
5135
5136       assert.deepEqual(args, [4, 3, array]);
5137     });
5138
5139     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5140       assert.expect(1);
5141
5142       assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
5143     });
5144
5145     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5146       assert.expect(1);
5147
5148       assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
5149     });
5150
5151     QUnit.test('should work with `_.property` shorthands', function(assert) {
5152       assert.expect(1);
5153
5154       assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
5155     });
5156
5157     QUnit.test('should return a wrapped value when chaining', function(assert) {
5158       assert.expect(2);
5159
5160       if (!isNpm) {
5161         var wrapped = _(array).dropRightWhile(function(n) {
5162           return n > 2;
5163         });
5164
5165         assert.ok(wrapped instanceof _);
5166         assert.deepEqual(wrapped.value(), [1, 2]);
5167       }
5168       else {
5169         skipAssert(assert, 2);
5170       }
5171     });
5172   }());
5173
5174   /*--------------------------------------------------------------------------*/
5175
5176   QUnit.module('lodash.dropWhile');
5177
5178   (function() {
5179     var array = [1, 2, 3, 4];
5180
5181     var objects = [
5182       { 'a': 2, 'b': 2 },
5183       { 'a': 1, 'b': 1 },
5184       { 'a': 0, 'b': 0 }
5185     ];
5186
5187     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5188       assert.expect(1);
5189
5190       var actual = _.dropWhile(array, function(n) {
5191         return n < 3;
5192       });
5193
5194       assert.deepEqual(actual, [3, 4]);
5195     });
5196
5197     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5198       assert.expect(1);
5199
5200       var args;
5201
5202       _.dropWhile(array, function() {
5203         args = slice.call(arguments);
5204       });
5205
5206       assert.deepEqual(args, [1, 0, array]);
5207     });
5208
5209     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5210       assert.expect(1);
5211
5212       assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
5213     });
5214
5215     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5216       assert.expect(1);
5217
5218       assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
5219     });
5220
5221     QUnit.test('should work with `_.property` shorthands', function(assert) {
5222       assert.expect(1);
5223
5224       assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
5225     });
5226
5227     QUnit.test('should work in a lazy sequence', function(assert) {
5228       assert.expect(3);
5229
5230       if (!isNpm) {
5231         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
5232             predicate = function(n) { return n < 3; },
5233             expected = _.dropWhile(array, predicate),
5234             wrapped = _(array).dropWhile(predicate);
5235
5236         assert.deepEqual(wrapped.value(), expected);
5237         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
5238         assert.strictEqual(wrapped.last(), _.last(expected));
5239       }
5240       else {
5241         skipAssert(assert, 3);
5242       }
5243     });
5244
5245     QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
5246       assert.expect(1);
5247
5248       if (!isNpm) {
5249         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
5250
5251         var actual = _(array)
5252           .dropWhile(function(n) { return n == 1; })
5253           .drop()
5254           .dropWhile(function(n) { return n == 3; })
5255           .value();
5256
5257         assert.deepEqual(actual, array.slice(3));
5258       }
5259       else {
5260         skipAssert(assert);
5261       }
5262     });
5263   }());
5264
5265   /*--------------------------------------------------------------------------*/
5266
5267   QUnit.module('lodash.endsWith');
5268
5269   (function() {
5270     var string = 'abc';
5271
5272     QUnit.test('should return `true` if a string ends with `target`', function(assert) {
5273       assert.expect(1);
5274
5275       assert.strictEqual(_.endsWith(string, 'c'), true);
5276     });
5277
5278     QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
5279       assert.expect(1);
5280
5281       assert.strictEqual(_.endsWith(string, 'b'), false);
5282     });
5283
5284     QUnit.test('should work with a `position` argument', function(assert) {
5285       assert.expect(1);
5286
5287       assert.strictEqual(_.endsWith(string, 'b', 2), true);
5288     });
5289
5290     QUnit.test('should work with `position` >= `length`', function(assert) {
5291       assert.expect(4);
5292
5293       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5294         assert.strictEqual(_.endsWith(string, 'c', position), true);
5295       });
5296     });
5297
5298     QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5299       assert.expect(1);
5300
5301       var expected = lodashStable.map(falsey, stubTrue);
5302
5303       var actual = lodashStable.map(falsey, function(position) {
5304         return _.endsWith(string, position === undefined ? 'c' : '', position);
5305       });
5306
5307       assert.deepEqual(actual, expected);
5308     });
5309
5310     QUnit.test('should treat a negative `position` as `0`', function(assert) {
5311       assert.expect(6);
5312
5313       lodashStable.each([-1, -3, -Infinity], function(position) {
5314         assert.ok(lodashStable.every(string, function(chr) {
5315           return !_.endsWith(string, chr, position);
5316         }));
5317         assert.strictEqual(_.endsWith(string, '', position), true);
5318       });
5319     });
5320
5321     QUnit.test('should coerce `position` to an integer', function(assert) {
5322       assert.expect(1);
5323
5324       assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5325     });
5326
5327     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
5328       assert.expect(1);
5329
5330       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5331         return _.endsWith(string, '', position, true);
5332       }));
5333     });
5334   }());
5335
5336   /*--------------------------------------------------------------------------*/
5337
5338   QUnit.module('lodash.eq');
5339
5340   (function() {
5341     QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5342       assert.expect(11);
5343
5344       assert.strictEqual(_.eq(), true);
5345       assert.strictEqual(_.eq(undefined), true);
5346       assert.strictEqual(_.eq(0, -0), true);
5347       assert.strictEqual(_.eq(NaN, NaN), true);
5348       assert.strictEqual(_.eq(1, 1), true);
5349
5350       assert.strictEqual(_.eq(null, undefined), false);
5351       assert.strictEqual(_.eq(1, Object(1)), false);
5352       assert.strictEqual(_.eq(1, '1'), false);
5353       assert.strictEqual(_.eq(1, '1'), false);
5354
5355       var object = { 'a': 1 };
5356       assert.strictEqual(_.eq(object, object), true);
5357       assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5358     });
5359   }());
5360
5361   /*--------------------------------------------------------------------------*/
5362
5363   QUnit.module('lodash.escape');
5364
5365   (function() {
5366     var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
5367         unescaped = '&<>"\'`\/';
5368
5369     escaped += escaped;
5370     unescaped += unescaped;
5371
5372     QUnit.test('should escape values', function(assert) {
5373       assert.expect(1);
5374
5375       assert.strictEqual(_.escape(unescaped), escaped);
5376     });
5377
5378     QUnit.test('should not escape the "/" character', function(assert) {
5379       assert.expect(1);
5380
5381       assert.strictEqual(_.escape('/'), '/');
5382     });
5383
5384     QUnit.test('should handle strings with nothing to escape', function(assert) {
5385       assert.expect(1);
5386
5387       assert.strictEqual(_.escape('abc'), 'abc');
5388     });
5389
5390     QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5391       assert.expect(1);
5392
5393       assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5394     });
5395   }());
5396
5397   /*--------------------------------------------------------------------------*/
5398
5399   QUnit.module('lodash.escapeRegExp');
5400
5401   (function() {
5402     var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5403         unescaped = '^$.*+?()[]{}|\\';
5404
5405     QUnit.test('should escape values', function(assert) {
5406       assert.expect(1);
5407
5408       assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5409     });
5410
5411     QUnit.test('should handle strings with nothing to escape', function(assert) {
5412       assert.expect(1);
5413
5414       assert.strictEqual(_.escapeRegExp('abc'), 'abc');
5415     });
5416
5417     QUnit.test('should return an empty string for empty values', function(assert) {
5418       assert.expect(1);
5419
5420       var values = [, null, undefined, ''],
5421           expected = lodashStable.map(values, stubString);
5422
5423       var actual = lodashStable.map(values, function(value, index) {
5424         return index ? _.escapeRegExp(value) : _.escapeRegExp();
5425       });
5426
5427       assert.deepEqual(actual, expected);
5428     });
5429   }());
5430
5431   /*--------------------------------------------------------------------------*/
5432
5433   QUnit.module('lodash.every');
5434
5435   (function() {
5436     QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5437       assert.expect(1);
5438
5439       assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5440     });
5441
5442     QUnit.test('should return `true` for empty collections', function(assert) {
5443       assert.expect(1);
5444
5445       var expected = lodashStable.map(empties, stubTrue);
5446
5447       var actual = lodashStable.map(empties, function(value) {
5448         try {
5449           return _.every(value, identity);
5450         } catch (e) {}
5451       });
5452
5453       assert.deepEqual(actual, expected);
5454     });
5455
5456     QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5457       assert.expect(2);
5458
5459       var count = 0;
5460
5461       assert.strictEqual(_.every([true, null, true], function(value) {
5462         count++;
5463         return value;
5464       }), false);
5465
5466       assert.strictEqual(count, 2);
5467     });
5468
5469     QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5470       assert.expect(1);
5471
5472       assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5473     });
5474
5475     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5476       assert.expect(2);
5477
5478       var values = [, null, undefined],
5479           expected = lodashStable.map(values, stubFalse);
5480
5481       var actual = lodashStable.map(values, function(value, index) {
5482         var array = [0];
5483         return index ? _.every(array, value) : _.every(array);
5484       });
5485
5486       assert.deepEqual(actual, expected);
5487
5488       expected = lodashStable.map(values, stubTrue);
5489       actual = lodashStable.map(values, function(value, index) {
5490         var array = [1];
5491         return index ? _.every(array, value) : _.every(array);
5492       });
5493
5494       assert.deepEqual(actual, expected);
5495     });
5496
5497     QUnit.test('should work with `_.property` shorthands', function(assert) {
5498       assert.expect(2);
5499
5500       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5501       assert.strictEqual(_.every(objects, 'a'), false);
5502       assert.strictEqual(_.every(objects, 'b'), true);
5503     });
5504
5505     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5506       assert.expect(2);
5507
5508       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5509       assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5510       assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5511     });
5512
5513     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5514       assert.expect(1);
5515
5516       var actual = lodashStable.map([[1]], _.every);
5517       assert.deepEqual(actual, [true]);
5518     });
5519   }());
5520
5521   /*--------------------------------------------------------------------------*/
5522
5523   QUnit.module('strict mode checks');
5524
5525   lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
5526     var func = _[methodName],
5527         isBindAll = methodName == 'bindAll';
5528
5529     QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5530       assert.expect(1);
5531
5532       if (freeze) {
5533         var object = freeze({ 'a': undefined, 'b': function() {} }),
5534             pass = !isStrict;
5535
5536         try {
5537           func(object, isBindAll ? 'b' : { 'a': 1 });
5538         } catch (e) {
5539           pass = !pass;
5540         }
5541         assert.ok(pass);
5542       }
5543       else {
5544         skipAssert(assert);
5545       }
5546     });
5547   });
5548
5549   /*--------------------------------------------------------------------------*/
5550
5551   QUnit.module('lodash.fill');
5552
5553   (function() {
5554     QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
5555       assert.expect(1);
5556
5557       var array = [1, 2, 3];
5558       assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5559     });
5560
5561     QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5562       assert.expect(2);
5563
5564       var array = [1, 2, 3],
5565           actual = _.fill(array);
5566
5567       assert.deepEqual(actual, Array(3));
5568       assert.ok(lodashStable.every(actual, function(value, index) {
5569         return index in actual;
5570       }));
5571     });
5572
5573     QUnit.test('should work with a positive `start`', function(assert) {
5574       assert.expect(1);
5575
5576       var array = [1, 2, 3];
5577       assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5578     });
5579
5580     QUnit.test('should work with a `start` >= `length`', function(assert) {
5581       assert.expect(4);
5582
5583       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5584         var array = [1, 2, 3];
5585         assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5586       });
5587     });
5588
5589     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5590       assert.expect(1);
5591
5592       var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5593
5594       var actual = lodashStable.map(falsey, function(start) {
5595         var array = [1, 2, 3];
5596         return _.fill(array, 'a', start);
5597       });
5598
5599       assert.deepEqual(actual, expected);
5600     });
5601
5602     QUnit.test('should work with a negative `start`', function(assert) {
5603       assert.expect(1);
5604
5605       var array = [1, 2, 3];
5606       assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5607     });
5608
5609     QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
5610       assert.expect(3);
5611
5612       lodashStable.each([-3, -4, -Infinity], function(start) {
5613         var array = [1, 2, 3];
5614         assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5615       });
5616     });
5617
5618     QUnit.test('should work with `start` >= `end`', function(assert) {
5619       assert.expect(2);
5620
5621       lodashStable.each([2, 3], function(start) {
5622         var array = [1, 2, 3];
5623         assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5624       });
5625     });
5626
5627     QUnit.test('should work with a positive `end`', function(assert) {
5628       assert.expect(1);
5629
5630       var array = [1, 2, 3];
5631       assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5632     });
5633
5634     QUnit.test('should work with a `end` >= `length`', function(assert) {
5635       assert.expect(4);
5636
5637       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5638         var array = [1, 2, 3];
5639         assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5640       });
5641     });
5642
5643     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5644       assert.expect(1);
5645
5646       var expected = lodashStable.map(falsey, function(value) {
5647         return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5648       });
5649
5650       var actual = lodashStable.map(falsey, function(end) {
5651         var array = [1, 2, 3];
5652         return _.fill(array, 'a', 0, end);
5653       });
5654
5655       assert.deepEqual(actual, expected);
5656     });
5657
5658     QUnit.test('should work with a negative `end`', function(assert) {
5659       assert.expect(1);
5660
5661       var array = [1, 2, 3];
5662       assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5663     });
5664
5665     QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
5666       assert.expect(3);
5667
5668       lodashStable.each([-3, -4, -Infinity], function(end) {
5669         var array = [1, 2, 3];
5670         assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5671       });
5672     });
5673
5674     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5675       assert.expect(1);
5676
5677       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5678
5679       var actual = lodashStable.map(positions, function(pos) {
5680         var array = [1, 2, 3];
5681         return _.fill.apply(_, [array, 'a'].concat(pos));
5682       });
5683
5684       assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5685     });
5686
5687     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5688       assert.expect(1);
5689
5690       var array = [[1, 2], [3, 4]],
5691           actual = lodashStable.map(array, _.fill);
5692
5693       assert.deepEqual(actual, [[0, 0], [1, 1]]);
5694     });
5695
5696     QUnit.test('should return a wrapped value when chaining', function(assert) {
5697       assert.expect(3);
5698
5699       if (!isNpm) {
5700         var array = [1, 2, 3],
5701             wrapped = _(array).fill('a'),
5702             actual = wrapped.value();
5703
5704         assert.ok(wrapped instanceof _);
5705         assert.strictEqual(actual, array);
5706         assert.deepEqual(actual, ['a', 'a', 'a']);
5707       }
5708       else {
5709         skipAssert(assert, 3);
5710       }
5711     });
5712   }());
5713
5714   /*--------------------------------------------------------------------------*/
5715
5716   QUnit.module('lodash.filter');
5717
5718   (function() {
5719     var array = [1, 2, 3];
5720
5721     QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5722       assert.expect(1);
5723
5724       assert.deepEqual(_.filter(array, isEven), [2]);
5725     });
5726
5727     QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
5728       assert.expect(1);
5729
5730       // Trigger a mobile Safari 8 JIT bug.
5731       // See https://github.com/lodash/lodash/issues/799.
5732       var counter = 0,
5733           object = { '1': 'foo', '8': 'bar', '50': 'baz' };
5734
5735       lodashStable.times(1000, function(assert) {
5736         _.filter([], stubTrue);
5737       });
5738
5739       _.filter(object, function() {
5740         counter++;
5741         return true;
5742       });
5743
5744       assert.strictEqual(counter, 3);
5745     });
5746   }());
5747
5748   /*--------------------------------------------------------------------------*/
5749
5750   lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
5751     QUnit.module('lodash.' + methodName);
5752
5753     var func = _[methodName];
5754
5755     (function() {
5756       var objects = [
5757         { 'a': 0, 'b': 0 },
5758         { 'a': 1, 'b': 1 },
5759         { 'a': 2, 'b': 2 }
5760       ];
5761
5762       var expected = ({
5763         'find': [objects[1], undefined, objects[2]],
5764         'findLast': [objects[2], undefined, objects[2]],
5765         'findIndex': [1, -1, 2],
5766         'findLastIndex': [2, -1, 2],
5767         'findKey': ['1', undefined, '2'],
5768         'findLastKey': ['2', undefined, '2']
5769       })[methodName];
5770
5771       QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
5772         assert.expect(1);
5773
5774         assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5775       });
5776
5777       QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
5778         assert.expect(1);
5779
5780         assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5781       });
5782
5783       QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
5784         assert.expect(1);
5785
5786         assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5787       });
5788
5789       QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
5790         assert.expect(1);
5791
5792         assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5793       });
5794
5795       QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5796         assert.expect(1);
5797
5798         assert.strictEqual(func(objects, 'b'), expected[0]);
5799       });
5800
5801       QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
5802         assert.expect(1);
5803
5804         var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5805             expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5806
5807         var actual = lodashStable.map(emptyValues, function(value) {
5808           try {
5809             return func(value, { 'a': 3 });
5810           } catch (e) {}
5811         });
5812
5813         assert.deepEqual(actual, expecting);
5814       });
5815     }());
5816
5817     (function() {
5818       var array = [1, 2, 3, 4];
5819
5820       var expected = ({
5821         'find': [0, 1, 2, 3],
5822         'findLast': [3, 2, 1, 0],
5823         'findIndex': [0, 1, 2, 3],
5824         'findLastIndex': [3, 2, 1, 0]
5825       })[methodName];
5826
5827       if (expected != null) {
5828         QUnit.test('`_.' + methodName + '` should pass the index as the second argument for `iteratee`', function(assert) {
5829           assert.expect(1);
5830
5831           var actual = [];
5832
5833           func(array, function(n, index) {
5834             actual.push(index);
5835             return false;
5836           });
5837
5838           assert.deepEqual(actual, expected);
5839         });
5840       }
5841     }());
5842
5843     (function() {
5844       var array = [1, 2, 3, 4];
5845
5846       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5847         assert.expect(1);
5848
5849         var expected = ({
5850           'find': 1,
5851           'findLast': 4,
5852           'findIndex': 0,
5853           'findLastIndex': 3,
5854           'findKey': '0',
5855           'findLastKey': '3'
5856         })[methodName];
5857
5858         if (!isNpm) {
5859           assert.strictEqual(_(array)[methodName](), expected);
5860         }
5861         else {
5862           skipAssert(assert);
5863         }
5864       });
5865
5866       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5867         assert.expect(1);
5868
5869         if (!isNpm) {
5870           assert.ok(_(array).chain()[methodName]() instanceof _);
5871         }
5872         else {
5873           skipAssert(assert);
5874         }
5875       });
5876
5877       QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
5878         assert.expect(1);
5879
5880         if (!isNpm) {
5881           var wrapped = _(array).chain()[methodName]();
5882           assert.strictEqual(wrapped.__wrapped__, array);
5883         }
5884         else {
5885           skipAssert(assert);
5886         }
5887       });
5888
5889       QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
5890         assert.expect(2);
5891
5892         if (!isNpm) {
5893           var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5894               smallArray = array;
5895
5896           lodashStable.times(2, function(index) {
5897             var array = index ? largeArray : smallArray,
5898                 wrapped = _(array).filter(isEven);
5899
5900             assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5901           });
5902         }
5903         else {
5904           skipAssert(assert, 2);
5905         }
5906       });
5907     }());
5908
5909     (function() {
5910       var expected = ({
5911         'find': 1,
5912         'findLast': 2,
5913         'findKey': 'a',
5914         'findLastKey': 'b'
5915       })[methodName];
5916
5917       if (expected != null) {
5918         QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
5919           assert.expect(1);
5920
5921           var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
5922             return n < 3;
5923           });
5924
5925           assert.strictEqual(actual, expected);
5926         });
5927       }
5928     }());
5929
5930     (function() {
5931       var expected = ({
5932         'find': ['a', 'b', 'c'],
5933         'findLast': ['c', 'b', 'a'],
5934         'findKey': ['a', 'b', 'c'],
5935         'findLastKey': ['c', 'b', 'a']
5936       })[methodName];
5937
5938       if (expected != null) {
5939         QUnit.test('`_.' + methodName + '` should pass the key as the second argument for `iteratee`', function(assert) {
5940           assert.expect(1);
5941
5942           var actual = [];
5943
5944           func({ 'a': 1, 'b': 2, 'c': 3 }, function(n, key) {
5945             actual.push(key);
5946             return false;
5947           });
5948
5949           assert.deepEqual(actual, expected);
5950         });
5951       }
5952     }());
5953   });
5954
5955   /*--------------------------------------------------------------------------*/
5956
5957   QUnit.module('lodash.find and lodash.findLast');
5958
5959   lodashStable.each(['find', 'findLast'], function(methodName) {
5960     var isFind = methodName == 'find';
5961
5962     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5963       assert.expect(3);
5964
5965       if (!isNpm) {
5966         var findCount = 0,
5967             mapCount = 0,
5968             array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5969             iteratee = function(value) { mapCount++; return square(value); },
5970             predicate = function(value) { findCount++; return isEven(value); },
5971             actual = _(array).map(iteratee)[methodName](predicate);
5972
5973         assert.strictEqual(findCount, isFind ? 2 : 1);
5974         assert.strictEqual(mapCount, isFind ? 2 : 1);
5975         assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
5976       }
5977       else {
5978         skipAssert(assert, 3);
5979       }
5980     });
5981   });
5982
5983   /*--------------------------------------------------------------------------*/
5984
5985   QUnit.module('lodash.find and lodash.includes');
5986
5987   lodashStable.each(['includes', 'find'], function(methodName) {
5988     var args = (function() { return arguments; }(1, 2, 3, 4)),
5989         func = _[methodName],
5990         isIncludes = methodName == 'includes',
5991         resolve = methodName == 'find' ? lodashStable.curry(lodashStable.eq) : identity;
5992
5993     lodashStable.each({
5994       'an `arguments` object': args,
5995       'an array': [1, 2, 3, 4]
5996     },
5997     function(collection, key) {
5998       var values = lodashStable.toArray(collection);
5999
6000       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6001         assert.expect(1);
6002
6003         var expected = [
6004           isIncludes || values[2],
6005           isIncludes ? false : undefined
6006         ];
6007
6008         var actual = [
6009           func(collection, resolve(values[2]), 2),
6010           func(collection, resolve(values[1]), 2)
6011         ];
6012
6013         assert.deepEqual(actual, expected);
6014       });
6015
6016       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6017         assert.expect(1);
6018
6019         var indexes = [4, 6, Math.pow(2, 32), Infinity];
6020
6021         var expected = lodashStable.map(indexes, function() {
6022           var result = isIncludes ? false : undefined;
6023           return [result, result, result];
6024         });
6025
6026         var actual = lodashStable.map(indexes, function(fromIndex) {
6027           return [
6028             func(collection, resolve(1), fromIndex),
6029             func(collection, resolve(undefined), fromIndex),
6030             func(collection, resolve(''), fromIndex)
6031           ];
6032         });
6033
6034         assert.deepEqual(actual, expected);
6035       });
6036
6037       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
6038         assert.expect(1);
6039
6040         var expected = lodashStable.map(falsey, lodashStable.constant(isIncludes || values[0]));
6041
6042         var actual = lodashStable.map(falsey, function(fromIndex) {
6043           return func(collection, resolve(values[0]), fromIndex);
6044         });
6045
6046         assert.deepEqual(actual, expected);
6047       });
6048
6049       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6050         assert.expect(1);
6051
6052         var expected = [
6053           isIncludes || values[0],
6054           isIncludes || values[0],
6055           isIncludes ? false : undefined
6056         ];
6057
6058         var actual = [
6059           func(collection, resolve(values[0]), 0.1),
6060           func(collection, resolve(values[0]), NaN),
6061           func(collection, resolve(values[0]), '1')
6062         ];
6063
6064         assert.deepEqual(actual, expected);
6065       });
6066
6067       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6068         assert.expect(1);
6069
6070         var expected = [
6071           isIncludes || values[2],
6072           isIncludes ? false : undefined
6073         ];
6074
6075         var actual = [
6076           func(collection, resolve(values[2]), -2),
6077           func(collection, resolve(values[1]), -2)
6078         ];
6079
6080         assert.deepEqual(actual, expected);
6081       });
6082
6083       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6084         assert.expect(1);
6085
6086         var indexes = [-4, -6, -Infinity],
6087             expected = lodashStable.map(indexes, lodashStable.constant(isIncludes || values[0]));
6088
6089         var actual = lodashStable.map(indexes, function(fromIndex) {
6090           return func(collection, resolve(values[0]), fromIndex);
6091         });
6092
6093         assert.deepEqual(actual, expected);
6094       });
6095     });
6096   });
6097
6098   /*--------------------------------------------------------------------------*/
6099
6100   QUnit.module('lodash.findIndex and lodash.indexOf');
6101
6102   lodashStable.each(['findIndex', 'indexOf'], function(methodName) {
6103     var array = [1, 2, 3, 1, 2, 3],
6104         func = _[methodName],
6105         resolve = methodName == 'findIndex' ? lodashStable.curry(lodashStable.eq) : identity;
6106
6107     QUnit.test('`_.' + methodName + '` should return the index of the first matched value', function(assert) {
6108       assert.expect(1);
6109
6110       assert.strictEqual(func(array, resolve(3)), 2);
6111     });
6112
6113     QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
6114       assert.expect(1);
6115
6116       assert.strictEqual(func(array, resolve(1), 2), 3);
6117     });
6118
6119     QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
6120       assert.expect(1);
6121
6122       var values = [6, 8, Math.pow(2, 32), Infinity],
6123           expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
6124
6125       var actual = lodashStable.map(values, function(fromIndex) {
6126         return [
6127           func(array, resolve(undefined), fromIndex),
6128           func(array, resolve(1), fromIndex),
6129           func(array, resolve(''), fromIndex)
6130         ];
6131       });
6132
6133       assert.deepEqual(actual, expected);
6134     });
6135
6136     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
6137       assert.expect(1);
6138
6139       assert.strictEqual(func(array, resolve(2), -3), 4);
6140     });
6141
6142     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
6143       assert.expect(1);
6144
6145       var values = [-6, -8, -Infinity],
6146           expected = lodashStable.map(values, stubZero);
6147
6148       var actual = lodashStable.map(values, function(fromIndex) {
6149         return func(array, resolve(1), fromIndex);
6150       });
6151
6152       assert.deepEqual(actual, expected);
6153     });
6154
6155     QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values as `0`', function(assert) {
6156       assert.expect(1);
6157
6158       var expected = lodashStable.map(falsey, stubZero);
6159
6160       var actual = lodashStable.map(falsey, function(fromIndex) {
6161         return func(array, resolve(1), fromIndex);
6162       });
6163
6164       assert.deepEqual(actual, expected);
6165     });
6166
6167     QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
6168       assert.expect(1);
6169
6170       assert.strictEqual(func(array, resolve(2), 1.2), 1);
6171     });
6172   });
6173
6174   /*--------------------------------------------------------------------------*/
6175
6176   QUnit.module('lodash.findLast');
6177
6178   (function() {
6179     var args = (function() { return arguments; }(1, 2, 3, 4)),
6180         resolve = lodashStable.curry(lodashStable.eq);
6181
6182     lodashStable.each({
6183       'an `arguments` object': args,
6184       'an array': [1, 2, 3, 4],
6185     },
6186     function(collection, key) {
6187       var values = lodashStable.toArray(collection);
6188
6189       QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6190         assert.expect(1);
6191
6192         var expected = [
6193           values[2],
6194           undefined
6195         ];
6196
6197         var actual = [
6198           _.findLast(collection, resolve(values[2]), 2),
6199           _.findLast(collection, resolve(values[3]), 2)
6200         ];
6201
6202         assert.deepEqual(actual, expected);
6203       });
6204
6205       QUnit.test('should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6206         assert.expect(1);
6207
6208         var indexes = [4, 6, Math.pow(2, 32), Infinity];
6209
6210         var expected = lodashStable.map(indexes, lodashStable.constant([values[0], undefined, undefined]));
6211
6212         var actual = lodashStable.map(indexes, function(fromIndex) {
6213           return [
6214             _.findLast(collection, resolve(1), fromIndex),
6215             _.findLast(collection, resolve(undefined), fromIndex),
6216             _.findLast(collection, resolve(''), fromIndex)
6217           ];
6218         });
6219
6220         assert.deepEqual(actual, expected);
6221       });
6222
6223       QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values correctly', function(assert) {
6224         assert.expect(1);
6225
6226         var expected = lodashStable.map(falsey, function(value) {
6227           return value === undefined ? values[3] : undefined;
6228         });
6229
6230         var actual = lodashStable.map(falsey, function(fromIndex) {
6231           return _.findLast(collection, resolve(values[3]), fromIndex);
6232         });
6233
6234         assert.deepEqual(actual, expected);
6235       });
6236
6237       QUnit.test('should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6238         assert.expect(1);
6239
6240         var expected = [
6241           values[0],
6242           values[0],
6243           undefined
6244         ];
6245
6246         var actual = [
6247           _.findLast(collection, resolve(values[0]), 0.1),
6248           _.findLast(collection, resolve(values[0]), NaN),
6249           _.findLast(collection, resolve(values[2]), '1')
6250         ];
6251
6252         assert.deepEqual(actual, expected);
6253       });
6254
6255       QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6256         assert.expect(1);
6257
6258         var expected = [
6259           values[2],
6260           undefined
6261         ];
6262
6263         var actual = [
6264           _.findLast(collection, resolve(values[2]), -2),
6265           _.findLast(collection, resolve(values[3]), -2)
6266         ];
6267
6268         assert.deepEqual(actual, expected);
6269       });
6270
6271       QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6272         assert.expect(1);
6273
6274         var indexes = [-4, -6, -Infinity],
6275             expected = lodashStable.map(indexes, lodashStable.constant(values[0]));
6276
6277         var actual = lodashStable.map(indexes, function(fromIndex) {
6278           return _.findLast(collection, resolve(values[0]), fromIndex);
6279         });
6280
6281         assert.deepEqual(actual, expected);
6282       });
6283     });
6284   }());
6285
6286   /*--------------------------------------------------------------------------*/
6287
6288   QUnit.module('lodash.flip');
6289
6290   (function() {
6291     function fn() {
6292       return slice.call(arguments);
6293     }
6294
6295     QUnit.test('should flip arguments provided to `func`', function(assert) {
6296       assert.expect(1);
6297
6298       var flipped = _.flip(fn);
6299       assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
6300     });
6301   }());
6302
6303   /*--------------------------------------------------------------------------*/
6304
6305   QUnit.module('lodash.flatMapDepth');
6306
6307   (function() {
6308     var array = [1, [2, [3, [4]], 5]];
6309
6310     QUnit.test('should use a default `depth` of `1`', function(assert) {
6311       assert.expect(1);
6312
6313       assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
6314     });
6315
6316     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
6317       assert.expect(1);
6318
6319       var values = [, null, undefined],
6320           expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
6321
6322       var actual = lodashStable.map(values, function(value, index) {
6323         return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
6324       });
6325
6326       assert.deepEqual(actual, expected);
6327     });
6328
6329     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6330       assert.expect(2);
6331
6332       lodashStable.each([-1, 0], function(depth) {
6333         assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
6334       });
6335     });
6336
6337     QUnit.test('should coerce `depth` to an integer', function(assert) {
6338       assert.expect(1);
6339
6340       assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
6341     });
6342   }());
6343
6344   /*--------------------------------------------------------------------------*/
6345
6346   QUnit.module('flatMap methods');
6347
6348   lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
6349     var func = _[methodName],
6350         array = [1, 2, 3, 4];
6351
6352     function duplicate(n) {
6353       return [n, n];
6354     }
6355
6356     QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
6357       assert.expect(1);
6358
6359       var actual = func(array, duplicate),
6360           expected = lodashStable.flatten(lodashStable.map(array, duplicate));
6361
6362       assert.deepEqual(actual, expected);
6363     });
6364
6365     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
6366       assert.expect(1);
6367
6368       var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
6369       assert.deepEqual(func(objects, 'a'), array);
6370     });
6371
6372     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
6373       assert.expect(1);
6374
6375       function Foo() {
6376         this.a = [1, 2];
6377       }
6378       Foo.prototype.b = [3, 4];
6379
6380       var actual = func(new Foo, identity);
6381       assert.deepEqual(actual, [1, 2]);
6382     });
6383
6384     QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
6385       assert.expect(2);
6386
6387       var array = [[1, 2], [3, 4]],
6388           object = { 'a': [1, 2], 'b': [3, 4] },
6389           values = [, null, undefined],
6390           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
6391
6392       lodashStable.each([array, object], function(collection) {
6393         var actual = lodashStable.map(values, function(value, index) {
6394           return index ? func(collection, value) : func(collection);
6395         });
6396
6397         assert.deepEqual(actual, expected);
6398       });
6399     });
6400
6401     QUnit.test('`_.' + methodName + '` should accept a falsey `collection` argument', function(assert) {
6402       assert.expect(1);
6403
6404       var expected = lodashStable.map(falsey, stubArray);
6405
6406       var actual = lodashStable.map(falsey, function(collection, index) {
6407         try {
6408           return index ? func(collection) : func();
6409         } catch (e) {}
6410       });
6411
6412       assert.deepEqual(actual, expected);
6413     });
6414
6415     QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
6416       assert.expect(1);
6417
6418       assert.deepEqual(func(1), []);
6419     });
6420
6421     QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
6422       assert.expect(1);
6423
6424       var object = { 'length': [1, 2] };
6425       assert.deepEqual(func(object, identity), [1, 2]);
6426     });
6427   });
6428
6429   /*--------------------------------------------------------------------------*/
6430
6431   QUnit.module('lodash.flattenDepth');
6432
6433   (function() {
6434     var array = [1, [2, [3, [4]], 5]];
6435
6436     QUnit.test('should use a default `depth` of `1`', function(assert) {
6437       assert.expect(1);
6438
6439       assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
6440     });
6441
6442     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6443       assert.expect(2);
6444
6445       lodashStable.each([-1, 0], function(depth) {
6446         assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
6447       });
6448     });
6449
6450     QUnit.test('should coerce `depth` to an integer', function(assert) {
6451       assert.expect(1);
6452
6453       assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
6454     });
6455   }());
6456
6457   /*--------------------------------------------------------------------------*/
6458
6459   QUnit.module('flatten methods');
6460
6461   (function() {
6462     var args = arguments,
6463         array = [1, [2, [3, [4]], 5]];
6464
6465     QUnit.test('should flatten `arguments` objects', function(assert) {
6466       assert.expect(3);
6467
6468       var array = [args, [args]];
6469
6470       assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
6471       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
6472       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
6473     });
6474
6475     QUnit.test('should treat sparse arrays as dense', function(assert) {
6476       assert.expect(6);
6477
6478       var array = [[1, 2, 3], Array(3)],
6479           expected = [1, 2, 3];
6480
6481       expected.push(undefined, undefined, undefined);
6482
6483       lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) {
6484         assert.deepEqual(actual, expected);
6485         assert.ok('4' in actual);
6486       });
6487     });
6488
6489     QUnit.test('should work with extremely large arrays', function(assert) {
6490       assert.expect(3);
6491
6492       lodashStable.times(3, function(index) {
6493         var expected = Array(5e5);
6494         try {
6495           var func = _.flatten;
6496           if (index == 1) {
6497             func = _.flattenDeep;
6498           } else if (index == 2) {
6499             func = _.flattenDepth;
6500           }
6501           assert.deepEqual(func([expected]), expected);
6502         } catch (e) {
6503           assert.ok(false, e.message);
6504         }
6505       });
6506     });
6507
6508     QUnit.test('should work with empty arrays', function(assert) {
6509       assert.expect(3);
6510
6511       var array = [[], [[]], [[], [[[]]]]];
6512
6513       assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
6514       assert.deepEqual(_.flattenDeep(array), []);
6515       assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
6516     });
6517
6518     QUnit.test('should support flattening of nested arrays', function(assert) {
6519       assert.expect(3);
6520
6521       assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
6522       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
6523       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
6524     });
6525
6526     QUnit.test('should return an empty array for non array-like objects', function(assert) {
6527       assert.expect(3);
6528
6529       var expected = [],
6530           nonArray = { 'a': 1 };
6531
6532       assert.deepEqual(_.flatten(nonArray), expected);
6533       assert.deepEqual(_.flattenDeep(nonArray), expected);
6534       assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
6535     });
6536
6537     QUnit.test('should return a wrapped value when chaining', function(assert) {
6538       assert.expect(6);
6539
6540       if (!isNpm) {
6541         var wrapped = _(array),
6542             actual = wrapped.flatten();
6543
6544         assert.ok(actual instanceof _);
6545         assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
6546
6547         actual = wrapped.flattenDeep();
6548
6549         assert.ok(actual instanceof _);
6550         assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
6551
6552         actual = wrapped.flattenDepth(2);
6553
6554         assert.ok(actual instanceof _);
6555         assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
6556       }
6557       else {
6558         skipAssert(assert, 6);
6559       }
6560     });
6561   }(1, 2, 3));
6562
6563   /*--------------------------------------------------------------------------*/
6564
6565   QUnit.module('flow methods');
6566
6567   lodashStable.each(['flow', 'flowRight'], function(methodName) {
6568     var func = _[methodName],
6569         isFlow = methodName == 'flow';
6570
6571     QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
6572       assert.expect(1);
6573
6574       var fixed = function(n) { return n.toFixed(1); },
6575           combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
6576
6577       assert.strictEqual(combined(1, 2), '9.0');
6578     });
6579
6580     QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
6581       assert.expect(1);
6582
6583       assert.notStrictEqual(func(noop), noop);
6584     });
6585
6586     QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
6587       assert.expect(6);
6588
6589       _.times(2, function(index) {
6590         try {
6591           var combined = index ? func([]) : func();
6592           assert.strictEqual(combined('a'), 'a');
6593         } catch (e) {
6594           assert.ok(false, e.message);
6595         }
6596         assert.strictEqual(combined.length, 0);
6597         assert.notStrictEqual(combined, identity);
6598       });
6599     });
6600
6601     QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
6602       assert.expect(1);
6603
6604       var curried = _.curry(identity);
6605
6606       var combined = isFlow
6607         ? func(_.head, curried)
6608         : func(curried, _.head);
6609
6610       assert.strictEqual(combined([1]), 1);
6611     });
6612
6613     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6614       assert.expect(6);
6615
6616       var filterCount,
6617           mapCount,
6618           array = lodashStable.range(LARGE_ARRAY_SIZE),
6619           iteratee = function(value) { mapCount++; return square(value); },
6620           predicate = function(value) { filterCount++; return isEven(value); };
6621
6622       lodashStable.times(2, function(index) {
6623         var filter1 = _.filter,
6624             filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
6625             filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
6626
6627         var map1 = _.map,
6628             map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
6629             map3 = (_.map = index ? map2 : map1, map2(iteratee));
6630
6631         var take1 = _.take,
6632             take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
6633             take3 = (_.take = index ? take2 : take1, take2(2));
6634
6635         var combined = isFlow
6636           ? func(map3, filter3, _.compact, take3)
6637           : func(take3, _.compact, filter3, map3);
6638
6639         filterCount = mapCount = 0;
6640         assert.deepEqual(combined(array), [4, 16]);
6641
6642         if (!isNpm && WeakMap && WeakMap.name) {
6643           assert.strictEqual(filterCount, 5, 'filterCount');
6644           assert.strictEqual(mapCount, 5, 'mapCount');
6645         }
6646         else {
6647           skipAssert(assert, 2);
6648         }
6649         _.filter = filter1;
6650         _.map = map1;
6651         _.take = take1;
6652       });
6653     });
6654
6655     QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
6656       assert.expect(1);
6657
6658       var curried = _.curry(_.ary(_.map, 2), 2),
6659           getProp = curried(curried.placeholder, 'a'),
6660           objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
6661
6662       var combined = isFlow
6663         ? func(getProp, _.uniq)
6664         : func(_.uniq, getProp);
6665
6666       assert.deepEqual(combined(objects), [1, 2]);
6667     });
6668
6669     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6670       assert.expect(1);
6671
6672       if (!isNpm) {
6673         var wrapped = _(noop)[methodName]();
6674         assert.ok(wrapped instanceof _);
6675       }
6676       else {
6677         skipAssert(assert);
6678       }
6679     });
6680   });
6681
6682   /*--------------------------------------------------------------------------*/
6683
6684   QUnit.module('lodash.forEach');
6685
6686   (function() {
6687     QUnit.test('should be aliased', function(assert) {
6688       assert.expect(1);
6689
6690       assert.strictEqual(_.each, _.forEach);
6691     });
6692   }());
6693
6694   /*--------------------------------------------------------------------------*/
6695
6696   QUnit.module('lodash.forEachRight');
6697
6698   (function() {
6699     QUnit.test('should be aliased', function(assert) {
6700       assert.expect(1);
6701
6702       assert.strictEqual(_.eachRight, _.forEachRight);
6703     });
6704   }());
6705
6706   /*--------------------------------------------------------------------------*/
6707
6708   QUnit.module('forIn methods');
6709
6710   lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6711     var func = _[methodName];
6712
6713     QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
6714       assert.expect(1);
6715
6716       function Foo() {
6717         this.a = 1;
6718       }
6719       Foo.prototype.b = 2;
6720
6721       var keys = [];
6722       func(new Foo, function(value, key) { keys.push(key); });
6723       assert.deepEqual(keys.sort(), ['a', 'b']);
6724     });
6725   });
6726
6727   /*--------------------------------------------------------------------------*/
6728
6729   QUnit.module('forOwn methods');
6730
6731   lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6732     var func = _[methodName];
6733
6734     QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
6735       assert.expect(1);
6736
6737       var object = { '0': 'zero', '1': 'one', 'length': 2 },
6738           props = [];
6739
6740       func(object, function(value, prop) { props.push(prop); });
6741       assert.deepEqual(props.sort(), ['0', '1', 'length']);
6742     });
6743   });
6744
6745   /*--------------------------------------------------------------------------*/
6746
6747   QUnit.module('iteration methods');
6748
6749   (function() {
6750     var methods = [
6751       '_baseEach',
6752       'countBy',
6753       'every',
6754       'filter',
6755       'find',
6756       'findIndex',
6757       'findKey',
6758       'findLast',
6759       'findLastIndex',
6760       'findLastKey',
6761       'forEach',
6762       'forEachRight',
6763       'forIn',
6764       'forInRight',
6765       'forOwn',
6766       'forOwnRight',
6767       'groupBy',
6768       'keyBy',
6769       'map',
6770       'mapKeys',
6771       'mapValues',
6772       'maxBy',
6773       'minBy',
6774       'omitBy',
6775       'partition',
6776       'pickBy',
6777       'reject',
6778       'some'
6779     ];
6780
6781     var arrayMethods = [
6782       'findIndex',
6783       'findLastIndex',
6784       'maxBy',
6785       'minBy'
6786     ];
6787
6788     var collectionMethods = [
6789       '_baseEach',
6790       'countBy',
6791       'every',
6792       'filter',
6793       'find',
6794       'findLast',
6795       'forEach',
6796       'forEachRight',
6797       'groupBy',
6798       'keyBy',
6799       'map',
6800       'partition',
6801       'reduce',
6802       'reduceRight',
6803       'reject',
6804       'some'
6805     ];
6806
6807     var forInMethods = [
6808       'forIn',
6809       'forInRight',
6810       'omitBy',
6811       'pickBy'
6812     ];
6813
6814     var iterationMethods = [
6815       '_baseEach',
6816       'forEach',
6817       'forEachRight',
6818       'forIn',
6819       'forInRight',
6820       'forOwn',
6821       'forOwnRight'
6822     ];
6823
6824     var objectMethods = [
6825       'findKey',
6826       'findLastKey',
6827       'forIn',
6828       'forInRight',
6829       'forOwn',
6830       'forOwnRight',
6831       'mapKeys',
6832       'mapValues',
6833       'omitBy',
6834       'pickBy'
6835     ];
6836
6837     var rightMethods = [
6838       'findLast',
6839       'findLastIndex',
6840       'findLastKey',
6841       'forEachRight',
6842       'forInRight',
6843       'forOwnRight'
6844     ];
6845
6846     var unwrappedMethods = [
6847       'each',
6848       'eachRight',
6849       'every',
6850       'find',
6851       'findIndex',
6852       'findKey',
6853       'findLast',
6854       'findLastIndex',
6855       'findLastKey',
6856       'forEach',
6857       'forEachRight',
6858       'forIn',
6859       'forInRight',
6860       'forOwn',
6861       'forOwnRight',
6862       'max',
6863       'maxBy',
6864       'min',
6865       'minBy',
6866       'some'
6867     ];
6868
6869     lodashStable.each(methods, function(methodName) {
6870       var array = [1, 2, 3],
6871           func = _[methodName],
6872           isBy = /(^partition|By)$/.test(methodName),
6873           isFind = /^find/.test(methodName),
6874           isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6875           isSome = methodName == 'some';
6876
6877       QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
6878         assert.expect(1);
6879
6880         if (func) {
6881           var args,
6882               expected = [1, 0, array];
6883
6884           func(array, function() {
6885             args || (args = slice.call(arguments));
6886           });
6887
6888           if (lodashStable.includes(rightMethods, methodName)) {
6889             expected[0] = 3;
6890             expected[1] = 2;
6891           }
6892           if (lodashStable.includes(objectMethods, methodName)) {
6893             expected[1] += '';
6894           }
6895           if (isBy) {
6896             expected.length = isOmitPick ? 2 : 1;
6897           }
6898           assert.deepEqual(args, expected);
6899         }
6900         else {
6901           skipAssert(assert);
6902         }
6903       });
6904
6905       QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
6906         assert.expect(1);
6907
6908         if (func) {
6909           var array = [1];
6910           array[2] = 3;
6911
6912           var expected = lodashStable.includes(objectMethods, methodName)
6913             ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
6914             : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
6915
6916           if (isBy) {
6917             expected = lodashStable.map(expected, function(args) {
6918               return args.slice(0, isOmitPick ? 2 : 1);
6919             });
6920           }
6921           else if (lodashStable.includes(objectMethods, methodName)) {
6922             expected = lodashStable.map(expected, function(args) {
6923               args[1] += '';
6924               return args;
6925             });
6926           }
6927           if (lodashStable.includes(rightMethods, methodName)) {
6928             expected.reverse();
6929           }
6930           var argsList = [];
6931           func(array, function() {
6932             argsList.push(slice.call(arguments));
6933             return !(isFind || isSome);
6934           });
6935
6936           assert.deepEqual(argsList, expected);
6937         }
6938         else {
6939           skipAssert(assert);
6940         }
6941       });
6942     });
6943
6944     lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
6945       var array = [1, 2, 3],
6946           func = _[methodName],
6947           isEvery = methodName == 'every';
6948
6949       array.a = 1;
6950
6951       QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
6952         assert.expect(1);
6953
6954         if (func) {
6955           var keys = [];
6956           func(array, function(value, key) {
6957             keys.push(key);
6958             return isEvery;
6959           });
6960
6961           assert.notOk(lodashStable.includes(keys, 'a'));
6962         }
6963         else {
6964           skipAssert(assert);
6965         }
6966       });
6967     });
6968
6969     lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
6970       var array = [1, 2, 3],
6971           isBaseEach = methodName == '_baseEach';
6972
6973       QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
6974         assert.expect(1);
6975
6976         if (!(isBaseEach || isNpm)) {
6977           var wrapped = _(array)[methodName](noop);
6978           assert.ok(wrapped instanceof _);
6979         }
6980         else {
6981           skipAssert(assert);
6982         }
6983       });
6984     });
6985
6986     lodashStable.each(unwrappedMethods, function(methodName) {
6987       var array = [1, 2, 3];
6988
6989       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
6990         assert.expect(1);
6991
6992         if (!isNpm) {
6993           var actual = _(array)[methodName](noop);
6994           assert.notOk(actual instanceof _);
6995         }
6996         else {
6997           skipAssert(assert);
6998         }
6999       });
7000
7001       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
7002         assert.expect(2);
7003
7004         if (!isNpm) {
7005           var wrapped = _(array).chain(),
7006               actual = wrapped[methodName](noop);
7007
7008           assert.ok(actual instanceof _);
7009           assert.notStrictEqual(actual, wrapped);
7010         }
7011         else {
7012           skipAssert(assert, 2);
7013         }
7014       });
7015     });
7016
7017     lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
7018       var func = _[methodName];
7019
7020       QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
7021         assert.expect(1);
7022
7023         function Foo() {
7024           this.a = 1;
7025         }
7026         Foo.prototype.b = 2;
7027
7028         if (func) {
7029           var values = [];
7030           func(new Foo, function(value) { values.push(value); });
7031           assert.deepEqual(values, [1]);
7032         }
7033         else {
7034           skipAssert(assert);
7035         }
7036       });
7037     });
7038
7039     lodashStable.each(iterationMethods, function(methodName) {
7040       var array = [1, 2, 3],
7041           func = _[methodName];
7042
7043       QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
7044         assert.expect(1);
7045
7046         if (func) {
7047           assert.strictEqual(func(array, Boolean), array);
7048         }
7049         else {
7050           skipAssert(assert);
7051         }
7052       });
7053     });
7054
7055     lodashStable.each(collectionMethods, function(methodName) {
7056       var func = _[methodName];
7057
7058       QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
7059         assert.expect(3);
7060
7061         if (func) {
7062           var isIteratedAsObject = function(object) {
7063             var result = false;
7064             func(object, function() { result = true; }, 0);
7065             return result;
7066           };
7067
7068           var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
7069               expected = lodashStable.map(values, stubTrue);
7070
7071           var actual = lodashStable.map(values, function(length) {
7072             return isIteratedAsObject({ 'length': length });
7073           });
7074
7075           var Foo = function(a) {};
7076           Foo.a = 1;
7077
7078           assert.deepEqual(actual, expected);
7079           assert.ok(isIteratedAsObject(Foo));
7080           assert.notOk(isIteratedAsObject({ 'length': 0 }));
7081         }
7082         else {
7083           skipAssert(assert, 3);
7084         }
7085       });
7086     });
7087
7088     lodashStable.each(methods, function(methodName) {
7089       var func = _[methodName],
7090           isFind = /^find/.test(methodName),
7091           isSome = methodName == 'some',
7092           isReduce = /^reduce/.test(methodName);
7093
7094       QUnit.test('`_.' + methodName + '` should ignore changes to `length`', function(assert) {
7095         assert.expect(1);
7096
7097         if (func) {
7098           var count = 0,
7099               array = [1];
7100
7101           func(array, function() {
7102             if (++count == 1) {
7103               array.push(2);
7104             }
7105             return !(isFind || isSome);
7106           }, isReduce ? array : null);
7107
7108           assert.strictEqual(count, 1);
7109         }
7110         else {
7111           skipAssert(assert);
7112         }
7113       });
7114     });
7115
7116     lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
7117       var func = _[methodName],
7118           isFind = /^find/.test(methodName),
7119           isSome = methodName == 'some',
7120           isReduce = /^reduce/.test(methodName);
7121
7122       QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
7123         assert.expect(1);
7124
7125         if (func) {
7126           var count = 0,
7127               object = { 'a': 1 };
7128
7129           func(object, function() {
7130             if (++count == 1) {
7131               object.b = 2;
7132             }
7133             return !(isFind || isSome);
7134           }, isReduce ? object : null);
7135
7136           assert.strictEqual(count, 1);
7137         }
7138         else {
7139           skipAssert(assert);
7140         }
7141       });
7142     });
7143   }());
7144
7145   /*--------------------------------------------------------------------------*/
7146
7147   QUnit.module('object assignments');
7148
7149   lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
7150     var func = _[methodName],
7151         isAssign = methodName == 'assign',
7152         isDefaults = methodName == 'defaults';
7153
7154     QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
7155       assert.expect(1);
7156
7157       var expected = lodashStable.map(primitives, function(value) {
7158         var object = Object(value);
7159         object.a = 1;
7160         return object;
7161       });
7162
7163       var actual = lodashStable.map(primitives, function(value) {
7164         return func(value, { 'a': 1 });
7165       });
7166
7167       assert.deepEqual(actual, expected);
7168     });
7169
7170     QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
7171       assert.expect(1);
7172
7173       function Foo() {
7174         this.a = 1;
7175       }
7176       Foo.prototype.b = 2;
7177
7178       var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
7179       assert.deepEqual(func({}, new Foo), expected);
7180     });
7181
7182     QUnit.test('`_.' + methodName + '` should not skip a trailing function source', function(assert) {
7183       assert.expect(1);
7184
7185       function fn() {}
7186       fn.b = 2;
7187
7188       assert.deepEqual(func({}, { 'a': 1 }, fn), { 'a': 1, 'b': 2 });
7189     });
7190
7191     QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
7192       assert.expect(1);
7193
7194       try {
7195         assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
7196       } catch (e) {
7197         assert.ok(false, e.message);
7198       }
7199     });
7200
7201     QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
7202       assert.expect(2);
7203
7204       var source = { 'a': 1 },
7205           values = [null, undefined],
7206           expected = lodashStable.map(values, stubTrue);
7207
7208       var actual = lodashStable.map(values, function(value) {
7209         var object = func(value, source);
7210         return object !== source && lodashStable.isEqual(object, source);
7211       });
7212
7213       assert.deepEqual(actual, expected);
7214
7215       actual = lodashStable.map(values, function(value) {
7216         return lodashStable.isEqual(func(value), {});
7217       });
7218
7219       assert.deepEqual(actual, expected);
7220     });
7221
7222     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
7223       assert.expect(2);
7224
7225       var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
7226           expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
7227
7228       function fn() {};
7229       fn.a = array[0];
7230       fn.b = array[1];
7231       fn.c = array[2];
7232
7233       assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
7234       assert.deepEqual(lodashStable.reduce(fn, func, { 'a': 0 }), expected);
7235     });
7236
7237     QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
7238       assert.expect(1);
7239
7240       if (!isNpm) {
7241         var wrapped = _({ 'a': 1 }),
7242             actual = wrapped[methodName]({ 'b': 2 });
7243
7244         assert.notStrictEqual(actual, wrapped);
7245       }
7246       else {
7247         skipAssert(assert);
7248       }
7249     });
7250   });
7251
7252   lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
7253     var func = _[methodName];
7254
7255     QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
7256       assert.expect(1);
7257
7258       function Foo() {}
7259       Foo.prototype.a = 1;
7260
7261       var actual = func(new Foo, { 'b': 2 });
7262       assert.notOk(_.has(actual, 'a'));
7263     });
7264   });
7265
7266   lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
7267     var func = _[methodName];
7268
7269     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
7270       assert.expect(4);
7271
7272       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
7273         var object = {},
7274             pass = true;
7275
7276         defineProperty(object, 'a', {
7277           'enumerable': true,
7278           'configurable': true,
7279           'get': lodashStable.constant(value),
7280           'set': function() { pass = false; }
7281         });
7282
7283         func(object, { 'a': value });
7284         assert.ok(pass);
7285       });
7286     });
7287   });
7288
7289   lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
7290     var func = _[methodName],
7291         isMergeWith = methodName == 'mergeWith';
7292
7293     QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
7294       assert.expect(3);
7295
7296       var args,
7297           object = { 'a': 1 },
7298           source = { 'a': 2 },
7299           expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
7300
7301       func(object, source, function() {
7302         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7303       });
7304
7305       assert.deepEqual(args, expected, 'primitive property values');
7306
7307       args = undefined;
7308       object = { 'a': 1 };
7309       source = { 'b': 2 };
7310       expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
7311
7312       func(object, source, function() {
7313         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7314       });
7315
7316       assert.deepEqual(args, expected, 'missing destination property');
7317
7318       var argsList = [],
7319           objectValue = [1, 2],
7320           sourceValue = { 'b': 2 };
7321
7322       object = { 'a': objectValue };
7323       source = { 'a': sourceValue };
7324       expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
7325
7326       if (isMergeWith) {
7327         expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
7328       }
7329       func(object, source, function() {
7330         argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7331       });
7332
7333       assert.deepEqual(argsList, expected, 'object property values');
7334     });
7335
7336     QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
7337       assert.expect(2);
7338
7339       function callback() {}
7340       callback.b = 2;
7341
7342       var actual = func({ 'a': 1 }, callback);
7343       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
7344
7345       actual = func({ 'a': 1 }, callback, { 'c': 3 });
7346       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
7347     });
7348   });
7349
7350   /*--------------------------------------------------------------------------*/
7351
7352   QUnit.module('exit early');
7353
7354   lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
7355     var func = _[methodName];
7356
7357     QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
7358       assert.expect(1);
7359
7360       if (func) {
7361         var array = [1, 2, 3],
7362             values = [];
7363
7364         func(array, function(value, other) {
7365           values.push(lodashStable.isArray(value) ? other : value);
7366           return false;
7367         });
7368
7369         assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
7370       }
7371       else {
7372         skipAssert(assert);
7373       }
7374     });
7375
7376     QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
7377       assert.expect(1);
7378
7379       if (func) {
7380         var object = { 'a': 1, 'b': 2, 'c': 3 },
7381             values = [];
7382
7383         func(object, function(value, other) {
7384           values.push(lodashStable.isArray(value) ? other : value);
7385           return false;
7386         });
7387
7388         assert.strictEqual(values.length, 1);
7389       }
7390       else {
7391         skipAssert(assert);
7392       }
7393     });
7394   });
7395
7396   /*--------------------------------------------------------------------------*/
7397
7398   QUnit.module('`__proto__` property bugs');
7399
7400   (function() {
7401     QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
7402       assert.expect(4);
7403
7404       var stringLiteral = '__proto__',
7405           stringObject = Object(stringLiteral),
7406           expected = [stringLiteral, stringObject];
7407
7408       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
7409         return isEven(count) ? stringLiteral : stringObject;
7410       });
7411
7412       assert.deepEqual(_.difference(largeArray, largeArray), []);
7413       assert.deepEqual(_.intersection(largeArray, largeArray), expected);
7414       assert.deepEqual(_.uniq(largeArray), expected);
7415       assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
7416     });
7417   }());
7418
7419   /*--------------------------------------------------------------------------*/
7420
7421   QUnit.module('lodash.fromPairs');
7422
7423   (function() {
7424     QUnit.test('should accept a two dimensional array', function(assert) {
7425       assert.expect(1);
7426
7427       var array = [['a', 1], ['b', 2]],
7428           object = { 'a': 1, 'b': 2 },
7429           actual = _.fromPairs(array);
7430
7431       assert.deepEqual(actual, object);
7432     });
7433
7434     QUnit.test('should accept a falsey `array` argument', function(assert) {
7435       assert.expect(1);
7436
7437       var expected = lodashStable.map(falsey, stubObject);
7438
7439       var actual = lodashStable.map(falsey, function(array, index) {
7440         try {
7441           return index ? _.fromPairs(array) : _.fromPairs();
7442         } catch (e) {}
7443       });
7444
7445       assert.deepEqual(actual, expected);
7446     });
7447
7448     QUnit.test('should not support deep paths', function(assert) {
7449       assert.expect(1);
7450
7451       var actual = _.fromPairs([['a.b', 1]]);
7452       assert.deepEqual(actual, { 'a.b': 1 });
7453     });
7454
7455     QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
7456       assert.expect(1);
7457
7458       var object = { 'a.b': 1 };
7459       assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
7460     });
7461
7462     QUnit.test('should work in a lazy sequence', function(assert) {
7463       assert.expect(1);
7464
7465       if (!isNpm) {
7466         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7467           return ['key' + index, index];
7468         });
7469
7470         var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
7471
7472         assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
7473       }
7474       else {
7475         skipAssert(assert);
7476       }
7477     });
7478   }());
7479
7480   /*--------------------------------------------------------------------------*/
7481
7482   QUnit.module('lodash.functions');
7483
7484   (function() {
7485     QUnit.test('should return the function names of an object', function(assert) {
7486       assert.expect(1);
7487
7488       var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
7489           actual = _.functions(object).sort();
7490
7491       assert.deepEqual(actual, ['b', 'd']);
7492     });
7493
7494     QUnit.test('should not include inherited functions', function(assert) {
7495       assert.expect(1);
7496
7497       function Foo() {
7498         this.a = identity;
7499         this.b = 'b';
7500       }
7501       Foo.prototype.c = noop;
7502
7503       assert.deepEqual(_.functions(new Foo), ['a']);
7504     });
7505   }());
7506
7507   /*--------------------------------------------------------------------------*/
7508
7509   QUnit.module('lodash.groupBy');
7510
7511   (function() {
7512     var array = [6.1, 4.2, 6.3];
7513
7514     QUnit.test('should transform keys by `iteratee`', function(assert) {
7515       assert.expect(1);
7516
7517       var actual = _.groupBy(array, Math.floor);
7518       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7519     });
7520
7521     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7522       assert.expect(1);
7523
7524       var array = [6, 4, 6],
7525           values = [, null, undefined],
7526           expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
7527
7528       var actual = lodashStable.map(values, function(value, index) {
7529         return index ? _.groupBy(array, value) : _.groupBy(array);
7530       });
7531
7532       assert.deepEqual(actual, expected);
7533     });
7534
7535     QUnit.test('should work with `_.property` shorthands', function(assert) {
7536       assert.expect(1);
7537
7538       var actual = _.groupBy(['one', 'two', 'three'], 'length');
7539       assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
7540     });
7541
7542     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
7543       assert.expect(2);
7544
7545       var actual = _.groupBy(array, function(n) {
7546         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
7547       });
7548
7549       assert.deepEqual(actual.constructor, [4.2]);
7550       assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
7551     });
7552
7553     QUnit.test('should work with a number for `iteratee`', function(assert) {
7554       assert.expect(2);
7555
7556       var array = [
7557         [1, 'a'],
7558         [2, 'a'],
7559         [2, 'b']
7560       ];
7561
7562       assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
7563       assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
7564     });
7565
7566     QUnit.test('should work with an object for `collection`', function(assert) {
7567       assert.expect(1);
7568
7569       var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
7570       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7571     });
7572
7573     QUnit.test('should work in a lazy sequence', function(assert) {
7574       assert.expect(1);
7575
7576       if (!isNpm) {
7577         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
7578           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
7579           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
7580         );
7581
7582         var iteratee = function(value) { value.push(value[0]); return value; },
7583             predicate = function(value) { return isEven(value[0]); },
7584             actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
7585
7586         assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
7587       }
7588       else {
7589         skipAssert(assert);
7590       }
7591     });
7592   }());
7593
7594   /*--------------------------------------------------------------------------*/
7595
7596   QUnit.module('lodash.gt');
7597
7598   (function() {
7599     QUnit.test('should return `true` if `value` > `other`', function(assert) {
7600       assert.expect(2);
7601
7602       assert.strictEqual(_.gt(3, 1), true);
7603       assert.strictEqual(_.gt('def', 'abc'), true);
7604     });
7605
7606     QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
7607       assert.expect(4);
7608
7609       assert.strictEqual(_.gt(1, 3), false);
7610       assert.strictEqual(_.gt(3, 3), false);
7611       assert.strictEqual(_.gt('abc', 'def'), false);
7612       assert.strictEqual(_.gt('def', 'def'), false);
7613     });
7614   }());
7615
7616   /*--------------------------------------------------------------------------*/
7617
7618   QUnit.module('lodash.gte');
7619
7620   (function() {
7621     QUnit.test('should return `true` if `value` >= `other`', function(assert) {
7622       assert.expect(4);
7623
7624       assert.strictEqual(_.gte(3, 1), true);
7625       assert.strictEqual(_.gte(3, 3), true);
7626       assert.strictEqual(_.gte('def', 'abc'), true);
7627       assert.strictEqual(_.gte('def', 'def'), true);
7628     });
7629
7630     QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
7631       assert.expect(2);
7632
7633       assert.strictEqual(_.gte(1, 3), false);
7634       assert.strictEqual(_.gte('abc', 'def'), false);
7635     });
7636   }());
7637
7638   /*--------------------------------------------------------------------------*/
7639
7640   QUnit.module('has methods');
7641
7642   lodashStable.each(['has', 'hasIn'], function(methodName) {
7643     var args = (function() { return arguments; }(1, 2, 3)),
7644         func = _[methodName],
7645         isHas = methodName == 'has';
7646
7647     QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
7648       assert.expect(2);
7649
7650       var object = { 'a': 1 };
7651
7652       lodashStable.each(['a', ['a']], function(path) {
7653         assert.strictEqual(func(object, path), true);
7654       });
7655     });
7656
7657     QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
7658       assert.expect(1);
7659
7660       var object = { 'hasOwnProperty': null, 'a': 1 };
7661       assert.strictEqual(func(object, 'a'), true);
7662     });
7663
7664     QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
7665       assert.expect(4);
7666
7667       var object = { 'a': { 'b': 2 } };
7668
7669       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7670         assert.strictEqual(func(object, path), true);
7671       });
7672
7673       lodashStable.each(['a.a', ['a', 'a']], function(path) {
7674         assert.strictEqual(func(object, path), false);
7675       });
7676     });
7677
7678     QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
7679       assert.expect(1);
7680
7681       function fn() {}
7682       fn.toString = lodashStable.constant('fn');
7683
7684       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
7685           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
7686           values = [null, undefined, fn, {}];
7687
7688       var actual = lodashStable.transform(objects, function(result, object, index) {
7689         var key = values[index];
7690         lodashStable.each([key, [key]], function(path) {
7691           var prop = _.property(key);
7692           result.push(prop(object));
7693         });
7694       });
7695
7696       assert.deepEqual(actual, expected);
7697     });
7698
7699     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7700       assert.expect(1);
7701
7702       assert.strictEqual(func(args, 1), true);
7703     });
7704
7705     QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
7706       assert.expect(2);
7707
7708       var array = [1, 2, 3];
7709
7710       lodashStable.each([1, [1]], function(path) {
7711         assert.strictEqual(func(array, path), true);
7712       });
7713     });
7714
7715     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
7716       assert.expect(1);
7717
7718       var object = { '-0': 'a', '0': 'b' },
7719           props = [-0, Object(-0), 0, Object(0)],
7720           expected = lodashStable.map(props, stubTrue);
7721
7722       var actual = lodashStable.map(props, function(key) {
7723         return func(object, key);
7724       });
7725
7726       assert.deepEqual(actual, expected);
7727     });
7728
7729     QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
7730       assert.expect(1);
7731
7732       function Foo() {
7733         this[symbol] = 1;
7734       }
7735
7736       if (Symbol) {
7737         var symbol2 = Symbol('b');
7738         Foo.prototype[symbol2] = 2;
7739         var path = isHas ? symbol : symbol2;
7740
7741         assert.strictEqual(func(new Foo, path), true);
7742       }
7743       else {
7744         skipAssert(assert);
7745       }
7746     });
7747
7748     QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
7749       assert.expect(1);
7750
7751       if (create)  {
7752         var object = create(null);
7753         object[1] = 'a';
7754         assert.strictEqual(func(object, 1), true);
7755       }
7756       else {
7757         skipAssert(assert);
7758       }
7759     });
7760
7761     QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7762       assert.expect(2);
7763
7764       var object = { 'a.b': 1 };
7765
7766       lodashStable.each(['a.b', ['a.b']], function(path) {
7767         assert.strictEqual(func(object, path), true);
7768       });
7769     });
7770
7771     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7772       assert.expect(2);
7773
7774       function Foo() {}
7775       Foo.prototype.a = 1;
7776
7777       lodashStable.each(['a', ['a']], function(path) {
7778         assert.strictEqual(func(new Foo, path), !isHas);
7779       });
7780     });
7781
7782     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
7783       assert.expect(2);
7784
7785       function Foo() {}
7786       Foo.prototype.a = { 'b': 1 };
7787
7788       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7789         assert.strictEqual(func(new Foo, path), !isHas);
7790       });
7791     });
7792
7793     QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
7794       assert.expect(2);
7795
7796       var string = Object('abc');
7797       delete args[0];
7798       delete string[0];
7799
7800       var values = [Array(3), args, string],
7801           expected = lodashStable.map(values, stubTrue);
7802
7803       var actual = lodashStable.map(values, function(value) {
7804         return func(value, 0);
7805       });
7806
7807       assert.deepEqual(actual, expected);
7808
7809       expected = lodashStable.map(values, lodashStable.constant([true, true]));
7810
7811       actual = lodashStable.map(values, function(value) {
7812         return lodashStable.map(['a[0]', ['a', '0']], function(path) {
7813           return func({ 'a': value }, path);
7814         });
7815       });
7816
7817       assert.deepEqual(actual, expected);
7818       args[0] = 1;
7819     });
7820
7821     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7822       assert.expect(2);
7823
7824       var values = [null, undefined],
7825           expected = lodashStable.map(values, stubFalse);
7826
7827       lodashStable.each(['constructor', ['constructor']], function(path) {
7828         var actual = lodashStable.map(values, function(value) {
7829           return func(value, path);
7830         });
7831
7832         assert.deepEqual(actual, expected);
7833       });
7834     });
7835
7836     QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
7837       assert.expect(2);
7838
7839       var values = [null, undefined],
7840           expected = lodashStable.map(values, stubFalse);
7841
7842       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
7843         var actual = lodashStable.map(values, function(value) {
7844           return func(value, path);
7845         });
7846
7847         assert.deepEqual(actual, expected);
7848       });
7849     });
7850
7851     QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
7852       assert.expect(2);
7853
7854       var values = [, null, undefined],
7855           expected = lodashStable.map(values, stubFalse);
7856
7857       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7858         var actual = lodashStable.map(values, function(value, index) {
7859           var object = index ? { 'a': value } : {};
7860           return func(object, path);
7861         });
7862
7863         assert.deepEqual(actual, expected);
7864       });
7865     });
7866   });
7867
7868   /*--------------------------------------------------------------------------*/
7869
7870   QUnit.module('lodash.head');
7871
7872   (function() {
7873     var array = [1, 2, 3, 4];
7874
7875     QUnit.test('should return the first element', function(assert) {
7876       assert.expect(1);
7877
7878       assert.strictEqual(_.head(array), 1);
7879     });
7880
7881     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
7882       assert.expect(1);
7883
7884       arrayProto[0] = 1;
7885       assert.strictEqual(_.head([]), undefined);
7886       arrayProto.length = 0;
7887     });
7888
7889     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7890       assert.expect(1);
7891
7892       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7893           actual = lodashStable.map(array, _.head);
7894
7895       assert.deepEqual(actual, [1, 4, 7]);
7896     });
7897
7898     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7899       assert.expect(1);
7900
7901       if (!isNpm) {
7902         assert.strictEqual(_(array).head(), 1);
7903       }
7904       else {
7905         skipAssert(assert);
7906       }
7907     });
7908
7909     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7910       assert.expect(1);
7911
7912       if (!isNpm) {
7913         assert.ok(_(array).chain().head() instanceof _);
7914       }
7915       else {
7916         skipAssert(assert);
7917       }
7918     });
7919
7920     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
7921       assert.expect(1);
7922
7923       if (!isNpm) {
7924         var wrapped = _(array).chain().head();
7925         assert.strictEqual(wrapped.__wrapped__, array);
7926       }
7927       else {
7928         skipAssert(assert);
7929       }
7930     });
7931
7932     QUnit.test('should work in a lazy sequence', function(assert) {
7933       assert.expect(2);
7934
7935       if (!isNpm) {
7936         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
7937             smallArray = array;
7938
7939         lodashStable.times(2, function(index) {
7940           var array = index ? largeArray : smallArray,
7941               wrapped = _(array).filter(isEven);
7942
7943           assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
7944         });
7945       }
7946       else {
7947         skipAssert(assert, 2);
7948       }
7949     });
7950
7951     QUnit.test('should be aliased', function(assert) {
7952       assert.expect(1);
7953
7954       assert.strictEqual(_.first, _.head);
7955     });
7956   }());
7957
7958   /*--------------------------------------------------------------------------*/
7959
7960   QUnit.module('lodash.identity');
7961
7962   (function() {
7963     QUnit.test('should return the first argument given', function(assert) {
7964       assert.expect(1);
7965
7966       var object = { 'name': 'fred' };
7967       assert.strictEqual(_.identity(object), object);
7968     });
7969   }());
7970
7971   /*--------------------------------------------------------------------------*/
7972
7973   QUnit.module('lodash.includes');
7974
7975   (function() {
7976     lodashStable.each({
7977       'an `arguments` object': arguments,
7978       'an array': [1, 2, 3, 4],
7979       'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
7980       'a string': '1234'
7981     },
7982     function(collection, key) {
7983       QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
7984         assert.expect(1);
7985
7986         assert.strictEqual(_.includes(collection, 3), true);
7987       });
7988
7989       QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
7990         assert.expect(1);
7991
7992         assert.strictEqual(_.includes(collection, 5), false);
7993       });
7994
7995       QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
7996         assert.expect(1);
7997
7998         assert.strictEqual(_.includes(collection, 2, 1.2), true);
7999       });
8000
8001       QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
8002         assert.expect(1);
8003
8004         if (!isNpm) {
8005           assert.strictEqual(_(collection).includes(3), true);
8006         }
8007         else {
8008           skipAssert(assert);
8009         }
8010       });
8011
8012       QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
8013         assert.expect(1);
8014
8015         if (!isNpm) {
8016           assert.ok(_(collection).chain().includes(3) instanceof _);
8017         }
8018         else {
8019           skipAssert(assert);
8020         }
8021       });
8022     });
8023
8024     lodashStable.each({
8025       'literal': 'abc',
8026       'object': Object('abc')
8027     },
8028     function(collection, key) {
8029       QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
8030         assert.expect(2);
8031
8032         assert.strictEqual(_.includes(collection, 'bc'), true);
8033         assert.strictEqual(_.includes(collection, 'd'), false);
8034       });
8035     });
8036
8037     QUnit.test('should return `false` for empty collections', function(assert) {
8038       assert.expect(1);
8039
8040       var expected = lodashStable.map(empties, stubFalse);
8041
8042       var actual = lodashStable.map(empties, function(value) {
8043         try {
8044           return _.includes(value);
8045         } catch (e) {}
8046       });
8047
8048       assert.deepEqual(actual, expected);
8049     });
8050
8051     QUnit.test('should work with a string and a `fromIndex` >= `length`', function(assert) {
8052       assert.expect(1);
8053
8054       var string = '1234',
8055           length = string.length,
8056           indexes = [4, 6, Math.pow(2, 32), Infinity];
8057
8058       var expected = lodashStable.map(indexes, function(index) {
8059         return [false, false, index == length];
8060       });
8061
8062       var actual = lodashStable.map(indexes, function(fromIndex) {
8063         return [
8064           _.includes(string, 1, fromIndex),
8065           _.includes(string, undefined, fromIndex),
8066           _.includes(string, '', fromIndex)
8067         ];
8068       });
8069
8070       assert.deepEqual(actual, expected);
8071     });
8072
8073     QUnit.test('should match `NaN`', function(assert) {
8074       assert.expect(1);
8075
8076       assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
8077     });
8078
8079     QUnit.test('should match `-0` as `0`', function(assert) {
8080       assert.expect(2);
8081
8082       assert.strictEqual(_.includes([-0], 0), true);
8083       assert.strictEqual(_.includes([0], -0), true);
8084     });
8085
8086     QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
8087       assert.expect(1);
8088
8089       var array1 = [1, 2, 3],
8090           array2 = [2, 3, 1];
8091
8092       assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
8093     });
8094   }(1, 2, 3, 4));
8095
8096   /*--------------------------------------------------------------------------*/
8097
8098   QUnit.module('lodash.initial');
8099
8100   (function() {
8101     var array = [1, 2, 3];
8102
8103     QUnit.test('should accept a falsey `array` argument', function(assert) {
8104       assert.expect(1);
8105
8106       var expected = lodashStable.map(falsey, stubArray);
8107
8108       var actual = lodashStable.map(falsey, function(array, index) {
8109         try {
8110           return index ? _.initial(array) : _.initial();
8111         } catch (e) {}
8112       });
8113
8114       assert.deepEqual(actual, expected);
8115     });
8116
8117     QUnit.test('should exclude last element', function(assert) {
8118       assert.expect(1);
8119
8120       assert.deepEqual(_.initial(array), [1, 2]);
8121     });
8122
8123     QUnit.test('should return an empty when querying empty arrays', function(assert) {
8124       assert.expect(1);
8125
8126       assert.deepEqual(_.initial([]), []);
8127     });
8128
8129     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
8130       assert.expect(1);
8131
8132       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
8133           actual = lodashStable.map(array, _.initial);
8134
8135       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
8136     });
8137
8138     QUnit.test('should work in a lazy sequence', function(assert) {
8139       assert.expect(4);
8140
8141       if (!isNpm) {
8142         var array = lodashStable.range(LARGE_ARRAY_SIZE),
8143             values = [];
8144
8145         var actual = _(array).initial().filter(function(value) {
8146           values.push(value);
8147           return false;
8148         })
8149         .value();
8150
8151         assert.deepEqual(actual, []);
8152         assert.deepEqual(values, _.initial(array));
8153
8154         values = [];
8155
8156         actual = _(array).filter(function(value) {
8157           values.push(value);
8158           return isEven(value);
8159         })
8160         .initial()
8161         .value();
8162
8163         assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
8164         assert.deepEqual(values, array);
8165       }
8166       else {
8167         skipAssert(assert, 4);
8168       }
8169     });
8170   }());
8171
8172   /*--------------------------------------------------------------------------*/
8173
8174   QUnit.module('lodash.inRange');
8175
8176   (function() {
8177     QUnit.test('should work with an `end` argument', function(assert) {
8178       assert.expect(3);
8179
8180       assert.strictEqual(_.inRange(3, 5), true);
8181       assert.strictEqual(_.inRange(5, 5), false);
8182       assert.strictEqual(_.inRange(6, 5), false);
8183     });
8184
8185     QUnit.test('should work with `start` and `end` arguments', function(assert) {
8186       assert.expect(4);
8187
8188       assert.strictEqual(_.inRange(1, 1, 5), true);
8189       assert.strictEqual(_.inRange(3, 1, 5), true);
8190       assert.strictEqual(_.inRange(0, 1, 5), false);
8191       assert.strictEqual(_.inRange(5, 1, 5), false);
8192     });
8193
8194     QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
8195       assert.expect(13);
8196
8197       lodashStable.each(falsey, function(value, index) {
8198         if (index) {
8199           assert.strictEqual(_.inRange(0, value), false);
8200           assert.strictEqual(_.inRange(0, value, 1), true);
8201         } else {
8202           assert.strictEqual(_.inRange(0), false);
8203         }
8204       });
8205     });
8206
8207     QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
8208       assert.expect(2);
8209
8210       assert.strictEqual(_.inRange(2, 5, 1), true);
8211       assert.strictEqual(_.inRange(-3, -2, -6), true);
8212     });
8213
8214     QUnit.test('should work with a floating point `n` value', function(assert) {
8215       assert.expect(4);
8216
8217       assert.strictEqual(_.inRange(0.5, 5), true);
8218       assert.strictEqual(_.inRange(1.2, 1, 5), true);
8219       assert.strictEqual(_.inRange(5.2, 5), false);
8220       assert.strictEqual(_.inRange(0.5, 1, 5), false);
8221     });
8222
8223     QUnit.test('should coerce arguments to finite numbers', function(assert) {
8224       assert.expect(1);
8225
8226       var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
8227           expected = lodashStable.map(actual, stubTrue);
8228
8229       assert.deepEqual(actual, expected);
8230     });
8231   }());
8232
8233   /*--------------------------------------------------------------------------*/
8234
8235   QUnit.module('intersection methods');
8236
8237   lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
8238     var args = (function() { return arguments; }(1, 2, 3)),
8239         func = _[methodName];
8240
8241     QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
8242       assert.expect(1);
8243
8244       var actual = func([2, 1], [2, 3]);
8245       assert.deepEqual(actual, [2]);
8246     });
8247
8248     QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
8249       assert.expect(1);
8250
8251       var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
8252       assert.deepEqual(actual, [3]);
8253     });
8254
8255     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
8256       assert.expect(1);
8257
8258       var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
8259       assert.deepEqual(actual, [1, 2]);
8260     });
8261
8262     QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
8263       assert.expect(1);
8264
8265       var actual = func([1, 1, 3, 2, 2]);
8266       assert.deepEqual(actual, [1, 3, 2]);
8267     });
8268
8269     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
8270       assert.expect(2);
8271
8272       var array = [0, 1, null, 3],
8273           expected = [1, 3];
8274
8275       assert.deepEqual(func(array, args), expected);
8276       assert.deepEqual(func(args, array), expected);
8277     });
8278
8279     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
8280       assert.expect(1);
8281
8282       var values = [-0, 0],
8283           expected = lodashStable.map(values, lodashStable.constant(['0']));
8284
8285       var actual = lodashStable.map(values, function(value) {
8286         return lodashStable.map(func(values, [value]), lodashStable.toString);
8287       });
8288
8289       assert.deepEqual(actual, expected);
8290     });
8291
8292     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
8293       assert.expect(1);
8294
8295       var actual = func([1, NaN, 3], [NaN, 5, NaN]);
8296       assert.deepEqual(actual, [NaN]);
8297     });
8298
8299     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
8300       assert.expect(1);
8301
8302       var values = [-0, 0],
8303           expected = lodashStable.map(values, lodashStable.constant(['0']));
8304
8305       var actual = lodashStable.map(values, function(value) {
8306         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
8307         return lodashStable.map(func(values, largeArray), lodashStable.toString);
8308       });
8309
8310       assert.deepEqual(actual, expected);
8311     });
8312
8313     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
8314       assert.expect(1);
8315
8316       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
8317       assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
8318     });
8319
8320     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
8321       assert.expect(2);
8322
8323       var object = {},
8324           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
8325
8326       assert.deepEqual(func([object], largeArray), [object]);
8327       assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
8328     });
8329
8330     QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
8331       assert.expect(3);
8332
8333       var array = [0, 1, null, 3];
8334       assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
8335       assert.deepEqual(func(null, array, null, [2, 3]), []);
8336       assert.deepEqual(func(array, null, args, null), []);
8337     });
8338
8339     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
8340       assert.expect(2);
8341
8342       if (!isNpm) {
8343         var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
8344         assert.ok(wrapped instanceof _);
8345         assert.deepEqual(wrapped.value(), [1, 2]);
8346       }
8347       else {
8348         skipAssert(assert, 2);
8349       }
8350     });
8351   });
8352
8353   /*--------------------------------------------------------------------------*/
8354
8355   QUnit.module('lodash.intersectionBy');
8356
8357   (function() {
8358     QUnit.test('should accept an `iteratee` argument', function(assert) {
8359       assert.expect(2);
8360
8361       var actual = _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8362       assert.deepEqual(actual, [2.1]);
8363
8364       actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8365       assert.deepEqual(actual, [{ 'x': 1 }]);
8366     });
8367
8368     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
8369       assert.expect(1);
8370
8371       var args;
8372
8373       _.intersectionBy([2.1, 1.2], [2.3, 3.4], function() {
8374         args || (args = slice.call(arguments));
8375       });
8376
8377       assert.deepEqual(args, [2.3]);
8378     });
8379   }());
8380
8381   /*--------------------------------------------------------------------------*/
8382
8383   QUnit.module('lodash.intersectionWith');
8384
8385   (function() {
8386     QUnit.test('should work with a `comparator` argument', function(assert) {
8387       assert.expect(1);
8388
8389       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
8390           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
8391           actual = _.intersectionWith(objects, others, lodashStable.isEqual);
8392
8393       assert.deepEqual(actual, [objects[0]]);
8394     });
8395
8396     QUnit.test('should preserve the sign of `0`', function(assert) {
8397       assert.expect(1);
8398
8399       var array = [-0],
8400           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubZero),
8401           others = [[0], largeArray],
8402           expected = lodashStable.map(others, lodashStable.constant(['-0']));
8403
8404       var actual = lodashStable.map(others, function(other) {
8405         return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
8406       });
8407
8408       assert.deepEqual(actual, expected);
8409     });
8410   }());
8411
8412   /*--------------------------------------------------------------------------*/
8413
8414   QUnit.module('lodash.invert');
8415
8416   (function() {
8417     QUnit.test('should invert an object', function(assert) {
8418       assert.expect(2);
8419
8420       var object = { 'a': 1, 'b': 2 },
8421           actual = _.invert(object);
8422
8423       assert.deepEqual(actual, { '1': 'a', '2': 'b' });
8424       assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
8425     });
8426
8427     QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
8428       assert.expect(1);
8429
8430       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
8431       assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
8432     });
8433
8434     QUnit.test('should work with an object that has a `length` property', function(assert) {
8435       assert.expect(1);
8436
8437       var object = { '0': 'a', '1': 'b', 'length': 2 };
8438       assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
8439     });
8440
8441     QUnit.test('should return a wrapped value when chaining', function(assert) {
8442       assert.expect(2);
8443
8444       if (!isNpm) {
8445         var object = { 'a': 1, 'b': 2 },
8446             wrapped = _(object).invert();
8447
8448         assert.ok(wrapped instanceof _);
8449         assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
8450       }
8451       else {
8452         skipAssert(assert, 2);
8453       }
8454     });
8455   }());
8456
8457   /*--------------------------------------------------------------------------*/
8458
8459   QUnit.module('lodash.invertBy');
8460
8461   (function() {
8462     var object = { 'a': 1, 'b': 2, 'c': 1 };
8463
8464     QUnit.test('should transform keys by `iteratee`', function(assert) {
8465       assert.expect(1);
8466
8467       var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
8468
8469       var actual = _.invertBy(object, function(value) {
8470         return 'group' + value;
8471       });
8472
8473       assert.deepEqual(actual, expected);
8474     });
8475
8476     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
8477       assert.expect(1);
8478
8479       var values = [, null, undefined],
8480           expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
8481
8482       var actual = lodashStable.map(values, function(value, index) {
8483         return index ? _.invertBy(object, value) : _.invertBy(object);
8484       });
8485
8486       assert.deepEqual(actual, expected);
8487     });
8488
8489     QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
8490       assert.expect(1);
8491
8492       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
8493           expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
8494
8495       assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
8496     });
8497
8498     QUnit.test('should return a wrapped value when chaining', function(assert) {
8499       assert.expect(2);
8500
8501       if (!isNpm) {
8502         var wrapped = _(object).invertBy();
8503
8504         assert.ok(wrapped instanceof _);
8505         assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
8506       }
8507       else {
8508         skipAssert(assert, 2);
8509       }
8510     });
8511   }());
8512
8513   /*--------------------------------------------------------------------------*/
8514
8515   QUnit.module('lodash.invoke');
8516
8517   (function() {
8518     QUnit.test('should invoke a method on `object`', function(assert) {
8519       assert.expect(1);
8520
8521       var object = { 'a': lodashStable.constant('A') },
8522           actual = _.invoke(object, 'a');
8523
8524       assert.strictEqual(actual, 'A');
8525     });
8526
8527     QUnit.test('should support invoking with arguments', function(assert) {
8528       assert.expect(1);
8529
8530       var object = { 'a': function(a, b) { return [a, b]; } },
8531           actual = _.invoke(object, 'a', 1, 2);
8532
8533       assert.deepEqual(actual, [1, 2]);
8534     });
8535
8536     QUnit.test('should not error on nullish elements', function(assert) {
8537       assert.expect(1);
8538
8539       var values = [null, undefined],
8540           expected = lodashStable.map(values, noop);
8541
8542       var actual = lodashStable.map(values, function(value) {
8543         try {
8544           return _.invoke(value, 'a.b', 1, 2);
8545         } catch (e) {}
8546       });
8547
8548       assert.deepEqual(actual, expected);
8549     });
8550
8551     QUnit.test('should preserve the sign of `0`', function(assert) {
8552       assert.expect(1);
8553
8554       var object = { '-0': stubA, '0': stubB },
8555           props = [-0, Object(-0), 0, Object(0)];
8556
8557       var actual = lodashStable.map(props, function(key) {
8558         return _.invoke(object, key);
8559       });
8560
8561       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
8562     });
8563
8564     QUnit.test('should support deep paths', function(assert) {
8565       assert.expect(2);
8566
8567       var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
8568
8569       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8570         var actual = _.invoke(object, path, 1, 2);
8571         assert.deepEqual(actual, [1, 2]);
8572       });
8573     });
8574
8575     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8576       assert.expect(2);
8577
8578       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8579
8580       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8581         assert.deepEqual(_.invoke(object, path), 1);
8582       });
8583     });
8584
8585     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8586       assert.expect(1);
8587
8588       if (!isNpm) {
8589         var object = { 'a': stubOne };
8590         assert.strictEqual(_(object).invoke('a'), 1);
8591       }
8592       else {
8593         skipAssert(assert);
8594       }
8595     });
8596
8597     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8598       assert.expect(1);
8599
8600       if (!isNpm) {
8601         var object = { 'a': stubOne };
8602         assert.ok(_(object).chain().invoke('a') instanceof _);
8603       }
8604       else {
8605         skipAssert(assert);
8606       }
8607     });
8608   }());
8609
8610   /*--------------------------------------------------------------------------*/
8611
8612   QUnit.module('lodash.invokeMap');
8613
8614   (function() {
8615     QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
8616       assert.expect(1);
8617
8618       var array = ['a', 'b', 'c'],
8619           actual = _.invokeMap(array, 'toUpperCase');
8620
8621       assert.deepEqual(actual, ['A', 'B', 'C']);
8622     });
8623
8624     QUnit.test('should support invoking with arguments', function(assert) {
8625       assert.expect(1);
8626
8627       var array = [function() { return slice.call(arguments); }],
8628           actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
8629
8630       assert.deepEqual(actual, [['a', 'b', 'c']]);
8631     });
8632
8633     QUnit.test('should work with a function for `methodName`', function(assert) {
8634       assert.expect(1);
8635
8636       var array = ['a', 'b', 'c'];
8637
8638       var actual = _.invokeMap(array, function(left, right) {
8639         return left + this.toUpperCase() + right;
8640       }, '(', ')');
8641
8642       assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
8643     });
8644
8645     QUnit.test('should work with an object for `collection`', function(assert) {
8646       assert.expect(1);
8647
8648       var object = { 'a': 1, 'b': 2, 'c': 3 },
8649           actual = _.invokeMap(object, 'toFixed', 1);
8650
8651       assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
8652     });
8653
8654     QUnit.test('should treat number values for `collection` as empty', function(assert) {
8655       assert.expect(1);
8656
8657       assert.deepEqual(_.invokeMap(1), []);
8658     });
8659
8660     QUnit.test('should not error on nullish elements', function(assert) {
8661       assert.expect(1);
8662
8663       var array = ['a', null, undefined, 'd'];
8664
8665       try {
8666         var actual = _.invokeMap(array, 'toUpperCase');
8667       } catch (e) {}
8668
8669       assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
8670     });
8671
8672     QUnit.test('should not error on elements with missing properties', function(assert) {
8673       assert.expect(1);
8674
8675       var objects = lodashStable.map([null, undefined, stubOne], function(value) {
8676         return { 'a': value };
8677       });
8678
8679       var expected = lodashStable.map(objects, function(object) {
8680         return object.a ? object.a() : undefined;
8681       });
8682
8683       try {
8684         var actual = _.invokeMap(objects, 'a');
8685       } catch (e) {}
8686
8687       assert.deepEqual(actual, expected);
8688     });
8689
8690     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8691       assert.expect(2);
8692
8693       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8694
8695       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8696         assert.deepEqual(_.invokeMap([object], path), [1]);
8697       });
8698     });
8699
8700     QUnit.test('should return a wrapped value when chaining', function(assert) {
8701       assert.expect(4);
8702
8703       if (!isNpm) {
8704         var array = ['a', 'b', 'c'],
8705             wrapped = _(array),
8706             actual = wrapped.invokeMap('toUpperCase');
8707
8708         assert.ok(actual instanceof _);
8709         assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8710
8711         actual = wrapped.invokeMap(function(left, right) {
8712           return left + this.toUpperCase() + right;
8713         }, '(', ')');
8714
8715         assert.ok(actual instanceof _);
8716         assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8717       }
8718       else {
8719         skipAssert(assert, 4);
8720       }
8721     });
8722
8723     QUnit.test('should support shortcut fusion', function(assert) {
8724       assert.expect(2);
8725
8726       if (!isNpm) {
8727         var count = 0,
8728             method = function() { count++; return this.index; };
8729
8730         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8731           return { 'index': index, 'method': method };
8732         });
8733
8734         var actual = _(array).invokeMap('method').take(1).value();
8735
8736         assert.strictEqual(count, 1);
8737         assert.deepEqual(actual, [0]);
8738       }
8739       else {
8740         skipAssert(assert, 2);
8741       }
8742     });
8743   }());
8744
8745   /*--------------------------------------------------------------------------*/
8746
8747   QUnit.module('lodash.isArguments');
8748
8749   (function() {
8750     var args = (function() { return arguments; }(1, 2, 3)),
8751         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
8752
8753     QUnit.test('should return `true` for `arguments` objects', function(assert) {
8754       assert.expect(2);
8755
8756       assert.strictEqual(_.isArguments(args), true);
8757       assert.strictEqual(_.isArguments(strictArgs), true);
8758     });
8759
8760     QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8761       assert.expect(12);
8762
8763       var expected = lodashStable.map(falsey, stubFalse);
8764
8765       var actual = lodashStable.map(falsey, function(value, index) {
8766         return index ? _.isArguments(value) : _.isArguments();
8767       });
8768
8769       assert.deepEqual(actual, expected);
8770
8771       assert.strictEqual(_.isArguments([1, 2, 3]), false);
8772       assert.strictEqual(_.isArguments(true), false);
8773       assert.strictEqual(_.isArguments(new Date), false);
8774       assert.strictEqual(_.isArguments(new Error), false);
8775       assert.strictEqual(_.isArguments(_), false);
8776       assert.strictEqual(_.isArguments(slice), false);
8777       assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8778       assert.strictEqual(_.isArguments(1), false);
8779       assert.strictEqual(_.isArguments(/x/), false);
8780       assert.strictEqual(_.isArguments('a'), false);
8781       assert.strictEqual(_.isArguments(symbol), false);
8782     });
8783
8784     QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8785       assert.expect(1);
8786
8787       if (realm.arguments) {
8788         assert.strictEqual(_.isArguments(realm.arguments), true);
8789       }
8790       else {
8791         skipAssert(assert);
8792       }
8793     });
8794   }());
8795
8796   /*--------------------------------------------------------------------------*/
8797
8798   QUnit.module('lodash.isArray');
8799
8800   (function() {
8801     var args = arguments;
8802
8803     QUnit.test('should return `true` for arrays', function(assert) {
8804       assert.expect(1);
8805
8806       assert.strictEqual(_.isArray([1, 2, 3]), true);
8807     });
8808
8809     QUnit.test('should return `false` for non-arrays', function(assert) {
8810       assert.expect(12);
8811
8812       var expected = lodashStable.map(falsey, stubFalse);
8813
8814       var actual = lodashStable.map(falsey, function(value, index) {
8815         return index ? _.isArray(value) : _.isArray();
8816       });
8817
8818       assert.deepEqual(actual, expected);
8819
8820       assert.strictEqual(_.isArray(args), false);
8821       assert.strictEqual(_.isArray(true), false);
8822       assert.strictEqual(_.isArray(new Date), false);
8823       assert.strictEqual(_.isArray(new Error), false);
8824       assert.strictEqual(_.isArray(_), false);
8825       assert.strictEqual(_.isArray(slice), false);
8826       assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
8827       assert.strictEqual(_.isArray(1), false);
8828       assert.strictEqual(_.isArray(/x/), false);
8829       assert.strictEqual(_.isArray('a'), false);
8830       assert.strictEqual(_.isArray(symbol), false);
8831     });
8832
8833     QUnit.test('should work with an array from another realm', function(assert) {
8834       assert.expect(1);
8835
8836       if (realm.array) {
8837         assert.strictEqual(_.isArray(realm.array), true);
8838       }
8839       else {
8840         skipAssert(assert);
8841       }
8842     });
8843   }(1, 2, 3));
8844
8845   /*--------------------------------------------------------------------------*/
8846
8847   QUnit.module('lodash.isArrayBuffer');
8848
8849   (function() {
8850     var args = arguments;
8851
8852     QUnit.test('should return `true` for array buffers', function(assert) {
8853       assert.expect(1);
8854
8855       if (ArrayBuffer) {
8856         assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
8857       }
8858       else {
8859         skipAssert(assert);
8860       }
8861     });
8862
8863     QUnit.test('should return `false` for non array buffers', function(assert) {
8864       assert.expect(13);
8865
8866       var expected = lodashStable.map(falsey, stubFalse);
8867
8868       var actual = lodashStable.map(falsey, function(value, index) {
8869         return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
8870       });
8871
8872       assert.deepEqual(actual, expected);
8873
8874       assert.strictEqual(_.isArrayBuffer(args), false);
8875       assert.strictEqual(_.isArrayBuffer([1, 2, 3]), false);
8876       assert.strictEqual(_.isArrayBuffer(true), false);
8877       assert.strictEqual(_.isArrayBuffer(new Date), false);
8878       assert.strictEqual(_.isArrayBuffer(new Error), false);
8879       assert.strictEqual(_.isArrayBuffer(_), false);
8880       assert.strictEqual(_.isArrayBuffer(slice), false);
8881       assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
8882       assert.strictEqual(_.isArrayBuffer(1), false);
8883       assert.strictEqual(_.isArrayBuffer(/x/), false);
8884       assert.strictEqual(_.isArrayBuffer('a'), false);
8885       assert.strictEqual(_.isArrayBuffer(symbol), false);
8886     });
8887
8888     QUnit.test('should work with array buffers from another realm', function(assert) {
8889       assert.expect(1);
8890
8891       if (realm.arrayBuffer) {
8892         assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
8893       }
8894       else {
8895         skipAssert(assert);
8896       }
8897     });
8898   }(1, 2, 3));
8899
8900   /*--------------------------------------------------------------------------*/
8901
8902   QUnit.module('lodash.isArrayLike');
8903
8904   (function() {
8905     var args = arguments;
8906
8907     QUnit.test('should return `true` for array-like values', function(assert) {
8908       assert.expect(1);
8909
8910       var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
8911           expected = lodashStable.map(values, stubTrue),
8912           actual = lodashStable.map(values, _.isArrayLike);
8913
8914       assert.deepEqual(actual, expected);
8915     });
8916
8917     QUnit.test('should return `false` for non-arrays', function(assert) {
8918       assert.expect(11);
8919
8920       var expected = lodashStable.map(falsey, function(value) {
8921         return value === '';
8922       });
8923
8924       var actual = lodashStable.map(falsey, function(value, index) {
8925         return index ? _.isArrayLike(value) : _.isArrayLike();
8926       });
8927
8928       assert.deepEqual(actual, expected);
8929
8930       assert.strictEqual(_.isArrayLike(true), false);
8931       assert.strictEqual(_.isArrayLike(new Date), false);
8932       assert.strictEqual(_.isArrayLike(new Error), false);
8933       assert.strictEqual(_.isArrayLike(_), false);
8934       assert.strictEqual(_.isArrayLike(generator), false);
8935       assert.strictEqual(_.isArrayLike(slice), false);
8936       assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
8937       assert.strictEqual(_.isArrayLike(1), false);
8938       assert.strictEqual(_.isArrayLike(/x/), false);
8939       assert.strictEqual(_.isArrayLike(symbol), false);
8940     });
8941
8942     QUnit.test('should work with an array from another realm', function(assert) {
8943       assert.expect(1);
8944
8945       if (realm.object) {
8946         var values = [realm.arguments, realm.array, realm.string],
8947             expected = lodashStable.map(values, stubTrue),
8948             actual = lodashStable.map(values, _.isArrayLike);
8949
8950         assert.deepEqual(actual, expected);
8951       }
8952       else {
8953         skipAssert(assert);
8954       }
8955     });
8956   }(1, 2, 3));
8957
8958   /*--------------------------------------------------------------------------*/
8959
8960   QUnit.module('lodash.isBoolean');
8961
8962   (function() {
8963     var args = arguments;
8964
8965     QUnit.test('should return `true` for booleans', function(assert) {
8966       assert.expect(4);
8967
8968       assert.strictEqual(_.isBoolean(true), true);
8969       assert.strictEqual(_.isBoolean(false), true);
8970       assert.strictEqual(_.isBoolean(Object(true)), true);
8971       assert.strictEqual(_.isBoolean(Object(false)), true);
8972     });
8973
8974     QUnit.test('should return `false` for non-booleans', function(assert) {
8975       assert.expect(12);
8976
8977       var expected = lodashStable.map(falsey, function(value) {
8978         return value === false;
8979       });
8980
8981       var actual = lodashStable.map(falsey, function(value, index) {
8982         return index ? _.isBoolean(value) : _.isBoolean();
8983       });
8984
8985       assert.deepEqual(actual, expected);
8986
8987       assert.strictEqual(_.isBoolean(args), false);
8988       assert.strictEqual(_.isBoolean([1, 2, 3]), false);
8989       assert.strictEqual(_.isBoolean(new Date), false);
8990       assert.strictEqual(_.isBoolean(new Error), false);
8991       assert.strictEqual(_.isBoolean(_), false);
8992       assert.strictEqual(_.isBoolean(slice), false);
8993       assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
8994       assert.strictEqual(_.isBoolean(1), false);
8995       assert.strictEqual(_.isBoolean(/x/), false);
8996       assert.strictEqual(_.isBoolean('a'), false);
8997       assert.strictEqual(_.isBoolean(symbol), false);
8998     });
8999
9000     QUnit.test('should work with a boolean from another realm', function(assert) {
9001       assert.expect(1);
9002
9003       if (realm.boolean) {
9004         assert.strictEqual(_.isBoolean(realm.boolean), true);
9005       }
9006       else {
9007         skipAssert(assert);
9008       }
9009     });
9010   }(1, 2, 3));
9011
9012   /*--------------------------------------------------------------------------*/
9013
9014   QUnit.module('lodash.isBuffer');
9015
9016   (function() {
9017     var args = arguments;
9018
9019     QUnit.test('should return `true` for buffers', function(assert) {
9020       assert.expect(1);
9021
9022       if (Buffer) {
9023         assert.strictEqual(_.isBuffer(new Buffer(2)), true);
9024       }
9025       else {
9026         skipAssert(assert);
9027       }
9028     });
9029
9030     QUnit.test('should return `false` for non-buffers', function(assert) {
9031       assert.expect(13);
9032
9033       var expected = lodashStable.map(falsey, stubFalse);
9034
9035       var actual = lodashStable.map(falsey, function(value, index) {
9036         return index ? _.isBuffer(value) : _.isBuffer();
9037       });
9038
9039       assert.deepEqual(actual, expected);
9040
9041       assert.strictEqual(_.isBuffer(args), false);
9042       assert.strictEqual(_.isBuffer([1, 2, 3]), false);
9043       assert.strictEqual(_.isBuffer(true), false);
9044       assert.strictEqual(_.isBuffer(new Date), false);
9045       assert.strictEqual(_.isBuffer(new Error), false);
9046       assert.strictEqual(_.isBuffer(_), false);
9047       assert.strictEqual(_.isBuffer(slice), false);
9048       assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
9049       assert.strictEqual(_.isBuffer(1), false);
9050       assert.strictEqual(_.isBuffer(/x/), false);
9051       assert.strictEqual(_.isBuffer('a'), false);
9052       assert.strictEqual(_.isBuffer(symbol), false);
9053     });
9054
9055     QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
9056       assert.expect(1);
9057
9058       if (!isStrict && Buffer && lodashBizarro) {
9059         assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
9060       }
9061       else {
9062         skipAssert(assert);
9063       }
9064     });
9065   }(1, 2, 3));
9066
9067   /*--------------------------------------------------------------------------*/
9068
9069   QUnit.module('lodash.isDate');
9070
9071   (function() {
9072     var args = arguments;
9073
9074     QUnit.test('should return `true` for dates', function(assert) {
9075       assert.expect(1);
9076
9077       assert.strictEqual(_.isDate(new Date), true);
9078     });
9079
9080     QUnit.test('should return `false` for non-dates', function(assert) {
9081       assert.expect(12);
9082
9083       var expected = lodashStable.map(falsey, stubFalse);
9084
9085       var actual = lodashStable.map(falsey, function(value, index) {
9086         return index ? _.isDate(value) : _.isDate();
9087       });
9088
9089       assert.deepEqual(actual, expected);
9090
9091       assert.strictEqual(_.isDate(args), false);
9092       assert.strictEqual(_.isDate([1, 2, 3]), false);
9093       assert.strictEqual(_.isDate(true), false);
9094       assert.strictEqual(_.isDate(new Error), false);
9095       assert.strictEqual(_.isDate(_), false);
9096       assert.strictEqual(_.isDate(slice), false);
9097       assert.strictEqual(_.isDate({ 'a': 1 }), false);
9098       assert.strictEqual(_.isDate(1), false);
9099       assert.strictEqual(_.isDate(/x/), false);
9100       assert.strictEqual(_.isDate('a'), false);
9101       assert.strictEqual(_.isDate(symbol), false);
9102     });
9103
9104     QUnit.test('should work with a date object from another realm', function(assert) {
9105       assert.expect(1);
9106
9107       if (realm.date) {
9108         assert.strictEqual(_.isDate(realm.date), true);
9109       }
9110       else {
9111         skipAssert(assert);
9112       }
9113     });
9114   }(1, 2, 3));
9115
9116   /*--------------------------------------------------------------------------*/
9117
9118   QUnit.module('lodash.isElement');
9119
9120   (function() {
9121     var args = arguments;
9122
9123     function Element() {
9124       this.nodeType = 1;
9125     }
9126
9127     QUnit.test('should return `false` for plain objects', function(assert) {
9128       assert.expect(7);
9129
9130       var element = body || new Element;
9131
9132       assert.strictEqual(_.isElement(element), true);
9133       assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
9134       assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
9135       assert.strictEqual(_.isElement({ 'nodeType': true }), false);
9136       assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
9137       assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
9138       assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
9139     });
9140
9141     QUnit.test('should return `false` for non DOM elements', function(assert) {
9142       assert.expect(13);
9143
9144       var expected = lodashStable.map(falsey, stubFalse);
9145
9146       var actual = lodashStable.map(falsey, function(value, index) {
9147         return index ? _.isElement(value) : _.isElement();
9148       });
9149
9150       assert.deepEqual(actual, expected);
9151
9152       assert.strictEqual(_.isElement(args), false);
9153       assert.strictEqual(_.isElement([1, 2, 3]), false);
9154       assert.strictEqual(_.isElement(true), false);
9155       assert.strictEqual(_.isElement(new Date), false);
9156       assert.strictEqual(_.isElement(new Error), false);
9157       assert.strictEqual(_.isElement(_), false);
9158       assert.strictEqual(_.isElement(slice), false);
9159       assert.strictEqual(_.isElement({ 'a': 1 }), false);
9160       assert.strictEqual(_.isElement(1), false);
9161       assert.strictEqual(_.isElement(/x/), false);
9162       assert.strictEqual(_.isElement('a'), false);
9163       assert.strictEqual(_.isElement(symbol), false);
9164     });
9165
9166     QUnit.test('should work with a DOM element from another realm', function(assert) {
9167       assert.expect(1);
9168
9169       if (realm.element) {
9170         assert.strictEqual(_.isElement(realm.element), true);
9171       }
9172       else {
9173         skipAssert(assert);
9174       }
9175     });
9176   }(1, 2, 3));
9177
9178   /*--------------------------------------------------------------------------*/
9179
9180   QUnit.module('lodash.isEmpty');
9181
9182   (function() {
9183     var args = arguments;
9184
9185     QUnit.test('should return `true` for empty values', function(assert) {
9186       assert.expect(10);
9187
9188       var expected = lodashStable.map(empties, stubTrue),
9189           actual = lodashStable.map(empties, _.isEmpty);
9190
9191       assert.deepEqual(actual, expected);
9192
9193       assert.strictEqual(_.isEmpty(true), true);
9194       assert.strictEqual(_.isEmpty(slice), true);
9195       assert.strictEqual(_.isEmpty(1), true);
9196       assert.strictEqual(_.isEmpty(NaN), true);
9197       assert.strictEqual(_.isEmpty(/x/), true);
9198       assert.strictEqual(_.isEmpty(symbol), true);
9199       assert.strictEqual(_.isEmpty(), true);
9200
9201       if (Buffer) {
9202         assert.strictEqual(_.isEmpty(new Buffer(0)), true);
9203         assert.strictEqual(_.isEmpty(new Buffer(1)), false);
9204       }
9205       else {
9206         skipAssert(assert, 2);
9207       }
9208     });
9209
9210     QUnit.test('should return `false` for non-empty values', function(assert) {
9211       assert.expect(3);
9212
9213       assert.strictEqual(_.isEmpty([0]), false);
9214       assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
9215       assert.strictEqual(_.isEmpty('a'), false);
9216     });
9217
9218     QUnit.test('should work with an object that has a `length` property', function(assert) {
9219       assert.expect(1);
9220
9221       assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
9222     });
9223
9224     QUnit.test('should work with `arguments` objects', function(assert) {
9225       assert.expect(1);
9226
9227       assert.strictEqual(_.isEmpty(args), false);
9228     });
9229
9230     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
9231       assert.expect(1);
9232
9233       function Foo(elements) {
9234         push.apply(this, elements);
9235       }
9236       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
9237
9238       assert.strictEqual(_.isEmpty(new Foo([])), true);
9239     });
9240
9241     QUnit.test('should work with maps', function(assert) {
9242       assert.expect(4);
9243
9244       if (Map) {
9245         lodashStable.each([new Map, realm.map], function(map) {
9246           assert.strictEqual(_.isEmpty(map), true);
9247           map.set('a', 1);
9248           assert.strictEqual(_.isEmpty(map), false);
9249           map.clear();
9250         });
9251       }
9252       else {
9253         skipAssert(assert, 4);
9254       }
9255     });
9256
9257     QUnit.test('should work with sets', function(assert) {
9258       assert.expect(4);
9259
9260       if (Set) {
9261         lodashStable.each([new Set, realm.set], function(set) {
9262           assert.strictEqual(_.isEmpty(set), true);
9263           set.add(1);
9264           assert.strictEqual(_.isEmpty(set), false);
9265           set.clear();
9266         });
9267       }
9268       else {
9269         skipAssert(assert, 4);
9270       }
9271     });
9272
9273     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
9274       assert.expect(1);
9275
9276       function Foo() {}
9277       Foo.prototype.length = -1;
9278
9279       assert.strictEqual(_.isEmpty(new Foo), true);
9280     });
9281
9282     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
9283       assert.expect(1);
9284
9285       function Foo() {}
9286       Foo.prototype.length = MAX_SAFE_INTEGER + 1;
9287
9288       assert.strictEqual(_.isEmpty(new Foo), true);
9289     });
9290
9291     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
9292       assert.expect(1);
9293
9294       assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
9295     });
9296
9297     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9298       assert.expect(1);
9299
9300       if (!isNpm) {
9301         assert.strictEqual(_({}).isEmpty(), true);
9302       }
9303       else {
9304         skipAssert(assert);
9305       }
9306     });
9307
9308     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9309       assert.expect(1);
9310
9311       if (!isNpm) {
9312         assert.ok(_({}).chain().isEmpty() instanceof _);
9313       }
9314       else {
9315         skipAssert(assert);
9316       }
9317     });
9318   }(1, 2, 3));
9319
9320   /*--------------------------------------------------------------------------*/
9321
9322   QUnit.module('lodash.isEqual');
9323
9324   (function() {
9325     var symbol1 = Symbol ? Symbol('a') : true,
9326         symbol2 = Symbol ? Symbol('b') : false;
9327
9328     QUnit.test('should compare primitives', function(assert) {
9329       assert.expect(1);
9330
9331       var pairs = [
9332         [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
9333         [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
9334         [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
9335         ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
9336         [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
9337         [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
9338         [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
9339         [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
9340         [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
9341       ];
9342
9343       var expected = lodashStable.map(pairs, function(pair) {
9344         return pair[2];
9345       });
9346
9347       var actual = lodashStable.map(pairs, function(pair) {
9348         return _.isEqual(pair[0], pair[1]);
9349       });
9350
9351       assert.deepEqual(actual, expected);
9352     });
9353
9354     QUnit.test('should compare arrays', function(assert) {
9355       assert.expect(6);
9356
9357       var array1 = [true, null, 1, 'a', undefined],
9358           array2 = [true, null, 1, 'a', undefined];
9359
9360       assert.strictEqual(_.isEqual(array1, array2), true);
9361
9362       array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9363       array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9364
9365       assert.strictEqual(_.isEqual(array1, array2), true);
9366
9367       array1 = [1];
9368       array1[2] = 3;
9369
9370       array2 = [1];
9371       array2[1] = undefined;
9372       array2[2] = 3;
9373
9374       assert.strictEqual(_.isEqual(array1, array2), true);
9375
9376       array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
9377       array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
9378
9379       assert.strictEqual(_.isEqual(array1, array2), true);
9380
9381       array1 = [1, 2, 3];
9382       array2 = [3, 2, 1];
9383
9384       assert.strictEqual(_.isEqual(array1, array2), false);
9385
9386       array1 = [1, 2];
9387       array2 = [1, 2, 3];
9388
9389       assert.strictEqual(_.isEqual(array1, array2), false);
9390     });
9391
9392     QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
9393       assert.expect(3);
9394
9395       var array1 = [1, 2, 3],
9396           array2 = [1, 2, 3];
9397
9398       array1.every = array1.filter = array1.forEach =
9399       array1.indexOf = array1.lastIndexOf = array1.map =
9400       array1.some = array1.reduce = array1.reduceRight = null;
9401
9402       array2.concat = array2.join = array2.pop =
9403       array2.reverse = array2.shift = array2.slice =
9404       array2.sort = array2.splice = array2.unshift = null;
9405
9406       assert.strictEqual(_.isEqual(array1, array2), true);
9407
9408       array1 = [1, 2, 3];
9409       array1.a = 1;
9410
9411       array2 = [1, 2, 3];
9412       array2.b = 1;
9413
9414       assert.strictEqual(_.isEqual(array1, array2), true);
9415
9416       array1 = /c/.exec('abcde');
9417       array2 = ['c'];
9418
9419       assert.strictEqual(_.isEqual(array1, array2), true);
9420     });
9421
9422     QUnit.test('should compare sparse arrays', function(assert) {
9423       assert.expect(3);
9424
9425       var array = Array(1);
9426
9427       assert.strictEqual(_.isEqual(array, Array(1)), true);
9428       assert.strictEqual(_.isEqual(array, [undefined]), true);
9429       assert.strictEqual(_.isEqual(array, Array(2)), false);
9430     });
9431
9432     QUnit.test('should compare plain objects', function(assert) {
9433       assert.expect(5);
9434
9435       var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
9436           object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
9437
9438       assert.strictEqual(_.isEqual(object1, object2), true);
9439
9440       object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9441       object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9442
9443       assert.strictEqual(_.isEqual(object1, object2), true);
9444
9445       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9446       object2 = { 'a': 3, 'b': 2, 'c': 1 };
9447
9448       assert.strictEqual(_.isEqual(object1, object2), false);
9449
9450       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9451       object2 = { 'd': 1, 'e': 2, 'f': 3 };
9452
9453       assert.strictEqual(_.isEqual(object1, object2), false);
9454
9455       object1 = { 'a': 1, 'b': 2 };
9456       object2 = { 'a': 1, 'b': 2, 'c': 3 };
9457
9458       assert.strictEqual(_.isEqual(object1, object2), false);
9459     });
9460
9461     QUnit.test('should compare objects regardless of key order', function(assert) {
9462       assert.expect(1);
9463
9464       var object1 = { 'a': 1, 'b': 2, 'c': 3 },
9465           object2 = { 'c': 3, 'a': 1, 'b': 2 };
9466
9467       assert.strictEqual(_.isEqual(object1, object2), true);
9468     });
9469
9470     QUnit.test('should compare nested objects', function(assert) {
9471       assert.expect(1);
9472
9473       var object1 = {
9474         'a': [1, 2, 3],
9475         'b': true,
9476         'c': Object(1),
9477         'd': 'a',
9478         'e': {
9479           'f': ['a', Object('b'), 'c'],
9480           'g': Object(false),
9481           'h': new Date(2012, 4, 23),
9482           'i': noop,
9483           'j': 'a'
9484         }
9485       };
9486
9487       var object2 = {
9488         'a': [1, Object(2), 3],
9489         'b': Object(true),
9490         'c': 1,
9491         'd': Object('a'),
9492         'e': {
9493           'f': ['a', 'b', 'c'],
9494           'g': false,
9495           'h': new Date(2012, 4, 23),
9496           'i': noop,
9497           'j': 'a'
9498         }
9499       };
9500
9501       assert.strictEqual(_.isEqual(object1, object2), true);
9502     });
9503
9504     QUnit.test('should compare object instances', function(assert) {
9505       assert.expect(4);
9506
9507       function Foo() {
9508         this.a = 1;
9509       }
9510       Foo.prototype.a = 1;
9511
9512       function Bar() {
9513         this.a = 1;
9514       }
9515       Bar.prototype.a = 2;
9516
9517       assert.strictEqual(_.isEqual(new Foo, new Foo), true);
9518       assert.strictEqual(_.isEqual(new Foo, new Bar), false);
9519       assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
9520       assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
9521     });
9522
9523     QUnit.test('should compare objects with constructor properties', function(assert) {
9524       assert.expect(5);
9525
9526       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
9527       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
9528       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
9529       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
9530       assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
9531     });
9532
9533     QUnit.test('should compare arrays with circular references', function(assert) {
9534       assert.expect(4);
9535
9536       var array1 = [],
9537           array2 = [];
9538
9539       array1.push(array1);
9540       array2.push(array2);
9541
9542       assert.strictEqual(_.isEqual(array1, array2), true);
9543
9544       array1.push('b');
9545       array2.push('b');
9546
9547       assert.strictEqual(_.isEqual(array1, array2), true);
9548
9549       array1.push('c');
9550       array2.push('d');
9551
9552       assert.strictEqual(_.isEqual(array1, array2), false);
9553
9554       array1 = ['a', 'b', 'c'];
9555       array1[1] = array1;
9556       array2 = ['a', ['a', 'b', 'c'], 'c'];
9557
9558       assert.strictEqual(_.isEqual(array1, array2), false);
9559     });
9560
9561     QUnit.test('should compare objects with circular references', function(assert) {
9562       assert.expect(4);
9563
9564       var object1 = {},
9565           object2 = {};
9566
9567       object1.a = object1;
9568       object2.a = object2;
9569
9570       assert.strictEqual(_.isEqual(object1, object2), true);
9571
9572       object1.b = 0;
9573       object2.b = Object(0);
9574
9575       assert.strictEqual(_.isEqual(object1, object2), true);
9576
9577       object1.c = Object(1);
9578       object2.c = Object(2);
9579
9580       assert.strictEqual(_.isEqual(object1, object2), false);
9581
9582       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9583       object1.b = object1;
9584       object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
9585
9586       assert.strictEqual(_.isEqual(object1, object2), false);
9587     });
9588
9589     QUnit.test('should compare objects with multiple circular references', function(assert) {
9590       assert.expect(3);
9591
9592       var array1 = [{}],
9593           array2 = [{}];
9594
9595       (array1[0].a = array1).push(array1);
9596       (array2[0].a = array2).push(array2);
9597
9598       assert.strictEqual(_.isEqual(array1, array2), true);
9599
9600       array1[0].b = 0;
9601       array2[0].b = Object(0);
9602
9603       assert.strictEqual(_.isEqual(array1, array2), true);
9604
9605       array1[0].c = Object(1);
9606       array2[0].c = Object(2);
9607
9608       assert.strictEqual(_.isEqual(array1, array2), false);
9609     });
9610
9611     QUnit.test('should compare objects with complex circular references', function(assert) {
9612       assert.expect(1);
9613
9614       var object1 = {
9615         'foo': { 'b': { 'c': { 'd': {} } } },
9616         'bar': { 'a': 2 }
9617       };
9618
9619       var object2 = {
9620         'foo': { 'b': { 'c': { 'd': {} } } },
9621         'bar': { 'a': 2 }
9622       };
9623
9624       object1.foo.b.c.d = object1;
9625       object1.bar.b = object1.foo.b;
9626
9627       object2.foo.b.c.d = object2;
9628       object2.bar.b = object2.foo.b;
9629
9630       assert.strictEqual(_.isEqual(object1, object2), true);
9631     });
9632
9633     QUnit.test('should compare objects with shared property values', function(assert) {
9634       assert.expect(1);
9635
9636       var object1 = {
9637         'a': [1, 2]
9638       };
9639
9640       var object2 = {
9641         'a': [1, 2],
9642         'b': [1, 2]
9643       };
9644
9645       object1.b = object1.a;
9646
9647       assert.strictEqual(_.isEqual(object1, object2), true);
9648     });
9649
9650     QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
9651       assert.expect(2);
9652
9653       function Foo() {
9654         this.a = 1;
9655       }
9656       Foo.prototype.constructor = null;
9657
9658       var object2 = { 'a': 1 };
9659       assert.strictEqual(_.isEqual(new Foo, object2), false);
9660
9661       if (create)  {
9662         var object1 = create(null);
9663         object1.a = 1;
9664         assert.strictEqual(_.isEqual(object1, object2), true);
9665       }
9666       else {
9667         skipAssert(assert);
9668       }
9669     });
9670
9671     QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
9672       assert.expect(1);
9673
9674       var primitive,
9675           object = { 'toString': function() { return primitive; } },
9676           values = [true, null, 1, 'a', undefined],
9677           expected = lodashStable.map(values, stubFalse);
9678
9679       var actual = lodashStable.map(values, function(value) {
9680         primitive = value;
9681         return _.isEqual(object, value);
9682       });
9683
9684       assert.deepEqual(actual, expected);
9685     });
9686
9687     QUnit.test('should avoid common type coercions', function(assert) {
9688       assert.expect(9);
9689
9690       assert.strictEqual(_.isEqual(true, Object(false)), false);
9691       assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
9692       assert.strictEqual(_.isEqual(false, Object('')), false);
9693       assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
9694       assert.strictEqual(_.isEqual(0, ''), false);
9695       assert.strictEqual(_.isEqual(1, true), false);
9696       assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
9697       assert.strictEqual(_.isEqual('36', 36), false);
9698       assert.strictEqual(_.isEqual(36, '36'), false);
9699     });
9700
9701     QUnit.test('should compare `arguments` objects', function(assert) {
9702       assert.expect(2);
9703
9704       var args1 = (function() { return arguments; }(1, 2, 3)),
9705           args2 = (function() { return arguments; }(1, 2, 3)),
9706           args3 = (function() { return arguments; }(1, 2));
9707
9708       assert.strictEqual(_.isEqual(args1, args2), true);
9709       assert.strictEqual(_.isEqual(args1, args3), false);
9710     });
9711
9712     QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
9713       assert.expect(4);
9714
9715       var args = (function() { return arguments; }(1, 2, 3)),
9716           object = { '0': 1, '1': 2, '2': 3 };
9717
9718       function Foo() {}
9719       Foo.prototype = object;
9720
9721       assert.strictEqual(_.isEqual(args, object), true);
9722       assert.strictEqual(_.isEqual(object, args), true);
9723
9724       assert.strictEqual(_.isEqual(args, new Foo), false);
9725       assert.strictEqual(_.isEqual(new Foo, args), false);
9726     });
9727
9728     QUnit.test('should compare array buffers', function(assert) {
9729       assert.expect(2);
9730
9731       if (ArrayBuffer) {
9732         var buffer1 = new ArrayBuffer(4),
9733             buffer2 = new ArrayBuffer(8);
9734
9735         assert.strictEqual(_.isEqual(buffer1, buffer2), false);
9736
9737         buffer1 = new Int8Array([-1]).buffer;
9738         buffer2 = new Uint8Array([255]).buffer;
9739
9740         assert.strictEqual(_.isEqual(buffer1, buffer2), true);
9741       }
9742       else {
9743         skipAssert(assert, 2);
9744       }
9745     });
9746
9747     QUnit.test('should compare array views', function(assert) {
9748       assert.expect(2);
9749
9750       lodashStable.times(2, function(index) {
9751         var ns = index ? realm : root;
9752
9753         var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
9754           var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
9755               CtorA = ns[type] || function(n) { this.n = n; },
9756               CtorB = ns[otherType] || function(n) { this.n = n; },
9757               bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
9758               bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
9759               bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
9760
9761           return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
9762         });
9763
9764         var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9765
9766         var actual = lodashStable.map(pairs, function(pair) {
9767           return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9768         });
9769
9770         assert.deepEqual(actual, expected);
9771       });
9772     });
9773
9774     QUnit.test('should compare date objects', function(assert) {
9775       assert.expect(4);
9776
9777       var date = new Date(2012, 4, 23);
9778
9779       assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
9780       assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
9781       assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
9782       assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
9783     });
9784
9785     QUnit.test('should compare error objects', function(assert) {
9786       assert.expect(1);
9787
9788       var pairs = lodashStable.map([
9789         'Error',
9790         'EvalError',
9791         'RangeError',
9792         'ReferenceError',
9793         'SyntaxError',
9794         'TypeError',
9795         'URIError'
9796       ], function(type, index, errorTypes) {
9797         var otherType = errorTypes[++index % errorTypes.length],
9798             CtorA = root[type],
9799             CtorB = root[otherType];
9800
9801         return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
9802       });
9803
9804       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9805
9806       var actual = lodashStable.map(pairs, function(pair) {
9807         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9808       });
9809
9810       assert.deepEqual(actual, expected);
9811     });
9812
9813     QUnit.test('should compare functions', function(assert) {
9814       assert.expect(2);
9815
9816       function a() { return 1 + 2; }
9817       function b() { return 1 + 2; }
9818
9819       assert.strictEqual(_.isEqual(a, a), true);
9820       assert.strictEqual(_.isEqual(a, b), false);
9821     });
9822
9823     QUnit.test('should compare maps', function(assert) {
9824       assert.expect(8);
9825
9826       if (Map) {
9827         lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
9828           var map1 = maps[0],
9829               map2 = maps[1];
9830
9831           map1.set('a', 1);
9832           map2.set('b', 2);
9833           assert.strictEqual(_.isEqual(map1, map2), false);
9834
9835           map1.set('b', 2);
9836           map2.set('a', 1);
9837           assert.strictEqual(_.isEqual(map1, map2), true);
9838
9839           map1['delete']('a');
9840           map1.set('a', 1);
9841           assert.strictEqual(_.isEqual(map1, map2), true);
9842
9843           map2['delete']('a');
9844           assert.strictEqual(_.isEqual(map1, map2), false);
9845
9846           map1.clear();
9847           map2.clear();
9848         });
9849       }
9850       else {
9851         skipAssert(assert, 8);
9852       }
9853     });
9854
9855     QUnit.test('should compare maps with circular references', function(assert) {
9856       assert.expect(2);
9857
9858       if (Map) {
9859         var map1 = new Map,
9860             map2 = new Map;
9861
9862         map1.set('a', map1);
9863         map2.set('a', map2);
9864         assert.strictEqual(_.isEqual(map1, map2), true);
9865
9866         map1.set('b', 1);
9867         map2.set('b', 2);
9868         assert.strictEqual(_.isEqual(map1, map2), false);
9869       }
9870       else {
9871         skipAssert(assert, 2);
9872       }
9873     });
9874
9875     QUnit.test('should compare promises by reference', function(assert) {
9876       assert.expect(4);
9877
9878       if (promise) {
9879         lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
9880           var promise1 = promises[0],
9881               promise2 = promises[1];
9882
9883           assert.strictEqual(_.isEqual(promise1, promise2), false);
9884           assert.strictEqual(_.isEqual(promise1, promise1), true);
9885         });
9886       }
9887       else {
9888         skipAssert(assert, 4);
9889       }
9890     });
9891
9892     QUnit.test('should compare regexes', function(assert) {
9893       assert.expect(5);
9894
9895       assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
9896       assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
9897       assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
9898       assert.strictEqual(_.isEqual(/x/, /y/), false);
9899       assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
9900     });
9901
9902     QUnit.test('should compare sets', function(assert) {
9903       assert.expect(8);
9904
9905       if (Set) {
9906         lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
9907           var set1 = sets[0],
9908               set2 = sets[1];
9909
9910           set1.add(1);
9911           set2.add(2);
9912           assert.strictEqual(_.isEqual(set1, set2), false);
9913
9914           set1.add(2);
9915           set2.add(1);
9916           assert.strictEqual(_.isEqual(set1, set2), true);
9917
9918           set1['delete'](1);
9919           set1.add(1);
9920           assert.strictEqual(_.isEqual(set1, set2), true);
9921
9922           set2['delete'](1);
9923           assert.strictEqual(_.isEqual(set1, set2), false);
9924
9925           set1.clear();
9926           set2.clear();
9927         });
9928       }
9929       else {
9930         skipAssert(assert, 8);
9931       }
9932     });
9933
9934     QUnit.test('should compare sets with circular references', function(assert) {
9935       assert.expect(2);
9936
9937       if (Set) {
9938         var set1 = new Set,
9939             set2 = new Set;
9940
9941         set1.add(set1);
9942         set2.add(set2);
9943         assert.strictEqual(_.isEqual(set1, set2), true);
9944
9945         set1.add(1);
9946         set2.add(2);
9947         assert.strictEqual(_.isEqual(set1, set2), false);
9948       }
9949       else {
9950         skipAssert(assert, 2);
9951       }
9952     });
9953
9954     QUnit.test('should work as an iteratee for `_.every`', function(assert) {
9955       assert.expect(1);
9956
9957       var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
9958       assert.ok(actual);
9959     });
9960
9961     QUnit.test('should return `true` for like-objects from different documents', function(assert) {
9962       assert.expect(4);
9963
9964       if (realm.object) {
9965         assert.strictEqual(_.isEqual([1], realm.array), true);
9966         assert.strictEqual(_.isEqual([2], realm.array), false);
9967         assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
9968         assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
9969       }
9970       else {
9971         skipAssert(assert, 4);
9972       }
9973     });
9974
9975     QUnit.test('should not error on DOM elements', function(assert) {
9976       assert.expect(1);
9977
9978       if (document) {
9979         var element1 = document.createElement('div'),
9980             element2 = element1.cloneNode(true);
9981
9982         try {
9983           assert.strictEqual(_.isEqual(element1, element2), false);
9984         } catch (e) {
9985           assert.ok(false, e.message);
9986         }
9987       }
9988       else {
9989         skipAssert(assert);
9990       }
9991     });
9992
9993     QUnit.test('should compare wrapped values', function(assert) {
9994       assert.expect(32);
9995
9996       var stamp = +new Date;
9997
9998       var values = [
9999         [[1, 2], [1, 2], [1, 2, 3]],
10000         [true, true, false],
10001         [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
10002         [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
10003         [1, 1, 2],
10004         [NaN, NaN, Infinity],
10005         [/x/, /x/, /x/i],
10006         ['a', 'a', 'A']
10007       ];
10008
10009       lodashStable.each(values, function(vals) {
10010         if (!isNpm) {
10011           var wrapped1 = _(vals[0]),
10012               wrapped2 = _(vals[1]),
10013               actual = wrapped1.isEqual(wrapped2);
10014
10015           assert.strictEqual(actual, true);
10016           assert.strictEqual(_.isEqual(_(actual), _(true)), true);
10017
10018           wrapped1 = _(vals[0]);
10019           wrapped2 = _(vals[2]);
10020
10021           actual = wrapped1.isEqual(wrapped2);
10022           assert.strictEqual(actual, false);
10023           assert.strictEqual(_.isEqual(_(actual), _(false)), true);
10024         }
10025         else {
10026           skipAssert(assert, 4);
10027         }
10028       });
10029     });
10030
10031     QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
10032       assert.expect(4);
10033
10034       if (!isNpm) {
10035         var object1 = _({ 'a': 1, 'b': 2 }),
10036             object2 = { 'a': 1, 'b': 2 };
10037
10038         assert.strictEqual(object1.isEqual(object2), true);
10039         assert.strictEqual(_.isEqual(object1, object2), true);
10040
10041         object1 = _({ 'a': 1, 'b': 2 });
10042         object2 = { 'a': 1, 'b': 1 };
10043
10044         assert.strictEqual(object1.isEqual(object2), false);
10045         assert.strictEqual(_.isEqual(object1, object2), false);
10046       }
10047       else {
10048         skipAssert(assert, 4);
10049       }
10050     });
10051
10052     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
10053       assert.expect(1);
10054
10055       if (!isNpm) {
10056         assert.strictEqual(_('a').isEqual('a'), true);
10057       }
10058       else {
10059         skipAssert(assert);
10060       }
10061     });
10062
10063     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
10064       assert.expect(1);
10065
10066       if (!isNpm) {
10067         assert.ok(_('a').chain().isEqual('a') instanceof _);
10068       }
10069       else {
10070         skipAssert(assert);
10071       }
10072     });
10073   }());
10074
10075   /*--------------------------------------------------------------------------*/
10076
10077   QUnit.module('lodash.isEqualWith');
10078
10079   (function() {
10080     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
10081       assert.expect(1);
10082
10083       var argsList = [],
10084           object1 = { 'a': [1, 2], 'b': null },
10085           object2 = { 'a': [1, 2], 'b': null };
10086
10087       object1.b = object2;
10088       object2.b = object1;
10089
10090       var expected = [
10091         [object1, object2],
10092         [object1.a, object2.a, 'a', object1, object2],
10093         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10094         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10095         [object1.b, object2.b, 'b', object1.b, object2.b],
10096         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10097         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10098         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10099         [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
10100       ];
10101
10102       _.isEqualWith(object1, object2, function(assert) {
10103         var length = arguments.length,
10104             args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10105
10106         argsList.push(args);
10107       });
10108
10109       assert.deepEqual(argsList, expected);
10110     });
10111
10112     QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10113       assert.expect(3);
10114
10115       assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
10116       assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
10117       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
10118     });
10119
10120     QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10121       assert.expect(3);
10122
10123       var customizer = function(value) {
10124         return _.isString(value) || undefined;
10125       };
10126
10127       assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
10128       assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
10129       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10130     });
10131
10132     QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10133       assert.expect(3);
10134
10135       var customizer = function(value) {
10136         return _.isString(value) ? false : undefined;
10137       };
10138
10139       assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
10140       assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
10141       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10142     });
10143
10144     QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10145       assert.expect(2);
10146
10147       var actual = _.isEqualWith('a', 'b', stubC);
10148       assert.strictEqual(actual, true);
10149
10150       var values = _.without(falsey, undefined),
10151           expected = lodashStable.map(values, stubFalse);
10152
10153       actual = [];
10154       lodashStable.each(values, function(value) {
10155         actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
10156       });
10157
10158       assert.deepEqual(actual, expected);
10159     });
10160
10161     QUnit.test('should ensure `customizer` is a function', function(assert) {
10162       assert.expect(1);
10163
10164       var array = [1, 2, 3],
10165           eq = _.partial(_.isEqualWith, array),
10166           actual = lodashStable.map([array, [1, 0, 3]], eq);
10167
10168       assert.deepEqual(actual, [true, false]);
10169     });
10170
10171     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10172       assert.expect(2);
10173
10174       var value = { 'a': { 'b': 2 } };
10175
10176       if (Map) {
10177         var map1 = new Map;
10178         map1.set('a', value);
10179
10180         var map2 = new Map;
10181         map2.set('a', value);
10182       }
10183       if (Set) {
10184         var set1 = new Set;
10185         set1.add(value);
10186
10187         var set2 = new Set;
10188         set2.add(value);
10189       }
10190       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10191         if (pair[0]) {
10192           var argsList = [],
10193               array = lodashStable.toArray(pair[0]);
10194
10195           var expected = [
10196             [pair[0], pair[1]],
10197             [array[0], array[0], 0, array, array],
10198             [array[0][0], array[0][0], 0, array[0], array[0]],
10199             [array[0][1], array[0][1], 1, array[0], array[0]]
10200           ];
10201
10202           if (index) {
10203             expected.length = 2;
10204           }
10205           _.isEqualWith(pair[0], pair[1], function() {
10206             var length = arguments.length,
10207                 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10208
10209             argsList.push(args);
10210           });
10211
10212           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10213         }
10214         else {
10215           skipAssert(assert);
10216         }
10217       });
10218     });
10219   }());
10220
10221   /*--------------------------------------------------------------------------*/
10222
10223   QUnit.module('lodash.isError');
10224
10225   (function() {
10226     var args = arguments;
10227
10228     QUnit.test('should return `true` for error objects', function(assert) {
10229       assert.expect(1);
10230
10231       var expected = lodashStable.map(errors, stubTrue);
10232
10233       var actual = lodashStable.map(errors, function(error) {
10234         return _.isError(error) === true;
10235       });
10236
10237       assert.deepEqual(actual, expected);
10238     });
10239
10240     QUnit.test('should return `true` for subclassed values', function(assert) {
10241       assert.expect(1);
10242
10243       assert.strictEqual(_.isError(new CustomError('x')), true);
10244     });
10245
10246     QUnit.test('should return `false` for non error objects', function(assert) {
10247       assert.expect(12);
10248
10249       var expected = lodashStable.map(falsey, stubFalse);
10250
10251       var actual = lodashStable.map(falsey, function(value, index) {
10252         return index ? _.isError(value) : _.isError();
10253       });
10254
10255       assert.deepEqual(actual, expected);
10256
10257       assert.strictEqual(_.isError(args), false);
10258       assert.strictEqual(_.isError([1, 2, 3]), false);
10259       assert.strictEqual(_.isError(true), false);
10260       assert.strictEqual(_.isError(new Date), false);
10261       assert.strictEqual(_.isError(_), false);
10262       assert.strictEqual(_.isError(slice), false);
10263       assert.strictEqual(_.isError({ 'a': 1 }), false);
10264       assert.strictEqual(_.isError(1), false);
10265       assert.strictEqual(_.isError(/x/), false);
10266       assert.strictEqual(_.isError('a'), false);
10267       assert.strictEqual(_.isError(symbol), false);
10268     });
10269
10270     QUnit.test('should work with an error object from another realm', function(assert) {
10271       assert.expect(1);
10272
10273       if (realm.errors) {
10274         var expected = lodashStable.map(realm.errors, stubTrue);
10275
10276         var actual = lodashStable.map(realm.errors, function(error) {
10277           return _.isError(error) === true;
10278         });
10279
10280         assert.deepEqual(actual, expected);
10281       }
10282       else {
10283         skipAssert(assert);
10284       }
10285     });
10286   }(1, 2, 3));
10287
10288   /*--------------------------------------------------------------------------*/
10289
10290   QUnit.module('lodash.isFinite');
10291
10292   (function() {
10293     var args = arguments;
10294
10295     QUnit.test('should return `true` for finite values', function(assert) {
10296       assert.expect(1);
10297
10298       var values = [0, 1, 3.14, -1],
10299           expected = lodashStable.map(values, stubTrue),
10300           actual = lodashStable.map(values, _.isFinite);
10301
10302       assert.deepEqual(actual, expected);
10303     });
10304
10305     QUnit.test('should return `false` for non-finite values', function(assert) {
10306       assert.expect(1);
10307
10308       var values = [NaN, Infinity, -Infinity, Object(1)],
10309           expected = lodashStable.map(values, stubFalse),
10310           actual = lodashStable.map(values, _.isFinite);
10311
10312       assert.deepEqual(actual, expected);
10313     });
10314
10315     QUnit.test('should return `false` for non-numeric values', function(assert) {
10316       assert.expect(10);
10317
10318       var values = [undefined, [], true, '', ' ', '2px'],
10319           expected = lodashStable.map(values, stubFalse),
10320           actual = lodashStable.map(values, _.isFinite);
10321
10322       assert.deepEqual(actual, expected);
10323
10324       assert.strictEqual(_.isFinite(args), false);
10325       assert.strictEqual(_.isFinite([1, 2, 3]), false);
10326       assert.strictEqual(_.isFinite(true), false);
10327       assert.strictEqual(_.isFinite(new Date), false);
10328       assert.strictEqual(_.isFinite(new Error), false);
10329       assert.strictEqual(_.isFinite({ 'a': 1 }), false);
10330       assert.strictEqual(_.isFinite(/x/), false);
10331       assert.strictEqual(_.isFinite('a'), false);
10332       assert.strictEqual(_.isFinite(symbol), false);
10333     });
10334
10335     QUnit.test('should return `false` for numeric string values', function(assert) {
10336       assert.expect(1);
10337
10338       var values = ['2', '0', '08'],
10339           expected = lodashStable.map(values, stubFalse),
10340           actual = lodashStable.map(values, _.isFinite);
10341
10342       assert.deepEqual(actual, expected);
10343     });
10344   }(1, 2, 3));
10345
10346   /*--------------------------------------------------------------------------*/
10347
10348   QUnit.module('lodash.isFunction');
10349
10350   (function() {
10351     var args = arguments;
10352
10353     QUnit.test('should return `true` for functions', function(assert) {
10354       assert.expect(2);
10355
10356       assert.strictEqual(_.isFunction(_), true);
10357       assert.strictEqual(_.isFunction(slice), true);
10358     });
10359
10360     QUnit.test('should return `true` for generator functions', function(assert) {
10361       assert.expect(1);
10362
10363       assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
10364     });
10365
10366     QUnit.test('should return `true` for array view constructors', function(assert) {
10367       assert.expect(1);
10368
10369       var expected = lodashStable.map(arrayViews, function(type) {
10370         return objToString.call(root[type]) == funcTag;
10371       });
10372
10373       var actual = lodashStable.map(arrayViews, function(type) {
10374         return _.isFunction(root[type]);
10375       });
10376
10377       assert.deepEqual(actual, expected);
10378     });
10379
10380     QUnit.test('should return `false` for non-functions', function(assert) {
10381       assert.expect(12);
10382
10383       var expected = lodashStable.map(falsey, stubFalse);
10384
10385       var actual = lodashStable.map(falsey, function(value, index) {
10386         return index ? _.isFunction(value) : _.isFunction();
10387       });
10388
10389       assert.deepEqual(actual, expected);
10390
10391       assert.strictEqual(_.isFunction(args), false);
10392       assert.strictEqual(_.isFunction([1, 2, 3]), false);
10393       assert.strictEqual(_.isFunction(true), false);
10394       assert.strictEqual(_.isFunction(new Date), false);
10395       assert.strictEqual(_.isFunction(new Error), false);
10396       assert.strictEqual(_.isFunction({ 'a': 1 }), false);
10397       assert.strictEqual(_.isFunction(1), false);
10398       assert.strictEqual(_.isFunction(/x/), false);
10399       assert.strictEqual(_.isFunction('a'), false);
10400       assert.strictEqual(_.isFunction(symbol), false);
10401
10402       if (document) {
10403         assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
10404       } else {
10405         skipAssert(assert);
10406       }
10407     });
10408
10409     QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
10410       assert.expect(2);
10411
10412       // Trigger a Chakra JIT bug.
10413       // See https://github.com/jashkenas/underscore/issues/1621.
10414       lodashStable.each([body, xml], function(object) {
10415         if (object) {
10416           lodashStable.times(100, _.isFunction);
10417           assert.strictEqual(_.isFunction(object), false);
10418         }
10419         else {
10420           skipAssert(assert);
10421         }
10422       });
10423     });
10424
10425     QUnit.test('should work with a function from another realm', function(assert) {
10426       assert.expect(1);
10427
10428       if (realm.function) {
10429         assert.strictEqual(_.isFunction(realm.function), true);
10430       }
10431       else {
10432         skipAssert(assert);
10433       }
10434     });
10435   }(1, 2, 3));
10436
10437   /*--------------------------------------------------------------------------*/
10438
10439   QUnit.module('isInteger methods');
10440
10441   lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
10442     var args = arguments,
10443         func = _[methodName],
10444         isSafe = methodName == 'isSafeInteger';
10445
10446     QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
10447       assert.expect(2);
10448
10449       var values = [-1, 0, 1],
10450           expected = lodashStable.map(values, stubTrue);
10451
10452       var actual = lodashStable.map(values, function(value) {
10453         return func(value);
10454       });
10455
10456       assert.deepEqual(actual, expected);
10457       assert.strictEqual(func(MAX_INTEGER), !isSafe);
10458     });
10459
10460     QUnit.test('should return `false` for non-integer number values', function(assert) {
10461       assert.expect(1);
10462
10463       var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
10464           expected = lodashStable.map(values, stubFalse);
10465
10466       var actual = lodashStable.map(values, function(value) {
10467         return func(value);
10468       });
10469
10470       assert.deepEqual(actual, expected);
10471     });
10472
10473     QUnit.test('should return `false` for non-numeric values', function(assert) {
10474       assert.expect(10);
10475
10476       var expected = lodashStable.map(falsey, function(value) {
10477         return value === 0;
10478       });
10479
10480       var actual = lodashStable.map(falsey, function(value, index) {
10481         return index ? func(value) : func();
10482       });
10483
10484       assert.deepEqual(actual, expected);
10485
10486       assert.strictEqual(func(args), false);
10487       assert.strictEqual(func([1, 2, 3]), false);
10488       assert.strictEqual(func(true), false);
10489       assert.strictEqual(func(new Date), false);
10490       assert.strictEqual(func(new Error), false);
10491       assert.strictEqual(func({ 'a': 1 }), false);
10492       assert.strictEqual(func(/x/), false);
10493       assert.strictEqual(func('a'), false);
10494       assert.strictEqual(func(symbol), false);
10495     });
10496   });
10497
10498   /*--------------------------------------------------------------------------*/
10499
10500   QUnit.module('lodash.isLength');
10501
10502   (function() {
10503     QUnit.test('should return `true` for lengths', function(assert) {
10504       assert.expect(1);
10505
10506       var values = [0, 3, MAX_SAFE_INTEGER],
10507           expected = lodashStable.map(values, stubTrue),
10508           actual = lodashStable.map(values, _.isLength);
10509
10510       assert.deepEqual(actual, expected);
10511     });
10512
10513     QUnit.test('should return `false` for non-lengths', function(assert) {
10514       assert.expect(1);
10515
10516       var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
10517           expected = lodashStable.map(values, stubFalse),
10518           actual = lodashStable.map(values, _.isLength);
10519
10520       assert.deepEqual(actual, expected);
10521     });
10522   }());
10523
10524   /*--------------------------------------------------------------------------*/
10525
10526   QUnit.module('lodash.isMap');
10527
10528   (function() {
10529     var args = arguments;
10530
10531     QUnit.test('should return `true` for maps', function(assert) {
10532       assert.expect(1);
10533
10534       if (Map) {
10535         assert.strictEqual(_.isMap(map), true);
10536       }
10537       else {
10538         skipAssert(assert);
10539       }
10540     });
10541
10542     QUnit.test('should return `false` for non-maps', function(assert) {
10543       assert.expect(14);
10544
10545       var expected = lodashStable.map(falsey, stubFalse);
10546
10547       var actual = lodashStable.map(falsey, function(value, index) {
10548         return index ? _.isMap(value) : _.isMap();
10549       });
10550
10551       assert.deepEqual(actual, expected);
10552
10553       assert.strictEqual(_.isMap(args), false);
10554       assert.strictEqual(_.isMap([1, 2, 3]), false);
10555       assert.strictEqual(_.isMap(true), false);
10556       assert.strictEqual(_.isMap(new Date), false);
10557       assert.strictEqual(_.isMap(new Error), false);
10558       assert.strictEqual(_.isMap(_), false);
10559       assert.strictEqual(_.isMap(slice), false);
10560       assert.strictEqual(_.isMap({ 'a': 1 }), false);
10561       assert.strictEqual(_.isMap(1), false);
10562       assert.strictEqual(_.isMap(/x/), false);
10563       assert.strictEqual(_.isMap('a'), false);
10564       assert.strictEqual(_.isMap(symbol), false);
10565       assert.strictEqual(_.isMap(weakMap), false);
10566     });
10567
10568     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
10569       assert.expect(1);
10570
10571       var values = [false, true],
10572           expected = lodashStable.map(values, stubFalse);
10573
10574       var actual = lodashStable.map(values, function(value) {
10575         return _.isMap({ 'constructor': value });
10576       });
10577
10578       assert.deepEqual(actual, expected);
10579     });
10580
10581     QUnit.test('should work with maps from another realm', function(assert) {
10582       assert.expect(1);
10583
10584       if (realm.map) {
10585         assert.strictEqual(_.isMap(realm.map), true);
10586       }
10587       else {
10588         skipAssert(assert);
10589       }
10590     });
10591   }(1, 2, 3));
10592
10593   /*--------------------------------------------------------------------------*/
10594
10595   QUnit.module('lodash.isMatch');
10596
10597   (function() {
10598     QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
10599       assert.expect(5);
10600
10601       var object = { 'a': 1, 'b': 2, 'c': 3 };
10602       assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
10603       assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
10604       assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
10605       assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
10606
10607       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
10608       assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
10609     });
10610
10611     QUnit.test('should match inherited string keyed `object` properties', function(assert) {
10612       assert.expect(1);
10613
10614       function Foo() {
10615         this.a = 1;
10616       }
10617       Foo.prototype.b = 2;
10618
10619       assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
10620     });
10621
10622     QUnit.test('should not match by inherited `source` properties', function(assert) {
10623       assert.expect(1);
10624
10625       function Foo() {
10626         this.a = 1;
10627       }
10628       Foo.prototype.b = 2;
10629
10630       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
10631           source = new Foo,
10632           expected = lodashStable.map(objects, stubTrue);
10633
10634       var actual = lodashStable.map(objects, function(object) {
10635         return _.isMatch(object, source);
10636       });
10637
10638       assert.deepEqual(actual, expected);
10639     });
10640
10641     QUnit.test('should compare a variety of `source` property values', function(assert) {
10642       assert.expect(2);
10643
10644       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
10645           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
10646
10647       assert.strictEqual(_.isMatch(object1, object1), true);
10648       assert.strictEqual(_.isMatch(object1, object2), false);
10649     });
10650
10651     QUnit.test('should match `-0` as `0`', function(assert) {
10652       assert.expect(2);
10653
10654       var object1 = { 'a': -0 },
10655           object2 = { 'a': 0 };
10656
10657       assert.strictEqual(_.isMatch(object1, object2), true);
10658       assert.strictEqual(_.isMatch(object2, object1), true);
10659     });
10660
10661     QUnit.test('should compare functions by reference', function(assert) {
10662       assert.expect(3);
10663
10664       var object1 = { 'a': lodashStable.noop },
10665           object2 = { 'a': noop },
10666           object3 = { 'a': {} };
10667
10668       assert.strictEqual(_.isMatch(object1, object1), true);
10669       assert.strictEqual(_.isMatch(object2, object1), false);
10670       assert.strictEqual(_.isMatch(object3, object1), false);
10671     });
10672
10673     QUnit.test('should work with a function for `object`', function(assert) {
10674       assert.expect(1);
10675
10676       function Foo() {}
10677       Foo.a = { 'b': 2, 'c': 3 };
10678
10679       assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 2 } }), true);
10680     });
10681
10682     QUnit.test('should work with a function for `source`', function(assert) {
10683       assert.expect(1);
10684
10685       function Foo() {}
10686       Foo.a = 1;
10687       Foo.b = function() {};
10688       Foo.c = 3;
10689
10690       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
10691
10692       var actual = lodashStable.map(objects, function(object) {
10693         return _.isMatch(object, Foo);
10694       });
10695
10696       assert.deepEqual(actual, [false, true]);
10697     });
10698
10699     QUnit.test('should work with a non-plain `object`', function(assert) {
10700       assert.expect(1);
10701
10702       function Foo(object) { lodashStable.assign(this, object); }
10703
10704       var object = new Foo({ 'a': new Foo({ 'b': 2, 'c': 3 }) });
10705       assert.strictEqual(_.isMatch(object, { 'a': { 'b': 2 } }), true);
10706     });
10707
10708     QUnit.test('should partial match arrays', function(assert) {
10709       assert.expect(3);
10710
10711       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
10712           source = { 'a': ['d'] },
10713           predicate = function(object) { return _.isMatch(object, source); },
10714           actual = lodashStable.filter(objects, predicate);
10715
10716       assert.deepEqual(actual, [objects[1]]);
10717
10718       source = { 'a': ['b', 'd'] };
10719       actual = lodashStable.filter(objects, predicate);
10720
10721       assert.deepEqual(actual, []);
10722
10723       source = { 'a': ['d', 'b'] };
10724       actual = lodashStable.filter(objects, predicate);
10725
10726       assert.deepEqual(actual, []);
10727     });
10728
10729     QUnit.test('should partial match arrays with duplicate values', function(assert) {
10730       assert.expect(1);
10731
10732       var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
10733           source = { 'a': [2, 2] };
10734
10735       var actual = lodashStable.filter(objects, function(object) {
10736         return _.isMatch(object, source);
10737       });
10738
10739       assert.deepEqual(actual, [objects[1]]);
10740     });
10741
10742     QUnit.test('should partial match arrays of objects', function(assert) {
10743       assert.expect(1);
10744
10745       var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
10746
10747       var objects = [
10748         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
10749         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
10750       ];
10751
10752       var actual = lodashStable.filter(objects, function(object) {
10753         return _.isMatch(object, source);
10754       });
10755
10756       assert.deepEqual(actual, [objects[0]]);
10757     });
10758
10759     QUnit.test('should partial match maps', function(assert) {
10760       assert.expect(3);
10761
10762       if (Map) {
10763         var objects = [{ 'a': new Map }, { 'a': new Map }];
10764         objects[0].a.set('a', 1);
10765         objects[1].a.set('a', 1);
10766         objects[1].a.set('b', 2);
10767
10768         var map = new Map;
10769         map.set('b', 2);
10770
10771         var source = { 'a': map },
10772             predicate = function(object) { return _.isMatch(object, source); },
10773             actual = lodashStable.filter(objects, predicate);
10774
10775         assert.deepEqual(actual, [objects[1]]);
10776
10777         map['delete']('b');
10778         actual = lodashStable.filter(objects, predicate);
10779
10780         assert.deepEqual(actual, objects);
10781
10782         map.set('c', 3);
10783         actual = lodashStable.filter(objects, predicate);
10784
10785         assert.deepEqual(actual, []);
10786       }
10787       else {
10788         skipAssert(assert, 3);
10789       }
10790     });
10791
10792     QUnit.test('should partial match sets', function(assert) {
10793       assert.expect(3);
10794
10795       if (Set) {
10796         var objects = [{ 'a': new Set }, { 'a': new Set }];
10797         objects[0].a.add(1);
10798         objects[1].a.add(1);
10799         objects[1].a.add(2);
10800
10801         var set = new Set;
10802         set.add(2);
10803
10804         var source = { 'a': set },
10805             predicate = function(object) { return _.isMatch(object, source); },
10806             actual = lodashStable.filter(objects, predicate);
10807
10808         assert.deepEqual(actual, [objects[1]]);
10809
10810         set['delete'](2);
10811         actual = lodashStable.filter(objects, predicate);
10812
10813         assert.deepEqual(actual, objects);
10814
10815         set.add(3);
10816         actual = lodashStable.filter(objects, predicate);
10817
10818         assert.deepEqual(actual, []);
10819       }
10820       else {
10821         skipAssert(assert, 3);
10822       }
10823     });
10824
10825     QUnit.test('should match `undefined` values', function(assert) {
10826       assert.expect(3);
10827
10828       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
10829           source = { 'b': undefined },
10830           predicate = function(object) { return _.isMatch(object, source); },
10831           actual = lodashStable.map(objects, predicate),
10832           expected = [false, false, true];
10833
10834       assert.deepEqual(actual, expected);
10835
10836       source = { 'a': 1, 'b': undefined };
10837       actual = lodashStable.map(objects, predicate);
10838
10839       assert.deepEqual(actual, expected);
10840
10841       objects = [{ 'a': { 'b': 2 } }, { 'a': { 'b': 2, 'c': 3 } }, { 'a': { 'b': 2, 'c': undefined } }];
10842       source = { 'a': { 'c': undefined } };
10843       actual = lodashStable.map(objects, predicate);
10844
10845       assert.deepEqual(actual, expected);
10846     });
10847
10848     QUnit.test('should match `undefined` values on primitives', function(assert) {
10849       assert.expect(3);
10850
10851       numberProto.a = 1;
10852       numberProto.b = undefined;
10853
10854       try {
10855         assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
10856       } catch (e) {
10857         assert.ok(false, e.message);
10858       }
10859       try {
10860         assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
10861       } catch (e) {
10862         assert.ok(false, e.message);
10863       }
10864       numberProto.a = { 'b': 1, 'c': undefined };
10865       try {
10866         assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
10867       } catch (e) {
10868         assert.ok(false, e.message);
10869       }
10870       delete numberProto.a;
10871       delete numberProto.b;
10872     });
10873
10874     QUnit.test('should return `false` when `object` is nullish', function(assert) {
10875       assert.expect(1);
10876
10877       var values = [null, undefined],
10878           expected = lodashStable.map(values, stubFalse),
10879           source = { 'a': 1 };
10880
10881       var actual = lodashStable.map(values, function(value) {
10882         try {
10883           return _.isMatch(value, source);
10884         } catch (e) {}
10885       });
10886
10887       assert.deepEqual(actual, expected);
10888     });
10889
10890     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
10891       assert.expect(1);
10892
10893       var values = [null, undefined],
10894           expected = lodashStable.map(values, stubTrue),
10895           source = {};
10896
10897       var actual = lodashStable.map(values, function(value) {
10898         try {
10899           return _.isMatch(value, source);
10900         } catch (e) {}
10901       });
10902
10903       assert.deepEqual(actual, expected);
10904     });
10905
10906     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
10907       assert.expect(1);
10908
10909       var object = { 'a': 1 },
10910           expected = lodashStable.map(empties, stubTrue);
10911
10912       var actual = lodashStable.map(empties, function(value) {
10913         return _.isMatch(object, value);
10914       });
10915
10916       assert.deepEqual(actual, expected);
10917     });
10918
10919     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
10920       assert.expect(1);
10921
10922       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
10923           source = { 'a': [], 'b': {} };
10924
10925       var actual = lodashStable.filter(objects, function(object) {
10926         return _.isMatch(object, source);
10927       });
10928
10929       assert.deepEqual(actual, objects);
10930     });
10931   }());
10932
10933   /*--------------------------------------------------------------------------*/
10934
10935   QUnit.module('lodash.isMatchWith');
10936
10937   (function() {
10938     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
10939       assert.expect(1);
10940
10941       var argsList = [],
10942           object1 = { 'a': [1, 2], 'b': null },
10943           object2 = { 'a': [1, 2], 'b': null };
10944
10945       object1.b = object2;
10946       object2.b = object1;
10947
10948       var expected = [
10949         [object1.a, object2.a, 'a', object1, object2],
10950         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10951         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10952         [object1.b, object2.b, 'b', object1, object2],
10953         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10954         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10955         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10956         [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
10957         [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
10958         [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
10959         [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
10960         [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
10961       ];
10962
10963       _.isMatchWith(object1, object2, function(assert) {
10964         argsList.push(slice.call(arguments, 0, -1));
10965       });
10966
10967       assert.deepEqual(argsList, expected);
10968     });
10969
10970     QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10971       assert.expect(1);
10972
10973       assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10974     });
10975
10976     QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10977       assert.expect(2);
10978
10979       var customizer = function(value) {
10980         return _.isString(value) || undefined;
10981       };
10982
10983       assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10984       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10985     });
10986
10987     QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10988       assert.expect(2);
10989
10990       var customizer = function(value) {
10991         return _.isString(value) ? false : undefined;
10992       };
10993
10994       assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10995       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10996     });
10997
10998     QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10999       assert.expect(2);
11000
11001       var object = { 'a': 1 },
11002           actual = _.isMatchWith(object, { 'a': 1 }, stubA);
11003
11004       assert.strictEqual(actual, true);
11005
11006       var expected = lodashStable.map(falsey, stubFalse);
11007
11008       actual = [];
11009       lodashStable.each(falsey, function(value) {
11010         actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
11011       });
11012
11013       assert.deepEqual(actual, expected);
11014     });
11015
11016     QUnit.test('should provide `stack` to `customizer`', function(assert) {
11017       assert.expect(1);
11018
11019       var actual;
11020
11021       _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() {
11022         actual = _.last(arguments);
11023       });
11024
11025       assert.ok(isNpm
11026         ? actual.constructor.name == 'Stack'
11027         : actual instanceof mapCaches.Stack
11028       );
11029     });
11030
11031     QUnit.test('should ensure `customizer` is a function', function(assert) {
11032       assert.expect(1);
11033
11034       var object = { 'a': 1 },
11035           matches = _.partial(_.isMatchWith, object),
11036           actual = lodashStable.map([object, { 'a': 2 }], matches);
11037
11038       assert.deepEqual(actual, [true, false]);
11039     });
11040
11041     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
11042       assert.expect(2);
11043
11044       var value = { 'a': { 'b': 2 } };
11045
11046       if (Map) {
11047         var map1 = new Map;
11048         map1.set('a', value);
11049
11050         var map2 = new Map;
11051         map2.set('a', value);
11052       }
11053       if (Set) {
11054         var set1 = new Set;
11055         set1.add(value);
11056
11057         var set2 = new Set;
11058         set2.add(value);
11059       }
11060       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
11061         if (pair[0]) {
11062           var argsList = [],
11063               array = lodashStable.toArray(pair[0]),
11064               object1 = { 'a': pair[0] },
11065               object2 = { 'a': pair[1] };
11066
11067           var expected = [
11068             [pair[0], pair[1], 'a', object1, object2],
11069             [array[0], array[0], 0, array, array],
11070             [array[0][0], array[0][0], 0, array[0], array[0]],
11071             [array[0][1], array[0][1], 1, array[0], array[0]]
11072           ];
11073
11074           if (index) {
11075             expected.length = 2;
11076           }
11077           _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
11078             argsList.push(slice.call(arguments, 0, -1));
11079           });
11080
11081           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
11082         }
11083         else {
11084           skipAssert(assert);
11085         }
11086       });
11087     });
11088   }());
11089
11090   /*--------------------------------------------------------------------------*/
11091
11092   QUnit.module('lodash.isNaN');
11093
11094   (function() {
11095     var args = arguments;
11096
11097     QUnit.test('should return `true` for NaNs', function(assert) {
11098       assert.expect(2);
11099
11100       assert.strictEqual(_.isNaN(NaN), true);
11101       assert.strictEqual(_.isNaN(Object(NaN)), true);
11102     });
11103
11104     QUnit.test('should return `false` for non-NaNs', function(assert) {
11105       assert.expect(14);
11106
11107       var expected = lodashStable.map(falsey, function(value) {
11108         return value !== value;
11109       });
11110
11111       var actual = lodashStable.map(falsey, function(value, index) {
11112         return index ? _.isNaN(value) : _.isNaN();
11113       });
11114
11115       assert.deepEqual(actual, expected);
11116
11117       assert.strictEqual(_.isNaN(args), false);
11118       assert.strictEqual(_.isNaN([1, 2, 3]), false);
11119       assert.strictEqual(_.isNaN(true), false);
11120       assert.strictEqual(_.isNaN(new Date), false);
11121       assert.strictEqual(_.isNaN(new Error), false);
11122       assert.strictEqual(_.isNaN(_), false);
11123       assert.strictEqual(_.isNaN(slice), false);
11124       assert.strictEqual(_.isNaN({ 'a': 1 }), false);
11125       assert.strictEqual(_.isNaN(1), false);
11126       assert.strictEqual(_.isNaN(Object(1)), false);
11127       assert.strictEqual(_.isNaN(/x/), false);
11128       assert.strictEqual(_.isNaN('a'), false);
11129       assert.strictEqual(_.isNaN(symbol), false);
11130     });
11131
11132     QUnit.test('should work with `NaN` from another realm', function(assert) {
11133       assert.expect(1);
11134
11135       if (realm.object) {
11136         assert.strictEqual(_.isNaN(realm.nan), true);
11137       }
11138       else {
11139         skipAssert(assert);
11140       }
11141     });
11142   }(1, 2, 3));
11143
11144   /*--------------------------------------------------------------------------*/
11145
11146   QUnit.module('lodash.isNative');
11147
11148   (function() {
11149     var args = arguments;
11150
11151     QUnit.test('should return `true` for native methods', function(assert) {
11152       assert.expect(1);
11153
11154       var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
11155           expected = lodashStable.map(values, Boolean),
11156           actual = lodashStable.map(values, _.isNative);
11157
11158       assert.deepEqual(actual, expected);
11159     });
11160
11161     QUnit.test('should return `false` for non-native methods', function(assert) {
11162       assert.expect(12);
11163
11164       var expected = lodashStable.map(falsey, stubFalse);
11165
11166       var actual = lodashStable.map(falsey, function(value, index) {
11167         return index ? _.isNative(value) : _.isNative();
11168       });
11169
11170       assert.deepEqual(actual, expected);
11171
11172       assert.strictEqual(_.isNative(args), false);
11173       assert.strictEqual(_.isNative([1, 2, 3]), false);
11174       assert.strictEqual(_.isNative(true), false);
11175       assert.strictEqual(_.isNative(new Date), false);
11176       assert.strictEqual(_.isNative(new Error), false);
11177       assert.strictEqual(_.isNative(_), false);
11178       assert.strictEqual(_.isNative({ 'a': 1 }), false);
11179       assert.strictEqual(_.isNative(1), false);
11180       assert.strictEqual(_.isNative(/x/), false);
11181       assert.strictEqual(_.isNative('a'), false);
11182       assert.strictEqual(_.isNative(symbol), false);
11183     });
11184
11185     QUnit.test('should work with native functions from another realm', function(assert) {
11186       assert.expect(2);
11187
11188       if (realm.element) {
11189         assert.strictEqual(_.isNative(realm.element.cloneNode), true);
11190       }
11191       else {
11192         skipAssert(assert);
11193       }
11194       if (realm.object) {
11195         assert.strictEqual(_.isNative(realm.object.valueOf), true);
11196       }
11197       else {
11198         skipAssert(assert);
11199       }
11200     });
11201
11202     QUnit.test('should throw an error if core-js is detected', function(assert) {
11203       assert.expect(1);
11204
11205       if (!isModularize) {
11206         var lodash = _.runInContext({
11207           '__core-js_shared__': {}
11208         });
11209
11210         assert.raises(function() { lodash.isNative(noop); });
11211       }
11212       else {
11213         skipAssert(assert);
11214       }
11215     });
11216
11217     QUnit.test('should detect methods masquerading as native', function(assert) {
11218       assert.expect(2);
11219
11220       if (_._baseEach) {
11221         var path = require('path'),
11222             basePath = path.dirname(filePath),
11223             uid = 'e0gvgyrad1jor',
11224             coreKey = '__core-js_shared__',
11225             fakeSrcKey = 'Symbol(src)_1.' + uid;
11226
11227         root[coreKey] = { 'keys': { 'IE_PROTO': 'Symbol(IE_PROTO)_3.' + uid } };
11228         emptyObject(require.cache);
11229
11230         var baseIsNative = interopRequire(path.join(basePath, '_baseIsNative'));
11231         assert.strictEqual(baseIsNative(slice), true);
11232
11233         slice[fakeSrcKey] = slice + '';
11234         assert.strictEqual(baseIsNative(slice), false);
11235
11236         delete slice[fakeSrcKey];
11237         delete root[coreKey];
11238       }
11239       else {
11240         skipAssert(assert, 2);
11241       }
11242     });
11243   }(1, 2, 3));
11244
11245   /*--------------------------------------------------------------------------*/
11246
11247   QUnit.module('lodash.isNil');
11248
11249   (function() {
11250     var args = arguments;
11251
11252     QUnit.test('should return `true` for nullish values', function(assert) {
11253       assert.expect(3);
11254
11255       assert.strictEqual(_.isNil(null), true);
11256       assert.strictEqual(_.isNil(), true);
11257       assert.strictEqual(_.isNil(undefined), true);
11258     });
11259
11260     QUnit.test('should return `false` for non-nullish values', function(assert) {
11261       assert.expect(13);
11262
11263       var expected = lodashStable.map(falsey, function(value) {
11264         return value == null;
11265       });
11266
11267       var actual = lodashStable.map(falsey, function(value, index) {
11268         return index ? _.isNil(value) : _.isNil();
11269       });
11270
11271       assert.deepEqual(actual, expected);
11272
11273       assert.strictEqual(_.isNil(args), false);
11274       assert.strictEqual(_.isNil([1, 2, 3]), false);
11275       assert.strictEqual(_.isNil(true), false);
11276       assert.strictEqual(_.isNil(new Date), false);
11277       assert.strictEqual(_.isNil(new Error), false);
11278       assert.strictEqual(_.isNil(_), false);
11279       assert.strictEqual(_.isNil(slice), false);
11280       assert.strictEqual(_.isNil({ 'a': 1 }), false);
11281       assert.strictEqual(_.isNil(1), false);
11282       assert.strictEqual(_.isNil(/x/), false);
11283       assert.strictEqual(_.isNil('a'), false);
11284
11285       if (Symbol) {
11286         assert.strictEqual(_.isNil(symbol), false);
11287       }
11288       else {
11289         skipAssert(assert);
11290       }
11291     });
11292
11293     QUnit.test('should work with nils from another realm', function(assert) {
11294       assert.expect(2);
11295
11296       if (realm.object) {
11297         assert.strictEqual(_.isNil(realm.null), true);
11298         assert.strictEqual(_.isNil(realm.undefined), true);
11299       }
11300       else {
11301         skipAssert(assert, 2);
11302       }
11303     });
11304   }(1, 2, 3));
11305
11306   /*--------------------------------------------------------------------------*/
11307
11308   QUnit.module('lodash.isNull');
11309
11310   (function() {
11311     var args = arguments;
11312
11313     QUnit.test('should return `true` for `null` values', function(assert) {
11314       assert.expect(1);
11315
11316       assert.strictEqual(_.isNull(null), true);
11317     });
11318
11319     QUnit.test('should return `false` for non `null` values', function(assert) {
11320       assert.expect(13);
11321
11322       var expected = lodashStable.map(falsey, function(value) {
11323         return value === null;
11324       });
11325
11326       var actual = lodashStable.map(falsey, function(value, index) {
11327         return index ? _.isNull(value) : _.isNull();
11328       });
11329
11330       assert.deepEqual(actual, expected);
11331
11332       assert.strictEqual(_.isNull(args), false);
11333       assert.strictEqual(_.isNull([1, 2, 3]), false);
11334       assert.strictEqual(_.isNull(true), false);
11335       assert.strictEqual(_.isNull(new Date), false);
11336       assert.strictEqual(_.isNull(new Error), false);
11337       assert.strictEqual(_.isNull(_), false);
11338       assert.strictEqual(_.isNull(slice), false);
11339       assert.strictEqual(_.isNull({ 'a': 1 }), false);
11340       assert.strictEqual(_.isNull(1), false);
11341       assert.strictEqual(_.isNull(/x/), false);
11342       assert.strictEqual(_.isNull('a'), false);
11343       assert.strictEqual(_.isNull(symbol), false);
11344     });
11345
11346     QUnit.test('should work with nulls from another realm', function(assert) {
11347       assert.expect(1);
11348
11349       if (realm.object) {
11350         assert.strictEqual(_.isNull(realm.null), true);
11351       }
11352       else {
11353         skipAssert(assert);
11354       }
11355     });
11356   }(1, 2, 3));
11357
11358   /*--------------------------------------------------------------------------*/
11359
11360   QUnit.module('lodash.isNumber');
11361
11362   (function() {
11363     var args = arguments;
11364
11365     QUnit.test('should return `true` for numbers', function(assert) {
11366       assert.expect(3);
11367
11368       assert.strictEqual(_.isNumber(0), true);
11369       assert.strictEqual(_.isNumber(Object(0)), true);
11370       assert.strictEqual(_.isNumber(NaN), true);
11371     });
11372
11373     QUnit.test('should return `false` for non-numbers', function(assert) {
11374       assert.expect(12);
11375
11376       var expected = lodashStable.map(falsey, function(value) {
11377         return typeof value == 'number';
11378       });
11379
11380       var actual = lodashStable.map(falsey, function(value, index) {
11381         return index ? _.isNumber(value) : _.isNumber();
11382       });
11383
11384       assert.deepEqual(actual, expected);
11385
11386       assert.strictEqual(_.isNumber(args), false);
11387       assert.strictEqual(_.isNumber([1, 2, 3]), false);
11388       assert.strictEqual(_.isNumber(true), false);
11389       assert.strictEqual(_.isNumber(new Date), false);
11390       assert.strictEqual(_.isNumber(new Error), false);
11391       assert.strictEqual(_.isNumber(_), false);
11392       assert.strictEqual(_.isNumber(slice), false);
11393       assert.strictEqual(_.isNumber({ 'a': 1 }), false);
11394       assert.strictEqual(_.isNumber(/x/), false);
11395       assert.strictEqual(_.isNumber('a'), false);
11396       assert.strictEqual(_.isNumber(symbol), false);
11397     });
11398
11399     QUnit.test('should work with numbers from another realm', function(assert) {
11400       assert.expect(1);
11401
11402       if (realm.number) {
11403         assert.strictEqual(_.isNumber(realm.number), true);
11404       }
11405       else {
11406         skipAssert(assert);
11407       }
11408     });
11409
11410     QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
11411       assert.expect(1);
11412
11413       assert.strictEqual(_.isNumber(+'2'), true);
11414     });
11415   }(1, 2, 3));
11416
11417   /*--------------------------------------------------------------------------*/
11418
11419   QUnit.module('lodash.isObject');
11420
11421   (function() {
11422     var args = arguments;
11423
11424     QUnit.test('should return `true` for objects', function(assert) {
11425       assert.expect(13);
11426
11427       assert.strictEqual(_.isObject(args), true);
11428       assert.strictEqual(_.isObject([1, 2, 3]), true);
11429       assert.strictEqual(_.isObject(Object(false)), true);
11430       assert.strictEqual(_.isObject(new Date), true);
11431       assert.strictEqual(_.isObject(new Error), true);
11432       assert.strictEqual(_.isObject(_), true);
11433       assert.strictEqual(_.isObject(slice), true);
11434       assert.strictEqual(_.isObject({ 'a': 1 }), true);
11435       assert.strictEqual(_.isObject(Object(0)), true);
11436       assert.strictEqual(_.isObject(/x/), true);
11437       assert.strictEqual(_.isObject(Object('a')), true);
11438
11439       if (document) {
11440         assert.strictEqual(_.isObject(body), true);
11441       }
11442       else {
11443         skipAssert(assert);
11444       }
11445       if (Symbol) {
11446         assert.strictEqual(_.isObject(Object(symbol)), true);
11447       }
11448       else {
11449         skipAssert(assert);
11450       }
11451     });
11452
11453     QUnit.test('should return `false` for non-objects', function(assert) {
11454       assert.expect(1);
11455
11456       var values = falsey.concat(true, 1, 'a', symbol),
11457           expected = lodashStable.map(values, stubFalse);
11458
11459       var actual = lodashStable.map(values, function(value, index) {
11460         return index ? _.isObject(value) : _.isObject();
11461       });
11462
11463       assert.deepEqual(actual, expected);
11464     });
11465
11466     QUnit.test('should work with objects from another realm', function(assert) {
11467       assert.expect(8);
11468
11469       if (realm.element) {
11470         assert.strictEqual(_.isObject(realm.element), true);
11471       }
11472       else {
11473         skipAssert(assert);
11474       }
11475       if (realm.object) {
11476         assert.strictEqual(_.isObject(realm.boolean), true);
11477         assert.strictEqual(_.isObject(realm.date), true);
11478         assert.strictEqual(_.isObject(realm.function), true);
11479         assert.strictEqual(_.isObject(realm.number), true);
11480         assert.strictEqual(_.isObject(realm.object), true);
11481         assert.strictEqual(_.isObject(realm.regexp), true);
11482         assert.strictEqual(_.isObject(realm.string), true);
11483       }
11484       else {
11485         skipAssert(assert, 7);
11486       }
11487     });
11488
11489     QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
11490       assert.expect(1);
11491
11492       // Trigger a V8 JIT bug.
11493       // See https://code.google.com/p/v8/issues/detail?id=2291.
11494       var object = {};
11495
11496       // First, have a comparison statement.
11497       object == object;
11498
11499       // Then perform the check with `object`.
11500       _.isObject(object);
11501
11502       assert.strictEqual(_.isObject('a'), false);
11503     });
11504   }(1, 2, 3));
11505
11506   /*--------------------------------------------------------------------------*/
11507
11508   QUnit.module('lodash.isObjectLike');
11509
11510   (function() {
11511     var args = arguments;
11512
11513     QUnit.test('should return `true` for objects', function(assert) {
11514       assert.expect(9);
11515
11516       assert.strictEqual(_.isObjectLike(args), true);
11517       assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
11518       assert.strictEqual(_.isObjectLike(Object(false)), true);
11519       assert.strictEqual(_.isObjectLike(new Date), true);
11520       assert.strictEqual(_.isObjectLike(new Error), true);
11521       assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
11522       assert.strictEqual(_.isObjectLike(Object(0)), true);
11523       assert.strictEqual(_.isObjectLike(/x/), true);
11524       assert.strictEqual(_.isObjectLike(Object('a')), true);
11525     });
11526
11527     QUnit.test('should return `false` for non-objects', function(assert) {
11528       assert.expect(1);
11529
11530       var values = falsey.concat(true, _, slice, 1, 'a', symbol),
11531           expected = lodashStable.map(values, stubFalse);
11532
11533       var actual = lodashStable.map(values, function(value, index) {
11534         return index ? _.isObjectLike(value) : _.isObjectLike();
11535       });
11536
11537       assert.deepEqual(actual, expected);
11538     });
11539
11540     QUnit.test('should work with objects from another realm', function(assert) {
11541       assert.expect(6);
11542
11543       if (realm.object) {
11544         assert.strictEqual(_.isObjectLike(realm.boolean), true);
11545         assert.strictEqual(_.isObjectLike(realm.date), true);
11546         assert.strictEqual(_.isObjectLike(realm.number), true);
11547         assert.strictEqual(_.isObjectLike(realm.object), true);
11548         assert.strictEqual(_.isObjectLike(realm.regexp), true);
11549         assert.strictEqual(_.isObjectLike(realm.string), true);
11550       }
11551       else {
11552         skipAssert(assert, 6);
11553       }
11554     });
11555   }(1, 2, 3));
11556
11557   /*--------------------------------------------------------------------------*/
11558
11559   QUnit.module('lodash.isPlainObject');
11560
11561   (function() {
11562     var element = document && document.createElement('div');
11563
11564     QUnit.test('should detect plain objects', function(assert) {
11565       assert.expect(5);
11566
11567       function Foo(a) {
11568         this.a = 1;
11569       }
11570
11571       assert.strictEqual(_.isPlainObject({}), true);
11572       assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
11573       assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
11574       assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
11575       assert.strictEqual(_.isPlainObject(new Foo(1)), false);
11576     });
11577
11578     QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
11579       assert.expect(2);
11580
11581       if (create) {
11582         var object = create(null);
11583         assert.strictEqual(_.isPlainObject(object), true);
11584
11585         object.constructor = objectProto.constructor;
11586         assert.strictEqual(_.isPlainObject(object), true);
11587       }
11588       else {
11589         skipAssert(assert, 2);
11590       }
11591     });
11592
11593     QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
11594       assert.expect(2);
11595
11596       assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
11597
11598       if (element) {
11599         var valueOf = element.valueOf;
11600         element.valueOf = 0;
11601
11602         assert.strictEqual(_.isPlainObject(element), false);
11603         element.valueOf = valueOf;
11604       }
11605       else {
11606         skipAssert(assert);
11607       }
11608     });
11609
11610     QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
11611       assert.expect(1);
11612
11613       if (create) {
11614         var object = create({ 'a': 1 });
11615         assert.strictEqual(_.isPlainObject(object), false);
11616       }
11617       else {
11618         skipAssert(assert);
11619       }
11620     });
11621
11622     QUnit.test('should return `false` for DOM elements', function(assert) {
11623       assert.expect(1);
11624
11625       if (element) {
11626         assert.strictEqual(_.isPlainObject(element), false);
11627       } else {
11628         skipAssert(assert);
11629       }
11630     });
11631
11632     QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
11633       assert.expect(3);
11634
11635       assert.strictEqual(_.isPlainObject(arguments), false);
11636       assert.strictEqual(_.isPlainObject(Error), false);
11637       assert.strictEqual(_.isPlainObject(Math), false);
11638     });
11639
11640     QUnit.test('should return `false` for non-objects', function(assert) {
11641       assert.expect(4);
11642
11643       var expected = lodashStable.map(falsey, stubFalse);
11644
11645       var actual = lodashStable.map(falsey, function(value, index) {
11646         return index ? _.isPlainObject(value) : _.isPlainObject();
11647       });
11648
11649       assert.deepEqual(actual, expected);
11650
11651       assert.strictEqual(_.isPlainObject(true), false);
11652       assert.strictEqual(_.isPlainObject('a'), false);
11653       assert.strictEqual(_.isPlainObject(symbol), false);
11654     });
11655
11656     QUnit.test('should work with objects from another realm', function(assert) {
11657       assert.expect(1);
11658
11659       if (realm.object) {
11660         assert.strictEqual(_.isPlainObject(realm.object), true);
11661       }
11662       else {
11663         skipAssert(assert);
11664       }
11665     });
11666   }());
11667
11668   /*--------------------------------------------------------------------------*/
11669
11670   QUnit.module('lodash.isRegExp');
11671
11672   (function() {
11673     var args = arguments;
11674
11675     QUnit.test('should return `true` for regexes', function(assert) {
11676       assert.expect(2);
11677
11678       assert.strictEqual(_.isRegExp(/x/), true);
11679       assert.strictEqual(_.isRegExp(RegExp('x')), true);
11680     });
11681
11682     QUnit.test('should return `false` for non-regexes', function(assert) {
11683       assert.expect(12);
11684
11685       var expected = lodashStable.map(falsey, stubFalse);
11686
11687       var actual = lodashStable.map(falsey, function(value, index) {
11688         return index ? _.isRegExp(value) : _.isRegExp();
11689       });
11690
11691       assert.deepEqual(actual, expected);
11692
11693       assert.strictEqual(_.isRegExp(args), false);
11694       assert.strictEqual(_.isRegExp([1, 2, 3]), false);
11695       assert.strictEqual(_.isRegExp(true), false);
11696       assert.strictEqual(_.isRegExp(new Date), false);
11697       assert.strictEqual(_.isRegExp(new Error), false);
11698       assert.strictEqual(_.isRegExp(_), false);
11699       assert.strictEqual(_.isRegExp(slice), false);
11700       assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
11701       assert.strictEqual(_.isRegExp(1), false);
11702       assert.strictEqual(_.isRegExp('a'), false);
11703       assert.strictEqual(_.isRegExp(symbol), false);
11704     });
11705
11706     QUnit.test('should work with regexes from another realm', function(assert) {
11707       assert.expect(1);
11708
11709       if (realm.regexp) {
11710         assert.strictEqual(_.isRegExp(realm.regexp), true);
11711       }
11712       else {
11713         skipAssert(assert);
11714       }
11715     });
11716   }(1, 2, 3));
11717
11718   /*--------------------------------------------------------------------------*/
11719
11720   QUnit.module('lodash.isSet');
11721
11722   (function() {
11723     var args = arguments;
11724
11725     QUnit.test('should return `true` for sets', function(assert) {
11726       assert.expect(1);
11727
11728       if (Set) {
11729         assert.strictEqual(_.isSet(set), true);
11730       }
11731       else {
11732         skipAssert(assert);
11733       }
11734     });
11735
11736     QUnit.test('should return `false` for non-sets', function(assert) {
11737       assert.expect(14);
11738
11739       var expected = lodashStable.map(falsey, stubFalse);
11740
11741       var actual = lodashStable.map(falsey, function(value, index) {
11742         return index ? _.isSet(value) : _.isSet();
11743       });
11744
11745       assert.deepEqual(actual, expected);
11746
11747       assert.strictEqual(_.isSet(args), false);
11748       assert.strictEqual(_.isSet([1, 2, 3]), false);
11749       assert.strictEqual(_.isSet(true), false);
11750       assert.strictEqual(_.isSet(new Date), false);
11751       assert.strictEqual(_.isSet(new Error), false);
11752       assert.strictEqual(_.isSet(_), false);
11753       assert.strictEqual(_.isSet(slice), false);
11754       assert.strictEqual(_.isSet({ 'a': 1 }), false);
11755       assert.strictEqual(_.isSet(1), false);
11756       assert.strictEqual(_.isSet(/x/), false);
11757       assert.strictEqual(_.isSet('a'), false);
11758       assert.strictEqual(_.isSet(symbol), false);
11759       assert.strictEqual(_.isSet(weakSet), false);
11760     });
11761
11762     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11763       assert.expect(1);
11764
11765       var values = [false, true],
11766           expected = lodashStable.map(values, stubFalse);
11767
11768       var actual = lodashStable.map(values, function(value) {
11769         return _.isSet({ 'constructor': value });
11770       });
11771
11772       assert.deepEqual(actual, expected);
11773     });
11774
11775     QUnit.test('should work with weak sets from another realm', function(assert) {
11776       assert.expect(1);
11777
11778       if (realm.set) {
11779         assert.strictEqual(_.isSet(realm.set), true);
11780       }
11781       else {
11782         skipAssert(assert);
11783       }
11784     });
11785   }(1, 2, 3));
11786
11787   /*--------------------------------------------------------------------------*/
11788
11789   QUnit.module('lodash.isString');
11790
11791   (function() {
11792     var args = arguments;
11793
11794     QUnit.test('should return `true` for strings', function(assert) {
11795       assert.expect(2);
11796
11797       assert.strictEqual(_.isString('a'), true);
11798       assert.strictEqual(_.isString(Object('a')), true);
11799     });
11800
11801     QUnit.test('should return `false` for non-strings', function(assert) {
11802       assert.expect(12);
11803
11804       var expected = lodashStable.map(falsey, function(value) {
11805         return value === '';
11806       });
11807
11808       var actual = lodashStable.map(falsey, function(value, index) {
11809         return index ? _.isString(value) : _.isString();
11810       });
11811
11812       assert.deepEqual(actual, expected);
11813
11814       assert.strictEqual(_.isString(args), false);
11815       assert.strictEqual(_.isString([1, 2, 3]), false);
11816       assert.strictEqual(_.isString(true), false);
11817       assert.strictEqual(_.isString(new Date), false);
11818       assert.strictEqual(_.isString(new Error), false);
11819       assert.strictEqual(_.isString(_), false);
11820       assert.strictEqual(_.isString(slice), false);
11821       assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
11822       assert.strictEqual(_.isString(1), false);
11823       assert.strictEqual(_.isString(/x/), false);
11824       assert.strictEqual(_.isString(symbol), false);
11825     });
11826
11827     QUnit.test('should work with strings from another realm', function(assert) {
11828       assert.expect(1);
11829
11830       if (realm.string) {
11831         assert.strictEqual(_.isString(realm.string), true);
11832       }
11833       else {
11834         skipAssert(assert);
11835       }
11836     });
11837   }(1, 2, 3));
11838
11839   /*--------------------------------------------------------------------------*/
11840
11841   QUnit.module('lodash.isSymbol');
11842
11843   (function() {
11844     var args = arguments;
11845
11846     QUnit.test('should return `true` for symbols', function(assert) {
11847       assert.expect(2);
11848
11849       if (Symbol) {
11850         assert.strictEqual(_.isSymbol(symbol), true);
11851         assert.strictEqual(_.isSymbol(Object(symbol)), true);
11852       }
11853       else {
11854         skipAssert(assert, 2);
11855       }
11856     });
11857
11858     QUnit.test('should return `false` for non-symbols', function(assert) {
11859       assert.expect(12);
11860
11861       var expected = lodashStable.map(falsey, stubFalse);
11862
11863       var actual = lodashStable.map(falsey, function(value, index) {
11864         return index ? _.isSymbol(value) : _.isSymbol();
11865       });
11866
11867       assert.deepEqual(actual, expected);
11868
11869       assert.strictEqual(_.isSymbol(args), false);
11870       assert.strictEqual(_.isSymbol([1, 2, 3]), false);
11871       assert.strictEqual(_.isSymbol(true), false);
11872       assert.strictEqual(_.isSymbol(new Date), false);
11873       assert.strictEqual(_.isSymbol(new Error), false);
11874       assert.strictEqual(_.isSymbol(_), false);
11875       assert.strictEqual(_.isSymbol(slice), false);
11876       assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
11877       assert.strictEqual(_.isSymbol(1), false);
11878       assert.strictEqual(_.isSymbol(/x/), false);
11879       assert.strictEqual(_.isSymbol('a'), false);
11880     });
11881
11882     QUnit.test('should work with symbols from another realm', function(assert) {
11883       assert.expect(1);
11884
11885       if (Symbol && realm.symbol) {
11886         assert.strictEqual(_.isSymbol(realm.symbol), true);
11887       }
11888       else {
11889         skipAssert(assert);
11890       }
11891     });
11892   }(1, 2, 3));
11893
11894   /*--------------------------------------------------------------------------*/
11895
11896   QUnit.module('lodash.isTypedArray');
11897
11898   (function() {
11899     var args = arguments;
11900
11901     QUnit.test('should return `true` for typed arrays', function(assert) {
11902       assert.expect(1);
11903
11904       var expected = lodashStable.map(typedArrays, function(type) {
11905         return type in root;
11906       });
11907
11908       var actual = lodashStable.map(typedArrays, function(type) {
11909         var Ctor = root[type];
11910         return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11911       });
11912
11913       assert.deepEqual(actual, expected);
11914     });
11915
11916     QUnit.test('should return `false` for non typed arrays', function(assert) {
11917       assert.expect(13);
11918
11919       var expected = lodashStable.map(falsey, stubFalse);
11920
11921       var actual = lodashStable.map(falsey, function(value, index) {
11922         return index ? _.isTypedArray(value) : _.isTypedArray();
11923       });
11924
11925       assert.deepEqual(actual, expected);
11926
11927       assert.strictEqual(_.isTypedArray(args), false);
11928       assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11929       assert.strictEqual(_.isTypedArray(true), false);
11930       assert.strictEqual(_.isTypedArray(new Date), false);
11931       assert.strictEqual(_.isTypedArray(new Error), false);
11932       assert.strictEqual(_.isTypedArray(_), false);
11933       assert.strictEqual(_.isTypedArray(slice), false);
11934       assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11935       assert.strictEqual(_.isTypedArray(1), false);
11936       assert.strictEqual(_.isTypedArray(/x/), false);
11937       assert.strictEqual(_.isTypedArray('a'), false);
11938       assert.strictEqual(_.isTypedArray(symbol), false);
11939     });
11940
11941     QUnit.test('should work with typed arrays from another realm', function(assert) {
11942       assert.expect(1);
11943
11944       if (realm.object) {
11945         var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11946
11947         var expected = lodashStable.map(props, function(key) {
11948           return realm[key] !== undefined;
11949         });
11950
11951         var actual = lodashStable.map(props, function(key) {
11952           var value = realm[key];
11953           return value ? _.isTypedArray(value) : false;
11954         });
11955
11956         assert.deepEqual(actual, expected);
11957       }
11958       else {
11959         skipAssert(assert);
11960       }
11961     });
11962   }(1, 2, 3));
11963
11964   /*--------------------------------------------------------------------------*/
11965
11966   QUnit.module('lodash.isUndefined');
11967
11968   (function() {
11969     var args = arguments;
11970
11971     QUnit.test('should return `true` for `undefined` values', function(assert) {
11972       assert.expect(2);
11973
11974       assert.strictEqual(_.isUndefined(), true);
11975       assert.strictEqual(_.isUndefined(undefined), true);
11976     });
11977
11978     QUnit.test('should return `false` for non `undefined` values', function(assert) {
11979       assert.expect(13);
11980
11981       var expected = lodashStable.map(falsey, function(value) {
11982         return value === undefined;
11983       });
11984
11985       var actual = lodashStable.map(falsey, function(value, index) {
11986         return index ? _.isUndefined(value) : _.isUndefined();
11987       });
11988
11989       assert.deepEqual(actual, expected);
11990
11991       assert.strictEqual(_.isUndefined(args), false);
11992       assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11993       assert.strictEqual(_.isUndefined(true), false);
11994       assert.strictEqual(_.isUndefined(new Date), false);
11995       assert.strictEqual(_.isUndefined(new Error), false);
11996       assert.strictEqual(_.isUndefined(_), false);
11997       assert.strictEqual(_.isUndefined(slice), false);
11998       assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11999       assert.strictEqual(_.isUndefined(1), false);
12000       assert.strictEqual(_.isUndefined(/x/), false);
12001       assert.strictEqual(_.isUndefined('a'), false);
12002
12003       if (Symbol) {
12004         assert.strictEqual(_.isUndefined(symbol), false);
12005       }
12006       else {
12007         skipAssert(assert);
12008       }
12009     });
12010
12011     QUnit.test('should work with `undefined` from another realm', function(assert) {
12012       assert.expect(1);
12013
12014       if (realm.object) {
12015         assert.strictEqual(_.isUndefined(realm.undefined), true);
12016       }
12017       else {
12018         skipAssert(assert);
12019       }
12020     });
12021   }(1, 2, 3));
12022
12023   /*--------------------------------------------------------------------------*/
12024
12025   QUnit.module('lodash.isWeakMap');
12026
12027   (function() {
12028     var args = arguments;
12029
12030     QUnit.test('should return `true` for weak maps', function(assert) {
12031       assert.expect(1);
12032
12033       if (WeakMap) {
12034         assert.strictEqual(_.isWeakMap(weakMap), true);
12035       }
12036       else {
12037         skipAssert(assert);
12038       }
12039     });
12040
12041     QUnit.test('should return `false` for non weak maps', function(assert) {
12042       assert.expect(14);
12043
12044       var expected = lodashStable.map(falsey, stubFalse);
12045
12046       var actual = lodashStable.map(falsey, function(value, index) {
12047         return index ? _.isWeakMap(value) : _.isWeakMap();
12048       });
12049
12050       assert.deepEqual(actual, expected);
12051
12052       assert.strictEqual(_.isWeakMap(args), false);
12053       assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
12054       assert.strictEqual(_.isWeakMap(true), false);
12055       assert.strictEqual(_.isWeakMap(new Date), false);
12056       assert.strictEqual(_.isWeakMap(new Error), false);
12057       assert.strictEqual(_.isWeakMap(_), false);
12058       assert.strictEqual(_.isWeakMap(slice), false);
12059       assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
12060       assert.strictEqual(_.isWeakMap(map), false);
12061       assert.strictEqual(_.isWeakMap(1), false);
12062       assert.strictEqual(_.isWeakMap(/x/), false);
12063       assert.strictEqual(_.isWeakMap('a'), false);
12064       assert.strictEqual(_.isWeakMap(symbol), false);
12065     });
12066
12067     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
12068       assert.expect(1);
12069
12070       var values = [false, true],
12071           expected = lodashStable.map(values, stubFalse);
12072
12073       var actual = lodashStable.map(values, function(value) {
12074         return _.isWeakMap({ 'constructor': value });
12075       });
12076
12077       assert.deepEqual(actual, expected);
12078     });
12079
12080     QUnit.test('should work with weak maps from another realm', function(assert) {
12081       assert.expect(1);
12082
12083       if (realm.weakMap) {
12084         assert.strictEqual(_.isWeakMap(realm.weakMap), true);
12085       }
12086       else {
12087         skipAssert(assert);
12088       }
12089     });
12090   }(1, 2, 3));
12091
12092   /*--------------------------------------------------------------------------*/
12093
12094   QUnit.module('lodash.isWeakSet');
12095
12096   (function() {
12097     var args = arguments;
12098
12099     QUnit.test('should return `true` for weak sets', function(assert) {
12100       assert.expect(1);
12101
12102       if (WeakSet) {
12103         assert.strictEqual(_.isWeakSet(weakSet), true);
12104       }
12105       else {
12106         skipAssert(assert);
12107       }
12108     });
12109
12110     QUnit.test('should return `false` for non weak sets', function(assert) {
12111       assert.expect(14);
12112
12113       var expected = lodashStable.map(falsey, stubFalse);
12114
12115       var actual = lodashStable.map(falsey, function(value, index) {
12116         return index ? _.isWeakSet(value) : _.isWeakSet();
12117       });
12118
12119       assert.deepEqual(actual, expected);
12120
12121       assert.strictEqual(_.isWeakSet(args), false);
12122       assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
12123       assert.strictEqual(_.isWeakSet(true), false);
12124       assert.strictEqual(_.isWeakSet(new Date), false);
12125       assert.strictEqual(_.isWeakSet(new Error), false);
12126       assert.strictEqual(_.isWeakSet(_), false);
12127       assert.strictEqual(_.isWeakSet(slice), false);
12128       assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
12129       assert.strictEqual(_.isWeakSet(1), false);
12130       assert.strictEqual(_.isWeakSet(/x/), false);
12131       assert.strictEqual(_.isWeakSet('a'), false);
12132       assert.strictEqual(_.isWeakSet(set), false);
12133       assert.strictEqual(_.isWeakSet(symbol), false);
12134     });
12135
12136     QUnit.test('should work with weak sets from another realm', function(assert) {
12137       assert.expect(1);
12138
12139       if (realm.weakSet) {
12140         assert.strictEqual(_.isWeakSet(realm.weakSet), true);
12141       }
12142       else {
12143         skipAssert(assert);
12144       }
12145     });
12146   }(1, 2, 3));
12147
12148   /*--------------------------------------------------------------------------*/
12149
12150   QUnit.module('isType checks');
12151
12152   (function() {
12153     QUnit.test('should return `false` for subclassed values', function(assert) {
12154       assert.expect(7);
12155
12156       var funcs = [
12157         'isArray', 'isBoolean', 'isDate', 'isFunction',
12158         'isNumber', 'isRegExp', 'isString'
12159       ];
12160
12161       lodashStable.each(funcs, function(methodName) {
12162         function Foo() {}
12163         Foo.prototype = root[methodName.slice(2)].prototype;
12164
12165         var object = new Foo;
12166         if (objToString.call(object) == objectTag) {
12167           assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
12168         }
12169         else {
12170           skipAssert(assert);
12171         }
12172       });
12173     });
12174
12175     QUnit.test('should not error on host objects (test in IE)', function(assert) {
12176       assert.expect(26);
12177
12178       var funcs = [
12179         'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
12180         'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
12181         'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
12182         'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
12183         'isUndefined', 'isWeakMap', 'isWeakSet'
12184       ];
12185
12186       lodashStable.each(funcs, function(methodName) {
12187         if (xml) {
12188           var pass = true;
12189
12190           try {
12191             _[methodName](xml);
12192           } catch (e) {
12193             pass = false;
12194           }
12195           assert.ok(pass, '`_.' + methodName + '` should not error');
12196         }
12197         else {
12198           skipAssert(assert);
12199         }
12200       });
12201     });
12202   }());
12203
12204   /*--------------------------------------------------------------------------*/
12205
12206   QUnit.module('lodash.iteratee');
12207
12208   (function() {
12209     QUnit.test('should provide arguments to `func`', function(assert) {
12210       assert.expect(1);
12211
12212       var fn = function() { return slice.call(arguments); },
12213           iteratee = _.iteratee(fn),
12214           actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
12215
12216       assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
12217     });
12218
12219     QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
12220       assert.expect(1);
12221
12222       var object = {},
12223           values = [, null, undefined],
12224           expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
12225
12226       var actual = lodashStable.map(values, function(value, index) {
12227         var identity = index ? _.iteratee(value) : _.iteratee();
12228         return [!isNpm && identity, identity(object)];
12229       });
12230
12231       assert.deepEqual(actual, expected);
12232     });
12233
12234     QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
12235       assert.expect(2);
12236
12237       var matches = _.iteratee({ 'a': 1, 'b': 2 });
12238       assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
12239       assert.strictEqual(matches({ 'b': 2 }), false);
12240     });
12241
12242     QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
12243       assert.expect(9);
12244
12245       var sources = [
12246         { 'a': { 'b': 2, 'c': 3 } },
12247         { 'a': 1, 'b': 2 },
12248         { 'a': 1 }
12249       ];
12250
12251       lodashStable.each(sources, function(source, index) {
12252         var object = lodashStable.cloneDeep(source),
12253             matches = _.iteratee(source);
12254
12255         assert.strictEqual(matches(object), true);
12256
12257         if (index) {
12258           source.a = 2;
12259           source.b = 1;
12260           source.c = 3;
12261         } else {
12262           source.a.b = 1;
12263           source.a.c = 2;
12264           source.a.d = 3;
12265         }
12266         assert.strictEqual(matches(object), true);
12267         assert.strictEqual(matches(source), false);
12268       });
12269     });
12270
12271     QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
12272       assert.expect(3);
12273
12274       var array = ['a', undefined],
12275           matches = _.iteratee([0, 'a']);
12276
12277       assert.strictEqual(matches(array), true);
12278
12279       matches = _.iteratee(['0', 'a']);
12280       assert.strictEqual(matches(array), true);
12281
12282       matches = _.iteratee([1, undefined]);
12283       assert.strictEqual(matches(array), true);
12284     });
12285
12286     QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
12287       assert.expect(1);
12288
12289       var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
12290           matches = _.iteratee(['a.b', { 'c': 1 }]);
12291
12292       assert.strictEqual(matches(object), true);
12293     });
12294
12295     QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
12296       assert.expect(9);
12297
12298       var sources = [
12299         { 'a': { 'b': 2, 'c': 3 } },
12300         { 'a': 1, 'b': 2 },
12301         { 'a': 1 }
12302       ];
12303
12304       lodashStable.each(sources, function(source, index) {
12305         var object = { 'a': lodashStable.cloneDeep(source) },
12306             matches = _.iteratee(['a', source]);
12307
12308         assert.strictEqual(matches(object), true);
12309
12310         if (index) {
12311           source.a = 2;
12312           source.b = 1;
12313           source.c = 3;
12314         } else {
12315           source.a.b = 1;
12316           source.a.c = 2;
12317           source.a.d = 3;
12318         }
12319         assert.strictEqual(matches(object), true);
12320         assert.strictEqual(matches({ 'a': source }), false);
12321       });
12322     });
12323
12324     QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
12325       assert.expect(2);
12326
12327       var array = ['a'],
12328           prop = _.iteratee(0);
12329
12330       assert.strictEqual(prop(array), 'a');
12331
12332       prop = _.iteratee('0');
12333       assert.strictEqual(prop(array), 'a');
12334     });
12335
12336     QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
12337       assert.expect(1);
12338
12339       var object = { 'a': { 'b': 2 } },
12340           prop = _.iteratee('a.b');
12341
12342       assert.strictEqual(prop(object), 2);
12343     });
12344
12345     QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
12346       assert.expect(2);
12347
12348       var fn = function() {
12349         var result = [this.a];
12350         push.apply(result, arguments);
12351         return result;
12352       };
12353
12354       var expected = [1, 2, 3],
12355           object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
12356
12357       assert.deepEqual(object.iteratee(3), expected);
12358
12359       object.iteratee = _.iteratee(_.partialRight(fn, 3));
12360       assert.deepEqual(object.iteratee(2), expected);
12361     });
12362
12363     QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
12364       assert.expect(1);
12365
12366       var iteratee = _.iteratee;
12367       delete _.iteratee;
12368
12369       assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
12370
12371       _.iteratee = iteratee;
12372     });
12373
12374     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12375       assert.expect(1);
12376
12377       var fn = function() { return this instanceof Number; },
12378           array = [fn, fn, fn],
12379           iteratees = lodashStable.map(array, _.iteratee),
12380           expected = lodashStable.map(array, stubFalse);
12381
12382       var actual = lodashStable.map(iteratees, function(iteratee) {
12383         return iteratee();
12384       });
12385
12386       assert.deepEqual(actual, expected);
12387     });
12388   }());
12389
12390   /*--------------------------------------------------------------------------*/
12391
12392   QUnit.module('custom `_.iteratee` methods');
12393
12394   (function() {
12395     var array = ['one', 'two', 'three'],
12396         getPropA = _.partial(_.property, 'a'),
12397         getPropB = _.partial(_.property, 'b'),
12398         getLength = _.partial(_.property, 'length'),
12399         iteratee = _.iteratee;
12400
12401     var getSum = function() {
12402       return function(result, object) {
12403         return result + object.a;
12404       };
12405     };
12406
12407     var objects = [
12408       { 'a': 0, 'b': 0 },
12409       { 'a': 1, 'b': 0 },
12410       { 'a': 1, 'b': 1 }
12411     ];
12412
12413     QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
12414       assert.expect(1);
12415
12416       if (!isModularize) {
12417         _.iteratee = getLength;
12418         assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
12419         _.iteratee = iteratee;
12420       }
12421       else {
12422         skipAssert(assert);
12423       }
12424     });
12425
12426     QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
12427       assert.expect(1);
12428
12429       if (!isModularize) {
12430         _.iteratee = getPropA;
12431         assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
12432         _.iteratee = iteratee;
12433       }
12434       else {
12435         skipAssert(assert);
12436       }
12437     });
12438
12439     QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
12440       assert.expect(1);
12441
12442       if (!isModularize) {
12443         _.iteratee = getPropB;
12444         assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
12445         _.iteratee = iteratee;
12446       }
12447       else {
12448         skipAssert(assert);
12449       }
12450     });
12451
12452     QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
12453       assert.expect(1);
12454
12455       if (!isModularize) {
12456         _.iteratee = getPropB;
12457         assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
12458         _.iteratee = iteratee;
12459       }
12460       else {
12461         skipAssert(assert);
12462       }
12463     });
12464
12465     QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
12466       assert.expect(1);
12467
12468       if (!isModularize) {
12469         _.iteratee = getPropA;
12470         assert.strictEqual(_.every(objects.slice(1)), true);
12471         _.iteratee = iteratee;
12472       }
12473       else {
12474         skipAssert(assert);
12475       }
12476     });
12477
12478     QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
12479       assert.expect(1);
12480
12481       if (!isModularize) {
12482         var objects = [{ 'a': 0 }, { 'a': 1 }];
12483
12484         _.iteratee = getPropA;
12485         assert.deepEqual(_.filter(objects), [objects[1]]);
12486         _.iteratee = iteratee;
12487       }
12488       else {
12489         skipAssert(assert);
12490       }
12491     });
12492
12493     QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
12494       assert.expect(1);
12495
12496       if (!isModularize) {
12497         _.iteratee = getPropA;
12498         assert.strictEqual(_.find(objects), objects[1]);
12499         _.iteratee = iteratee;
12500       }
12501       else {
12502         skipAssert(assert);
12503       }
12504     });
12505
12506     QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
12507       assert.expect(1);
12508
12509       if (!isModularize) {
12510         _.iteratee = getPropA;
12511         assert.strictEqual(_.findIndex(objects), 1);
12512         _.iteratee = iteratee;
12513       }
12514       else {
12515         skipAssert(assert);
12516       }
12517     });
12518
12519     QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
12520       assert.expect(1);
12521
12522       if (!isModularize) {
12523         _.iteratee = getPropA;
12524         assert.strictEqual(_.findLast(objects), objects[2]);
12525         _.iteratee = iteratee;
12526       }
12527       else {
12528         skipAssert(assert);
12529       }
12530     });
12531
12532     QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
12533       assert.expect(1);
12534
12535       if (!isModularize) {
12536         _.iteratee = getPropA;
12537         assert.strictEqual(_.findLastIndex(objects), 2);
12538         _.iteratee = iteratee;
12539       }
12540       else {
12541         skipAssert(assert);
12542       }
12543     });
12544
12545     QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
12546       assert.expect(1);
12547
12548       if (!isModularize) {
12549         _.iteratee = getPropB;
12550         assert.strictEqual(_.findKey(objects), '2');
12551         _.iteratee = iteratee;
12552       }
12553       else {
12554         skipAssert(assert);
12555       }
12556     });
12557
12558     QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
12559       assert.expect(1);
12560
12561       if (!isModularize) {
12562         _.iteratee = getPropB;
12563         assert.strictEqual(_.findLastKey(objects), '2');
12564         _.iteratee = iteratee;
12565       }
12566       else {
12567         skipAssert(assert);
12568       }
12569     });
12570
12571     QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
12572       assert.expect(1);
12573
12574       if (!isModularize) {
12575         _.iteratee = getLength;
12576         assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
12577         _.iteratee = iteratee;
12578       }
12579       else {
12580         skipAssert(assert);
12581       }
12582     });
12583
12584     QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
12585       assert.expect(1);
12586
12587       if (!isModularize) {
12588         _.iteratee = getPropA;
12589         assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
12590         _.iteratee = iteratee;
12591       }
12592       else {
12593         skipAssert(assert);
12594       }
12595     });
12596
12597     QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
12598       assert.expect(1);
12599
12600       if (!isModularize) {
12601         _.iteratee = getLength;
12602         assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
12603         _.iteratee = iteratee;
12604       }
12605       else {
12606         skipAssert(assert);
12607       }
12608     });
12609
12610     QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
12611       assert.expect(1);
12612
12613       if (!isModularize) {
12614         _.iteratee = getPropA;
12615         assert.deepEqual(_.map(objects), [0, 1, 1]);
12616         _.iteratee = iteratee;
12617       }
12618       else {
12619         skipAssert(assert);
12620       }
12621     });
12622
12623     QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
12624       assert.expect(1);
12625
12626       if (!isModularize) {
12627         _.iteratee = getPropB;
12628         assert.deepEqual(_.mapKeys({ 'a': { 'b': 2 } }), { '2':  { 'b': 2 } });
12629         _.iteratee = iteratee;
12630       }
12631       else {
12632         skipAssert(assert);
12633       }
12634     });
12635
12636     QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
12637       assert.expect(1);
12638
12639       if (!isModularize) {
12640         _.iteratee = getPropB;
12641         assert.deepEqual(_.mapValues({ 'a': { 'b': 2 } }), { 'a': 2 });
12642         _.iteratee = iteratee;
12643       }
12644       else {
12645         skipAssert(assert);
12646       }
12647     });
12648
12649     QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
12650       assert.expect(1);
12651
12652       if (!isModularize) {
12653         _.iteratee = getPropB;
12654         assert.deepEqual(_.maxBy(objects), objects[2]);
12655         _.iteratee = iteratee;
12656       }
12657       else {
12658         skipAssert(assert);
12659       }
12660     });
12661
12662     QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
12663       assert.expect(1);
12664
12665       if (!isModularize) {
12666         _.iteratee = getPropA;
12667         assert.strictEqual(_.meanBy(objects), 2 / 3);
12668         _.iteratee = iteratee;
12669       }
12670       else {
12671         skipAssert(assert);
12672       }
12673     });
12674
12675     QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
12676       assert.expect(1);
12677
12678       if (!isModularize) {
12679         _.iteratee = getPropB;
12680         assert.deepEqual(_.minBy(objects), objects[0]);
12681         _.iteratee = iteratee;
12682       }
12683       else {
12684         skipAssert(assert);
12685       }
12686     });
12687
12688     QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
12689       assert.expect(1);
12690
12691       if (!isModularize) {
12692         var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
12693
12694         _.iteratee = getPropA;
12695         assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
12696         _.iteratee = iteratee;
12697       }
12698       else {
12699         skipAssert(assert);
12700       }
12701     });
12702
12703     QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
12704       assert.expect(1);
12705
12706       if (!isModularize) {
12707         _.iteratee = getPropA;
12708         assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
12709         _.iteratee = iteratee;
12710       }
12711       else {
12712         skipAssert(assert);
12713       }
12714     });
12715
12716     QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
12717       assert.expect(1);
12718
12719       if (!isModularize) {
12720         _.iteratee = getSum;
12721         assert.strictEqual(_.reduce(objects, undefined, 0), 2);
12722         _.iteratee = iteratee;
12723       }
12724       else {
12725         skipAssert(assert);
12726       }
12727     });
12728
12729     QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
12730       assert.expect(1);
12731
12732       if (!isModularize) {
12733         _.iteratee = getSum;
12734         assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
12735         _.iteratee = iteratee;
12736       }
12737       else {
12738         skipAssert(assert);
12739       }
12740     });
12741
12742     QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
12743       assert.expect(1);
12744
12745       if (!isModularize) {
12746         var objects = [{ 'a': 0 }, { 'a': 1 }];
12747
12748         _.iteratee = getPropA;
12749         assert.deepEqual(_.reject(objects), [objects[0]]);
12750         _.iteratee = iteratee;
12751       }
12752       else {
12753         skipAssert(assert);
12754       }
12755     });
12756
12757     QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
12758       assert.expect(1);
12759
12760       if (!isModularize) {
12761         var objects = [{ 'a': 0 }, { 'a': 1 }];
12762
12763         _.iteratee = getPropA;
12764         _.remove(objects);
12765         assert.deepEqual(objects, [{ 'a': 0 }]);
12766         _.iteratee = iteratee;
12767       }
12768       else {
12769         skipAssert(assert);
12770       }
12771     });
12772
12773     QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
12774       assert.expect(1);
12775
12776       if (!isModularize) {
12777         _.iteratee = getPropB;
12778         assert.strictEqual(_.some(objects), true);
12779         _.iteratee = iteratee;
12780       }
12781       else {
12782         skipAssert(assert);
12783       }
12784     });
12785
12786     QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
12787       assert.expect(1);
12788
12789       if (!isModularize) {
12790         _.iteratee = getPropA;
12791         assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
12792         _.iteratee = iteratee;
12793       }
12794       else {
12795         skipAssert(assert);
12796       }
12797     });
12798
12799     QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
12800       assert.expect(1);
12801
12802       if (!isModularize) {
12803         var objects = [{ 'a': 30 }, { 'a': 50 }];
12804
12805         _.iteratee = getPropA;
12806         assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
12807         _.iteratee = iteratee;
12808       }
12809       else {
12810         skipAssert(assert);
12811       }
12812     });
12813
12814     QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
12815       assert.expect(1);
12816
12817       if (!isModularize) {
12818         var objects = [{ 'a': 30 }, { 'a': 50 }];
12819
12820         _.iteratee = getPropA;
12821         assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
12822         _.iteratee = iteratee;
12823       }
12824       else {
12825         skipAssert(assert);
12826       }
12827     });
12828
12829     QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
12830       assert.expect(1);
12831
12832       if (!isModularize) {
12833         _.iteratee = getPropB;
12834         assert.strictEqual(_.sumBy(objects), 1);
12835         _.iteratee = iteratee;
12836       }
12837       else {
12838         skipAssert(assert);
12839       }
12840     });
12841
12842     QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
12843       assert.expect(1);
12844
12845       if (!isModularize) {
12846         _.iteratee = getPropB;
12847         assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
12848         _.iteratee = iteratee;
12849       }
12850       else {
12851         skipAssert(assert);
12852       }
12853     });
12854
12855     QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
12856       assert.expect(1);
12857
12858       if (!isModularize) {
12859         _.iteratee = getPropB;
12860         assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
12861         _.iteratee = iteratee;
12862       }
12863       else {
12864         skipAssert(assert);
12865       }
12866     });
12867
12868     QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
12869       assert.expect(1);
12870
12871       if (!isModularize) {
12872         _.iteratee = function() {
12873           return function(result, object) {
12874             result.sum += object.a;
12875           };
12876         };
12877
12878         assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
12879         _.iteratee = iteratee;
12880       }
12881       else {
12882         skipAssert(assert);
12883       }
12884     });
12885
12886     QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
12887       assert.expect(1);
12888
12889       if (!isModularize) {
12890         _.iteratee = getPropB;
12891         assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
12892         _.iteratee = iteratee;
12893       }
12894       else {
12895         skipAssert(assert);
12896       }
12897     });
12898
12899     QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
12900       assert.expect(1);
12901
12902       if (!isModularize) {
12903         _.iteratee = getPropB;
12904         assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
12905         _.iteratee = iteratee;
12906       }
12907       else {
12908         skipAssert(assert);
12909       }
12910     });
12911
12912     QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
12913       assert.expect(1);
12914
12915       if (!isModularize) {
12916         _.iteratee = getPropA;
12917         assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
12918         _.iteratee = iteratee;
12919       }
12920       else {
12921         skipAssert(assert);
12922       }
12923     });
12924   }());
12925
12926   /*--------------------------------------------------------------------------*/
12927
12928   QUnit.module('lodash.join');
12929
12930   (function() {
12931     var array = ['a', 'b', 'c'];
12932
12933     QUnit.test('should return join all array elements into a string', function(assert) {
12934       assert.expect(1);
12935
12936       assert.strictEqual(_.join(array, '~'), 'a~b~c');
12937     });
12938
12939     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12940       assert.expect(2);
12941
12942       if (!isNpm) {
12943         var wrapped = _(array);
12944         assert.strictEqual(wrapped.join('~'), 'a~b~c');
12945         assert.strictEqual(wrapped.value(), array);
12946       }
12947       else {
12948         skipAssert(assert, 2);
12949       }
12950     });
12951
12952     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12953       assert.expect(1);
12954
12955       if (!isNpm) {
12956         assert.ok(_(array).chain().join('~') instanceof _);
12957       }
12958       else {
12959         skipAssert(assert);
12960       }
12961     });
12962   }());
12963
12964   /*--------------------------------------------------------------------------*/
12965
12966   QUnit.module('lodash.keyBy');
12967
12968   (function() {
12969     var array = [
12970       { 'dir': 'left', 'code': 97 },
12971       { 'dir': 'right', 'code': 100 }
12972     ];
12973
12974     QUnit.test('should transform keys by `iteratee`', function(assert) {
12975       assert.expect(1);
12976
12977       var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12978
12979       var actual = _.keyBy(array, function(object) {
12980         return String.fromCharCode(object.code);
12981       });
12982
12983       assert.deepEqual(actual, expected);
12984     });
12985
12986     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12987       assert.expect(1);
12988
12989       var array = [4, 6, 6],
12990           values = [, null, undefined],
12991           expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12992
12993       var actual = lodashStable.map(values, function(value, index) {
12994         return index ? _.keyBy(array, value) : _.keyBy(array);
12995       });
12996
12997       assert.deepEqual(actual, expected);
12998     });
12999
13000     QUnit.test('should work with `_.property` shorthands', function(assert) {
13001       assert.expect(1);
13002
13003       var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
13004           actual = _.keyBy(array, 'dir');
13005
13006       assert.deepEqual(actual, expected);
13007     });
13008
13009     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
13010       assert.expect(2);
13011
13012       var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
13013         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
13014       });
13015
13016       assert.deepEqual(actual.constructor, 4.2);
13017       assert.deepEqual(actual.hasOwnProperty, 6.3);
13018     });
13019
13020     QUnit.test('should work with a number for `iteratee`', function(assert) {
13021       assert.expect(2);
13022
13023       var array = [
13024         [1, 'a'],
13025         [2, 'a'],
13026         [2, 'b']
13027       ];
13028
13029       assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
13030       assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
13031     });
13032
13033     QUnit.test('should work with an object for `collection`', function(assert) {
13034       assert.expect(1);
13035
13036       var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
13037       assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
13038     });
13039
13040     QUnit.test('should work in a lazy sequence', function(assert) {
13041       assert.expect(1);
13042
13043       if (!isNpm) {
13044         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
13045           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
13046           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
13047         );
13048
13049         var actual = _(array).keyBy().map(square).filter(isEven).take().value();
13050
13051         assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
13052       }
13053       else {
13054         skipAssert(assert);
13055       }
13056     });
13057   }());
13058
13059   /*--------------------------------------------------------------------------*/
13060
13061   QUnit.module('keys methods');
13062
13063   lodashStable.each(['keys', 'keysIn'], function(methodName) {
13064     var args = (function() { return arguments; }(1, 2, 3)),
13065         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
13066         func = _[methodName],
13067         isKeys = methodName == 'keys';
13068
13069     QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
13070       assert.expect(1);
13071
13072       var actual = func({ 'a': 1, 'b': 1 }).sort();
13073
13074       assert.deepEqual(actual, ['a', 'b']);
13075     });
13076
13077     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
13078       assert.expect(1);
13079
13080       function Foo() {
13081         this.a = 1;
13082       }
13083       Foo.prototype.b = 2;
13084
13085       var expected = isKeys ? ['a'] : ['a', 'b'],
13086           actual = func(new Foo).sort();
13087
13088       assert.deepEqual(actual, expected);
13089     });
13090
13091     QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
13092       assert.expect(2);
13093
13094       var expected = lodashStable.map(primitives, function(value) {
13095         return typeof value == 'string' ? ['0'] : [];
13096       });
13097
13098       var actual = lodashStable.map(primitives, func);
13099       assert.deepEqual(actual, expected);
13100
13101       // IE 9 doesn't box numbers in for-in loops.
13102       numberProto.a = 1;
13103       assert.deepEqual(func(0), isKeys ? [] : ['a']);
13104       delete numberProto.a;
13105     });
13106
13107     QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
13108       assert.expect(1);
13109
13110       var array = [1];
13111       array[2] = 3;
13112
13113       var actual = func(array).sort();
13114
13115       assert.deepEqual(actual, ['0', '1', '2']);
13116     });
13117
13118     QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
13119       assert.expect(2);
13120
13121       objectProto.a = 1;
13122       lodashStable.each([null, undefined], function(value) {
13123         assert.deepEqual(func(value), []);
13124       });
13125       delete objectProto.a;
13126     });
13127
13128     QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
13129       assert.expect(1);
13130
13131       var array = [1];
13132       array.a = 1;
13133
13134       var actual = func(array).sort();
13135
13136       assert.deepEqual(actual, ['0', 'a']);
13137     });
13138
13139     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
13140       assert.expect(1);
13141
13142       arrayProto.a = 1;
13143
13144       var expected = isKeys ? ['0'] : ['0', 'a'],
13145           actual = func([1]).sort();
13146
13147       assert.deepEqual(actual, expected);
13148
13149       delete arrayProto.a;
13150     });
13151
13152     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
13153       assert.expect(1);
13154
13155       var values = [args, strictArgs],
13156           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
13157
13158       var actual = lodashStable.map(values, function(value) {
13159         return func(value).sort();
13160       });
13161
13162       assert.deepEqual(actual, expected);
13163     });
13164
13165     QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
13166       assert.expect(1);
13167
13168       var values = [args, strictArgs],
13169           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
13170
13171       var actual = lodashStable.map(values, function(value) {
13172         value.a = 1;
13173         var result = func(value).sort();
13174         delete value.a;
13175         return result;
13176       });
13177
13178       assert.deepEqual(actual, expected);
13179     });
13180
13181     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
13182       assert.expect(1);
13183
13184       var values = [args, strictArgs],
13185           expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
13186
13187       var actual = lodashStable.map(values, function(value) {
13188         objectProto.a = 1;
13189         var result = func(value).sort();
13190         delete objectProto.a;
13191         return result;
13192       });
13193
13194       assert.deepEqual(actual, expected);
13195     });
13196
13197     QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
13198       assert.expect(1);
13199
13200       var actual = func(Object('abc')).sort();
13201
13202       assert.deepEqual(actual, ['0', '1', '2']);
13203     });
13204
13205     QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
13206       assert.expect(1);
13207
13208       var object = Object('a');
13209       object.a = 1;
13210
13211       var actual = func(object).sort();
13212
13213       assert.deepEqual(actual, ['0', 'a']);
13214     });
13215
13216     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
13217       assert.expect(1);
13218
13219       stringProto.a = 1;
13220
13221       var expected = isKeys ? ['0'] : ['0', 'a'],
13222           actual = func(Object('a')).sort();
13223
13224       assert.deepEqual(actual, expected);
13225
13226       delete stringProto.a;
13227     });
13228
13229     QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
13230       assert.expect(3);
13231
13232       function Foo() {}
13233       Foo.prototype.a = 1;
13234
13235       var expected = ['a'];
13236       assert.deepEqual(func(Foo.prototype), expected);
13237
13238       Foo.prototype = { 'constructor': Foo, 'a': 1 };
13239       assert.deepEqual(func(Foo.prototype), expected);
13240
13241       var Fake = { 'prototype': {} };
13242       Fake.prototype.constructor = Fake;
13243       assert.deepEqual(func(Fake.prototype), ['constructor']);
13244     });
13245   });
13246
13247   /*--------------------------------------------------------------------------*/
13248
13249   QUnit.module('lodash.last');
13250
13251   (function() {
13252     var array = [1, 2, 3, 4];
13253
13254     QUnit.test('should return the last element', function(assert) {
13255       assert.expect(1);
13256
13257       assert.strictEqual(_.last(array), 4);
13258     });
13259
13260     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
13261       assert.expect(1);
13262
13263       var array = [];
13264       array['-1'] = 1;
13265
13266       assert.strictEqual(_.last([]), undefined);
13267     });
13268
13269     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
13270       assert.expect(1);
13271
13272       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
13273           actual = lodashStable.map(array, _.last);
13274
13275       assert.deepEqual(actual, [3, 6, 9]);
13276     });
13277
13278     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
13279       assert.expect(1);
13280
13281       if (!isNpm) {
13282         assert.strictEqual(_(array).last(), 4);
13283       }
13284       else {
13285         skipAssert(assert);
13286       }
13287     });
13288
13289     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
13290       assert.expect(1);
13291
13292       if (!isNpm) {
13293         assert.ok(_(array).chain().last() instanceof _);
13294       }
13295       else {
13296         skipAssert(assert);
13297       }
13298     });
13299
13300     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
13301       assert.expect(1);
13302
13303       if (!isNpm) {
13304         var wrapped = _(array).chain().last();
13305         assert.strictEqual(wrapped.__wrapped__, array);
13306       }
13307       else {
13308         skipAssert(assert);
13309       }
13310     });
13311
13312     QUnit.test('should work in a lazy sequence', function(assert) {
13313       assert.expect(2);
13314
13315       if (!isNpm) {
13316         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
13317             smallArray = array;
13318
13319         lodashStable.times(2, function(index) {
13320           var array = index ? largeArray : smallArray,
13321               wrapped = _(array).filter(isEven);
13322
13323           assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
13324         });
13325       }
13326       else {
13327         skipAssert(assert, 2);
13328       }
13329     });
13330   }());
13331
13332   /*--------------------------------------------------------------------------*/
13333
13334   QUnit.module('lodash.lowerCase');
13335
13336   (function() {
13337     QUnit.test('should lowercase as space-separated words', function(assert) {
13338       assert.expect(3);
13339
13340       assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
13341       assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
13342       assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
13343     });
13344   }());
13345
13346   /*--------------------------------------------------------------------------*/
13347
13348   QUnit.module('lodash.lowerFirst');
13349
13350   (function() {
13351     QUnit.test('should lowercase only the first character', function(assert) {
13352       assert.expect(3);
13353
13354       assert.strictEqual(_.lowerFirst('fred'), 'fred');
13355       assert.strictEqual(_.lowerFirst('Fred'), 'fred');
13356       assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
13357     });
13358   }());
13359
13360   /*--------------------------------------------------------------------------*/
13361
13362   QUnit.module('lodash.lt');
13363
13364   (function() {
13365     QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
13366       assert.expect(2);
13367
13368       assert.strictEqual(_.lt(1, 3), true);
13369       assert.strictEqual(_.lt('abc', 'def'), true);
13370     });
13371
13372     QUnit.test('should return `false` if `value` >= `other`', function(assert) {
13373       assert.expect(4);
13374
13375       assert.strictEqual(_.lt(3, 1), false);
13376       assert.strictEqual(_.lt(3, 3), false);
13377       assert.strictEqual(_.lt('def', 'abc'), false);
13378       assert.strictEqual(_.lt('def', 'def'), false);
13379     });
13380   }());
13381
13382   /*--------------------------------------------------------------------------*/
13383
13384   QUnit.module('lodash.lte');
13385
13386   (function() {
13387     QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
13388       assert.expect(4);
13389
13390       assert.strictEqual(_.lte(1, 3), true);
13391       assert.strictEqual(_.lte(3, 3), true);
13392       assert.strictEqual(_.lte('abc', 'def'), true);
13393       assert.strictEqual(_.lte('def', 'def'), true);
13394     });
13395
13396     QUnit.test('should return `false` if `value` > `other`', function(assert) {
13397       assert.expect(2);
13398
13399       assert.strictEqual(_.lt(3, 1), false);
13400       assert.strictEqual(_.lt('def', 'abc'), false);
13401     });
13402   }());
13403
13404   /*--------------------------------------------------------------------------*/
13405
13406   QUnit.module('lodash.findLastIndex and lodash.lastIndexOf');
13407
13408   lodashStable.each(['findLastIndex', 'lastIndexOf'], function(methodName) {
13409     var array = [1, 2, 3, 1, 2, 3],
13410         func = _[methodName],
13411         resolve = methodName == 'findLastIndex' ? lodashStable.curry(lodashStable.eq) : identity;
13412
13413     QUnit.test('`_.' + methodName + '` should return the index of the last matched value', function(assert) {
13414       assert.expect(1);
13415
13416       assert.strictEqual(func(array, resolve(3)), 5);
13417     });
13418
13419     QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
13420       assert.expect(1);
13421
13422       assert.strictEqual(func(array, resolve(1), 2), 0);
13423     });
13424
13425     QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
13426       assert.expect(1);
13427
13428       var values = [6, 8, Math.pow(2, 32), Infinity],
13429           expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
13430
13431       var actual = lodashStable.map(values, function(fromIndex) {
13432         return [
13433           func(array, resolve(undefined), fromIndex),
13434           func(array, resolve(1), fromIndex),
13435           func(array, resolve(''), fromIndex)
13436         ];
13437       });
13438
13439       assert.deepEqual(actual, expected);
13440     });
13441
13442     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
13443       assert.expect(1);
13444
13445       assert.strictEqual(func(array, resolve(2), -3), 1);
13446     });
13447
13448     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
13449       assert.expect(1);
13450
13451       var values = [-6, -8, -Infinity],
13452           expected = lodashStable.map(values, stubZero);
13453
13454       var actual = lodashStable.map(values, function(fromIndex) {
13455         return func(array, resolve(1), fromIndex);
13456       });
13457
13458       assert.deepEqual(actual, expected);
13459     });
13460
13461     QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values correctly', function(assert) {
13462       assert.expect(1);
13463
13464       var expected = lodashStable.map(falsey, function(value) {
13465         return value === undefined ? 5 : -1;
13466       });
13467
13468       var actual = lodashStable.map(falsey, function(fromIndex) {
13469         return func(array, resolve(3), fromIndex);
13470       });
13471
13472       assert.deepEqual(actual, expected);
13473     });
13474
13475     QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
13476       assert.expect(1);
13477
13478       assert.strictEqual(func(array, resolve(2), 4.2), 4);
13479     });
13480   });
13481
13482   /*--------------------------------------------------------------------------*/
13483
13484   QUnit.module('indexOf methods');
13485
13486   lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
13487     var func = _[methodName],
13488         isIndexOf = !/last/i.test(methodName),
13489         isSorted = /^sorted/.test(methodName);
13490
13491     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
13492       assert.expect(1);
13493
13494       var expected = lodashStable.map(falsey, lodashStable.constant(-1));
13495
13496       var actual = lodashStable.map(falsey, function(array, index) {
13497         try {
13498           return index ? func(array) : func();
13499         } catch (e) {}
13500       });
13501
13502       assert.deepEqual(actual, expected);
13503     });
13504
13505     QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
13506       assert.expect(5);
13507
13508       var array = [1, 2, 3],
13509           empty = [];
13510
13511       assert.strictEqual(func(array, 4), -1);
13512       assert.strictEqual(func(array, 4, true), -1);
13513       assert.strictEqual(func(array, undefined, true), -1);
13514
13515       assert.strictEqual(func(empty, undefined), -1);
13516       assert.strictEqual(func(empty, undefined, true), -1);
13517     });
13518
13519     QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
13520       assert.expect(2);
13521
13522       var array = [];
13523       array[-1] = 0;
13524
13525       assert.strictEqual(func(array, undefined), -1);
13526       assert.strictEqual(func(array, 0, true), -1);
13527     });
13528
13529     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
13530       assert.expect(3);
13531
13532       var array = isSorted
13533         ? [1, 2, NaN, NaN]
13534         : [1, NaN, 3, NaN, 5, NaN];
13535
13536       if (isSorted) {
13537         assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
13538         skipAssert(assert, 2);
13539       }
13540       else {
13541         assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
13542         assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
13543         assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
13544       }
13545     });
13546
13547     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13548       assert.expect(2);
13549
13550       assert.strictEqual(func([-0], 0), 0);
13551       assert.strictEqual(func([0], -0), 0);
13552     });
13553   });
13554
13555   /*--------------------------------------------------------------------------*/
13556
13557   QUnit.module('lodash.map');
13558
13559   (function() {
13560     var array = [1, 2];
13561
13562     QUnit.test('should map values in `collection` to a new array', function(assert) {
13563       assert.expect(2);
13564
13565       var object = { 'a': 1, 'b': 2 },
13566           expected = ['1', '2'];
13567
13568       assert.deepEqual(_.map(array, String), expected);
13569       assert.deepEqual(_.map(object, String), expected);
13570     });
13571
13572     QUnit.test('should work with `_.property` shorthands', function(assert) {
13573       assert.expect(1);
13574
13575       var objects = [{ 'a': 'x' }, { 'a': 'y' }];
13576       assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
13577     });
13578
13579     QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
13580       assert.expect(1);
13581
13582       function Foo() {
13583         this.a = 1;
13584       }
13585       Foo.prototype.b = 2;
13586
13587       var actual = _.map(new Foo, identity);
13588       assert.deepEqual(actual, [1]);
13589     });
13590
13591     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13592       assert.expect(2);
13593
13594       var object = { 'a': 1, 'b': 2 },
13595           values = [, null, undefined],
13596           expected = lodashStable.map(values, lodashStable.constant([1, 2]));
13597
13598       lodashStable.each([array, object], function(collection) {
13599         var actual = lodashStable.map(values, function(value, index) {
13600           return index ? _.map(collection, value) : _.map(collection);
13601         });
13602
13603         assert.deepEqual(actual, expected);
13604       });
13605     });
13606
13607     QUnit.test('should accept a falsey `collection` argument', function(assert) {
13608       assert.expect(1);
13609
13610       var expected = lodashStable.map(falsey, stubArray);
13611
13612       var actual = lodashStable.map(falsey, function(collection, index) {
13613         try {
13614           return index ? _.map(collection) : _.map();
13615         } catch (e) {}
13616       });
13617
13618       assert.deepEqual(actual, expected);
13619     });
13620
13621     QUnit.test('should treat number values for `collection` as empty', function(assert) {
13622       assert.expect(1);
13623
13624       assert.deepEqual(_.map(1), []);
13625     });
13626
13627     QUnit.test('should treat a nodelist as an array-like object', function(assert) {
13628       assert.expect(1);
13629
13630       if (document) {
13631         var actual = _.map(document.getElementsByTagName('body'), function(element) {
13632           return element.nodeName.toLowerCase();
13633         });
13634
13635         assert.deepEqual(actual, ['body']);
13636       }
13637       else {
13638         skipAssert(assert);
13639       }
13640     });
13641
13642     QUnit.test('should work with objects with non-number length properties', function(assert) {
13643       assert.expect(1);
13644
13645       var value = { 'value': 'x' },
13646           object = { 'length': { 'value': 'x' } };
13647
13648       assert.deepEqual(_.map(object, identity), [value]);
13649     });
13650
13651     QUnit.test('should return a wrapped value when chaining', function(assert) {
13652       assert.expect(1);
13653
13654       if (!isNpm) {
13655         assert.ok(_(array).map(noop) instanceof _);
13656       }
13657       else {
13658         skipAssert(assert);
13659       }
13660     });
13661
13662     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
13663       assert.expect(5);
13664
13665       if (!isNpm) {
13666         var args,
13667             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
13668             expected = [1, 0, _.map(array.slice(1), square)];
13669
13670         _(array).slice(1).map(function(value, index, array) {
13671           args || (args = slice.call(arguments));
13672         }).value();
13673
13674         assert.deepEqual(args, [1, 0, array.slice(1)]);
13675
13676         args = undefined;
13677         _(array).slice(1).map(square).map(function(value, index, array) {
13678           args || (args = slice.call(arguments));
13679         }).value();
13680
13681         assert.deepEqual(args, expected);
13682
13683         args = undefined;
13684         _(array).slice(1).map(square).map(function(value, index) {
13685           args || (args = slice.call(arguments));
13686         }).value();
13687
13688         assert.deepEqual(args, expected);
13689
13690         args = undefined;
13691         _(array).slice(1).map(square).map(function(value) {
13692           args || (args = slice.call(arguments));
13693         }).value();
13694
13695         assert.deepEqual(args, [1]);
13696
13697         args = undefined;
13698         _(array).slice(1).map(square).map(function() {
13699           args || (args = slice.call(arguments));
13700         }).value();
13701
13702         assert.deepEqual(args, expected);
13703       }
13704       else {
13705         skipAssert(assert, 5);
13706       }
13707     });
13708   }());
13709
13710   /*--------------------------------------------------------------------------*/
13711
13712   QUnit.module('lodash.mapKeys');
13713
13714   (function() {
13715     var array = [1, 2],
13716         object = { 'a': 1, 'b': 2 };
13717
13718     QUnit.test('should map keys in `object` to a new object', function(assert) {
13719       assert.expect(1);
13720
13721       var actual = _.mapKeys(object, String);
13722       assert.deepEqual(actual, { '1': 1, '2': 2 });
13723     });
13724
13725     QUnit.test('should treat arrays like objects', function(assert) {
13726       assert.expect(1);
13727
13728       var actual = _.mapKeys(array, String);
13729       assert.deepEqual(actual, { '1': 1, '2': 2 });
13730     });
13731
13732     QUnit.test('should work with `_.property` shorthands', function(assert) {
13733       assert.expect(1);
13734
13735       var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
13736       assert.deepEqual(actual, { 'c': { 'b': 'c' } });
13737     });
13738
13739     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13740       assert.expect(1);
13741
13742       var object = { 'a': 1, 'b': 2 },
13743           values = [, null, undefined],
13744           expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
13745
13746       var actual = lodashStable.map(values, function(value, index) {
13747         return index ? _.mapKeys(object, value) : _.mapKeys(object);
13748       });
13749
13750       assert.deepEqual(actual, expected);
13751     });
13752   }());
13753
13754   /*--------------------------------------------------------------------------*/
13755
13756   QUnit.module('lodash.mapValues');
13757
13758   (function() {
13759     var array = [1, 2],
13760         object = { 'a': 1, 'b': 2 };
13761
13762     QUnit.test('should map values in `object` to a new object', function(assert) {
13763       assert.expect(1);
13764
13765       var actual = _.mapValues(object, String);
13766       assert.deepEqual(actual, { 'a': '1', 'b': '2' });
13767     });
13768
13769     QUnit.test('should treat arrays like objects', function(assert) {
13770       assert.expect(1);
13771
13772       var actual = _.mapValues(array, String);
13773       assert.deepEqual(actual, { '0': '1', '1': '2' });
13774     });
13775
13776     QUnit.test('should work with `_.property` shorthands', function(assert) {
13777       assert.expect(1);
13778
13779       var actual = _.mapValues({ 'a': { 'b': 2 } }, 'b');
13780       assert.deepEqual(actual, { 'a': 2 });
13781     });
13782
13783     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13784       assert.expect(1);
13785
13786       var object = { 'a': 1, 'b': 2 },
13787           values = [, null, undefined],
13788           expected = lodashStable.map(values, lodashStable.constant([true, false]));
13789
13790       var actual = lodashStable.map(values, function(value, index) {
13791         var result = index ? _.mapValues(object, value) : _.mapValues(object);
13792         return [lodashStable.isEqual(result, object), result === object];
13793       });
13794
13795       assert.deepEqual(actual, expected);
13796     });
13797   }());
13798
13799   /*--------------------------------------------------------------------------*/
13800
13801   QUnit.module('lodash.mapKeys and lodash.mapValues');
13802
13803   lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
13804     var func = _[methodName],
13805         object = { 'a': 1, 'b': 2 };
13806
13807     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
13808       assert.expect(1);
13809
13810       function Foo() {
13811         this.a = 'a';
13812       }
13813       Foo.prototype.b = 'b';
13814
13815       var actual = func(new Foo, function(value, key) { return key; });
13816       assert.deepEqual(actual, { 'a': 'a' });
13817     });
13818
13819     QUnit.test('`_.' + methodName + '` should accept a falsey `object` argument', function(assert) {
13820       assert.expect(1);
13821
13822       var expected = lodashStable.map(falsey, stubObject);
13823
13824       var actual = lodashStable.map(falsey, function(object, index) {
13825         try {
13826           return index ? func(object) : func();
13827         } catch (e) {}
13828       });
13829
13830       assert.deepEqual(actual, expected);
13831     });
13832
13833     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
13834       assert.expect(1);
13835
13836       if (!isNpm) {
13837         assert.ok(_(object)[methodName](noop) instanceof _);
13838       }
13839       else {
13840         skipAssert(assert);
13841       }
13842     });
13843   });
13844
13845   /*--------------------------------------------------------------------------*/
13846
13847   QUnit.module('lodash.matches');
13848
13849   (function() {
13850     QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
13851       assert.expect(6);
13852
13853       var object = { 'a': 1, 'b': 2, 'c': 3 },
13854           matches = _.matches({ 'a': 1 });
13855
13856       assert.strictEqual(matches.length, 1);
13857       assert.strictEqual(matches(object), true);
13858
13859       matches = _.matches({ 'b': 1 });
13860       assert.strictEqual(matches(object), false);
13861
13862       matches = _.matches({ 'a': 1, 'c': 3 });
13863       assert.strictEqual(matches(object), true);
13864
13865       matches = _.matches({ 'c': 3, 'd': 4 });
13866       assert.strictEqual(matches(object), false);
13867
13868       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13869       matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
13870
13871       assert.strictEqual(matches(object), true);
13872     });
13873
13874     QUnit.test('should match inherited string keyed `object` properties', function(assert) {
13875       assert.expect(1);
13876
13877       function Foo() {
13878         this.a = 1;
13879       }
13880       Foo.prototype.b = 2;
13881
13882       var object = { 'a': new Foo },
13883           matches = _.matches({ 'a': { 'b': 2 } });
13884
13885       assert.strictEqual(matches(object), true);
13886     });
13887
13888     QUnit.test('should not match by inherited `source` properties', function(assert) {
13889       assert.expect(1);
13890
13891       function Foo() {
13892         this.a = 1;
13893       }
13894       Foo.prototype.b = 2;
13895
13896       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
13897           source = new Foo,
13898           actual = lodashStable.map(objects, _.matches(source)),
13899           expected = lodashStable.map(objects, stubTrue);
13900
13901       assert.deepEqual(actual, expected);
13902     });
13903
13904     QUnit.test('should compare a variety of `source` property values', function(assert) {
13905       assert.expect(2);
13906
13907       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13908           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13909           matches = _.matches(object1);
13910
13911       assert.strictEqual(matches(object1), true);
13912       assert.strictEqual(matches(object2), false);
13913     });
13914
13915     QUnit.test('should match `-0` as `0`', function(assert) {
13916       assert.expect(2);
13917
13918       var object1 = { 'a': -0 },
13919           object2 = { 'a': 0 },
13920           matches = _.matches(object1);
13921
13922       assert.strictEqual(matches(object2), true);
13923
13924       matches = _.matches(object2);
13925       assert.strictEqual(matches(object1), true);
13926     });
13927
13928     QUnit.test('should compare functions by reference', function(assert) {
13929       assert.expect(3);
13930
13931       var object1 = { 'a': lodashStable.noop },
13932           object2 = { 'a': noop },
13933           object3 = { 'a': {} },
13934           matches = _.matches(object1);
13935
13936       assert.strictEqual(matches(object1), true);
13937       assert.strictEqual(matches(object2), false);
13938       assert.strictEqual(matches(object3), false);
13939     });
13940
13941     QUnit.test('should work with a function for `object`', function(assert) {
13942       assert.expect(1);
13943
13944       function Foo() {}
13945       Foo.a = { 'b': 2, 'c': 3 };
13946
13947       var matches = _.matches({ 'a': { 'b': 2 } });
13948       assert.strictEqual(matches(Foo), true);
13949     });
13950
13951     QUnit.test('should work with a function for `source`', function(assert) {
13952       assert.expect(1);
13953
13954       function Foo() {}
13955       Foo.a = 1;
13956       Foo.b = function() {};
13957       Foo.c = 3;
13958
13959       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
13960           actual = lodashStable.map(objects, _.matches(Foo));
13961
13962       assert.deepEqual(actual, [false, true]);
13963     });
13964
13965     QUnit.test('should work with a non-plain `object`', function(assert) {
13966       assert.expect(1);
13967
13968       function Foo(object) { lodashStable.assign(this, object); }
13969
13970       var object = new Foo({ 'a': new Foo({ 'b': 2, 'c': 3 }) }),
13971           matches = _.matches({ 'a': { 'b': 2 } });
13972
13973       assert.strictEqual(matches(object), true);
13974     });
13975
13976     QUnit.test('should partial match arrays', function(assert) {
13977       assert.expect(3);
13978
13979       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13980           actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
13981
13982       assert.deepEqual(actual, [objects[1]]);
13983
13984       actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
13985       assert.deepEqual(actual, []);
13986
13987       actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
13988       assert.deepEqual(actual, []);
13989     });
13990
13991     QUnit.test('should partial match arrays with duplicate values', function(assert) {
13992       assert.expect(1);
13993
13994       var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
13995           actual = lodashStable.filter(objects, _.matches({ 'a': [2, 2] }));
13996
13997       assert.deepEqual(actual, [objects[1]]);
13998     });
13999
14000     QUnit.test('should partial match arrays of objects', function(assert) {
14001       assert.expect(1);
14002
14003       var objects = [
14004         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
14005         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
14006       ];
14007
14008       var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
14009       assert.deepEqual(actual, [objects[0]]);
14010     });
14011
14012     QUnit.test('should partial match maps', function(assert) {
14013       assert.expect(3);
14014
14015       if (Map) {
14016         var objects = [{ 'a': new Map }, { 'a': new Map }];
14017         objects[0].a.set('a', 1);
14018         objects[1].a.set('a', 1);
14019         objects[1].a.set('b', 2);
14020
14021         var map = new Map;
14022         map.set('b', 2);
14023         var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
14024
14025         assert.deepEqual(actual, [objects[1]]);
14026
14027         map['delete']('b');
14028         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
14029
14030         assert.deepEqual(actual, objects);
14031
14032         map.set('c', 3);
14033         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
14034
14035         assert.deepEqual(actual, []);
14036       }
14037       else {
14038         skipAssert(assert, 3);
14039       }
14040     });
14041
14042     QUnit.test('should partial match sets', function(assert) {
14043       assert.expect(3);
14044
14045       if (Set) {
14046         var objects = [{ 'a': new Set }, { 'a': new Set }];
14047         objects[0].a.add(1);
14048         objects[1].a.add(1);
14049         objects[1].a.add(2);
14050
14051         var set = new Set;
14052         set.add(2);
14053         var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
14054
14055         assert.deepEqual(actual, [objects[1]]);
14056
14057         set['delete'](2);
14058         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
14059
14060         assert.deepEqual(actual, objects);
14061
14062         set.add(3);
14063         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
14064
14065         assert.deepEqual(actual, []);
14066       }
14067       else {
14068         skipAssert(assert, 3);
14069       }
14070     });
14071
14072     QUnit.test('should match `undefined` values', function(assert) {
14073       assert.expect(3);
14074
14075       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14076           actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
14077           expected = [false, false, true];
14078
14079       assert.deepEqual(actual, expected);
14080
14081       actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
14082
14083       assert.deepEqual(actual, expected);
14084
14085       objects = [{ 'a': { 'b': 2 } }, { 'a': { 'b': 2, 'c': 3 } }, { 'a': { 'b': 2, 'c': undefined } }];
14086       actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
14087
14088       assert.deepEqual(actual, expected);
14089     });
14090
14091     QUnit.test('should match `undefined` values on primitives', function(assert) {
14092       assert.expect(3);
14093
14094       numberProto.a = 1;
14095       numberProto.b = undefined;
14096
14097       try {
14098         var matches = _.matches({ 'b': undefined });
14099         assert.strictEqual(matches(1), true);
14100       } catch (e) {
14101         assert.ok(false, e.message);
14102       }
14103       try {
14104         matches = _.matches({ 'a': 1, 'b': undefined });
14105         assert.strictEqual(matches(1), true);
14106       } catch (e) {
14107         assert.ok(false, e.message);
14108       }
14109       numberProto.a = { 'b': 1, 'c': undefined };
14110       try {
14111         matches = _.matches({ 'a': { 'c': undefined } });
14112         assert.strictEqual(matches(1), true);
14113       } catch (e) {
14114         assert.ok(false, e.message);
14115       }
14116       delete numberProto.a;
14117       delete numberProto.b;
14118     });
14119
14120     QUnit.test('should return `false` when `object` is nullish', function(assert) {
14121       assert.expect(1);
14122
14123       var values = [, null, undefined],
14124           expected = lodashStable.map(values, stubFalse),
14125           matches = _.matches({ 'a': 1 });
14126
14127       var actual = lodashStable.map(values, function(value, index) {
14128         try {
14129           return index ? matches(value) : matches();
14130         } catch (e) {}
14131       });
14132
14133       assert.deepEqual(actual, expected);
14134     });
14135
14136     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
14137       assert.expect(1);
14138
14139       var values = [, null, undefined],
14140           expected = lodashStable.map(values, stubTrue),
14141           matches = _.matches({});
14142
14143       var actual = lodashStable.map(values, function(value, index) {
14144         try {
14145           return index ? matches(value) : matches();
14146         } catch (e) {}
14147       });
14148
14149       assert.deepEqual(actual, expected);
14150     });
14151
14152     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
14153       assert.expect(1);
14154
14155       var object = { 'a': 1 },
14156           expected = lodashStable.map(empties, stubTrue);
14157
14158       var actual = lodashStable.map(empties, function(value) {
14159         var matches = _.matches(value);
14160         return matches(object);
14161       });
14162
14163       assert.deepEqual(actual, expected);
14164     });
14165
14166     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
14167       assert.expect(1);
14168
14169       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14170           actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
14171
14172       assert.deepEqual(actual, objects);
14173     });
14174
14175     QUnit.test('should not change behavior if `source` is modified', function(assert) {
14176       assert.expect(9);
14177
14178       var sources = [
14179         { 'a': { 'b': 2, 'c': 3 } },
14180         { 'a': 1, 'b': 2 },
14181         { 'a': 1 }
14182       ];
14183
14184       lodashStable.each(sources, function(source, index) {
14185         var object = lodashStable.cloneDeep(source),
14186             matches = _.matches(source);
14187
14188         assert.strictEqual(matches(object), true);
14189
14190         if (index) {
14191           source.a = 2;
14192           source.b = 1;
14193           source.c = 3;
14194         } else {
14195           source.a.b = 1;
14196           source.a.c = 2;
14197           source.a.d = 3;
14198         }
14199         assert.strictEqual(matches(object), true);
14200         assert.strictEqual(matches(source), false);
14201       });
14202     });
14203   }());
14204
14205   /*--------------------------------------------------------------------------*/
14206
14207   QUnit.module('lodash.matchesProperty');
14208
14209   (function() {
14210     QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
14211       assert.expect(6);
14212
14213       var object = { 'a': 1, 'b': 2, 'c': 3 },
14214           matches = _.matchesProperty('a', 1);
14215
14216       assert.strictEqual(matches.length, 1);
14217       assert.strictEqual(matches(object), true);
14218
14219       matches = _.matchesProperty('b', 3);
14220       assert.strictEqual(matches(object), false);
14221
14222       matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
14223       assert.strictEqual(matches({ 'a': object }), true);
14224
14225       matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
14226       assert.strictEqual(matches(object), false);
14227
14228       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
14229       matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
14230
14231       assert.strictEqual(matches(object), true);
14232     });
14233
14234     QUnit.test('should support deep paths', function(assert) {
14235       assert.expect(2);
14236
14237       var object = { 'a': { 'b': 2 } };
14238
14239       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14240         var matches = _.matchesProperty(path, 2);
14241         assert.strictEqual(matches(object), true);
14242       });
14243     });
14244
14245     QUnit.test('should work with a non-string `path`', function(assert) {
14246       assert.expect(2);
14247
14248       var array = [1, 2, 3];
14249
14250       lodashStable.each([1, [1]], function(path) {
14251         var matches = _.matchesProperty(path, 2);
14252         assert.strictEqual(matches(array), true);
14253       });
14254     });
14255
14256     QUnit.test('should preserve the sign of `0`', function(assert) {
14257       assert.expect(1);
14258
14259       var object1 = { '-0': 'a' },
14260           object2 = { '0': 'b' },
14261           pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
14262           props = [-0, Object(-0), 0, Object(0)],
14263           values = ['a', 'a', 'b', 'b'],
14264           expected = lodashStable.map(props, lodashStable.constant([true, false]));
14265
14266       var actual = lodashStable.map(props, function(key, index) {
14267         var matches = _.matchesProperty(key, values[index]),
14268             pair = pairs[index];
14269
14270         return [matches(pair[0]), matches(pair[1])];
14271       });
14272
14273       assert.deepEqual(actual, expected);
14274     });
14275
14276     QUnit.test('should coerce key to a string', function(assert) {
14277       assert.expect(1);
14278
14279       function fn() {}
14280       fn.toString = lodashStable.constant('fn');
14281
14282       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
14283           values = [null, undefined, fn, {}];
14284
14285       var expected = lodashStable.transform(values, function(result) {
14286         result.push(true, true);
14287       });
14288
14289       var actual = lodashStable.transform(objects, function(result, object, index) {
14290         var key = values[index];
14291         lodashStable.each([key, [key]], function(path) {
14292           var matches = _.matchesProperty(path, object[key]);
14293           result.push(matches(object));
14294         });
14295       });
14296
14297       assert.deepEqual(actual, expected);
14298     });
14299
14300     QUnit.test('should match a key over a path', function(assert) {
14301       assert.expect(2);
14302
14303       var object = { 'a.b': 1, 'a': { 'b': 2 } };
14304
14305       lodashStable.each(['a.b', ['a.b']], function(path) {
14306         var matches = _.matchesProperty(path, 1);
14307         assert.strictEqual(matches(object), true);
14308       });
14309     });
14310
14311     QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
14312       assert.expect(4);
14313
14314       var object = {};
14315
14316       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
14317         var matches = _.matchesProperty(path, 1);
14318         assert.strictEqual(matches(object), false);
14319       });
14320     });
14321
14322     QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
14323       assert.expect(2);
14324
14325       var values = [, null, undefined],
14326           expected = lodashStable.map(values, stubFalse);
14327
14328       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
14329         var matches = _.matchesProperty(path, 1);
14330
14331         var actual = lodashStable.map(values, function(value, index) {
14332           try {
14333             return index ? matches(value) : matches();
14334           } catch (e) {}
14335         });
14336
14337         assert.deepEqual(actual, expected);
14338       });
14339     });
14340
14341     QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
14342       assert.expect(2);
14343
14344       function Foo() {}
14345       Foo.prototype.b = 2;
14346
14347       var object = { 'a': new Foo };
14348
14349       lodashStable.each(['a', ['a']], function(path) {
14350         var matches = _.matchesProperty(path, { 'b': 2 });
14351         assert.strictEqual(matches(object), true);
14352       });
14353     });
14354
14355     QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
14356       assert.expect(2);
14357
14358       function Foo() {
14359         this.a = 1;
14360       }
14361       Foo.prototype.b = 2;
14362
14363       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
14364           expected = lodashStable.map(objects, stubTrue);
14365
14366       lodashStable.each(['a', ['a']], function(path) {
14367         assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
14368       });
14369     });
14370
14371     QUnit.test('should compare a variety of values', function(assert) {
14372       assert.expect(2);
14373
14374       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
14375           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
14376           matches = _.matchesProperty('a', object1);
14377
14378       assert.strictEqual(matches({ 'a': object1 }), true);
14379       assert.strictEqual(matches({ 'a': object2 }), false);
14380     });
14381
14382     QUnit.test('should match `-0` as `0`', function(assert) {
14383       assert.expect(2);
14384
14385       var matches = _.matchesProperty('a', -0);
14386       assert.strictEqual(matches({ 'a': 0 }), true);
14387
14388       matches = _.matchesProperty('a', 0);
14389       assert.strictEqual(matches({ 'a': -0 }), true);
14390     });
14391
14392     QUnit.test('should compare functions by reference', function(assert) {
14393       assert.expect(3);
14394
14395       var object1 = { 'a': lodashStable.noop },
14396           object2 = { 'a': noop },
14397           object3 = { 'a': {} },
14398           matches = _.matchesProperty('a', object1);
14399
14400       assert.strictEqual(matches({ 'a': object1 }), true);
14401       assert.strictEqual(matches({ 'a': object2 }), false);
14402       assert.strictEqual(matches({ 'a': object3 }), false);
14403     });
14404
14405     QUnit.test('should work with a function for `srcValue`', function(assert) {
14406       assert.expect(1);
14407
14408       function Foo() {}
14409       Foo.a = 1;
14410       Foo.b = function() {};
14411       Foo.c = 3;
14412
14413       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
14414           actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
14415
14416       assert.deepEqual(actual, [false, true]);
14417     });
14418
14419     QUnit.test('should work with a non-plain `srcValue`', function(assert) {
14420       assert.expect(1);
14421
14422       function Foo(object) { lodashStable.assign(this, object); }
14423
14424       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
14425           matches = _.matchesProperty('a', { 'b': 1 });
14426
14427       assert.strictEqual(matches(object), true);
14428     });
14429
14430     QUnit.test('should partial match arrays', function(assert) {
14431       assert.expect(3);
14432
14433       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
14434           actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
14435
14436       assert.deepEqual(actual, [objects[1]]);
14437
14438       actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
14439       assert.deepEqual(actual, []);
14440
14441       actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
14442       assert.deepEqual(actual, []);
14443     });
14444
14445     QUnit.test('should partial match arrays with duplicate values', function(assert) {
14446       assert.expect(1);
14447
14448       var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
14449           actual = lodashStable.filter(objects, _.matchesProperty('a', [2, 2]));
14450
14451       assert.deepEqual(actual, [objects[1]]);
14452     });
14453
14454     QUnit.test('should partial match arrays of objects', function(assert) {
14455       assert.expect(1);
14456
14457       var objects = [
14458         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
14459         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
14460       ];
14461
14462       var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
14463       assert.deepEqual(actual, [objects[0]]);
14464     });
14465     QUnit.test('should partial match maps', function(assert) {
14466       assert.expect(3);
14467
14468       if (Map) {
14469         var objects = [{ 'a': new Map }, { 'a': new Map }];
14470         objects[0].a.set('a', 1);
14471         objects[1].a.set('a', 1);
14472         objects[1].a.set('b', 2);
14473
14474         var map = new Map;
14475         map.set('b', 2);
14476         var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14477
14478         assert.deepEqual(actual, [objects[1]]);
14479
14480         map['delete']('b');
14481         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14482
14483         assert.deepEqual(actual, objects);
14484
14485         map.set('c', 3);
14486         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14487
14488         assert.deepEqual(actual, []);
14489       }
14490       else {
14491         skipAssert(assert, 3);
14492       }
14493     });
14494
14495     QUnit.test('should partial match sets', function(assert) {
14496       assert.expect(3);
14497
14498       if (Set) {
14499         var objects = [{ 'a': new Set }, { 'a': new Set }];
14500         objects[0].a.add(1);
14501         objects[1].a.add(1);
14502         objects[1].a.add(2);
14503
14504         var set = new Set;
14505         set.add(2);
14506         var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14507
14508         assert.deepEqual(actual, [objects[1]]);
14509
14510         set['delete'](2);
14511         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14512
14513         assert.deepEqual(actual, objects);
14514
14515         set.add(3);
14516         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14517
14518         assert.deepEqual(actual, []);
14519       }
14520       else {
14521         skipAssert(assert, 3);
14522       }
14523     });
14524
14525     QUnit.test('should match `undefined` values', function(assert) {
14526       assert.expect(2);
14527
14528       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14529           actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
14530           expected = [false, false, true];
14531
14532       assert.deepEqual(actual, expected);
14533
14534       objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
14535       actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
14536
14537       assert.deepEqual(actual, expected);
14538     });
14539
14540     QUnit.test('should match `undefined` values of nested objects', function(assert) {
14541       assert.expect(4);
14542
14543       var object = { 'a': { 'b': undefined } };
14544
14545       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14546         var matches = _.matchesProperty(path, undefined);
14547         assert.strictEqual(matches(object), true);
14548       });
14549
14550       lodashStable.each(['a.a', ['a', 'a']], function(path) {
14551         var matches = _.matchesProperty(path, undefined);
14552         assert.strictEqual(matches(object), false);
14553       });
14554     });
14555
14556     QUnit.test('should match `undefined` values on primitives', function(assert) {
14557       assert.expect(2);
14558
14559       numberProto.a = 1;
14560       numberProto.b = undefined;
14561
14562       try {
14563         var matches = _.matchesProperty('b', undefined);
14564         assert.strictEqual(matches(1), true);
14565       } catch (e) {
14566         assert.ok(false, e.message);
14567       }
14568       numberProto.a = { 'b': 1, 'c': undefined };
14569       try {
14570         matches = _.matchesProperty('a', { 'c': undefined });
14571         assert.strictEqual(matches(1), true);
14572       } catch (e) {
14573         assert.ok(false, e.message);
14574       }
14575       delete numberProto.a;
14576       delete numberProto.b;
14577     });
14578
14579     QUnit.test('should return `false` when `object` is nullish', function(assert) {
14580       assert.expect(2);
14581
14582       var values = [, null, undefined],
14583           expected = lodashStable.map(values, stubFalse);
14584
14585       lodashStable.each(['constructor', ['constructor']], function(path) {
14586         var matches = _.matchesProperty(path, 1);
14587
14588         var actual = lodashStable.map(values, function(value, index) {
14589           try {
14590             return index ? matches(value) : matches();
14591           } catch (e) {}
14592         });
14593
14594         assert.deepEqual(actual, expected);
14595       });
14596     });
14597
14598     QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
14599       assert.expect(1);
14600
14601       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14602           matches = _.matchesProperty('a', { 'a': [], 'b': {} });
14603
14604       var actual = lodashStable.filter(objects, function(object) {
14605         return matches({ 'a': object });
14606       });
14607
14608       assert.deepEqual(actual, objects);
14609     });
14610
14611     QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
14612       assert.expect(9);
14613
14614       lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
14615         var object = lodashStable.cloneDeep(source),
14616             matches = _.matchesProperty('a', source);
14617
14618         assert.strictEqual(matches({ 'a': object }), true);
14619
14620         if (index) {
14621           source.a = 2;
14622           source.b = 1;
14623           source.c = 3;
14624         } else {
14625           source.a.b = 1;
14626           source.a.c = 2;
14627           source.a.d = 3;
14628         }
14629         assert.strictEqual(matches({ 'a': object }), true);
14630         assert.strictEqual(matches({ 'a': source }), false);
14631       });
14632     });
14633   }());
14634
14635   /*--------------------------------------------------------------------------*/
14636
14637   QUnit.module('lodash.max');
14638
14639   (function() {
14640     QUnit.test('should return the largest value from a collection', function(assert) {
14641       assert.expect(1);
14642
14643       assert.strictEqual(_.max([1, 2, 3]), 3);
14644     });
14645
14646     QUnit.test('should return `undefined` for empty collections', function(assert) {
14647       assert.expect(1);
14648
14649       var values = falsey.concat([[]]),
14650           expected = lodashStable.map(values, noop);
14651
14652       var actual = lodashStable.map(values, function(value, index) {
14653         try {
14654           return index ? _.max(value) : _.max();
14655         } catch (e) {}
14656       });
14657
14658       assert.deepEqual(actual, expected);
14659     });
14660
14661     QUnit.test('should work with non-numeric collection values', function(assert) {
14662       assert.expect(1);
14663
14664       assert.strictEqual(_.max(['a', 'b']), 'b');
14665     });
14666   }());
14667
14668   /*--------------------------------------------------------------------------*/
14669
14670   QUnit.module('lodash.mean');
14671
14672   (function() {
14673     QUnit.test('should return the mean of an array of numbers', function(assert) {
14674       assert.expect(1);
14675
14676       var array = [4, 2, 8, 6];
14677       assert.strictEqual(_.mean(array), 5);
14678     });
14679
14680     QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
14681       assert.expect(1);
14682
14683       var expected = lodashStable.map(empties, stubNaN),
14684           actual = lodashStable.map(empties, _.mean);
14685
14686       assert.deepEqual(actual, expected);
14687     });
14688   }());
14689
14690   /*--------------------------------------------------------------------------*/
14691
14692   QUnit.module('lodash.meanBy');
14693
14694   (function() {
14695     var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
14696
14697     QUnit.test('should work with an `iteratee` argument', function(assert) {
14698       assert.expect(1);
14699
14700       var actual = _.meanBy(objects, function(object) {
14701         return object.a;
14702       });
14703
14704       assert.deepEqual(actual, 2);
14705     });
14706
14707     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
14708       assert.expect(1);
14709
14710       var args;
14711
14712       _.meanBy(objects, function() {
14713         args || (args = slice.call(arguments));
14714       });
14715
14716       assert.deepEqual(args, [{ 'a': 2 }]);
14717     });
14718
14719     QUnit.test('should work with `_.property` shorthands', function(assert) {
14720       assert.expect(2);
14721
14722       var arrays = [[2], [3], [1]];
14723       assert.strictEqual(_.meanBy(arrays, 0), 2);
14724       assert.strictEqual(_.meanBy(objects, 'a'), 2);
14725     });
14726   }());
14727
14728   /*--------------------------------------------------------------------------*/
14729
14730   QUnit.module('lodash.memoize');
14731
14732   (function() {
14733     QUnit.test('should memoize results based on the first argument given', function(assert) {
14734       assert.expect(2);
14735
14736       var memoized = _.memoize(function(a, b, c) {
14737         return a + b + c;
14738       });
14739
14740       assert.strictEqual(memoized(1, 2, 3), 6);
14741       assert.strictEqual(memoized(1, 3, 5), 6);
14742     });
14743
14744     QUnit.test('should support a `resolver` argument', function(assert) {
14745       assert.expect(2);
14746
14747       var fn = function(a, b, c) { return a + b + c; },
14748           memoized = _.memoize(fn, fn);
14749
14750       assert.strictEqual(memoized(1, 2, 3), 6);
14751       assert.strictEqual(memoized(1, 3, 5), 9);
14752     });
14753
14754     QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
14755       assert.expect(2);
14756
14757       var fn = function(a, b, c) { return a + this.b + this.c; },
14758           memoized = _.memoize(fn, fn);
14759
14760       var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
14761       assert.strictEqual(object.memoized(1), 6);
14762
14763       object.b = 3;
14764       object.c = 5;
14765       assert.strictEqual(object.memoized(1), 9);
14766     });
14767
14768     QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
14769       assert.expect(1);
14770
14771       assert.raises(function() { _.memoize(noop, true); }, TypeError);
14772     });
14773
14774     QUnit.test('should not error if `resolver` is falsey', function(assert) {
14775       assert.expect(1);
14776
14777       var expected = lodashStable.map(falsey, stubTrue);
14778
14779       var actual = lodashStable.map(falsey, function(resolver, index) {
14780         try {
14781           return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
14782         } catch (e) {}
14783       });
14784
14785       assert.deepEqual(actual, expected);
14786     });
14787
14788     QUnit.test('should check cache for own properties', function(assert) {
14789       assert.expect(1);
14790
14791       var props = [
14792         'constructor',
14793         'hasOwnProperty',
14794         'isPrototypeOf',
14795         'propertyIsEnumerable',
14796         'toLocaleString',
14797         'toString',
14798         'valueOf'
14799       ];
14800
14801       var memoized = _.memoize(identity);
14802
14803       var actual = lodashStable.map(props, function(value) {
14804         return memoized(value);
14805       });
14806
14807       assert.deepEqual(actual, props);
14808     });
14809
14810     QUnit.test('should cache the `__proto__` key', function(assert) {
14811       assert.expect(8);
14812
14813       var array = [],
14814           key = '__proto__';
14815
14816       lodashStable.times(2, function(index) {
14817         var count = 0,
14818             resolver = index && identity;
14819
14820         var memoized = _.memoize(function() {
14821           count++;
14822           return array;
14823         }, resolver);
14824
14825         var cache = memoized.cache;
14826
14827         memoized(key);
14828         memoized(key);
14829
14830         assert.strictEqual(count, 1);
14831         assert.strictEqual(cache.get(key), array);
14832         assert.notOk(cache.__data__ instanceof Array);
14833         assert.strictEqual(cache['delete'](key), true);
14834       });
14835     });
14836
14837     QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
14838       assert.expect(4);
14839
14840       var oldCache = _.memoize.Cache;
14841
14842       function Cache() {
14843         this.__data__ = [];
14844       }
14845
14846       Cache.prototype = {
14847         'get': function(key) {
14848           var entry = _.find(this.__data__, function(entry) {
14849             return key === entry.key;
14850           });
14851           return entry && entry.value;
14852         },
14853         'has': function(key) {
14854           return _.some(this.__data__, function(entry) {
14855             return key === entry.key;
14856           });
14857         },
14858         'set': function(key, value) {
14859           this.__data__.push({ 'key': key, 'value': value });
14860           return this;
14861         }
14862       };
14863
14864       _.memoize.Cache = Cache;
14865
14866       var memoized = _.memoize(function(object) {
14867         return 'value:' + object.id;
14868       });
14869
14870       var cache = memoized.cache,
14871           key1 = { 'id': 'a' },
14872           key2 = { 'id': 'b' };
14873
14874       assert.strictEqual(memoized(key1), 'value:a');
14875       assert.strictEqual(cache.has(key1), true);
14876
14877       assert.strictEqual(memoized(key2), 'value:b');
14878       assert.strictEqual(cache.has(key2), true);
14879
14880       _.memoize.Cache = oldCache;
14881     });
14882
14883     QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
14884       assert.expect(2);
14885
14886       var oldCache = _.memoize.Cache;
14887
14888       function Cache() {
14889         this.__data__ = [];
14890       }
14891
14892       Cache.prototype = {
14893         'get': function(key) {
14894           return _.find(this.__data__, function(entry) {
14895             return key === entry.key;
14896           }).value;
14897         },
14898         'has': function(key) {
14899           return _.some(this.__data__, function(entry) {
14900             return key === entry.key;
14901           });
14902         },
14903         'set': function(key, value) {
14904           var result = new Cache;
14905           result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
14906           return result;
14907         }
14908       };
14909
14910       _.memoize.Cache = Cache;
14911
14912       var memoized = _.memoize(function(object) {
14913         return object.id;
14914       });
14915
14916       var key1 = { 'id': 'a' },
14917           key2 = { 'id': 'b' };
14918
14919       memoized(key1);
14920       memoized(key2);
14921
14922       var cache = memoized.cache;
14923       assert.strictEqual(cache.has(key1), true);
14924       assert.strictEqual(cache.has(key2), true);
14925
14926       _.memoize.Cache = oldCache;
14927     });
14928   }());
14929
14930   /*--------------------------------------------------------------------------*/
14931
14932   QUnit.module('lodash.merge');
14933
14934   (function() {
14935     var args = arguments;
14936
14937     QUnit.test('should merge `source` into `object`', function(assert) {
14938       assert.expect(1);
14939
14940       var names = {
14941         'characters': [
14942           { 'name': 'barney' },
14943           { 'name': 'fred' }
14944         ]
14945       };
14946
14947       var ages = {
14948         'characters': [
14949           { 'age': 36 },
14950           { 'age': 40 }
14951         ]
14952       };
14953
14954       var heights = {
14955         'characters': [
14956           { 'height': '5\'4"' },
14957           { 'height': '5\'5"' }
14958         ]
14959       };
14960
14961       var expected = {
14962         'characters': [
14963           { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
14964           { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
14965         ]
14966       };
14967
14968       assert.deepEqual(_.merge(names, ages, heights), expected);
14969     });
14970
14971     QUnit.test('should merge sources containing circular references', function(assert) {
14972       assert.expect(2);
14973
14974       var object = {
14975         'foo': { 'a': 1 },
14976         'bar': { 'a': 2 }
14977       };
14978
14979       var source = {
14980         'foo': { 'b': { 'c': { 'd': {} } } },
14981         'bar': {}
14982       };
14983
14984       source.foo.b.c.d = source;
14985       source.bar.b = source.foo.b;
14986
14987       var actual = _.merge(object, source);
14988
14989       assert.notStrictEqual(actual.bar.b, actual.foo.b);
14990       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
14991     });
14992
14993     QUnit.test('should work with four arguments', function(assert) {
14994       assert.expect(1);
14995
14996       var expected = { 'a': 4 },
14997           actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
14998
14999       assert.deepEqual(actual, expected);
15000     });
15001
15002     QUnit.test('should merge onto function `object` values', function(assert) {
15003       assert.expect(2);
15004
15005       function Foo() {}
15006
15007       var source = { 'a': 1 },
15008           actual = _.merge(Foo, source);
15009
15010       assert.strictEqual(actual, Foo);
15011       assert.strictEqual(Foo.a, 1);
15012     });
15013
15014     QUnit.test('should not merge onto function values of sources', function(assert) {
15015       assert.expect(3);
15016
15017       var source1 = { 'a': function() {} },
15018           source2 = { 'a': { 'b': 2 } },
15019           actual = _.merge({}, source1, source2);
15020
15021       assert.deepEqual(actual, { 'a': { 'b': 2 } });
15022
15023       actual = _.merge(source1, source2);
15024
15025       assert.strictEqual(typeof actual.a, 'function');
15026       assert.strictEqual(actual.a.b, 2);
15027     });
15028
15029     QUnit.test('should merge onto non-plain `object` values', function(assert) {
15030       assert.expect(2);
15031
15032       function Foo() {}
15033
15034       var object = new Foo,
15035           actual = _.merge(object, { 'a': 1 });
15036
15037       assert.strictEqual(actual, object);
15038       assert.strictEqual(object.a, 1);
15039     });
15040
15041     QUnit.test('should treat sparse array sources as dense', function(assert) {
15042       assert.expect(2);
15043
15044       var array = [1];
15045       array[2] = 3;
15046
15047       var actual = _.merge([], array),
15048           expected = array.slice();
15049
15050       expected[1] = undefined;
15051
15052       assert.ok('1' in actual);
15053       assert.deepEqual(actual, expected);
15054     });
15055
15056     QUnit.test('should merge `arguments` objects', function(assert) {
15057       assert.expect(7);
15058
15059       var object1 = { 'value': args },
15060           object2 = { 'value': { '3': 4 } },
15061           expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
15062           actual = _.merge(object1, object2);
15063
15064       assert.notOk('3' in args);
15065       assert.notOk(_.isArguments(actual.value));
15066       assert.deepEqual(actual.value, expected);
15067       object1.value = args;
15068
15069       actual = _.merge(object2, object1);
15070       assert.notOk(_.isArguments(actual.value));
15071       assert.deepEqual(actual.value, expected);
15072
15073       expected = { '0': 1, '1': 2, '2': 3 };
15074
15075       actual = _.merge({}, object1);
15076       assert.notOk(_.isArguments(actual.value));
15077       assert.deepEqual(actual.value, expected);
15078     });
15079
15080     QUnit.test('should merge typed arrays', function(assert) {
15081       assert.expect(4);
15082
15083       var array1 = [0],
15084           array2 = [0, 0],
15085           array3 = [0, 0, 0, 0],
15086           array4 = [0, 0, 0, 0, 0, 0, 0, 0];
15087
15088       var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
15089           buffer = ArrayBuffer && new ArrayBuffer(8);
15090
15091       // Juggle for `Float64Array` shim.
15092       if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
15093         arrays[1] = array4;
15094       }
15095       var expected = lodashStable.map(typedArrays, function(type, index) {
15096         var array = arrays[index].slice();
15097         array[0] = 1;
15098         return root[type] ? { 'value': array } : false;
15099       });
15100
15101       var actual = lodashStable.map(typedArrays, function(type) {
15102         var Ctor = root[type];
15103         return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
15104       });
15105
15106       assert.ok(lodashStable.isArray(actual));
15107       assert.deepEqual(actual, expected);
15108
15109       expected = lodashStable.map(typedArrays, function(type, index) {
15110         var array = arrays[index].slice();
15111         array.push(1);
15112         return root[type] ? { 'value': array } : false;
15113       });
15114
15115       actual = lodashStable.map(typedArrays, function(type, index) {
15116         var Ctor = root[type],
15117             array = lodashStable.range(arrays[index].length);
15118
15119         array.push(1);
15120         return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
15121       });
15122
15123       assert.ok(lodashStable.isArray(actual));
15124       assert.deepEqual(actual, expected);
15125     });
15126
15127     QUnit.test('should assign `null` values', function(assert) {
15128       assert.expect(1);
15129
15130       var actual = _.merge({ 'a': 1 }, { 'a': null });
15131       assert.strictEqual(actual.a, null);
15132     });
15133
15134     QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
15135       assert.expect(1);
15136
15137       function Foo() {}
15138
15139       var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
15140           expected = lodashStable.map(values, stubTrue);
15141
15142       var actual = lodashStable.map(values, function(value) {
15143         var object = _.merge({}, { 'value': value });
15144         return object.value === value;
15145       });
15146
15147       assert.deepEqual(actual, expected);
15148     });
15149
15150     QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) {
15151       assert.expect(1);
15152
15153       var typedArray = Uint8Array
15154         ? new Uint8Array(new ArrayBuffer(2))
15155         : { 'buffer': [0, 0] };
15156
15157       var props = ['0', 'a', 'buffer'],
15158           values = [[{ 'a': 1 }], { 'a': [1] }, typedArray],
15159           expected = lodashStable.map(values, stubTrue);
15160
15161       var actual = lodashStable.map(values, function(value, index) {
15162         var key = props[index],
15163             object = _.merge({}, { 'value': value }),
15164             newValue = object.value;
15165
15166         return (
15167           newValue !== value &&
15168           newValue[key] !== value[key] &&
15169           lodashStable.isEqual(newValue, value)
15170         );
15171       });
15172
15173       assert.deepEqual(actual, expected);
15174     });
15175
15176     QUnit.test('should not augment source objects', function(assert) {
15177       assert.expect(6);
15178
15179       var source1 = { 'a': [{ 'a': 1 }] },
15180           source2 = { 'a': [{ 'b': 2 }] },
15181           actual = _.merge({}, source1, source2);
15182
15183       assert.deepEqual(source1.a, [{ 'a': 1 }]);
15184       assert.deepEqual(source2.a, [{ 'b': 2 }]);
15185       assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
15186
15187       var source1 = { 'a': [[1, 2, 3]] },
15188           source2 = { 'a': [[3, 4]] },
15189           actual = _.merge({}, source1, source2);
15190
15191       assert.deepEqual(source1.a, [[1, 2, 3]]);
15192       assert.deepEqual(source2.a, [[3, 4]]);
15193       assert.deepEqual(actual.a, [[3, 4, 3]]);
15194     });
15195
15196     QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
15197       assert.expect(4);
15198
15199       function Foo(object) {
15200         lodashStable.assign(this, object);
15201       }
15202
15203       var object = { 'a': 1 },
15204           actual = _.merge(new Foo, object);
15205
15206       assert.ok(actual instanceof Foo);
15207       assert.deepEqual(actual, new Foo(object));
15208
15209       actual = _.merge([new Foo], [object]);
15210       assert.ok(actual[0] instanceof Foo);
15211       assert.deepEqual(actual, [new Foo(object)]);
15212     });
15213
15214     QUnit.test('should not assign `undefined` values', function(assert) {
15215       assert.expect(1);
15216
15217       var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
15218       assert.deepEqual(actual, { 'a': 1 });
15219     });
15220
15221     QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
15222       assert.expect(2);
15223
15224       var array = [1];
15225       array[2] = 3;
15226
15227       var actual = _.merge([4, 5, 6], array),
15228           expected = [1, 5, 3];
15229
15230       assert.deepEqual(actual, expected);
15231
15232       array = [1, , 3];
15233       array[1] = undefined;
15234
15235       actual = _.merge([4, 5, 6], array);
15236       assert.deepEqual(actual, expected);
15237     });
15238
15239     QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
15240       assert.expect(1);
15241
15242       var object = {},
15243           pass = true;
15244
15245       defineProperty(object, 'a', {
15246         'enumerable': true,
15247         'configurable': true,
15248         'get': function() { pass = false; },
15249         'set': function() { pass = false; }
15250       });
15251
15252       _.merge(object, object);
15253       assert.ok(pass);
15254     });
15255
15256     QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
15257       assert.expect(2);
15258
15259       var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
15260           actual = _.merge(object, { 'a': ['x'] });
15261
15262       assert.deepEqual(actual, { 'a': ['x', 'y'] });
15263
15264       actual = _.merge({ 'a': {} }, { 'a': [] });
15265       assert.deepEqual(actual, { 'a': [] });
15266     });
15267
15268     QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
15269       assert.expect(1);
15270
15271       var object = { 'a': 'abcde' },
15272           actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
15273
15274       assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
15275     });
15276
15277     QUnit.test('should not error on DOM elements', function(assert) {
15278       assert.expect(1);
15279
15280       var object1 = { 'el': document && document.createElement('div') },
15281           object2 = { 'el': document && document.createElement('div') },
15282           pairs = [[{}, object1], [object1, object2]],
15283           expected = lodashStable.map(pairs, stubTrue);
15284
15285       var actual = lodashStable.map(pairs, function(pair) {
15286         try {
15287           return _.merge(pair[0], pair[1]).el === pair[1].el;
15288         } catch (e) {}
15289       });
15290
15291       assert.deepEqual(actual, expected);
15292     });
15293   }(1, 2, 3));
15294
15295   /*--------------------------------------------------------------------------*/
15296
15297   QUnit.module('lodash.mergeWith');
15298
15299   (function() {
15300     QUnit.test('should handle merging when `customizer` returns `undefined`', function(assert) {
15301       assert.expect(2);
15302
15303       var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
15304       assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
15305
15306       actual = _.mergeWith([], [undefined], identity);
15307       assert.deepEqual(actual, [undefined]);
15308     });
15309
15310     QUnit.test('should clone sources when `customizer` returns `undefined`', function(assert) {
15311       assert.expect(1);
15312
15313       var source1 = { 'a': { 'b': { 'c': 1 } } },
15314           source2 = { 'a': { 'b': { 'd': 2 } } };
15315
15316       _.mergeWith({}, source1, source2, noop);
15317       assert.deepEqual(source1.a.b, { 'c': 1 });
15318     });
15319
15320     QUnit.test('should defer to `customizer` for non `undefined` results', function(assert) {
15321       assert.expect(1);
15322
15323       var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
15324         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15325       });
15326
15327       assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
15328     });
15329
15330     QUnit.test('should provide `stack` to `customizer`', function(assert) {
15331       assert.expect(1);
15332
15333       var actual;
15334
15335       _.mergeWith({}, { 'a': { 'b': 2 } }, function() {
15336         actual = _.last(arguments);
15337       });
15338
15339       assert.ok(isNpm
15340         ? actual.constructor.name == 'Stack'
15341         : actual instanceof mapCaches.Stack
15342       );
15343     });
15344
15345     QUnit.test('should overwrite primitives with source object clones', function(assert) {
15346       assert.expect(1);
15347
15348       var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
15349         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15350       });
15351
15352       assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
15353     });
15354
15355     QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
15356       assert.expect(1);
15357
15358       var array = ['b', 'c'],
15359           object = { 'a': ['a'] },
15360           source = { 'a': array, 'b': array };
15361
15362       var actual = _.mergeWith(object, source, function(a, b) {
15363         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15364       });
15365
15366       assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
15367     });
15368   }());
15369
15370   /*--------------------------------------------------------------------------*/
15371
15372   QUnit.module('lodash.method');
15373
15374   (function() {
15375     QUnit.test('should create a function that calls a method of a given object', function(assert) {
15376       assert.expect(4);
15377
15378       var object = { 'a': stubOne };
15379
15380       lodashStable.each(['a', ['a']], function(path) {
15381         var method = _.method(path);
15382         assert.strictEqual(method.length, 1);
15383         assert.strictEqual(method(object), 1);
15384       });
15385     });
15386
15387     QUnit.test('should work with deep property values', function(assert) {
15388       assert.expect(2);
15389
15390       var object = { 'a': { 'b': stubTwo } };
15391
15392       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15393         var method = _.method(path);
15394         assert.strictEqual(method(object), 2);
15395       });
15396     });
15397
15398     QUnit.test('should work with a non-string `path`', function(assert) {
15399       assert.expect(2);
15400
15401       var array = lodashStable.times(3, _.constant);
15402
15403       lodashStable.each([1, [1]], function(path) {
15404         var method = _.method(path);
15405         assert.strictEqual(method(array), 1);
15406       });
15407     });
15408
15409     QUnit.test('should coerce key to a string', function(assert) {
15410       assert.expect(1);
15411
15412       function fn() {}
15413       fn.toString = lodashStable.constant('fn');
15414
15415       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15416           objects = [{ 'null': stubOne }, { 'undefined': stubTwo }, { 'fn': stubThree }, { '[object Object]': stubFour }],
15417           values = [null, undefined, fn, {}];
15418
15419       var actual = lodashStable.transform(objects, function(result, object, index) {
15420         var key = values[index];
15421         lodashStable.each([key, [key]], function(path) {
15422           var method = _.method(key);
15423           result.push(method(object));
15424         });
15425       });
15426
15427       assert.deepEqual(actual, expected);
15428     });
15429
15430     QUnit.test('should work with inherited property values', function(assert) {
15431       assert.expect(2);
15432
15433       function Foo() {}
15434       Foo.prototype.a = stubOne;
15435
15436       lodashStable.each(['a', ['a']], function(path) {
15437         var method = _.method(path);
15438         assert.strictEqual(method(new Foo), 1);
15439       });
15440     });
15441
15442     QUnit.test('should use a key over a path', function(assert) {
15443       assert.expect(2);
15444
15445       var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15446
15447       lodashStable.each(['a.b', ['a.b']], function(path) {
15448         var method = _.method(path);
15449         assert.strictEqual(method(object), 1);
15450       });
15451     });
15452
15453     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15454       assert.expect(2);
15455
15456       var values = [, null, undefined],
15457           expected = lodashStable.map(values, noop);
15458
15459       lodashStable.each(['constructor', ['constructor']], function(path) {
15460         var method = _.method(path);
15461
15462         var actual = lodashStable.map(values, function(value, index) {
15463           return index ? method(value) : method();
15464         });
15465
15466         assert.deepEqual(actual, expected);
15467       });
15468     });
15469
15470     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15471       assert.expect(2);
15472
15473       var values = [, null, undefined],
15474           expected = lodashStable.map(values, noop);
15475
15476       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15477         var method = _.method(path);
15478
15479         var actual = lodashStable.map(values, function(value, index) {
15480           return index ? method(value) : method();
15481         });
15482
15483         assert.deepEqual(actual, expected);
15484       });
15485     });
15486
15487     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15488       assert.expect(4);
15489
15490       var object = {};
15491
15492       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15493         var method = _.method(path);
15494         assert.strictEqual(method(object), undefined);
15495       });
15496     });
15497
15498     QUnit.test('should apply partial arguments to function', function(assert) {
15499       assert.expect(2);
15500
15501       var object = {
15502         'fn': function() {
15503           return slice.call(arguments);
15504         }
15505       };
15506
15507       lodashStable.each(['fn', ['fn']], function(path) {
15508         var method = _.method(path, 1, 2, 3);
15509         assert.deepEqual(method(object), [1, 2, 3]);
15510       });
15511     });
15512
15513     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15514       assert.expect(2);
15515
15516       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
15517
15518       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15519         var method = _.method(path);
15520         assert.strictEqual(method(object), 1);
15521       });
15522     });
15523   }());
15524
15525   /*--------------------------------------------------------------------------*/
15526
15527   QUnit.module('lodash.methodOf');
15528
15529   (function() {
15530     QUnit.test('should create a function that calls a method of a given key', function(assert) {
15531       assert.expect(4);
15532
15533       var object = { 'a': stubOne };
15534
15535       lodashStable.each(['a', ['a']], function(path) {
15536         var methodOf = _.methodOf(object);
15537         assert.strictEqual(methodOf.length, 1);
15538         assert.strictEqual(methodOf(path), 1);
15539       });
15540     });
15541
15542     QUnit.test('should work with deep property values', function(assert) {
15543       assert.expect(2);
15544
15545       var object = { 'a': { 'b': stubTwo } };
15546
15547       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15548         var methodOf = _.methodOf(object);
15549         assert.strictEqual(methodOf(path), 2);
15550       });
15551     });
15552
15553     QUnit.test('should work with a non-string `path`', function(assert) {
15554       assert.expect(2);
15555
15556       var array = lodashStable.times(3, _.constant);
15557
15558       lodashStable.each([1, [1]], function(path) {
15559         var methodOf = _.methodOf(array);
15560         assert.strictEqual(methodOf(path), 1);
15561       });
15562     });
15563
15564     QUnit.test('should coerce key to a string', function(assert) {
15565       assert.expect(1);
15566
15567       function fn() {}
15568       fn.toString = lodashStable.constant('fn');
15569
15570       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15571           objects = [{ 'null': stubOne }, { 'undefined': stubTwo }, { 'fn': stubThree }, { '[object Object]': stubFour }],
15572           values = [null, undefined, fn, {}];
15573
15574       var actual = lodashStable.transform(objects, function(result, object, index) {
15575         var key = values[index];
15576         lodashStable.each([key, [key]], function(path) {
15577           var methodOf = _.methodOf(object);
15578           result.push(methodOf(key));
15579         });
15580       });
15581
15582       assert.deepEqual(actual, expected);
15583     });
15584
15585     QUnit.test('should work with inherited property values', function(assert) {
15586       assert.expect(2);
15587
15588       function Foo() {}
15589       Foo.prototype.a = stubOne;
15590
15591       lodashStable.each(['a', ['a']], function(path) {
15592         var methodOf = _.methodOf(new Foo);
15593         assert.strictEqual(methodOf(path), 1);
15594       });
15595     });
15596
15597     QUnit.test('should use a key over a path', function(assert) {
15598       assert.expect(2);
15599
15600       var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15601
15602       lodashStable.each(['a.b', ['a.b']], function(path) {
15603         var methodOf = _.methodOf(object);
15604         assert.strictEqual(methodOf(path), 1);
15605       });
15606     });
15607
15608     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15609       assert.expect(2);
15610
15611       var values = [, null, undefined],
15612           expected = lodashStable.map(values, noop);
15613
15614       lodashStable.each(['constructor', ['constructor']], function(path) {
15615         var actual = lodashStable.map(values, function(value, index) {
15616           var methodOf = index ? _.methodOf() : _.methodOf(value);
15617           return methodOf(path);
15618         });
15619
15620         assert.deepEqual(actual, expected);
15621       });
15622     });
15623
15624     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15625       assert.expect(2);
15626
15627       var values = [, null, undefined],
15628           expected = lodashStable.map(values, noop);
15629
15630       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15631         var actual = lodashStable.map(values, function(value, index) {
15632           var methodOf = index ? _.methodOf() : _.methodOf(value);
15633           return methodOf(path);
15634         });
15635
15636         assert.deepEqual(actual, expected);
15637       });
15638     });
15639
15640     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15641       assert.expect(4);
15642
15643       var object = {},
15644           methodOf = _.methodOf(object);
15645
15646       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15647         assert.strictEqual(methodOf(path), undefined);
15648       });
15649     });
15650
15651     QUnit.test('should apply partial arguments to function', function(assert) {
15652       assert.expect(2);
15653
15654       var object = {
15655         'fn': function() {
15656           return slice.call(arguments);
15657         }
15658       };
15659
15660       var methodOf = _.methodOf(object, 1, 2, 3);
15661
15662       lodashStable.each(['fn', ['fn']], function(path) {
15663         assert.deepEqual(methodOf(path), [1, 2, 3]);
15664       });
15665     });
15666
15667     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15668       assert.expect(2);
15669
15670       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
15671           methodOf = _.methodOf(object);
15672
15673       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15674         assert.strictEqual(methodOf(path), 1);
15675       });
15676     });
15677   }());
15678
15679   /*--------------------------------------------------------------------------*/
15680
15681   QUnit.module('lodash.min');
15682
15683   (function() {
15684     QUnit.test('should return the smallest value from a collection', function(assert) {
15685       assert.expect(1);
15686
15687       assert.strictEqual(_.min([1, 2, 3]), 1);
15688     });
15689
15690     QUnit.test('should return `undefined` for empty collections', function(assert) {
15691       assert.expect(1);
15692
15693       var values = falsey.concat([[]]),
15694           expected = lodashStable.map(values, noop);
15695
15696       var actual = lodashStable.map(values, function(value, index) {
15697         try {
15698           return index ? _.min(value) : _.min();
15699         } catch (e) {}
15700       });
15701
15702       assert.deepEqual(actual, expected);
15703     });
15704
15705     QUnit.test('should work with non-numeric collection values', function(assert) {
15706       assert.expect(1);
15707
15708       assert.strictEqual(_.min(['a', 'b']), 'a');
15709     });
15710   }());
15711
15712   /*--------------------------------------------------------------------------*/
15713
15714   QUnit.module('extremum methods');
15715
15716   lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
15717     var func = _[methodName],
15718         isMax = /^max/.test(methodName);
15719
15720     QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
15721       assert.expect(1);
15722
15723       var curr = new Date,
15724           past = new Date(0);
15725
15726       assert.strictEqual(func([curr, past]), isMax ? curr : past);
15727     });
15728
15729     QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
15730       assert.expect(1);
15731
15732       var array = lodashStable.range(0, 5e5);
15733       assert.strictEqual(func(array), isMax ? 499999 : 0);
15734     });
15735
15736     QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
15737       assert.expect(1);
15738
15739       if (!isNpm) {
15740         var actual = _([40])[methodName]();
15741         assert.strictEqual(actual, 40);
15742       }
15743       else {
15744         skipAssert(assert);
15745       }
15746     });
15747   });
15748
15749   lodashStable.each(['maxBy', 'minBy'], function(methodName) {
15750     var array = [1, 2, 3],
15751         func = _[methodName],
15752         isMax = methodName == 'maxBy';
15753
15754     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
15755       assert.expect(1);
15756
15757       var actual = func(array, function(n) {
15758         return -n;
15759       });
15760
15761       assert.strictEqual(actual, isMax ? 1 : 3);
15762     });
15763
15764     QUnit.test('should work with `_.property` shorthands', function(assert) {
15765       assert.expect(2);
15766
15767       var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
15768           actual = func(objects, 'a');
15769
15770       assert.deepEqual(actual, objects[isMax ? 1 : 2]);
15771
15772       var arrays = [[2], [3], [1]];
15773       actual = func(arrays, 0);
15774
15775       assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
15776     });
15777
15778     QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
15779       assert.expect(1);
15780
15781       var value = isMax ? -Infinity : Infinity,
15782           object = { 'a': value };
15783
15784       var actual = func([object, { 'a': value }], function(object) {
15785         return object.a;
15786       });
15787
15788       assert.strictEqual(actual, object);
15789     });
15790   });
15791
15792   /*--------------------------------------------------------------------------*/
15793
15794   QUnit.module('lodash.mixin');
15795
15796   (function() {
15797     function reset(wrapper) {
15798       delete wrapper.a;
15799       delete wrapper.prototype.a;
15800       delete wrapper.b;
15801       delete wrapper.prototype.b;
15802     }
15803
15804     function Wrapper(value) {
15805       if (!(this instanceof Wrapper)) {
15806         return new Wrapper(value);
15807       }
15808       if (_.has(value, '__wrapped__')) {
15809         var actions = slice.call(value.__actions__),
15810             chain = value.__chain__;
15811
15812         value = value.__wrapped__;
15813       }
15814       this.__wrapped__ = value;
15815       this.__actions__ = actions || [];
15816       this.__chain__ = chain || false;
15817     }
15818
15819     Wrapper.prototype.value = function() {
15820       return getUnwrappedValue(this);
15821     };
15822
15823     var array = ['a'],
15824         source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
15825
15826     QUnit.test('should mixin `source` methods into lodash', function(assert) {
15827       assert.expect(4);
15828
15829       if (!isNpm) {
15830         _.mixin(source);
15831
15832         assert.strictEqual(_.a(array), 'a');
15833         assert.strictEqual(_(array).a().value(), 'a');
15834         assert.notOk('b' in _);
15835         assert.notOk('b' in _.prototype);
15836
15837         reset(_);
15838       }
15839       else {
15840         skipAssert(assert, 4);
15841       }
15842     });
15843
15844     QUnit.test('should mixin chaining methods by reference', function(assert) {
15845       assert.expect(2);
15846
15847       if (!isNpm) {
15848         _.mixin(source);
15849         _.a = stubB;
15850
15851         assert.strictEqual(_.a(array), 'b');
15852         assert.strictEqual(_(array).a().value(), 'a');
15853
15854         reset(_);
15855       }
15856       else {
15857         skipAssert(assert, 2);
15858       }
15859     });
15860
15861     QUnit.test('should use a default `object` of `this`', function(assert) {
15862       assert.expect(3);
15863
15864       var object = lodashStable.create(_);
15865       object.mixin(source);
15866
15867       assert.strictEqual(object.a(array), 'a');
15868       assert.notOk('a' in _);
15869       assert.notOk('a' in _.prototype);
15870
15871       reset(_);
15872     });
15873
15874     QUnit.test('should accept an `object` argument', function(assert) {
15875       assert.expect(1);
15876
15877       var object = {};
15878       _.mixin(object, source);
15879       assert.strictEqual(object.a(array), 'a');
15880     });
15881
15882     QUnit.test('should accept a function `object`', function(assert) {
15883       assert.expect(2);
15884
15885       _.mixin(Wrapper, source);
15886
15887       var wrapped = Wrapper(array),
15888           actual = wrapped.a();
15889
15890       assert.strictEqual(actual.value(), 'a');
15891       assert.ok(actual instanceof Wrapper);
15892
15893       reset(Wrapper);
15894     });
15895
15896     QUnit.test('should return `object`', function(assert) {
15897       assert.expect(3);
15898
15899       var object = {};
15900       assert.strictEqual(_.mixin(object, source), object);
15901       assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
15902       assert.strictEqual(_.mixin(), _);
15903
15904       reset(Wrapper);
15905     });
15906
15907     QUnit.test('should not assign inherited `source` methods', function(assert) {
15908       assert.expect(1);
15909
15910       function Foo() {}
15911       Foo.prototype.a = noop;
15912
15913       var object = {};
15914       assert.strictEqual(_.mixin(object, new Foo), object);
15915     });
15916
15917     QUnit.test('should accept an `options` argument', function(assert) {
15918       assert.expect(8);
15919
15920       function message(func, chain) {
15921         return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
15922       }
15923
15924       lodashStable.each([_, Wrapper], function(func) {
15925         lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
15926           if (!isNpm) {
15927             if (func === _) {
15928               _.mixin(source, options);
15929             } else {
15930               _.mixin(func, source, options);
15931             }
15932             var wrapped = func(array),
15933                 actual = wrapped.a();
15934
15935             if (options.chain) {
15936               assert.strictEqual(actual.value(), 'a', message(func, true));
15937               assert.ok(actual instanceof func, message(func, true));
15938             } else {
15939               assert.strictEqual(actual, 'a', message(func, false));
15940               assert.notOk(actual instanceof func, message(func, false));
15941             }
15942             reset(func);
15943           }
15944           else {
15945             skipAssert(assert, 2);
15946           }
15947         });
15948       });
15949     });
15950
15951     QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
15952       assert.expect(1);
15953
15954       _.mixin({ 'a': noop }, {});
15955       assert.notOk('a' in _);
15956       reset(_);
15957     });
15958
15959     QUnit.test('should not error for non-object `options` values', function(assert) {
15960       assert.expect(2);
15961
15962       var pass = true;
15963
15964       try {
15965         _.mixin({}, source, 1);
15966       } catch (e) {
15967         pass = false;
15968       }
15969       assert.ok(pass);
15970
15971       pass = true;
15972
15973       try {
15974         _.mixin(source, 1);
15975       } catch (e) {
15976         pass = false;
15977       }
15978       assert.ok(pass);
15979
15980       reset(_);
15981     });
15982
15983     QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
15984       assert.expect(2);
15985
15986       lodashStable.each([_, Wrapper], function(func) {
15987         if (!isNpm) {
15988           if (func === _) {
15989             var wrapped = _(source),
15990                 actual = wrapped.mixin();
15991
15992             assert.strictEqual(actual.value(), _);
15993           }
15994           else {
15995             wrapped = _(func);
15996             actual = wrapped.mixin(source);
15997             assert.notStrictEqual(actual, wrapped);
15998           }
15999           reset(func);
16000         }
16001         else {
16002           skipAssert(assert);
16003         }
16004       });
16005     });
16006
16007     QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
16008       assert.expect(1);
16009
16010       if (!isNpm) {
16011         _.mixin({ 'a': _.countBy, 'b': _.filter });
16012
16013         var array = lodashStable.range(LARGE_ARRAY_SIZE),
16014             actual = _(array).a().map(square).b(isEven).take().value();
16015
16016         assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
16017
16018         reset(_);
16019       }
16020       else {
16021         skipAssert(assert);
16022       }
16023     });
16024   }());
16025
16026   /*--------------------------------------------------------------------------*/
16027
16028   QUnit.module('lodash.multiply');
16029
16030   (function() {
16031     QUnit.test('should multiply two numbers', function(assert) {
16032       assert.expect(3);
16033
16034       assert.strictEqual(_.multiply(6, 4), 24);
16035       assert.strictEqual(_.multiply(-6, 4), -24);
16036       assert.strictEqual(_.multiply(-6, -4), 24);
16037     });
16038
16039     QUnit.test('should coerce arguments to numbers', function(assert) {
16040       assert.expect(2);
16041
16042       assert.strictEqual(_.multiply('6', '4'), 24);
16043       assert.deepEqual(_.multiply('x', 'y'), NaN);
16044     });
16045   }());
16046
16047   /*--------------------------------------------------------------------------*/
16048
16049   QUnit.module('lodash.orderBy');
16050
16051   (function() {
16052     var objects = [
16053       { 'a': 'x', 'b': 3 },
16054       { 'a': 'y', 'b': 4 },
16055       { 'a': 'x', 'b': 1 },
16056       { 'a': 'y', 'b': 2 }
16057     ];
16058
16059     QUnit.test('should sort by a single property by a specified order', function(assert) {
16060       assert.expect(1);
16061
16062       var actual = _.orderBy(objects, 'a', 'desc');
16063       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
16064     });
16065
16066     QUnit.test('should sort by multiple properties by specified orders', function(assert) {
16067       assert.expect(1);
16068
16069       var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
16070       assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
16071     });
16072
16073     QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
16074       assert.expect(2);
16075
16076       var expected = [objects[2], objects[0], objects[3], objects[1]],
16077           actual = _.orderBy(objects, ['a', 'b']);
16078
16079       assert.deepEqual(actual, expected);
16080
16081       expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
16082
16083       actual = lodashStable.map(falsey, function(order, index) {
16084         return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
16085       });
16086
16087       assert.deepEqual(actual, expected);
16088     });
16089
16090     QUnit.test('should work with `orders` specified as string objects', function(assert) {
16091       assert.expect(1);
16092
16093       var actual = _.orderBy(objects, ['a'], [Object('desc')]);
16094       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
16095     });
16096   }());
16097
16098   /*--------------------------------------------------------------------------*/
16099
16100   QUnit.module('lodash.overArgs');
16101
16102   (function() {
16103     function fn() {
16104       return slice.call(arguments);
16105     }
16106
16107     QUnit.test('should transform each argument', function(assert) {
16108       assert.expect(1);
16109
16110       var over = _.overArgs(fn, doubled, square);
16111       assert.deepEqual(over(5, 10), [10, 100]);
16112     });
16113
16114     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16115       assert.expect(1);
16116
16117       var over = _.overArgs(fn, undefined, null);
16118       assert.deepEqual(over('a', 'b'), ['a', 'b']);
16119     });
16120
16121     QUnit.test('should work with `_.property` shorthands', function(assert) {
16122       assert.expect(1);
16123
16124       var over = _.overArgs(fn, 'b', 'a');
16125       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
16126     });
16127
16128     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16129       assert.expect(1);
16130
16131       var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
16132       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16133     });
16134
16135     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16136       assert.expect(1);
16137
16138       var over = _.overArgs(fn, ['b', 1], [['a', 1]]);
16139       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16140     });
16141
16142     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16143       assert.expect(2);
16144
16145       var over = _.overArgs(fn, ['a', 1]);
16146       assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
16147
16148       over = _.overArgs(fn, [['a', 1]]);
16149       assert.deepEqual(over({ 'a': 1 }), [true]);
16150     });
16151
16152     QUnit.test('should flatten `transforms`', function(assert) {
16153       assert.expect(1);
16154
16155       var over = _.overArgs(fn, [doubled, square], String);
16156       assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
16157     });
16158
16159     QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
16160       assert.expect(1);
16161
16162       var over = _.overArgs(fn, doubled, square);
16163       assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
16164     });
16165
16166     QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
16167       assert.expect(1);
16168
16169       var over = _.overArgs(fn);
16170       assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
16171     });
16172
16173     QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
16174       assert.expect(1);
16175
16176       var over = _.overArgs(fn, doubled, identity);
16177       assert.deepEqual(over(5), [10]);
16178     });
16179
16180     QUnit.test('should provide the correct argument to each transform', function(assert) {
16181       assert.expect(1);
16182
16183       var argsList = [],
16184           transform = function() { argsList.push(slice.call(arguments)); },
16185           over = _.overArgs(noop, transform, transform, transform);
16186
16187       over('a', 'b');
16188       assert.deepEqual(argsList, [['a'], ['b']]);
16189     });
16190
16191     QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
16192       assert.expect(1);
16193
16194       var over = _.overArgs(function(x) {
16195         return this[x];
16196       }, function(x) {
16197         return this === x;
16198       });
16199
16200       var object = { 'over': over, 'true': 1 };
16201       assert.strictEqual(object.over(object), 1);
16202     });
16203   }());
16204
16205   /*--------------------------------------------------------------------------*/
16206
16207   QUnit.module('lodash.negate');
16208
16209   (function() {
16210     QUnit.test('should create a function that negates the result of `func`', function(assert) {
16211       assert.expect(2);
16212
16213       var negate = _.negate(isEven);
16214
16215       assert.strictEqual(negate(1), true);
16216       assert.strictEqual(negate(2), false);
16217     });
16218   }());
16219
16220   /*--------------------------------------------------------------------------*/
16221
16222   QUnit.module('lodash.noConflict');
16223
16224   (function() {
16225     QUnit.test('should return the `lodash` function', function(assert) {
16226       assert.expect(2);
16227
16228       if (!isModularize) {
16229         assert.strictEqual(_.noConflict(), oldDash);
16230         assert.notStrictEqual(root._, oldDash);
16231         root._ = oldDash;
16232       }
16233       else {
16234         skipAssert(assert, 2);
16235       }
16236     });
16237
16238     QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
16239       assert.expect(2);
16240
16241       if (!isModularize) {
16242         var object = root._ = {};
16243         assert.strictEqual(_.noConflict(), oldDash);
16244         assert.strictEqual(root._, object);
16245         root._ = oldDash;
16246       }
16247       else {
16248         skipAssert(assert, 2);
16249       }
16250     });
16251
16252     QUnit.test('should work with a `root` of `this`', function(assert) {
16253       assert.expect(2);
16254
16255       if (!coverage && !document && !isModularize && realm.object) {
16256         var fs = require('fs'),
16257             vm = require('vm'),
16258             expected = {},
16259             context = vm.createContext({ '_': expected, 'console': console }),
16260             source = fs.readFileSync(filePath, 'utf8');
16261
16262         vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
16263
16264         assert.strictEqual(context._, expected);
16265         assert.ok(context.lodash);
16266       }
16267       else {
16268         skipAssert(assert, 2);
16269       }
16270     });
16271   }());
16272
16273   /*--------------------------------------------------------------------------*/
16274
16275   QUnit.module('lodash.now');
16276
16277   (function() {
16278     QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
16279       assert.expect(2);
16280
16281       var done = assert.async();
16282
16283       var stamp = +new Date,
16284           actual = _.now();
16285
16286       assert.ok(actual >= stamp);
16287
16288       setTimeout(function() {
16289         assert.ok(_.now() > actual);
16290         done();
16291       }, 32);
16292     });
16293
16294     QUnit.test('should work with mocked `Date.now`', function(assert) {
16295       assert.expect(1);
16296
16297       var now = Date.now;
16298       Date.now = stubA;
16299
16300       var actual = _.now();
16301       Date.now = now;
16302
16303       assert.strictEqual(actual, 'a');
16304     });
16305   }());
16306
16307   /*--------------------------------------------------------------------------*/
16308
16309   QUnit.module('lodash.nth');
16310
16311   (function() {
16312     var array = ['a', 'b', 'c', 'd'];
16313
16314     QUnit.test('should get the nth element of `array`', function(assert) {
16315       assert.expect(1);
16316
16317       var actual = lodashStable.map(array, function(value, index) {
16318         return _.nth(array, index);
16319       });
16320
16321       assert.deepEqual(actual, array);
16322     });
16323
16324     QUnit.test('should work with a negative `n`', function(assert) {
16325       assert.expect(1);
16326
16327       var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
16328         return _.nth(array, -n);
16329       });
16330
16331       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16332     });
16333
16334     QUnit.test('should coerce `n` to an integer', function(assert) {
16335       assert.expect(2);
16336
16337       var values = falsey,
16338           expected = lodashStable.map(values, stubA);
16339
16340       var actual = lodashStable.map(values, function(n) {
16341         return n ? _.nth(array, n) : _.nth(array);
16342       });
16343
16344       assert.deepEqual(actual, expected);
16345
16346       values = ['1', 1.6];
16347       expected = lodashStable.map(values, stubB);
16348
16349       actual = lodashStable.map(values, function(n) {
16350         return _.nth(array, n);
16351       });
16352
16353       assert.deepEqual(actual, expected);
16354     });
16355
16356     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16357       assert.expect(1);
16358
16359       var values = [null, undefined, []],
16360           expected = lodashStable.map(values, noop);
16361
16362       var actual = lodashStable.map(values, function(array) {
16363         return _.nth(array, 1);
16364       });
16365
16366       assert.deepEqual(actual, expected);
16367     });
16368
16369     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16370       assert.expect(1);
16371
16372       var array = [1, 2],
16373           values = [Infinity, array.length],
16374           expected = lodashStable.map(values, noop);
16375
16376       array[-1] = 3;
16377
16378       var actual = lodashStable.map(values, function(n) {
16379         return _.nth(array, n);
16380       });
16381
16382       assert.deepEqual(actual, expected);
16383     });
16384   }());
16385
16386   /*--------------------------------------------------------------------------*/
16387
16388   QUnit.module('lodash.nthArg');
16389
16390   (function() {
16391     var args = ['a', 'b', 'c', 'd'];
16392
16393     QUnit.test('should create a function that returns its nth argument', function(assert) {
16394       assert.expect(1);
16395
16396       var actual = lodashStable.map(args, function(value, index) {
16397         var func = _.nthArg(index);
16398         return func.apply(undefined, args);
16399       });
16400
16401       assert.deepEqual(actual, args);
16402     });
16403
16404     QUnit.test('should work with a negative `n`', function(assert) {
16405       assert.expect(1);
16406
16407       var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
16408         var func = _.nthArg(-n);
16409         return func.apply(undefined, args);
16410       });
16411
16412       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16413     });
16414
16415     QUnit.test('should coerce `n` to an integer', function(assert) {
16416       assert.expect(2);
16417
16418       var values = falsey,
16419           expected = lodashStable.map(values, stubA);
16420
16421       var actual = lodashStable.map(values, function(n) {
16422         var func = n ? _.nthArg(n) : _.nthArg();
16423         return func.apply(undefined, args);
16424       });
16425
16426       assert.deepEqual(actual, expected);
16427
16428       values = ['1', 1.6];
16429       expected = lodashStable.map(values, stubB);
16430
16431       actual = lodashStable.map(values, function(n) {
16432         var func = _.nthArg(n);
16433         return func.apply(undefined, args);
16434       });
16435
16436       assert.deepEqual(actual, expected);
16437     });
16438
16439     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16440       assert.expect(1);
16441
16442       var func = _.nthArg(1);
16443       assert.strictEqual(func(), undefined);
16444     });
16445
16446     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16447       assert.expect(1);
16448
16449       var values = [Infinity, args.length],
16450           expected = lodashStable.map(values, noop);
16451
16452       var actual = lodashStable.map(values, function(n) {
16453         var func = _.nthArg(n);
16454         return func.apply(undefined, args);
16455       });
16456
16457       assert.deepEqual(actual, expected);
16458     });
16459   }());
16460
16461   /*--------------------------------------------------------------------------*/
16462
16463   QUnit.module('lodash.omit');
16464
16465   (function() {
16466     var args = arguments,
16467         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16468
16469     QUnit.test('should flatten `props`', function(assert) {
16470       assert.expect(2);
16471
16472       assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
16473       assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
16474     });
16475
16476     QUnit.test('should work with a primitive `object` argument', function(assert) {
16477       assert.expect(1);
16478
16479       stringProto.a = 1;
16480       stringProto.b = 2;
16481
16482       assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
16483
16484       delete stringProto.a;
16485       delete stringProto.b;
16486     });
16487
16488     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16489       assert.expect(2);
16490
16491       objectProto.a = 1;
16492       lodashStable.each([null, undefined], function(value) {
16493         assert.deepEqual(_.omit(value, 'valueOf'), {});
16494       });
16495       delete objectProto.a;
16496     });
16497
16498     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
16499       assert.expect(1);
16500
16501       assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
16502     });
16503
16504     QUnit.test('should coerce property names to strings', function(assert) {
16505       assert.expect(1);
16506
16507       assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
16508     });
16509   }('a', 'c'));
16510
16511   /*--------------------------------------------------------------------------*/
16512
16513   QUnit.module('lodash.omitBy');
16514
16515   (function() {
16516     QUnit.test('should work with a predicate argument', function(assert) {
16517       assert.expect(1);
16518
16519       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16520
16521       var actual = _.omitBy(object, function(n) {
16522         return n != 2 && n != 4;
16523       });
16524
16525       assert.deepEqual(actual, { 'b': 2, 'd': 4 });
16526     });
16527   }());
16528
16529   /*--------------------------------------------------------------------------*/
16530
16531   QUnit.module('omit methods');
16532
16533   lodashStable.each(['omit', 'omitBy'], function(methodName) {
16534     var expected = { 'b': 2, 'd': 4 },
16535         func = _[methodName],
16536         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16537         resolve = lodashStable.nthArg(1);
16538
16539     if (methodName == 'omitBy') {
16540       resolve = function(object, props) {
16541         props = lodashStable.castArray(props);
16542         return function(value) {
16543           return lodashStable.some(props, function(key) {
16544             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
16545             return object[key] === value;
16546           });
16547         };
16548       };
16549     }
16550     QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
16551       assert.expect(2);
16552
16553       assert.deepEqual(func(object, resolve(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
16554       assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
16555     });
16556
16557     QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
16558       assert.expect(1);
16559
16560       function Foo() {}
16561       Foo.prototype = object;
16562
16563       assert.deepEqual(func(new Foo, resolve(object, ['a', 'c'])), expected);
16564     });
16565
16566     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
16567       assert.expect(1);
16568
16569       var object = { '-0': 'a', '0': 'b' },
16570           props = [-0, Object(-0), 0, Object(0)],
16571           expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
16572
16573       var actual = lodashStable.map(props, function(key) {
16574         return func(object, resolve(object, key));
16575       });
16576
16577       assert.deepEqual(actual, expected);
16578     });
16579
16580     QUnit.test('`_.' + methodName + '` should include symbol properties', function(assert) {
16581       assert.expect(2);
16582
16583       function Foo() {
16584         this.a = 0;
16585         this[symbol] = 1;
16586       }
16587
16588       if (Symbol) {
16589         var symbol2 = Symbol('b');
16590         Foo.prototype[symbol2] = 2;
16591
16592         var foo = new Foo,
16593             actual = func(foo, resolve(foo, 'a'));
16594
16595         assert.strictEqual(actual[symbol], 1);
16596         assert.strictEqual(actual[symbol2], 2);
16597       }
16598       else {
16599         skipAssert(assert, 2);
16600       }
16601     });
16602
16603     QUnit.test('`_.' + methodName + '` should create an object with omitted symbol properties', function(assert) {
16604       assert.expect(6);
16605
16606       function Foo() {
16607         this.a = 0;
16608         this[symbol] = 1;
16609       }
16610
16611       if (Symbol) {
16612         var symbol2 = Symbol('b');
16613         Foo.prototype[symbol2] = 2;
16614
16615         var foo = new Foo,
16616             actual = func(foo, resolve(foo, symbol));
16617
16618         assert.strictEqual(actual.a, 0);
16619         assert.strictEqual(actual[symbol], undefined);
16620         assert.strictEqual(actual[symbol2], 2);
16621
16622         actual = func(foo, resolve(foo, symbol2));
16623
16624         assert.strictEqual(actual.a, 0);
16625         assert.strictEqual(actual[symbol], 1);
16626         assert.strictEqual(actual[symbol2], undefined);
16627       }
16628       else {
16629         skipAssert(assert, 6);
16630       }
16631     });
16632
16633     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
16634       assert.expect(1);
16635
16636       var array = [1, 2, 3];
16637       assert.deepEqual(func(array, resolve(array, ['0', '2'])), { '1': 2 });
16638     });
16639   });
16640
16641   /*--------------------------------------------------------------------------*/
16642
16643   QUnit.module('lodash.once');
16644
16645   (function() {
16646     QUnit.test('should invoke `func` once', function(assert) {
16647       assert.expect(2);
16648
16649       var count = 0,
16650           once = _.once(function() { return ++count; });
16651
16652       once();
16653       assert.strictEqual(once(), 1);
16654       assert.strictEqual(count, 1);
16655     });
16656
16657     QUnit.test('should ignore recursive calls', function(assert) {
16658       assert.expect(2);
16659
16660       var count = 0;
16661
16662       var once = _.once(function() {
16663         once();
16664         return ++count;
16665       });
16666
16667       assert.strictEqual(once(), 1);
16668       assert.strictEqual(count, 1);
16669     });
16670
16671     QUnit.test('should not throw more than once', function(assert) {
16672       assert.expect(2);
16673
16674       var pass = true;
16675
16676       var once = _.once(function() {
16677         throw new Error;
16678       });
16679
16680       assert.raises(once);
16681
16682       try {
16683         once();
16684       } catch (e) {
16685         pass = false;
16686       }
16687       assert.ok(pass);
16688     });
16689   }());
16690
16691   /*--------------------------------------------------------------------------*/
16692
16693   QUnit.module('lodash.over');
16694
16695   (function() {
16696     QUnit.test('should create a function that invokes `iteratees`', function(assert) {
16697       assert.expect(1);
16698
16699       var over = _.over(Math.max, Math.min);
16700       assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
16701     });
16702
16703     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16704       assert.expect(1);
16705
16706       var over = _.over(undefined, null);
16707       assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
16708     });
16709
16710     QUnit.test('should work with `_.property` shorthands', function(assert) {
16711       assert.expect(1);
16712
16713       var over = _.over('b', 'a');
16714       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
16715     });
16716
16717     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16718       assert.expect(1);
16719
16720       var over = _.over({ 'b': 1 }, { 'a': 1 });
16721       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
16722     });
16723
16724     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16725       assert.expect(2);
16726
16727       var over = _.over(['b', 2], [['a', 2]]);
16728
16729       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
16730       assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
16731     });
16732
16733     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16734       assert.expect(4);
16735
16736       var over = _.over(['a', 1]);
16737
16738       assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
16739       assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
16740
16741       over = _.over([['a', 1]]);
16742
16743       assert.deepEqual(over({ 'a': 1 }), [true]);
16744       assert.deepEqual(over({ 'a': 2 }), [false]);
16745     });
16746
16747     QUnit.test('should provide arguments to predicates', function(assert) {
16748       assert.expect(1);
16749
16750       var over = _.over(function() {
16751         return slice.call(arguments);
16752       });
16753
16754       assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
16755     });
16756
16757     QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
16758       assert.expect(1);
16759
16760       var over = _.over(function() { return this.b; }, function() { return this.a; }),
16761           object = { 'over': over, 'a': 1, 'b': 2 };
16762
16763       assert.deepEqual(object.over(), [2, 1]);
16764     });
16765   }());
16766
16767   /*--------------------------------------------------------------------------*/
16768
16769   QUnit.module('lodash.overEvery');
16770
16771   (function() {
16772     QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
16773       assert.expect(1);
16774
16775       var over = _.overEvery(stubTrue, stubOne, stubA);
16776       assert.strictEqual(over(), true);
16777     });
16778
16779     QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
16780       assert.expect(2);
16781
16782       var count = 0,
16783           countFalse = function() { count++; return false; },
16784           countTrue = function() { count++; return true; },
16785           over = _.overEvery(countTrue, countFalse, countTrue);
16786
16787       assert.strictEqual(over(), false);
16788       assert.strictEqual(count, 2);
16789     });
16790
16791     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16792       assert.expect(2);
16793
16794       var over = _.overEvery(undefined, null);
16795
16796       assert.strictEqual(over(true), true);
16797       assert.strictEqual(over(false), false);
16798     });
16799
16800     QUnit.test('should work with `_.property` shorthands', function(assert) {
16801       assert.expect(2);
16802
16803       var over = _.overEvery('b', 'a');
16804
16805       assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
16806       assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
16807     });
16808
16809     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16810       assert.expect(2);
16811
16812       var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
16813
16814       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16815       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16816     });
16817
16818     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16819       assert.expect(2);
16820
16821       var over = _.overEvery(['b', 2], [['a', 1]]);
16822
16823       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16824       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16825     });
16826
16827     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16828       assert.expect(5);
16829
16830       var over = _.overEvery(['a', 1]);
16831
16832       assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
16833       assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
16834       assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
16835
16836       over = _.overEvery([['a', 1]]);
16837
16838       assert.strictEqual(over({ 'a': 1 }), true);
16839       assert.strictEqual(over({ 'a': 2 }), false);
16840     });
16841
16842     QUnit.test('should flatten `predicates`', function(assert) {
16843       assert.expect(1);
16844
16845       var over = _.overEvery(stubTrue, [stubFalse]);
16846       assert.strictEqual(over(), false);
16847     });
16848
16849     QUnit.test('should provide arguments to predicates', function(assert) {
16850       assert.expect(1);
16851
16852       var args;
16853
16854       var over = _.overEvery(function() {
16855         args = slice.call(arguments);
16856       });
16857
16858       over('a', 'b', 'c');
16859       assert.deepEqual(args, ['a', 'b', 'c']);
16860     });
16861
16862     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16863       assert.expect(2);
16864
16865       var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
16866           object = { 'over': over, 'a': 1, 'b': 2 };
16867
16868       assert.strictEqual(object.over(), true);
16869
16870       object.a = 0;
16871       assert.strictEqual(object.over(), false);
16872     });
16873   }());
16874
16875   /*--------------------------------------------------------------------------*/
16876
16877   QUnit.module('lodash.overSome');
16878
16879   (function() {
16880     QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
16881       assert.expect(2);
16882
16883       var over = _.overSome(stubFalse, stubOne, stubString);
16884       assert.strictEqual(over(), true);
16885
16886       over = _.overSome(stubNull, stubA, stubZero);
16887       assert.strictEqual(over(), true);
16888     });
16889
16890     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
16891       assert.expect(2);
16892
16893       var count = 0,
16894           countFalse = function() { count++; return false; },
16895           countTrue = function() { count++; return true; },
16896           over = _.overSome(countFalse, countTrue, countFalse);
16897
16898       assert.strictEqual(over(), true);
16899       assert.strictEqual(count, 2);
16900     });
16901
16902     QUnit.test('should return `false` if all predicates return falsey', function(assert) {
16903       assert.expect(2);
16904
16905       var over = _.overSome(stubFalse, stubFalse, stubFalse);
16906       assert.strictEqual(over(), false);
16907
16908       over = _.overSome(stubNull, stubZero, stubString);
16909       assert.strictEqual(over(), false);
16910     });
16911
16912     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16913       assert.expect(2);
16914
16915       var over = _.overSome(undefined, null);
16916
16917       assert.strictEqual(over(true), true);
16918       assert.strictEqual(over(false), false);
16919     });
16920
16921     QUnit.test('should work with `_.property` shorthands', function(assert) {
16922       assert.expect(2);
16923
16924       var over = _.overSome('b', 'a');
16925
16926       assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
16927       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16928     });
16929
16930     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16931       assert.expect(2);
16932
16933       var over = _.overSome({ 'b': 2 }, { 'a': 1 });
16934
16935       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16936       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16937     });
16938
16939     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16940       assert.expect(2);
16941
16942       var over = _.overSome(['a', 1], [['b', 2]]);
16943
16944       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16945       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16946     });
16947
16948     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16949       assert.expect(5);
16950
16951       var over = _.overSome(['a', 1]);
16952
16953       assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
16954       assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
16955       assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
16956
16957       over = _.overSome([['a', 1]]);
16958
16959       assert.strictEqual(over({ 'a': 1 }), true);
16960       assert.strictEqual(over({ 'a': 2 }), false);
16961     });
16962
16963     QUnit.test('should flatten `predicates`', function(assert) {
16964       assert.expect(1);
16965
16966       var over = _.overSome(stubFalse, [stubTrue]);
16967       assert.strictEqual(over(), true);
16968     });
16969
16970     QUnit.test('should provide arguments to predicates', function(assert) {
16971       assert.expect(1);
16972
16973       var args;
16974
16975       var over = _.overSome(function() {
16976         args = slice.call(arguments);
16977       });
16978
16979       over('a', 'b', 'c');
16980       assert.deepEqual(args, ['a', 'b', 'c']);
16981     });
16982
16983     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16984       assert.expect(2);
16985
16986       var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
16987           object = { 'over': over, 'a': 1, 'b': 2 };
16988
16989       assert.strictEqual(object.over(), true);
16990
16991       object.a = object.b = 0;
16992       assert.strictEqual(object.over(), false);
16993     });
16994   }());
16995
16996   /*--------------------------------------------------------------------------*/
16997
16998   QUnit.module('lodash.pad');
16999
17000   (function() {
17001     var string = 'abc';
17002
17003     QUnit.test('should pad a string to a given length', function(assert) {
17004       assert.expect(1);
17005
17006       var values = [, undefined],
17007           expected = lodashStable.map(values, lodashStable.constant(' abc  '));
17008
17009       var actual = lodashStable.map(values, function(value, index) {
17010         return index ? _.pad(string, 6, value) : _.pad(string, 6);
17011       });
17012
17013       assert.deepEqual(actual, expected);
17014     });
17015
17016     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17017       assert.expect(2);
17018
17019       assert.strictEqual(_.pad(string, 8), '  abc   ');
17020       assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
17021     });
17022
17023     QUnit.test('should coerce `string` to a string', function(assert) {
17024       assert.expect(1);
17025
17026       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17027           expected = lodashStable.map(values, stubTrue);
17028
17029       var actual = lodashStable.map(values, function(value) {
17030         return _.pad(value, 6) === ' abc  ';
17031       });
17032
17033       assert.deepEqual(actual, expected);
17034     });
17035   }());
17036
17037   /*--------------------------------------------------------------------------*/
17038
17039   QUnit.module('lodash.padEnd');
17040
17041   (function() {
17042     var string = 'abc';
17043
17044     QUnit.test('should pad a string to a given length', function(assert) {
17045       assert.expect(1);
17046
17047       var values = [, undefined],
17048           expected = lodashStable.map(values, lodashStable.constant('abc   '));
17049
17050       var actual = lodashStable.map(values, function(value, index) {
17051         return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
17052       });
17053
17054       assert.deepEqual(actual, expected);
17055     });
17056
17057     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17058       assert.expect(1);
17059
17060       assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
17061     });
17062
17063     QUnit.test('should coerce `string` to a string', function(assert) {
17064       assert.expect(1);
17065
17066       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17067           expected = lodashStable.map(values, stubTrue);
17068
17069       var actual = lodashStable.map(values, function(value) {
17070         return _.padEnd(value, 6) === 'abc   ';
17071       });
17072
17073       assert.deepEqual(actual, expected);
17074     });
17075   }());
17076
17077   /*--------------------------------------------------------------------------*/
17078
17079   QUnit.module('lodash.padStart');
17080
17081   (function() {
17082     var string = 'abc';
17083
17084     QUnit.test('should pad a string to a given length', function(assert) {
17085       assert.expect(1);
17086
17087       var values = [, undefined],
17088           expected = lodashStable.map(values, lodashStable.constant('   abc'));
17089
17090       var actual = lodashStable.map(values, function(value, index) {
17091         return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
17092       });
17093
17094       assert.deepEqual(actual, expected);
17095     });
17096
17097     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17098       assert.expect(1);
17099
17100       assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
17101     });
17102
17103     QUnit.test('should coerce `string` to a string', function(assert) {
17104       assert.expect(1);
17105
17106       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17107           expected = lodashStable.map(values, stubTrue);
17108
17109       var actual = lodashStable.map(values, function(value) {
17110         return _.padStart(value, 6) === '   abc';
17111       });
17112
17113       assert.deepEqual(actual, expected);
17114     });
17115   }());
17116
17117   /*--------------------------------------------------------------------------*/
17118
17119   QUnit.module('pad methods');
17120
17121   lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
17122     var func = _[methodName],
17123         isPad = methodName == 'pad',
17124         isStart = methodName == 'padStart',
17125         string = 'abc';
17126
17127     QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
17128       assert.expect(2);
17129
17130       assert.strictEqual(func(string, 2), string);
17131       assert.strictEqual(func(string, 3), string);
17132     });
17133
17134     QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
17135       assert.expect(2);
17136
17137       lodashStable.each([0, -2], function(length) {
17138         assert.strictEqual(func(string, length), string);
17139       });
17140     });
17141
17142     QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
17143       assert.expect(2);
17144
17145       lodashStable.each(['', '4'], function(length) {
17146         var actual = length ? (isStart ? ' abc' : 'abc ') : string;
17147         assert.strictEqual(func(string, length), actual);
17148       });
17149     });
17150
17151     QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
17152       assert.expect(6);
17153
17154       lodashStable.each([undefined, '_-'], function(chars) {
17155         var expected = chars ? (isPad ? '__' : chars) : '  ';
17156         assert.strictEqual(func(null, 2, chars), expected);
17157         assert.strictEqual(func(undefined, 2, chars), expected);
17158         assert.strictEqual(func('', 2, chars), expected);
17159       });
17160     });
17161
17162     QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
17163       assert.expect(1);
17164
17165       var values = ['', Object('')],
17166           expected = lodashStable.map(values, lodashStable.constant(string));
17167
17168       var actual = lodashStable.map(values, function(value) {
17169         return _.pad(string, 6, value);
17170       });
17171
17172       assert.deepEqual(actual, expected);
17173     });
17174   });
17175
17176   /*--------------------------------------------------------------------------*/
17177
17178   QUnit.module('lodash.parseInt');
17179
17180   (function() {
17181     QUnit.test('should accept a `radix` argument', function(assert) {
17182       assert.expect(1);
17183
17184       var expected = lodashStable.range(2, 37);
17185
17186       var actual = lodashStable.map(expected, function(radix) {
17187         return _.parseInt('10', radix);
17188       });
17189
17190       assert.deepEqual(actual, expected);
17191     });
17192
17193     QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17194       assert.expect(4);
17195
17196       assert.strictEqual(_.parseInt('10'), 10);
17197       assert.strictEqual(_.parseInt('10', 0), 10);
17198       assert.strictEqual(_.parseInt('10', 10), 10);
17199       assert.strictEqual(_.parseInt('10', undefined), 10);
17200     });
17201
17202     QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17203       assert.expect(8);
17204
17205       lodashStable.each(['0x20', '0X20'], function(string) {
17206         assert.strictEqual(_.parseInt(string), 32);
17207         assert.strictEqual(_.parseInt(string, 0), 32);
17208         assert.strictEqual(_.parseInt(string, 16), 32);
17209         assert.strictEqual(_.parseInt(string, undefined), 32);
17210       });
17211     });
17212
17213     QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
17214       assert.expect(2);
17215
17216       assert.strictEqual(_.parseInt('08'), 8);
17217       assert.strictEqual(_.parseInt('08', 10), 8);
17218     });
17219
17220     QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
17221       assert.expect(2);
17222
17223       var expected = [8, 8, 10, 10, 32, 32, 32, 32];
17224
17225       lodashStable.times(2, function(index) {
17226         var actual = [],
17227             func = (index ? (lodashBizarro || {}) : _).parseInt;
17228
17229         if (func) {
17230           lodashStable.times(2, function(otherIndex) {
17231             var string = otherIndex ? '10' : '08';
17232             actual.push(
17233               func(whitespace + string, 10),
17234               func(whitespace + string)
17235             );
17236           });
17237
17238           lodashStable.each(['0x20', '0X20'], function(string) {
17239             actual.push(
17240               func(whitespace + string),
17241               func(whitespace + string, 16)
17242             );
17243           });
17244
17245           assert.deepEqual(actual, expected);
17246         }
17247         else {
17248           skipAssert(assert);
17249         }
17250       });
17251     });
17252
17253     QUnit.test('should coerce `radix` to a number', function(assert) {
17254       assert.expect(2);
17255
17256       var object = { 'valueOf': stubZero };
17257       assert.strictEqual(_.parseInt('08', object), 8);
17258       assert.strictEqual(_.parseInt('0x20', object), 32);
17259     });
17260
17261     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17262       assert.expect(2);
17263
17264       var strings = lodashStable.map(['6', '08', '10'], Object),
17265           actual = lodashStable.map(strings, _.parseInt);
17266
17267       assert.deepEqual(actual, [6, 8, 10]);
17268
17269       actual = lodashStable.map('123', _.parseInt);
17270       assert.deepEqual(actual, [1, 2, 3]);
17271     });
17272   }());
17273
17274   /*--------------------------------------------------------------------------*/
17275
17276   QUnit.module('partial methods');
17277
17278   lodashStable.each(['partial', 'partialRight'], function(methodName) {
17279     var func = _[methodName],
17280         isPartial = methodName == 'partial',
17281         ph = func.placeholder;
17282
17283     QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
17284       assert.expect(1);
17285
17286       var par = func(identity, 'a');
17287       assert.strictEqual(par(), 'a');
17288     });
17289
17290     QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
17291       assert.expect(1);
17292
17293       var fn = function(a, b) { return [a, b]; },
17294           par = func(fn, 'a'),
17295           expected = isPartial ? ['a', 'b'] : ['b', 'a'];
17296
17297       assert.deepEqual(par('b'), expected);
17298     });
17299
17300     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
17301       assert.expect(1);
17302
17303       var fn = function() { return arguments.length; },
17304           par = func(fn);
17305
17306       assert.strictEqual(par(), 0);
17307     });
17308
17309     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
17310       assert.expect(1);
17311
17312       var par = func(identity);
17313       assert.strictEqual(par('a'), 'a');
17314     });
17315
17316     QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
17317       assert.expect(4);
17318
17319       var fn = function() { return slice.call(arguments); },
17320           par = func(fn, ph, 'b', ph);
17321
17322       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
17323       assert.deepEqual(par('a'), ['a', 'b', undefined]);
17324       assert.deepEqual(par(), [undefined, 'b', undefined]);
17325
17326       if (isPartial) {
17327         assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
17328       } else {
17329         par = func(fn, ph, 'c', ph);
17330         assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
17331       }
17332     });
17333
17334     QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
17335       assert.expect(1);
17336
17337       if (!isModularize) {
17338         var _ph = _.placeholder = {},
17339             fn = function() { return slice.call(arguments); },
17340             par = func(fn, _ph, 'b', ph),
17341             expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
17342
17343         assert.deepEqual(par('a', 'c'), expected);
17344         delete _.placeholder;
17345       }
17346       else {
17347         skipAssert(assert);
17348       }
17349     });
17350
17351     QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
17352       assert.expect(1);
17353
17354       var fn = function(a, b, c) {},
17355           par = func(fn, 'a');
17356
17357       assert.strictEqual(par.length, 0);
17358     });
17359
17360     QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
17361       assert.expect(2);
17362
17363       function Foo(value) {
17364         return value && object;
17365       }
17366
17367       var object = {},
17368           par = func(Foo);
17369
17370       assert.ok(new par instanceof Foo);
17371       assert.strictEqual(new par(true), object);
17372     });
17373
17374     QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
17375       assert.expect(3);
17376
17377       function greet(greeting, name) {
17378         return greeting + ' ' + name;
17379       }
17380
17381       var par1 = func(greet, 'hi'),
17382           par2 = func(par1, 'barney'),
17383           par3 = func(par1, 'pebbles');
17384
17385       assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
17386       assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
17387       assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
17388     });
17389
17390     QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
17391       assert.expect(2);
17392
17393       var fn = function(a, b, c) { return a + b + c; },
17394           curried = _.curry(func(fn, 1), 2);
17395
17396       assert.strictEqual(curried(2, 3), 6);
17397       assert.strictEqual(curried(2)(3), 6);
17398     });
17399
17400     QUnit.test('should work with placeholders and curried functions', function(assert) {
17401       assert.expect(1);
17402
17403       var fn = function() { return slice.call(arguments); },
17404           curried = _.curry(fn),
17405           par = func(curried, ph, 'b', ph, 'd');
17406
17407       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
17408     });
17409   });
17410
17411   /*--------------------------------------------------------------------------*/
17412
17413   QUnit.module('lodash.partialRight');
17414
17415   (function() {
17416     QUnit.test('should work as a deep `_.defaults`', function(assert) {
17417       assert.expect(1);
17418
17419       var object = { 'a': { 'b': 2 } },
17420           source = { 'a': { 'b': 3, 'c': 3 } },
17421           expected = { 'a': { 'b': 2, 'c': 3 } };
17422
17423       var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
17424         return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
17425       });
17426
17427       assert.deepEqual(defaultsDeep(object, source), expected);
17428     });
17429   }());
17430
17431   /*--------------------------------------------------------------------------*/
17432
17433   QUnit.module('methods using `createWrapper`');
17434
17435   (function() {
17436     function fn() {
17437       return slice.call(arguments);
17438     }
17439
17440     var ph1 = _.bind.placeholder,
17441         ph2 = _.bindKey.placeholder,
17442         ph3 = _.partial.placeholder,
17443         ph4 = _.partialRight.placeholder;
17444
17445     QUnit.test('should work with combinations of partial functions', function(assert) {
17446       assert.expect(1);
17447
17448       var a = _.partial(fn),
17449           b = _.partialRight(a, 3),
17450           c = _.partial(b, 1);
17451
17452       assert.deepEqual(c(2), [1, 2, 3]);
17453     });
17454
17455     QUnit.test('should work with combinations of bound and partial functions', function(assert) {
17456       assert.expect(3);
17457
17458       var fn = function() {
17459         var result = [this.a];
17460         push.apply(result, arguments);
17461         return result;
17462       };
17463
17464       var expected = [1, 2, 3, 4],
17465           object = { 'a': 1, 'fn': fn };
17466
17467       var a = _.bindKey(object, 'fn'),
17468           b = _.partialRight(a, 4),
17469           c = _.partial(b, 2);
17470
17471       assert.deepEqual(c(3), expected);
17472
17473       a = _.bind(fn, object);
17474       b = _.partialRight(a, 4);
17475       c = _.partial(b, 2);
17476
17477       assert.deepEqual(c(3), expected);
17478
17479       a = _.partial(fn, 2);
17480       b = _.bind(a, object);
17481       c = _.partialRight(b, 4);
17482
17483       assert.deepEqual(c(3), expected);
17484     });
17485
17486     QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
17487       assert.expect(2);
17488
17489       function Foo(a, b, c) {
17490         return b === 0 && object;
17491       }
17492
17493       var combo = _.partial(_.partialRight(Foo, 3), 1),
17494           object = {};
17495
17496       assert.ok(new combo(2) instanceof Foo);
17497       assert.strictEqual(new combo(0), object);
17498     });
17499
17500     QUnit.test('should work with combinations of functions with placeholders', function(assert) {
17501       assert.expect(3);
17502
17503       var expected = [1, 2, 3, 4, 5, 6],
17504           object = { 'fn': fn };
17505
17506       var a = _.bindKey(object, 'fn', ph2, 2),
17507           b = _.partialRight(a, ph4, 6),
17508           c = _.partial(b, 1, ph3, 4);
17509
17510       assert.deepEqual(c(3, 5), expected);
17511
17512       a = _.bind(fn, object, ph1, 2);
17513       b = _.partialRight(a, ph4, 6);
17514       c = _.partial(b, 1, ph3, 4);
17515
17516       assert.deepEqual(c(3, 5), expected);
17517
17518       a = _.partial(fn, ph3, 2);
17519       b = _.bind(a, object, 1, ph1, 4);
17520       c = _.partialRight(b, ph4, 6);
17521
17522       assert.deepEqual(c(3, 5), expected);
17523     });
17524
17525     QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
17526       assert.expect(3);
17527
17528       var expected = [1, 2, 3, 4],
17529           object = { 'fn': fn };
17530
17531       var a = _.bindKey(object, 'fn', ph2, 2),
17532           b = _.partialRight(a, ph4, 4),
17533           c = _.partial(b, ph3, 3);
17534
17535       assert.deepEqual(c(1), expected);
17536
17537       a = _.bind(fn, object, ph1, 2);
17538       b = _.partialRight(a, ph4, 4);
17539       c = _.partial(b, ph3, 3);
17540
17541       assert.deepEqual(c(1), expected);
17542
17543       a = _.partial(fn, ph3, 2);
17544       b = _.bind(a, object, ph1, 3);
17545       c = _.partialRight(b, ph4, 4);
17546
17547       assert.deepEqual(c(1), expected);
17548     });
17549
17550     QUnit.test('should work with recursively bound functions', function(assert) {
17551       assert.expect(1);
17552
17553       var fn = function() {
17554         return this.a;
17555       };
17556
17557       var a = _.bind(fn, { 'a': 1 }),
17558           b = _.bind(a,  { 'a': 2 }),
17559           c = _.bind(b,  { 'a': 3 });
17560
17561       assert.strictEqual(c(), 1);
17562     });
17563
17564     QUnit.test('should work when hot', function(assert) {
17565       assert.expect(12);
17566
17567       lodashStable.times(2, function(index) {
17568         var fn = function() {
17569           var result = [this];
17570           push.apply(result, arguments);
17571           return result;
17572         };
17573
17574         var object = {},
17575             bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17576             expected = [object, 1, 2, 3];
17577
17578         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17579           var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17580           return index ? bound2(3) : bound2(1, 2, 3);
17581         }));
17582
17583         assert.deepEqual(actual, expected);
17584
17585         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17586           var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17587               bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17588
17589           return index ? bound2(3) : bound2(1, 2, 3);
17590         }));
17591
17592         assert.deepEqual(actual, expected);
17593       });
17594
17595       lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
17596         var fn = function(a, b, c) { return [a, b, c]; },
17597             curried = _[methodName](fn),
17598             expected = index ? [3, 2, 1] :  [1, 2, 3];
17599
17600         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17601           return curried(1)(2)(3);
17602         }));
17603
17604         assert.deepEqual(actual, expected);
17605
17606         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17607           var curried = _[methodName](fn);
17608           return curried(1)(2)(3);
17609         }));
17610
17611         assert.deepEqual(actual, expected);
17612       });
17613
17614       lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
17615         var func = _[methodName],
17616             fn = function() { return slice.call(arguments); },
17617             par1 = func(fn, 1),
17618             expected = index ? [3, 2, 1] : [1, 2, 3];
17619
17620         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17621           var par2 = func(par1, 2);
17622           return par2(3);
17623         }));
17624
17625         assert.deepEqual(actual, expected);
17626
17627         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17628           var par1 = func(fn, 1),
17629               par2 = func(par1, 2);
17630
17631           return par2(3);
17632         }));
17633
17634         assert.deepEqual(actual, expected);
17635       });
17636     });
17637   }());
17638
17639   /*--------------------------------------------------------------------------*/
17640
17641   QUnit.module('lodash.partition');
17642
17643   (function() {
17644     var array = [1, 0, 1];
17645
17646     QUnit.test('should split elements into two groups by `predicate`', function(assert) {
17647       assert.expect(3);
17648
17649       assert.deepEqual(_.partition([], identity), [[], []]);
17650       assert.deepEqual(_.partition(array, stubTrue), [array, []]);
17651       assert.deepEqual(_.partition(array, stubFalse), [[], array]);
17652     });
17653
17654     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17655       assert.expect(1);
17656
17657       var values = [, null, undefined],
17658           expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
17659
17660       var actual = lodashStable.map(values, function(value, index) {
17661         return index ? _.partition(array, value) : _.partition(array);
17662       });
17663
17664       assert.deepEqual(actual, expected);
17665     });
17666
17667     QUnit.test('should work with `_.property` shorthands', function(assert) {
17668       assert.expect(1);
17669
17670       var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
17671           actual = _.partition(objects, 'a');
17672
17673       assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
17674     });
17675
17676     QUnit.test('should work with a number for `predicate`', function(assert) {
17677       assert.expect(2);
17678
17679       var array = [
17680         [1, 0],
17681         [0, 1],
17682         [1, 0]
17683       ];
17684
17685       assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
17686       assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
17687     });
17688
17689     QUnit.test('should work with an object for `collection`', function(assert) {
17690       assert.expect(1);
17691
17692       var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
17693       assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
17694     });
17695   }());
17696
17697   /*--------------------------------------------------------------------------*/
17698
17699   QUnit.module('lodash.pick');
17700
17701   (function() {
17702     var args = arguments,
17703         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17704
17705     QUnit.test('should flatten `props`', function(assert) {
17706       assert.expect(2);
17707
17708       assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
17709       assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
17710     });
17711
17712     QUnit.test('should work with a primitive `object` argument', function(assert) {
17713       assert.expect(1);
17714
17715       assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
17716     });
17717
17718     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
17719       assert.expect(2);
17720
17721       lodashStable.each([null, undefined], function(value) {
17722         assert.deepEqual(_.pick(value, 'valueOf'), {});
17723       });
17724     });
17725
17726     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
17727       assert.expect(1);
17728
17729       assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
17730     });
17731
17732     QUnit.test('should coerce property names to strings', function(assert) {
17733       assert.expect(1);
17734
17735       assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
17736     });
17737   }('a', 'c'));
17738
17739   /*--------------------------------------------------------------------------*/
17740
17741   QUnit.module('lodash.pickBy');
17742
17743   (function() {
17744     QUnit.test('should work with a predicate argument', function(assert) {
17745       assert.expect(1);
17746
17747       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17748
17749       var actual = _.pickBy(object, function(n) {
17750         return n == 1 || n == 3;
17751       });
17752
17753       assert.deepEqual(actual, { 'a': 1, 'c': 3 });
17754     });
17755   }());
17756
17757   /*--------------------------------------------------------------------------*/
17758
17759   QUnit.module('pick methods');
17760
17761   lodashStable.each(['pick', 'pickBy'], function(methodName) {
17762     var expected = { 'a': 1, 'c': 3 },
17763         func = _[methodName],
17764         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17765         resolve = lodashStable.nthArg(1);
17766
17767     if (methodName == 'pickBy') {
17768       resolve = function(object, props) {
17769         props = lodashStable.castArray(props);
17770         return function(value) {
17771           return lodashStable.some(props, function(key) {
17772             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
17773             return object[key] === value;
17774           });
17775         };
17776       };
17777     }
17778     QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
17779       assert.expect(2);
17780
17781       assert.deepEqual(func(object, resolve(object, 'a')), { 'a': 1 });
17782       assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
17783     });
17784
17785     QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
17786       assert.expect(1);
17787
17788       function Foo() {}
17789       Foo.prototype = object;
17790
17791       var foo = new Foo;
17792       assert.deepEqual(func(foo, resolve(foo, ['a', 'c'])), expected);
17793     });
17794
17795     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
17796       assert.expect(1);
17797
17798       var object = { '-0': 'a', '0': 'b' },
17799           props = [-0, Object(-0), 0, Object(0)],
17800           expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
17801
17802       var actual = lodashStable.map(props, function(key) {
17803         return func(object, resolve(object, key));
17804       });
17805
17806       assert.deepEqual(actual, expected);
17807     });
17808
17809     QUnit.test('`_.' + methodName + '` should pick symbol properties', function(assert) {
17810       assert.expect(2);
17811
17812       function Foo() {
17813         this[symbol] = 1;
17814       }
17815
17816       if (Symbol) {
17817         var symbol2 = Symbol('b');
17818         Foo.prototype[symbol2] = 2;
17819
17820         var foo = new Foo,
17821             actual = func(foo, resolve(foo, [symbol, symbol2]));
17822
17823         assert.strictEqual(actual[symbol], 1);
17824         assert.strictEqual(actual[symbol2], 2);
17825       }
17826       else {
17827         skipAssert(assert, 2);
17828       }
17829     });
17830
17831     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
17832       assert.expect(1);
17833
17834       var array = [1, 2, 3];
17835       assert.deepEqual(func(array, resolve(array, '1')), { '1': 2 });
17836     });
17837   });
17838
17839   /*--------------------------------------------------------------------------*/
17840
17841   QUnit.module('lodash.property');
17842
17843   (function() {
17844     QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
17845       assert.expect(4);
17846
17847       var object = { 'a': 1 };
17848
17849       lodashStable.each(['a', ['a']], function(path) {
17850         var prop = _.property(path);
17851         assert.strictEqual(prop.length, 1);
17852         assert.strictEqual(prop(object), 1);
17853       });
17854     });
17855
17856     QUnit.test('should pluck deep property values', function(assert) {
17857       assert.expect(2);
17858
17859       var object = { 'a': { 'b': 2 } };
17860
17861       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17862         var prop = _.property(path);
17863         assert.strictEqual(prop(object), 2);
17864       });
17865     });
17866
17867     QUnit.test('should pluck inherited property values', function(assert) {
17868       assert.expect(2);
17869
17870       function Foo() {}
17871       Foo.prototype.a = 1;
17872
17873       lodashStable.each(['a', ['a']], function(path) {
17874         var prop = _.property(path);
17875         assert.strictEqual(prop(new Foo), 1);
17876       });
17877     });
17878
17879     QUnit.test('should work with a non-string `path`', function(assert) {
17880       assert.expect(2);
17881
17882       var array = [1, 2, 3];
17883
17884       lodashStable.each([1, [1]], function(path) {
17885         var prop = _.property(path);
17886         assert.strictEqual(prop(array), 2);
17887       });
17888     });
17889
17890     QUnit.test('should preserve the sign of `0`', function(assert) {
17891       assert.expect(1);
17892
17893       var object = { '-0': 'a', '0': 'b' },
17894           props = [-0, Object(-0), 0, Object(0)];
17895
17896       var actual = lodashStable.map(props, function(key) {
17897         var prop = _.property(key);
17898         return prop(object);
17899       });
17900
17901       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17902     });
17903
17904     QUnit.test('should coerce key to a string', function(assert) {
17905       assert.expect(1);
17906
17907       function fn() {}
17908       fn.toString = lodashStable.constant('fn');
17909
17910       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
17911           values = [null, undefined, fn, {}];
17912
17913       var actual = lodashStable.transform(objects, function(result, object, index) {
17914         var key = values[index];
17915         lodashStable.each([key, [key]], function(path) {
17916           var prop = _.property(key);
17917           result.push(prop(object));
17918         });
17919       });
17920
17921       assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
17922     });
17923
17924     QUnit.test('should pluck a key over a path', function(assert) {
17925       assert.expect(2);
17926
17927       var object = { 'a.b': 1, 'a': { 'b': 2 } };
17928
17929       lodashStable.each(['a.b', ['a.b']], function(path) {
17930         var prop = _.property(path);
17931         assert.strictEqual(prop(object), 1);
17932       });
17933     });
17934
17935     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17936       assert.expect(2);
17937
17938       var values = [, null, undefined],
17939           expected = lodashStable.map(values, noop);
17940
17941       lodashStable.each(['constructor', ['constructor']], function(path) {
17942         var prop = _.property(path);
17943
17944         var actual = lodashStable.map(values, function(value, index) {
17945           return index ? prop(value) : prop();
17946         });
17947
17948         assert.deepEqual(actual, expected);
17949       });
17950     });
17951
17952     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
17953       assert.expect(2);
17954
17955       var values = [, null, undefined],
17956           expected = lodashStable.map(values, noop);
17957
17958       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17959         var prop = _.property(path);
17960
17961         var actual = lodashStable.map(values, function(value, index) {
17962           return index ? prop(value) : prop();
17963         });
17964
17965         assert.deepEqual(actual, expected);
17966       });
17967     });
17968
17969     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17970       assert.expect(4);
17971
17972       var object = {};
17973
17974       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17975         var prop = _.property(path);
17976         assert.strictEqual(prop(object), undefined);
17977       });
17978     });
17979   }());
17980
17981   /*--------------------------------------------------------------------------*/
17982
17983   QUnit.module('lodash.propertyOf');
17984
17985   (function() {
17986     QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
17987       assert.expect(3);
17988
17989       var object = { 'a': 1 },
17990           propOf = _.propertyOf(object);
17991
17992       assert.strictEqual(propOf.length, 1);
17993       lodashStable.each(['a', ['a']], function(path) {
17994         assert.strictEqual(propOf(path), 1);
17995       });
17996     });
17997
17998     QUnit.test('should pluck deep property values', function(assert) {
17999       assert.expect(2);
18000
18001       var object = { 'a': { 'b': 2 } },
18002           propOf = _.propertyOf(object);
18003
18004       lodashStable.each(['a.b', ['a', 'b']], function(path) {
18005         assert.strictEqual(propOf(path), 2);
18006       });
18007     });
18008
18009     QUnit.test('should pluck inherited property values', function(assert) {
18010       assert.expect(2);
18011
18012       function Foo() {
18013         this.a = 1;
18014       }
18015       Foo.prototype.b = 2;
18016
18017       var propOf = _.propertyOf(new Foo);
18018
18019       lodashStable.each(['b', ['b']], function(path) {
18020         assert.strictEqual(propOf(path), 2);
18021       });
18022     });
18023
18024     QUnit.test('should work with a non-string `path`', function(assert) {
18025       assert.expect(2);
18026
18027       var array = [1, 2, 3],
18028           propOf = _.propertyOf(array);
18029
18030       lodashStable.each([1, [1]], function(path) {
18031         assert.strictEqual(propOf(path), 2);
18032       });
18033     });
18034
18035     QUnit.test('should preserve the sign of `0`', function(assert) {
18036       assert.expect(1);
18037
18038       var object = { '-0': 'a', '0': 'b' },
18039           props = [-0, Object(-0), 0, Object(0)];
18040
18041       var actual = lodashStable.map(props, function(key) {
18042         var propOf = _.propertyOf(object);
18043         return propOf(key);
18044       });
18045
18046       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
18047     });
18048
18049     QUnit.test('should coerce key to a string', function(assert) {
18050       assert.expect(1);
18051
18052       function fn() {}
18053       fn.toString = lodashStable.constant('fn');
18054
18055       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
18056           values = [null, undefined, fn, {}];
18057
18058       var actual = lodashStable.transform(objects, function(result, object, index) {
18059         var key = values[index];
18060         lodashStable.each([key, [key]], function(path) {
18061           var propOf = _.propertyOf(object);
18062           result.push(propOf(key));
18063         });
18064       });
18065
18066       assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
18067     });
18068
18069     QUnit.test('should pluck a key over a path', function(assert) {
18070       assert.expect(2);
18071
18072       var object = { 'a.b': 1, 'a': { 'b': 2 } },
18073           propOf = _.propertyOf(object);
18074
18075       lodashStable.each(['a.b', ['a.b']], function(path) {
18076         assert.strictEqual(propOf(path), 1);
18077       });
18078     });
18079
18080     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
18081       assert.expect(2);
18082
18083       var values = [, null, undefined],
18084           expected = lodashStable.map(values, noop);
18085
18086       lodashStable.each(['constructor', ['constructor']], function(path) {
18087         var actual = lodashStable.map(values, function(value, index) {
18088           var propOf = index ? _.propertyOf(value) : _.propertyOf();
18089           return propOf(path);
18090         });
18091
18092         assert.deepEqual(actual, expected);
18093       });
18094     });
18095
18096     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
18097       assert.expect(2);
18098
18099       var values = [, null, undefined],
18100           expected = lodashStable.map(values, noop);
18101
18102       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
18103         var actual = lodashStable.map(values, function(value, index) {
18104           var propOf = index ? _.propertyOf(value) : _.propertyOf();
18105           return propOf(path);
18106         });
18107
18108         assert.deepEqual(actual, expected);
18109       });
18110     });
18111
18112     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
18113       assert.expect(4);
18114
18115       var propOf = _.propertyOf({});
18116
18117       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
18118         assert.strictEqual(propOf(path), undefined);
18119       });
18120     });
18121   }());
18122
18123   /*--------------------------------------------------------------------------*/
18124
18125   QUnit.module('lodash.pullAll');
18126
18127   (function() {
18128     QUnit.test('should work with the same value for `array` and `values`', function(assert) {
18129       assert.expect(1);
18130
18131       var array = [{ 'a': 1 }, { 'b': 2 }],
18132           actual = _.pullAll(array, array);
18133
18134       assert.deepEqual(actual, []);
18135     });
18136   }());
18137
18138   /*--------------------------------------------------------------------------*/
18139
18140   QUnit.module('lodash.pullAllBy');
18141
18142   (function() {
18143     QUnit.test('should accept an `iteratee` argument', function(assert) {
18144       assert.expect(1);
18145
18146       var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18147
18148       var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
18149         return object.x;
18150       });
18151
18152       assert.deepEqual(actual, [{ 'x': 2 }]);
18153     });
18154
18155     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
18156       assert.expect(1);
18157
18158       var args,
18159           array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18160
18161       _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
18162         args || (args = slice.call(arguments));
18163       });
18164
18165       assert.deepEqual(args, [{ 'x': 1 }]);
18166     });
18167   }());
18168
18169   /*--------------------------------------------------------------------------*/
18170
18171   QUnit.module('lodash.pullAllWith');
18172
18173   (function() {
18174     QUnit.test('should work with a `comparator` argument', function(assert) {
18175       assert.expect(1);
18176
18177       var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
18178           expected = [objects[0], objects[2]],
18179           actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
18180
18181       assert.deepEqual(actual, expected);
18182     });
18183   }());
18184
18185   /*--------------------------------------------------------------------------*/
18186
18187   QUnit.module('pull methods');
18188
18189   lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
18190     var func = _[methodName],
18191         isPull = methodName == 'pull';
18192
18193     function pull(array, values) {
18194       return isPull
18195         ? func.apply(undefined, [array].concat(values))
18196         : func(array, values);
18197     }
18198
18199     QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
18200       assert.expect(2);
18201
18202       var array = [1, 2, 3],
18203           actual = pull(array, [1, 3]);
18204
18205       assert.strictEqual(actual, array);
18206       assert.deepEqual(array, [2]);
18207     });
18208
18209     QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
18210       assert.expect(2);
18211
18212       var array = [1, 2, 3, 4];
18213       delete array[1];
18214       delete array[3];
18215
18216       pull(array, [1]);
18217       assert.notOk('0' in array);
18218       assert.notOk('2' in array);
18219     });
18220
18221     QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
18222       assert.expect(1);
18223
18224       var array = [1, 2, 3];
18225       delete array[1];
18226
18227       pull(array, [undefined]);
18228       assert.deepEqual(array, [1, 3]);
18229     });
18230
18231     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
18232       assert.expect(1);
18233
18234       var array = [1, NaN, 3, NaN];
18235
18236       pull(array, [NaN]);
18237       assert.deepEqual(array, [1, 3]);
18238     });
18239   });
18240
18241   /*--------------------------------------------------------------------------*/
18242
18243   QUnit.module('lodash.pullAt');
18244
18245   (function() {
18246     QUnit.test('should modify the array and return removed elements', function(assert) {
18247       assert.expect(2);
18248
18249       var array = [1, 2, 3],
18250           actual = _.pullAt(array, [0, 1]);
18251
18252       assert.deepEqual(array, [3]);
18253       assert.deepEqual(actual, [1, 2]);
18254     });
18255
18256     QUnit.test('should work with unsorted indexes', function(assert) {
18257       assert.expect(2);
18258
18259       var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
18260           actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
18261
18262       assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
18263       assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
18264     });
18265
18266     QUnit.test('should work with repeated indexes', function(assert) {
18267       assert.expect(2);
18268
18269       var array = [1, 2, 3, 4],
18270           actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
18271
18272       assert.deepEqual(array, [4]);
18273       assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
18274     });
18275
18276     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18277       assert.expect(2);
18278
18279       var array = ['a', 'b', 'c'],
18280           actual = _.pullAt(array, [2, 4, 0]);
18281
18282       assert.deepEqual(array, ['b']);
18283       assert.deepEqual(actual, ['c', undefined, 'a']);
18284     });
18285
18286     QUnit.test('should flatten `indexes`', function(assert) {
18287       assert.expect(4);
18288
18289       var array = ['a', 'b', 'c'];
18290       assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
18291       assert.deepEqual(array, ['b']);
18292
18293       array = ['a', 'b', 'c', 'd'];
18294       assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
18295       assert.deepEqual(array, ['b']);
18296     });
18297
18298     QUnit.test('should return an empty array when no indexes are given', function(assert) {
18299       assert.expect(4);
18300
18301       var array = ['a', 'b', 'c'],
18302           actual = _.pullAt(array);
18303
18304       assert.deepEqual(array, ['a', 'b', 'c']);
18305       assert.deepEqual(actual, []);
18306
18307       actual = _.pullAt(array, [], []);
18308
18309       assert.deepEqual(array, ['a', 'b', 'c']);
18310       assert.deepEqual(actual, []);
18311     });
18312
18313     QUnit.test('should work with non-index paths', function(assert) {
18314       assert.expect(2);
18315
18316       var values = lodashStable.reject(empties, function(value) {
18317         return (value === 0) || lodashStable.isArray(value);
18318       }).concat(-1, 1.1);
18319
18320       var array = lodashStable.transform(values, function(result, value) {
18321         result[value] = 1;
18322       }, []);
18323
18324       var expected = lodashStable.map(values, stubOne),
18325           actual = _.pullAt(array, values);
18326
18327       assert.deepEqual(actual, expected);
18328
18329       expected = lodashStable.map(values, noop),
18330       actual = lodashStable.at(array, values);
18331
18332       assert.deepEqual(actual, expected);
18333     });
18334
18335     QUnit.test('should preserve the sign of `0`', function(assert) {
18336       assert.expect(1);
18337
18338       var props = [-0, Object(-0), 0, Object(0)];
18339
18340       var actual = lodashStable.map(props, function(key) {
18341         var array = [-1];
18342         array['-0'] = -2;
18343         return _.pullAt(array, key);
18344       });
18345
18346       assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
18347     });
18348
18349     QUnit.test('should work with deep paths', function(assert) {
18350       assert.expect(3);
18351
18352       var array = [];
18353       array.a = { 'b': 2 };
18354
18355       var actual = _.pullAt(array, 'a.b');
18356
18357       assert.deepEqual(actual, [2]);
18358       assert.deepEqual(array.a, {});
18359
18360       try {
18361         actual = _.pullAt(array, 'a.b.c');
18362       } catch (e) {}
18363
18364       assert.deepEqual(actual, [undefined]);
18365     });
18366
18367     QUnit.test('should work with a falsey `array` argument when keys are given', function(assert) {
18368       assert.expect(1);
18369
18370       var values = falsey.slice(),
18371           expected = lodashStable.map(values, lodashStable.constant(Array(4)));
18372
18373       var actual = lodashStable.map(values, function(array) {
18374         try {
18375           return _.pullAt(array, 0, 1, 'pop', 'push');
18376         } catch (e) {}
18377       });
18378
18379       assert.deepEqual(actual, expected);
18380     });
18381   }());
18382
18383   /*--------------------------------------------------------------------------*/
18384
18385   QUnit.module('lodash.random');
18386
18387   (function() {
18388     var array = Array(1000);
18389
18390     QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
18391       assert.expect(1);
18392
18393       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18394         return _.random();
18395       })).sort();
18396
18397       assert.deepEqual(actual, [0, 1]);
18398     });
18399
18400     QUnit.test('should support a `min` and `max` argument', function(assert) {
18401       assert.expect(1);
18402
18403       var min = 5,
18404           max = 10;
18405
18406       assert.ok(lodashStable.some(array, function() {
18407         var result = _.random(min, max);
18408         return result >= min && result <= max;
18409       }));
18410     });
18411
18412     QUnit.test('should support not providing a `max` argument', function(assert) {
18413       assert.expect(1);
18414
18415       var min = 0,
18416           max = 5;
18417
18418       assert.ok(lodashStable.some(array, function() {
18419         var result = _.random(max);
18420         return result >= min && result <= max;
18421       }));
18422     });
18423
18424     QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
18425       assert.expect(1);
18426
18427       var min = 4,
18428           max = 2,
18429           expected = [2, 3, 4];
18430
18431       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18432         return _.random(min, max);
18433       })).sort();
18434
18435       assert.deepEqual(actual, expected);
18436     });
18437
18438     QUnit.test('should support large integer values', function(assert) {
18439       assert.expect(2);
18440
18441       var min = Math.pow(2, 31),
18442           max = Math.pow(2, 62);
18443
18444       assert.ok(lodashStable.every(array, function() {
18445         var result = _.random(min, max);
18446         return result >= min && result <= max;
18447       }));
18448
18449       assert.ok(lodashStable.some(array, function() {
18450         return _.random(MAX_INTEGER);
18451       }));
18452     });
18453
18454     QUnit.test('should coerce arguments to finite numbers', function(assert) {
18455       assert.expect(2);
18456
18457       assert.strictEqual(_.random('1', '1'), 1);
18458       assert.strictEqual(_.random(NaN, NaN), 0);
18459     });
18460
18461     QUnit.test('should support floats', function(assert) {
18462       assert.expect(2);
18463
18464       var min = 1.5,
18465           max = 1.6,
18466           actual = _.random(min, max);
18467
18468       assert.ok(actual % 1);
18469       assert.ok(actual >= min && actual <= max);
18470     });
18471
18472     QUnit.test('should support providing a `floating` argument', function(assert) {
18473       assert.expect(3);
18474
18475       var actual = _.random(true);
18476       assert.ok(actual % 1 && actual >= 0 && actual <= 1);
18477
18478       actual = _.random(2, true);
18479       assert.ok(actual % 1 && actual >= 0 && actual <= 2);
18480
18481       actual = _.random(2, 4, true);
18482       assert.ok(actual % 1 && actual >= 2 && actual <= 4);
18483     });
18484
18485     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18486       assert.expect(1);
18487
18488       var array = [1, 2, 3],
18489           expected = lodashStable.map(array, stubTrue),
18490           randoms = lodashStable.map(array, _.random);
18491
18492       var actual = lodashStable.map(randoms, function(result, index) {
18493         return result >= 0 && result <= array[index] && (result % 1) == 0;
18494       });
18495
18496       assert.deepEqual(actual, expected);
18497     });
18498   }());
18499
18500   /*--------------------------------------------------------------------------*/
18501
18502   QUnit.module('range methods');
18503
18504   lodashStable.each(['range', 'rangeRight'], function(methodName) {
18505     var func = _[methodName],
18506         isRange = methodName == 'range';
18507
18508     function resolve(range) {
18509       return isRange ? range : range.reverse();
18510     }
18511
18512     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
18513       assert.expect(2);
18514
18515       assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
18516       assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
18517     });
18518
18519     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
18520       assert.expect(2);
18521
18522       assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
18523       assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
18524     });
18525
18526     QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
18527       assert.expect(3);
18528
18529       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18530       assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
18531       assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
18532     });
18533
18534     QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
18535       assert.expect(1);
18536
18537       assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
18538     });
18539
18540     QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
18541       assert.expect(1);
18542
18543       assert.deepEqual(func(1, 5, 20), [1]);
18544     });
18545
18546     QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
18547       assert.expect(2);
18548
18549       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18550       assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
18551     });
18552
18553     QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
18554       assert.expect(1);
18555
18556       var actual = func(-0, 1);
18557       assert.strictEqual(1 / actual[0], -Infinity);
18558     });
18559
18560     QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
18561       assert.expect(13);
18562
18563       lodashStable.each(falsey, function(value, index) {
18564         if (index) {
18565           assert.deepEqual(func(value), []);
18566           assert.deepEqual(func(value, 1), [0]);
18567         } else {
18568           assert.deepEqual(func(), []);
18569         }
18570       });
18571     });
18572
18573     QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
18574       assert.expect(1);
18575
18576       var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
18577       assert.deepEqual(actual, [[0], [0], [0], [], []]);
18578     });
18579
18580     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
18581       assert.expect(2);
18582
18583       var array = [1, 2, 3],
18584           object = { 'a': 1, 'b': 2, 'c': 3 },
18585           expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
18586
18587       lodashStable.each([array, object], function(collection) {
18588         var actual = lodashStable.map(collection, func);
18589         assert.deepEqual(actual, expected);
18590       });
18591     });
18592   });
18593
18594   /*--------------------------------------------------------------------------*/
18595
18596   QUnit.module('lodash.rearg');
18597
18598   (function() {
18599     function fn() {
18600       return slice.call(arguments);
18601     }
18602
18603     QUnit.test('should reorder arguments provided to `func`', function(assert) {
18604       assert.expect(1);
18605
18606       var rearged = _.rearg(fn, [2, 0, 1]);
18607       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18608     });
18609
18610     QUnit.test('should work with repeated indexes', function(assert) {
18611       assert.expect(1);
18612
18613       var rearged = _.rearg(fn, [1, 1, 1]);
18614       assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
18615     });
18616
18617     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18618       assert.expect(1);
18619
18620       var rearged = _.rearg(fn, [1, 4]);
18621       assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
18622     });
18623
18624     QUnit.test('should use `undefined` for non-index values', function(assert) {
18625       assert.expect(1);
18626
18627       var values = lodashStable.reject(empties, function(value) {
18628         return (value === 0) || lodashStable.isArray(value);
18629       }).concat(-1, 1.1);
18630
18631       var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
18632
18633       var actual = lodashStable.map(values, function(value) {
18634         var rearged = _.rearg(fn, [value]);
18635         return rearged('a', 'b', 'c');
18636       });
18637
18638       assert.deepEqual(actual, expected);
18639     });
18640
18641     QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
18642       assert.expect(2);
18643
18644       var rearged = _.rearg(fn);
18645       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18646
18647       rearged = _.rearg(fn, [], []);
18648       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18649     });
18650
18651     QUnit.test('should accept multiple index arguments', function(assert) {
18652       assert.expect(1);
18653
18654       var rearged = _.rearg(fn, 2, 0, 1);
18655       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18656     });
18657
18658     QUnit.test('should accept multiple arrays of indexes', function(assert) {
18659       assert.expect(1);
18660
18661       var rearged = _.rearg(fn, [2], [0, 1]);
18662       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18663     });
18664
18665     QUnit.test('should work with fewer indexes than arguments', function(assert) {
18666       assert.expect(1);
18667
18668       var rearged = _.rearg(fn, [1, 0]);
18669       assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
18670     });
18671
18672     QUnit.test('should work on functions that have been rearged', function(assert) {
18673       assert.expect(1);
18674
18675       var rearged1 = _.rearg(fn, 2, 1, 0),
18676           rearged2 = _.rearg(rearged1, 1, 0, 2);
18677
18678       assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
18679     });
18680   }());
18681
18682   /*--------------------------------------------------------------------------*/
18683
18684   QUnit.module('lodash.reduce');
18685
18686   (function() {
18687     var array = [1, 2, 3];
18688
18689     QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
18690       assert.expect(1);
18691
18692       assert.strictEqual(_.reduce(array), 1);
18693     });
18694
18695     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18696       assert.expect(2);
18697
18698       var args;
18699
18700       _.reduce(array, function() {
18701         args || (args = slice.call(arguments));
18702       }, 0);
18703
18704       assert.deepEqual(args, [0, 1, 0, array]);
18705
18706       args = undefined;
18707       _.reduce(array, function() {
18708         args || (args = slice.call(arguments));
18709       });
18710
18711       assert.deepEqual(args, [1, 2, 1, array]);
18712     });
18713
18714     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18715       assert.expect(2);
18716
18717       var args,
18718           object = { 'a': 1, 'b': 2 },
18719           firstKey = _.head(_.keys(object));
18720
18721       var expected = firstKey == 'a'
18722         ? [0, 1, 'a', object]
18723         : [0, 2, 'b', object];
18724
18725       _.reduce(object, function() {
18726         args || (args = slice.call(arguments));
18727       }, 0);
18728
18729       assert.deepEqual(args, expected);
18730
18731       args = undefined;
18732       expected = firstKey == 'a'
18733         ? [1, 2, 'b', object]
18734         : [2, 1, 'a', object];
18735
18736       _.reduce(object, function() {
18737         args || (args = slice.call(arguments));
18738       });
18739
18740       assert.deepEqual(args, expected);
18741     });
18742   }());
18743
18744   /*--------------------------------------------------------------------------*/
18745
18746   QUnit.module('lodash.reduceRight');
18747
18748   (function() {
18749     var array = [1, 2, 3];
18750
18751     QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
18752       assert.expect(1);
18753
18754       assert.strictEqual(_.reduceRight(array), 3);
18755     });
18756
18757     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18758       assert.expect(2);
18759
18760       var args;
18761
18762       _.reduceRight(array, function() {
18763         args || (args = slice.call(arguments));
18764       }, 0);
18765
18766       assert.deepEqual(args, [0, 3, 2, array]);
18767
18768       args = undefined;
18769       _.reduceRight(array, function() {
18770         args || (args = slice.call(arguments));
18771       });
18772
18773       assert.deepEqual(args, [3, 2, 1, array]);
18774     });
18775
18776     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18777       assert.expect(2);
18778
18779       var args,
18780           object = { 'a': 1, 'b': 2 },
18781           isFIFO = lodashStable.keys(object)[0] == 'a';
18782
18783       var expected = isFIFO
18784         ? [0, 2, 'b', object]
18785         : [0, 1, 'a', object];
18786
18787       _.reduceRight(object, function() {
18788         args || (args = slice.call(arguments));
18789       }, 0);
18790
18791       assert.deepEqual(args, expected);
18792
18793       args = undefined;
18794       expected = isFIFO
18795         ? [2, 1, 'a', object]
18796         : [1, 2, 'b', object];
18797
18798       _.reduceRight(object, function() {
18799         args || (args = slice.call(arguments));
18800       });
18801
18802       assert.deepEqual(args, expected);
18803     });
18804   }());
18805
18806   /*--------------------------------------------------------------------------*/
18807
18808   QUnit.module('reduce methods');
18809
18810   lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
18811     var func = _[methodName],
18812         array = [1, 2, 3],
18813         isReduce = methodName == 'reduce';
18814
18815     QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
18816       assert.expect(1);
18817
18818       var actual = func(['a', 'b', 'c'], function(accumulator, value) {
18819         return accumulator + value;
18820       }, '');
18821
18822       assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
18823     });
18824
18825     QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
18826       assert.expect(1);
18827
18828       var actual = [],
18829           expected = lodashStable.map(empties, noop);
18830
18831       lodashStable.each(empties, function(value) {
18832         try {
18833           actual.push(func(value, noop));
18834         } catch (e) {}
18835       });
18836
18837       assert.deepEqual(actual, expected);
18838     });
18839
18840     QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
18841       assert.expect(1);
18842
18843       var expected = lodashStable.map(empties, lodashStable.constant('x'));
18844
18845       var actual = lodashStable.map(empties, function(value) {
18846         try {
18847           return func(value, noop, 'x');
18848         } catch (e) {}
18849       });
18850
18851       assert.deepEqual(actual, expected);
18852     });
18853
18854     QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
18855       assert.expect(1);
18856
18857       var actual = func([], noop, undefined);
18858       assert.strictEqual(actual, undefined);
18859     });
18860
18861     QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
18862       assert.expect(2);
18863
18864       var array = [],
18865           object = { '0': 1, 'length': 0 };
18866
18867       if ('__proto__' in array) {
18868         array.__proto__ = object;
18869         assert.strictEqual(func(array, noop), undefined);
18870       }
18871       else {
18872         skipAssert(assert);
18873       }
18874       assert.strictEqual(func(object, noop), undefined);
18875     });
18876
18877     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
18878       assert.expect(1);
18879
18880       if (!isNpm) {
18881         assert.strictEqual(_(array)[methodName](add), 6);
18882       }
18883       else {
18884         skipAssert(assert);
18885       }
18886     });
18887
18888     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
18889       assert.expect(1);
18890
18891       if (!isNpm) {
18892         assert.ok(_(array).chain()[methodName](add) instanceof _);
18893       }
18894       else {
18895         skipAssert(assert);
18896       }
18897     });
18898   });
18899
18900   /*--------------------------------------------------------------------------*/
18901
18902   QUnit.module('lodash.reject');
18903
18904   (function() {
18905     var array = [1, 2, 3];
18906
18907     QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
18908       assert.expect(1);
18909
18910       assert.deepEqual(_.reject(array, isEven), [1, 3]);
18911     });
18912   }());
18913
18914   /*--------------------------------------------------------------------------*/
18915
18916   QUnit.module('filter methods');
18917
18918   lodashStable.each(['filter', 'reject'], function(methodName) {
18919     var array = [1, 2, 3, 4],
18920         func = _[methodName],
18921         isFilter = methodName == 'filter',
18922         objects = [{ 'a': 0 }, { 'a': 1 }];
18923
18924     QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
18925       assert.expect(1);
18926
18927       var actual = func([0], function(value, index, array) {
18928         array[index] = 1;
18929         return isFilter;
18930       });
18931
18932       assert.deepEqual(actual, [0]);
18933     });
18934
18935     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
18936       assert.expect(1);
18937
18938       assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
18939     });
18940
18941     QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
18942       assert.expect(1);
18943
18944       assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
18945     });
18946
18947     QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
18948       assert.expect(2);
18949
18950       if (!isNpm) {
18951         var wrapped = _(array);
18952
18953         var actual = wrapped[methodName](function(n) {
18954           return n < 3;
18955         });
18956
18957         assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
18958
18959         actual = wrapped[methodName](function(n) {
18960           return n > 2;
18961         });
18962
18963         assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
18964       }
18965       else {
18966         skipAssert(assert, 2);
18967       }
18968     });
18969
18970     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
18971       assert.expect(2);
18972
18973       if (!isNpm) {
18974         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18975             predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
18976             actual = _(array).slice(1).map(square)[methodName](predicate).value();
18977
18978         assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
18979
18980         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
18981           return ['key' + index, index];
18982         }));
18983
18984         actual = _(object).mapValues(square)[methodName](predicate).value();
18985         assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
18986       }
18987       else {
18988         skipAssert(assert, 2);
18989       }
18990     });
18991
18992     QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
18993       assert.expect(5);
18994
18995       if (!isNpm) {
18996         var args,
18997             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18998             expected = [1, 0, lodashStable.map(array.slice(1), square)];
18999
19000         _(array).slice(1)[methodName](function(value, index, array) {
19001           args || (args = slice.call(arguments));
19002         }).value();
19003
19004         assert.deepEqual(args, [1, 0, array.slice(1)]);
19005
19006         args = undefined;
19007         _(array).slice(1).map(square)[methodName](function(value, index, array) {
19008           args || (args = slice.call(arguments));
19009         }).value();
19010
19011         assert.deepEqual(args, expected);
19012
19013         args = undefined;
19014         _(array).slice(1).map(square)[methodName](function(value, index) {
19015           args || (args = slice.call(arguments));
19016         }).value();
19017
19018         assert.deepEqual(args, expected);
19019
19020         args = undefined;
19021         _(array).slice(1).map(square)[methodName](function(value) {
19022           args || (args = slice.call(arguments));
19023         }).value();
19024
19025         assert.deepEqual(args, [1]);
19026
19027         args = undefined;
19028         _(array).slice(1).map(square)[methodName](function() {
19029           args || (args = slice.call(arguments));
19030         }).value();
19031
19032         assert.deepEqual(args, expected);
19033       }
19034       else {
19035         skipAssert(assert, 5);
19036       }
19037     });
19038   });
19039
19040   /*--------------------------------------------------------------------------*/
19041
19042   QUnit.module('lodash.remove');
19043
19044   (function() {
19045     QUnit.test('should modify the array and return removed elements', function(assert) {
19046       assert.expect(2);
19047
19048       var array = [1, 2, 3, 4],
19049           actual = _.remove(array, isEven);
19050
19051       assert.deepEqual(array, [1, 3]);
19052       assert.deepEqual(actual, [2, 4]);
19053     });
19054
19055     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
19056       assert.expect(1);
19057
19058       var argsList = [],
19059           array = [1, 2, 3],
19060           clone = array.slice();
19061
19062       _.remove(array, function(n, index) {
19063         var args = slice.call(arguments);
19064         args[2] = args[2].slice();
19065         argsList.push(args);
19066         return isEven(index);
19067       });
19068
19069       assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
19070     });
19071
19072     QUnit.test('should work with `_.matches` shorthands', function(assert) {
19073       assert.expect(1);
19074
19075       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19076       _.remove(objects, { 'a': 1 });
19077       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19078     });
19079
19080     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
19081       assert.expect(1);
19082
19083       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19084       _.remove(objects, ['a', 1]);
19085       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19086     });
19087
19088     QUnit.test('should work with `_.property` shorthands', function(assert) {
19089       assert.expect(1);
19090
19091       var objects = [{ 'a': 0 }, { 'a': 1 }];
19092       _.remove(objects, 'a');
19093       assert.deepEqual(objects, [{ 'a': 0 }]);
19094     });
19095
19096     QUnit.test('should preserve holes in arrays', function(assert) {
19097       assert.expect(2);
19098
19099       var array = [1, 2, 3, 4];
19100       delete array[1];
19101       delete array[3];
19102
19103       _.remove(array, function(n) {
19104         return n === 1;
19105       });
19106
19107       assert.notOk('0' in array);
19108       assert.notOk('2' in array);
19109     });
19110
19111     QUnit.test('should treat holes as `undefined`', function(assert) {
19112       assert.expect(1);
19113
19114       var array = [1, 2, 3];
19115       delete array[1];
19116
19117       _.remove(array, function(n) {
19118         return n == null;
19119       });
19120
19121       assert.deepEqual(array, [1, 3]);
19122     });
19123
19124     QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
19125       assert.expect(1);
19126
19127       var array = [1, 2, 3];
19128
19129       _.remove(array, function(n, index) {
19130         return isEven(index);
19131       });
19132
19133       assert.deepEqual(array, [2]);
19134     });
19135   }());
19136
19137   /*--------------------------------------------------------------------------*/
19138
19139   QUnit.module('lodash.repeat');
19140
19141   (function() {
19142     var string = 'abc';
19143
19144     QUnit.test('should repeat a string `n` times', function(assert) {
19145       assert.expect(2);
19146
19147       assert.strictEqual(_.repeat('*', 3), '***');
19148       assert.strictEqual(_.repeat(string, 2), 'abcabc');
19149     });
19150
19151     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
19152       assert.expect(1);
19153
19154       var expected = lodashStable.map(falsey, function(value) {
19155         return value === undefined ? string : '';
19156       });
19157
19158       var actual = lodashStable.map(falsey, function(n, index) {
19159         return index ? _.repeat(string, n) : _.repeat(string);
19160       });
19161
19162       assert.deepEqual(actual, expected);
19163     });
19164
19165     QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
19166       assert.expect(2);
19167
19168       assert.strictEqual(_.repeat(string, 0), '');
19169       assert.strictEqual(_.repeat(string, -2), '');
19170     });
19171
19172     QUnit.test('should coerce `n` to an integer', function(assert) {
19173       assert.expect(3);
19174
19175       assert.strictEqual(_.repeat(string, '2'), 'abcabc');
19176       assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
19177       assert.strictEqual(_.repeat('*', { 'valueOf': stubThree }), '***');
19178     });
19179
19180     QUnit.test('should coerce `string` to a string', function(assert) {
19181       assert.expect(2);
19182
19183       assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
19184       assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
19185     });
19186
19187     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19188       assert.expect(1);
19189
19190       var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
19191       assert.deepEqual(actual, ['a', 'b', 'c']);
19192     });
19193   }());
19194
19195   /*--------------------------------------------------------------------------*/
19196
19197   QUnit.module('lodash.replace');
19198
19199   (function() {
19200     QUnit.test('should replace the matched pattern', function(assert) {
19201       assert.expect(2);
19202
19203       var string = 'abcde';
19204       assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
19205       assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
19206     });
19207   }());
19208
19209   /*--------------------------------------------------------------------------*/
19210
19211   QUnit.module('lodash.result');
19212
19213   (function() {
19214     var object = { 'a': 1, 'b': stubB };
19215
19216     QUnit.test('should invoke function values', function(assert) {
19217       assert.expect(1);
19218
19219       assert.strictEqual(_.result(object, 'b'), 'b');
19220     });
19221
19222     QUnit.test('should invoke default function values', function(assert) {
19223       assert.expect(1);
19224
19225       var actual = _.result(object, 'c', object.b);
19226       assert.strictEqual(actual, 'b');
19227     });
19228
19229     QUnit.test('should invoke nested function values', function(assert) {
19230       assert.expect(2);
19231
19232       var value = { 'a': lodashStable.constant({ 'b': stubB }) };
19233
19234       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19235         assert.strictEqual(_.result(value, path), 'b');
19236       });
19237     });
19238
19239     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
19240       assert.expect(2);
19241
19242       var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
19243
19244       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19245         assert.strictEqual(_.result(value, path), 1);
19246       });
19247     });
19248   }());
19249
19250   /*--------------------------------------------------------------------------*/
19251
19252   QUnit.module('lodash.get and lodash.result');
19253
19254   lodashStable.each(['get', 'result'], function(methodName) {
19255     var func = _[methodName];
19256
19257     QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
19258       assert.expect(2);
19259
19260       var object = { 'a': 1 };
19261
19262       lodashStable.each(['a', ['a']], function(path) {
19263         assert.strictEqual(func(object, path), 1);
19264       });
19265     });
19266
19267     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19268       assert.expect(1);
19269
19270       var object = { '-0': 'a', '0': 'b' },
19271           props = [-0, Object(-0), 0, Object(0)];
19272
19273       var actual = lodashStable.map(props, function(key) {
19274         return func(object, key);
19275       });
19276
19277       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
19278     });
19279
19280     QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
19281       assert.expect(1);
19282
19283       if (Symbol) {
19284         var object = {};
19285         object[symbol] = 1;
19286
19287         assert.strictEqual(func(object, symbol), 1);
19288       }
19289       else {
19290         skipAssert(assert);
19291       }
19292     });
19293
19294     QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
19295       assert.expect(2);
19296
19297       var object = { 'a': { 'b': 2 } };
19298
19299       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19300         assert.strictEqual(func(object, path), 2);
19301       });
19302     });
19303
19304     QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
19305       assert.expect(2);
19306
19307       var object = { 'a.b': 1, 'a': { 'b': 2 } };
19308
19309       lodashStable.each(['a.b', ['a.b']], function(path) {
19310         assert.strictEqual(func(object, path), 1);
19311       });
19312     });
19313
19314     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
19315       assert.expect(1);
19316
19317       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
19318       assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
19319     });
19320
19321     QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
19322       assert.expect(1);
19323
19324       var object = { 'a': { '': 1 } };
19325       assert.strictEqual(func(object, 'a[]'), 1);
19326     });
19327
19328     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
19329       assert.expect(4);
19330
19331       lodashStable.each([['', ''], [[], ['']]], function(pair) {
19332         assert.strictEqual(func({}, pair[0]), undefined);
19333         assert.strictEqual(func({ '': 3 }, pair[1]), 3);
19334       });
19335     });
19336
19337     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
19338       assert.expect(2);
19339
19340       var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
19341
19342       var paths = [
19343         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19344         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19345       ];
19346
19347       lodashStable.each(paths, function(path) {
19348         assert.strictEqual(func(object, path), 8);
19349       });
19350     });
19351
19352     QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
19353       assert.expect(4);
19354
19355       lodashStable.each(['constructor', ['constructor']], function(path) {
19356         assert.strictEqual(func(null, path), undefined);
19357         assert.strictEqual(func(undefined, path), undefined);
19358       });
19359     });
19360
19361     QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
19362       assert.expect(2);
19363
19364       var values = [null, undefined],
19365           expected = lodashStable.map(values, noop),
19366           paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
19367
19368       lodashStable.each(paths, function(path) {
19369         var actual = lodashStable.map(values, function(value) {
19370           return func(value, path);
19371         });
19372
19373         assert.deepEqual(actual, expected);
19374       });
19375     });
19376
19377     QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
19378       assert.expect(2);
19379
19380       var object = { 'a': [, null] };
19381
19382       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19383         assert.strictEqual(func(object, path), undefined);
19384       });
19385     });
19386
19387     QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
19388       assert.expect(2);
19389
19390       var object = { 'a': { 'b': null } };
19391
19392       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19393         assert.strictEqual(func(object, path), null);
19394       });
19395     });
19396
19397     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19398       assert.expect(2);
19399
19400       var paths = ['a.b', ['a', 'b']];
19401
19402       lodashStable.each(paths, function(path) {
19403         numberProto.a = { 'b': 2 };
19404         assert.strictEqual(func(0, path), 2);
19405         delete numberProto.a;
19406       });
19407     });
19408
19409     QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
19410       assert.expect(1);
19411
19412       var object = { 'a': {} },
19413           values = empties.concat(true, new Date, 1, /x/, 'a');
19414
19415       var expected = lodashStable.transform(values, function(result, value) {
19416         result.push(value, value, value, value);
19417       });
19418
19419       var actual = lodashStable.transform(values, function(result, value) {
19420         lodashStable.each(['a.b', ['a', 'b']], function(path) {
19421           result.push(
19422             func(object, path, value),
19423             func(null, path, value)
19424           );
19425         });
19426       });
19427
19428       assert.deepEqual(actual, expected);
19429     });
19430
19431     QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
19432       assert.expect(1);
19433
19434       assert.strictEqual(func({}, [], 'a'), 'a');
19435     });
19436   });
19437
19438   /*--------------------------------------------------------------------------*/
19439
19440   QUnit.module('lodash.rest');
19441
19442   (function() {
19443     function fn(a, b, c) {
19444       return slice.call(arguments);
19445     }
19446
19447     QUnit.test('should apply a rest parameter to `func`', function(assert) {
19448       assert.expect(1);
19449
19450       var rest = _.rest(fn);
19451       assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
19452     });
19453
19454     QUnit.test('should work with `start`', function(assert) {
19455       assert.expect(1);
19456
19457       var rest = _.rest(fn, 1);
19458       assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
19459     });
19460
19461     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
19462       assert.expect(1);
19463
19464       var values = [-1, NaN, 'a'],
19465           expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
19466
19467       var actual = lodashStable.map(values, function(value) {
19468         var rest = _.rest(fn, value);
19469         return rest(1, 2, 3, 4);
19470       });
19471
19472       assert.deepEqual(actual, expected);
19473     });
19474
19475     QUnit.test('should coerce `start` to an integer', function(assert) {
19476       assert.expect(1);
19477
19478       var rest = _.rest(fn, 1.6);
19479       assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
19480     });
19481
19482     QUnit.test('should use an empty array when `start` is not reached', function(assert) {
19483       assert.expect(1);
19484
19485       var rest = _.rest(fn);
19486       assert.deepEqual(rest(1), [1, undefined, []]);
19487     });
19488
19489     QUnit.test('should work on functions with more than three parameters', function(assert) {
19490       assert.expect(1);
19491
19492       var rest = _.rest(function(a, b, c, d) {
19493         return slice.call(arguments);
19494       });
19495
19496       assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
19497     });
19498   }());
19499
19500   /*--------------------------------------------------------------------------*/
19501
19502   QUnit.module('lodash.reverse');
19503
19504   (function() {
19505     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
19506         smallArray = [0, 1, 2, null];
19507
19508     QUnit.test('should reverse `array`', function(assert) {
19509       assert.expect(2);
19510
19511       var array = [1, 2, 3],
19512           actual = _.reverse(array);
19513
19514       assert.strictEqual(actual, array);
19515       assert.deepEqual(array, [3, 2, 1]);
19516     });
19517
19518     QUnit.test('should return the wrapped reversed `array`', function(assert) {
19519       assert.expect(6);
19520
19521       if (!isNpm) {
19522         lodashStable.times(2, function(index) {
19523           var array = (index ? largeArray : smallArray).slice(),
19524               clone = array.slice(),
19525               wrapped = _(array).reverse(),
19526               actual = wrapped.value();
19527
19528           assert.ok(wrapped instanceof _);
19529           assert.strictEqual(actual, array);
19530           assert.deepEqual(actual, clone.slice().reverse());
19531         });
19532       }
19533       else {
19534         skipAssert(assert, 6);
19535       }
19536     });
19537
19538     QUnit.test('should work in a lazy sequence', function(assert) {
19539       assert.expect(4);
19540
19541       if (!isNpm) {
19542         lodashStable.times(2, function(index) {
19543           var array = (index ? largeArray : smallArray).slice(),
19544               expected = array.slice(),
19545               actual = _(array).slice(1).reverse().value();
19546
19547           assert.deepEqual(actual, expected.slice(1).reverse());
19548           assert.deepEqual(array, expected);
19549         });
19550       }
19551       else {
19552         skipAssert(assert, 4);
19553       }
19554     });
19555
19556     QUnit.test('should be lazy when in a lazy sequence', function(assert) {
19557       assert.expect(3);
19558
19559       if (!isNpm) {
19560         var spy = {
19561           'toString': function() {
19562             throw new Error('spy was revealed');
19563           }
19564         };
19565
19566         var array = largeArray.concat(spy),
19567             expected = array.slice();
19568
19569         try {
19570           var wrapped = _(array).slice(1).map(String).reverse(),
19571               actual = wrapped.last();
19572         } catch (e) {}
19573
19574         assert.ok(wrapped instanceof _);
19575         assert.strictEqual(actual, '1');
19576         assert.deepEqual(array, expected);
19577       }
19578       else {
19579         skipAssert(assert, 3);
19580       }
19581     });
19582
19583     QUnit.test('should work in a hybrid sequence', function(assert) {
19584       assert.expect(8);
19585
19586       if (!isNpm) {
19587         lodashStable.times(2, function(index) {
19588           var clone = (index ? largeArray : smallArray).slice();
19589
19590           lodashStable.each(['map', 'filter'], function(methodName) {
19591             var array = clone.slice(),
19592                 expected = clone.slice(1, -1).reverse(),
19593                 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
19594
19595             assert.deepEqual(actual, expected);
19596
19597             array = clone.slice();
19598             actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
19599
19600             assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
19601           });
19602         });
19603       }
19604       else {
19605         skipAssert(assert, 8);
19606       }
19607     });
19608
19609     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
19610       assert.expect(6);
19611
19612       if (!isNpm) {
19613         lodashStable.times(2, function(index) {
19614           var array = (index ? largeArray : smallArray).slice(),
19615               expected = array.slice().reverse(),
19616               wrapped = _(array).chain().reverse().head();
19617
19618           assert.ok(wrapped instanceof _);
19619           assert.strictEqual(wrapped.value(), _.head(expected));
19620           assert.deepEqual(array, expected);
19621         });
19622       }
19623       else {
19624         skipAssert(assert, 6);
19625       }
19626     });
19627   }());
19628
19629   /*--------------------------------------------------------------------------*/
19630
19631   QUnit.module('round methods');
19632
19633   lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
19634     var func = _[methodName],
19635         isCeil = methodName == 'ceil',
19636         isFloor = methodName == 'floor';
19637
19638     QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
19639       assert.expect(1);
19640
19641       var actual = func(4.006);
19642       assert.strictEqual(actual, isCeil ? 5 : 4);
19643     });
19644
19645     QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
19646       assert.expect(1);
19647
19648       var actual = func(4.006, 0);
19649       assert.strictEqual(actual, isCeil ? 5 : 4);
19650     });
19651
19652     QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
19653       assert.expect(2);
19654
19655       var actual = func(4.016, 2);
19656       assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
19657
19658       actual = func(4.1, 2);
19659       assert.strictEqual(actual, 4.1);
19660     });
19661
19662     QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
19663       assert.expect(1);
19664
19665       var actual = func(4160, -2);
19666       assert.strictEqual(actual, isFloor ? 4100 : 4200);
19667     });
19668
19669     QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
19670       assert.expect(3);
19671
19672       var actual = func(4.006, NaN);
19673       assert.strictEqual(actual, isCeil ? 5 : 4);
19674
19675       var expected = isFloor ? 4.01 : 4.02;
19676
19677       actual = func(4.016, 2.6);
19678       assert.strictEqual(actual, expected);
19679
19680       actual = func(4.016, '+2');
19681       assert.strictEqual(actual, expected);
19682     });
19683
19684     QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
19685       assert.expect(3);
19686
19687       var actual = func(5e1, 2);
19688       assert.deepEqual(actual, 50);
19689
19690       actual = func('5e', 1);
19691       assert.deepEqual(actual, NaN);
19692
19693       actual = func('5e1e1', 1);
19694       assert.deepEqual(actual, NaN);
19695     });
19696
19697     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19698       assert.expect(1);
19699
19700       var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
19701           expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
19702
19703       var actual = lodashStable.map(values, function(args) {
19704         return 1 / func.apply(undefined, args);
19705       });
19706
19707       assert.deepEqual(actual, expected);
19708     });
19709
19710     QUnit.test('`_.' + methodName + '` should not return `NaN` for large `precision` values', function(assert) {
19711       assert.expect(1);
19712
19713       var results = [
19714         _.round(10.0000001, 1000),
19715         _.round(MAX_SAFE_INTEGER, 293)
19716       ];
19717
19718       var expected = lodashStable.map(results, stubFalse),
19719           actual = lodashStable.map(results, lodashStable.isNaN);
19720
19721       assert.deepEqual(actual, expected);
19722     });
19723   });
19724
19725   /*--------------------------------------------------------------------------*/
19726
19727   QUnit.module('lodash.runInContext');
19728
19729   (function() {
19730     QUnit.test('should not require a fully populated `context` object', function(assert) {
19731       assert.expect(1);
19732
19733       if (!isModularize) {
19734         var lodash = _.runInContext({
19735           'setTimeout': function(func) { func(); }
19736         });
19737
19738         var pass = false;
19739         lodash.delay(function() { pass = true; }, 32);
19740         assert.ok(pass);
19741       }
19742       else {
19743         skipAssert(assert);
19744       }
19745     });
19746
19747     QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
19748       assert.expect(3);
19749
19750       if (!isModularize) {
19751         lodashStable.times(2, _.uniqueId);
19752
19753         var oldId = Number(_.uniqueId()),
19754             lodash = _.runInContext();
19755
19756         assert.ok(_.uniqueId() > oldId);
19757
19758         var id = lodash.uniqueId();
19759         assert.strictEqual(id, '1');
19760         assert.ok(id < oldId);
19761       }
19762       else {
19763         skipAssert(assert, 3);
19764       }
19765     });
19766   }());
19767
19768   /*--------------------------------------------------------------------------*/
19769
19770   QUnit.module('lodash.sample');
19771
19772   (function() {
19773     var array = [1, 2, 3];
19774
19775     QUnit.test('should return a random element', function(assert) {
19776       assert.expect(1);
19777
19778       var actual = _.sample(array);
19779       assert.ok(lodashStable.includes(array, actual));
19780     });
19781
19782     QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
19783       assert.expect(1);
19784
19785       var expected = lodashStable.map(empties, noop);
19786
19787       var actual = lodashStable.transform(empties, function(result, value) {
19788         try {
19789           result.push(_.sample(value));
19790         } catch (e) {}
19791       });
19792
19793       assert.deepEqual(actual, expected);
19794     });
19795
19796     QUnit.test('should sample an object', function(assert) {
19797       assert.expect(1);
19798
19799       var object = { 'a': 1, 'b': 2, 'c': 3 },
19800           actual = _.sample(object);
19801
19802       assert.ok(lodashStable.includes(array, actual));
19803     });
19804   }());
19805
19806   /*--------------------------------------------------------------------------*/
19807
19808   QUnit.module('lodash.sampleSize');
19809
19810   (function() {
19811     var array = [1, 2, 3];
19812
19813     QUnit.test('should return an array of random elements', function(assert) {
19814       assert.expect(2);
19815
19816       var actual = _.sampleSize(array, 2);
19817
19818       assert.strictEqual(actual.length, 2);
19819       assert.deepEqual(lodashStable.difference(actual, array), []);
19820     });
19821
19822     QUnit.test('should contain elements of the collection', function(assert) {
19823       assert.expect(1);
19824
19825       var actual = _.sampleSize(array, array.length).sort();
19826
19827       assert.deepEqual(actual, array);
19828     });
19829
19830     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
19831       assert.expect(1);
19832
19833       var expected = lodashStable.map(falsey, function(value) {
19834         return value === undefined ? ['a'] : [];
19835       });
19836
19837       var actual = lodashStable.map(falsey, function(size, index) {
19838         return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
19839       });
19840
19841       assert.deepEqual(actual, expected);
19842     });
19843
19844     QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
19845       assert.expect(3);
19846
19847       lodashStable.each([0, -1, -Infinity], function(n) {
19848         assert.deepEqual(_.sampleSize(array, n), []);
19849       });
19850     });
19851
19852     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
19853       assert.expect(4);
19854
19855       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19856         var actual = _.sampleSize(array, n).sort();
19857         assert.deepEqual(actual, array);
19858       });
19859     });
19860
19861     QUnit.test('should coerce `n` to an integer', function(assert) {
19862       assert.expect(1);
19863
19864       var actual = _.sampleSize(array, 1.6);
19865       assert.strictEqual(actual.length, 1);
19866     });
19867
19868     QUnit.test('should return an empty array for empty collections', function(assert) {
19869       assert.expect(1);
19870
19871       var expected = lodashStable.map(empties, stubArray);
19872
19873       var actual = lodashStable.transform(empties, function(result, value) {
19874         try {
19875           result.push(_.sampleSize(value, 1));
19876         } catch (e) {}
19877       });
19878
19879       assert.deepEqual(actual, expected);
19880     });
19881
19882     QUnit.test('should sample an object', function(assert) {
19883       assert.expect(2);
19884
19885       var object = { 'a': 1, 'b': 2, 'c': 3 },
19886           actual = _.sampleSize(object, 2);
19887
19888       assert.strictEqual(actual.length, 2);
19889       assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
19890     });
19891
19892     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19893       assert.expect(1);
19894
19895       var actual = lodashStable.map([['a']], _.sampleSize);
19896       assert.deepEqual(actual, [['a']]);
19897     });
19898   }());
19899
19900   /*--------------------------------------------------------------------------*/
19901
19902   QUnit.module('lodash.setWith');
19903
19904   (function() {
19905     QUnit.test('should work with a `customizer` callback', function(assert) {
19906       assert.expect(1);
19907
19908       var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
19909         return lodashStable.isObject(value) ? undefined : {};
19910       });
19911
19912       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
19913     });
19914
19915     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
19916       assert.expect(1);
19917
19918       var actual = _.setWith({}, 'a[0].b.c', 4, noop);
19919       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
19920     });
19921   }());
19922
19923   /*--------------------------------------------------------------------------*/
19924
19925   QUnit.module('set methods');
19926
19927   lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
19928     var func = _[methodName],
19929         isUpdate = methodName == 'update' || methodName == 'updateWith';
19930
19931     var oldValue = 1,
19932         value = 2,
19933         updater = isUpdate ? lodashStable.constant(value) : value;
19934
19935     QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
19936       assert.expect(4);
19937
19938       lodashStable.each(['a', ['a']], function(path) {
19939         var object = { 'a': oldValue },
19940             actual = func(object, path, updater);
19941
19942         assert.strictEqual(actual, object);
19943         assert.strictEqual(object.a, value);
19944       });
19945     });
19946
19947     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19948       assert.expect(1);
19949
19950       var props = [-0, Object(-0), 0, Object(0)],
19951           expected = lodashStable.map(props, lodashStable.constant(value));
19952
19953       var actual = lodashStable.map(props, function(key) {
19954         var object = { '-0': 'a', '0': 'b' };
19955         func(object, key, updater);
19956         return object[lodashStable.toString(key)];
19957       });
19958
19959       assert.deepEqual(actual, expected);
19960     });
19961
19962     QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
19963       assert.expect(2);
19964
19965       if (Symbol) {
19966         var object = {};
19967         object[symbol] = 1;
19968
19969         assert.strictEqual(_.unset(object, symbol), true);
19970         assert.notOk(symbol in object);
19971       }
19972       else {
19973         skipAssert(assert, 2);
19974       }
19975     });
19976
19977     QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
19978       assert.expect(4);
19979
19980       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19981         var object = { 'a': { 'b': oldValue } },
19982             actual = func(object, path, updater);
19983
19984         assert.strictEqual(actual, object);
19985         assert.strictEqual(object.a.b, value);
19986       });
19987     });
19988
19989     QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
19990       assert.expect(4);
19991
19992       lodashStable.each(['a.b', ['a.b']], function(path) {
19993         var object = { 'a.b': oldValue },
19994             actual = func(object, path, updater);
19995
19996         assert.strictEqual(actual, object);
19997         assert.deepEqual(object, { 'a.b': value });
19998       });
19999     });
20000
20001     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
20002       assert.expect(1);
20003
20004       var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
20005
20006       func(object, ['a', 'b', 'c'], updater);
20007       assert.strictEqual(object.a.b.c, value);
20008     });
20009
20010     QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
20011       assert.expect(1);
20012
20013       var object = {};
20014
20015       func(object, 'a[]', updater);
20016       assert.deepEqual(object, { 'a': { '': value } });
20017     });
20018
20019     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
20020       assert.expect(4);
20021
20022       lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
20023         var object = {};
20024
20025         func(object, pair[0], updater);
20026         assert.deepEqual(object, index ? {} : { '': value });
20027
20028         func(object, pair[1], updater);
20029         assert.deepEqual(object, { '': value });
20030       });
20031     });
20032
20033     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
20034       assert.expect(2);
20035
20036       var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
20037
20038       var paths = [
20039         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
20040         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
20041       ];
20042
20043       lodashStable.each(paths, function(path) {
20044         func(object, path, updater);
20045         assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
20046         object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
20047       });
20048     });
20049
20050     QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
20051       assert.expect(6);
20052
20053       var object = {};
20054
20055       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
20056         var actual = func(object, path, updater);
20057
20058         assert.strictEqual(actual, object);
20059         assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
20060         assert.notOk('0' in object.a);
20061
20062         delete object.a;
20063       });
20064     });
20065
20066     QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
20067       assert.expect(1);
20068
20069       var values = [null, undefined],
20070           expected = [[null, null], [undefined, undefined]];
20071
20072       var actual = lodashStable.map(values, function(value) {
20073         try {
20074           return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
20075         } catch (e) {
20076           return e.message;
20077         }
20078       });
20079
20080       assert.deepEqual(actual, expected);
20081     });
20082
20083     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
20084       assert.expect(4);
20085
20086       var object = { 'a': '' },
20087           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
20088
20089       lodashStable.each(paths, function(path) {
20090         func(0, path, updater);
20091         assert.strictEqual(0..a, value);
20092         delete numberProto.a;
20093       });
20094
20095       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
20096         func(object, path, updater);
20097         assert.strictEqual(stringProto.replace.b, value);
20098         delete stringProto.replace.b;
20099       });
20100     });
20101
20102     QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
20103       'use strict';
20104
20105       assert.expect(2);
20106
20107       lodashStable.each(['a', 'a.a.a'], function(path) {
20108         numberProto.a = oldValue;
20109         try {
20110           func(0, path, updater);
20111           assert.strictEqual(0..a, oldValue);
20112         } catch (e) {
20113           assert.ok(false, e.message);
20114         }
20115       });
20116
20117       delete numberProto.a;
20118     });
20119
20120     QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
20121       assert.expect(1);
20122
20123       var object = {};
20124
20125       func(object, ['1a', '2b', '3c'], updater);
20126       assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
20127     });
20128
20129     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
20130       assert.expect(4);
20131
20132       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
20133         var object = {},
20134             pass = true,
20135             updater = isUpdate ? lodashStable.constant(value) : value;
20136
20137         defineProperty(object, 'a', {
20138           'enumerable': true,
20139           'configurable': true,
20140           'get': lodashStable.constant(value),
20141           'set': function() { pass = false; }
20142         });
20143
20144         func(object, 'a', updater);
20145         assert.ok(pass);
20146       });
20147     });
20148   });
20149
20150   /*--------------------------------------------------------------------------*/
20151
20152   QUnit.module('lodash.shuffle');
20153
20154   (function() {
20155     var array = [1, 2, 3],
20156         object = { 'a': 1, 'b': 2, 'c': 3 };
20157
20158     QUnit.test('should return a new array', function(assert) {
20159       assert.expect(1);
20160
20161       assert.notStrictEqual(_.shuffle(array), array);
20162     });
20163
20164     QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
20165       assert.expect(2);
20166
20167       assert.deepEqual(_.shuffle(array).sort(), array);
20168       assert.deepEqual(_.shuffle(object).sort(), array);
20169     });
20170
20171     QUnit.test('should shuffle small collections', function(assert) {
20172       assert.expect(1);
20173
20174       var actual = lodashStable.times(1000, function(assert) {
20175         return _.shuffle([1, 2]);
20176       });
20177
20178       assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
20179     });
20180
20181     QUnit.test('should treat number values for `collection` as empty', function(assert) {
20182       assert.expect(1);
20183
20184       assert.deepEqual(_.shuffle(1), []);
20185     });
20186   }());
20187
20188   /*--------------------------------------------------------------------------*/
20189
20190   QUnit.module('lodash.size');
20191
20192   (function() {
20193     var args = arguments,
20194         array = [1, 2, 3];
20195
20196     QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
20197       assert.expect(1);
20198
20199       assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
20200     });
20201
20202     QUnit.test('should return the length of an array', function(assert) {
20203       assert.expect(1);
20204
20205       assert.strictEqual(_.size(array), 3);
20206     });
20207
20208     QUnit.test('should accept a falsey `object` argument', function(assert) {
20209       assert.expect(1);
20210
20211       var expected = lodashStable.map(falsey, stubZero);
20212
20213       var actual = lodashStable.map(falsey, function(object, index) {
20214         try {
20215           return index ? _.size(object) : _.size();
20216         } catch (e) {}
20217       });
20218
20219       assert.deepEqual(actual, expected);
20220     });
20221
20222     QUnit.test('should work with `arguments` objects', function(assert) {
20223       assert.expect(1);
20224
20225       assert.strictEqual(_.size(args), 3);
20226     });
20227
20228     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
20229       assert.expect(1);
20230
20231       function Foo(elements) {
20232         push.apply(this, elements);
20233       }
20234       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
20235
20236       assert.strictEqual(_.size(new Foo(array)), 3);
20237     });
20238
20239     QUnit.test('should work with maps', function(assert) {
20240       assert.expect(2);
20241
20242       if (Map) {
20243         lodashStable.each([new Map, realm.map], function(map) {
20244           map.set('a', 1);
20245           map.set('b', 2);
20246           assert.strictEqual(_.size(map), 2);
20247           map.clear();
20248         });
20249       }
20250       else {
20251         skipAssert(assert, 2);
20252       }
20253     });
20254
20255     QUnit.test('should work with sets', function(assert) {
20256       assert.expect(2);
20257
20258       if (Set) {
20259         lodashStable.each([new Set, realm.set], function(set) {
20260           set.add(1);
20261           set.add(2);
20262           assert.strictEqual(_.size(set), 2);
20263           set.clear();
20264         });
20265       }
20266       else {
20267         skipAssert(assert, 2);
20268       }
20269     });
20270
20271     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
20272       assert.expect(1);
20273
20274       assert.strictEqual(_.size({ 'length': -1 }), 1);
20275     });
20276
20277     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
20278       assert.expect(1);
20279
20280       assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
20281     });
20282
20283     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
20284       assert.expect(1);
20285
20286       assert.strictEqual(_.size({ 'length': '0' }), 1);
20287     });
20288   }(1, 2, 3));
20289
20290   /*--------------------------------------------------------------------------*/
20291
20292   QUnit.module('lodash.slice');
20293
20294   (function() {
20295     var array = [1, 2, 3];
20296
20297     QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
20298       assert.expect(2);
20299
20300       var actual = _.slice(array);
20301       assert.deepEqual(actual, array);
20302       assert.notStrictEqual(actual, array);
20303     });
20304
20305     QUnit.test('should work with a positive `start`', function(assert) {
20306       assert.expect(2);
20307
20308       assert.deepEqual(_.slice(array, 1), [2, 3]);
20309       assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
20310     });
20311
20312     QUnit.test('should work with a `start` >= `length`', function(assert) {
20313       assert.expect(4);
20314
20315       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
20316         assert.deepEqual(_.slice(array, start), []);
20317       });
20318     });
20319
20320     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
20321       assert.expect(1);
20322
20323       var expected = lodashStable.map(falsey, lodashStable.constant(array));
20324
20325       var actual = lodashStable.map(falsey, function(start) {
20326         return _.slice(array, start);
20327       });
20328
20329       assert.deepEqual(actual, expected);
20330     });
20331
20332     QUnit.test('should work with a negative `start`', function(assert) {
20333       assert.expect(1);
20334
20335       assert.deepEqual(_.slice(array, -1), [3]);
20336     });
20337
20338     QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
20339       assert.expect(3);
20340
20341       lodashStable.each([-3, -4, -Infinity], function(start) {
20342         assert.deepEqual(_.slice(array, start), array);
20343       });
20344     });
20345
20346     QUnit.test('should work with `start` >= `end`', function(assert) {
20347       assert.expect(2);
20348
20349       lodashStable.each([2, 3], function(start) {
20350         assert.deepEqual(_.slice(array, start, 2), []);
20351       });
20352     });
20353
20354     QUnit.test('should work with a positive `end`', function(assert) {
20355       assert.expect(1);
20356
20357       assert.deepEqual(_.slice(array, 0, 1), [1]);
20358     });
20359
20360     QUnit.test('should work with a `end` >= `length`', function(assert) {
20361       assert.expect(4);
20362
20363       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
20364         assert.deepEqual(_.slice(array, 0, end), array);
20365       });
20366     });
20367
20368     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
20369       assert.expect(1);
20370
20371       var expected = lodashStable.map(falsey, function(value) {
20372         return value === undefined ? array : [];
20373       });
20374
20375       var actual = lodashStable.map(falsey, function(end, index) {
20376         return index ? _.slice(array, 0, end) : _.slice(array, 0);
20377       });
20378
20379       assert.deepEqual(actual, expected);
20380     });
20381
20382     QUnit.test('should work with a negative `end`', function(assert) {
20383       assert.expect(1);
20384
20385       assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
20386     });
20387
20388     QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
20389       assert.expect(3);
20390
20391       lodashStable.each([-3, -4, -Infinity], function(end) {
20392         assert.deepEqual(_.slice(array, 0, end), []);
20393       });
20394     });
20395
20396     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
20397       assert.expect(1);
20398
20399       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
20400
20401       var actual = lodashStable.map(positions, function(pos) {
20402         return _.slice.apply(_, [array].concat(pos));
20403       });
20404
20405       assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
20406     });
20407
20408     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20409       assert.expect(2);
20410
20411       var array = [[1], [2, 3]],
20412           actual = lodashStable.map(array, _.slice);
20413
20414       assert.deepEqual(actual, array);
20415       assert.notStrictEqual(actual, array);
20416     });
20417
20418     QUnit.test('should work in a lazy sequence', function(assert) {
20419       assert.expect(38);
20420
20421       if (!isNpm) {
20422         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
20423             length = array.length,
20424             wrapped = _(array);
20425
20426         lodashStable.each(['map', 'filter'], function(methodName) {
20427           assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
20428           assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
20429           assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
20430           assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
20431
20432           assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
20433           assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
20434           assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
20435           assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
20436
20437           assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
20438           assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
20439           assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
20440
20441           assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
20442           assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
20443
20444           assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
20445           assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
20446           assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
20447           assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
20448           assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
20449           assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
20450         });
20451       }
20452       else {
20453         skipAssert(assert, 38);
20454       }
20455     });
20456   }());
20457
20458   /*--------------------------------------------------------------------------*/
20459
20460   QUnit.module('lodash.some');
20461
20462   (function() {
20463     QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
20464       assert.expect(2);
20465
20466       assert.strictEqual(_.some([false, 1, ''], identity), true);
20467       assert.strictEqual(_.some([null, 'a', 0], identity), true);
20468     });
20469
20470     QUnit.test('should return `false` for empty collections', function(assert) {
20471       assert.expect(1);
20472
20473       var expected = lodashStable.map(empties, stubFalse);
20474
20475       var actual = lodashStable.map(empties, function(value) {
20476         try {
20477           return _.some(value, identity);
20478         } catch (e) {}
20479       });
20480
20481       assert.deepEqual(actual, expected);
20482     });
20483
20484     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
20485       assert.expect(2);
20486
20487       var count = 0;
20488
20489       assert.strictEqual(_.some([null, true, null], function(value) {
20490         count++;
20491         return value;
20492       }), true);
20493
20494       assert.strictEqual(count, 2);
20495     });
20496
20497     QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
20498       assert.expect(2);
20499
20500       assert.strictEqual(_.some([false, false, false], identity), false);
20501       assert.strictEqual(_.some([null, 0, ''], identity), false);
20502     });
20503
20504     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
20505       assert.expect(2);
20506
20507       var values = [, null, undefined],
20508           expected = lodashStable.map(values, stubFalse);
20509
20510       var actual = lodashStable.map(values, function(value, index) {
20511         var array = [0, 0];
20512         return index ? _.some(array, value) : _.some(array);
20513       });
20514
20515       assert.deepEqual(actual, expected);
20516
20517       expected = lodashStable.map(values, stubTrue);
20518       actual = lodashStable.map(values, function(value, index) {
20519         var array = [0, 1];
20520         return index ? _.some(array, value) : _.some(array);
20521       });
20522
20523       assert.deepEqual(actual, expected);
20524     });
20525
20526     QUnit.test('should work with `_.property` shorthands', function(assert) {
20527       assert.expect(2);
20528
20529       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
20530       assert.strictEqual(_.some(objects, 'a'), false);
20531       assert.strictEqual(_.some(objects, 'b'), true);
20532     });
20533
20534     QUnit.test('should work with `_.matches` shorthands', function(assert) {
20535       assert.expect(2);
20536
20537       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
20538       assert.strictEqual(_.some(objects, { 'a': 0 }), true);
20539       assert.strictEqual(_.some(objects, { 'b': 2 }), false);
20540     });
20541
20542     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20543       assert.expect(1);
20544
20545       var actual = lodashStable.map([[1]], _.some);
20546       assert.deepEqual(actual, [true]);
20547     });
20548   }());
20549
20550   /*--------------------------------------------------------------------------*/
20551
20552   QUnit.module('lodash.sortBy');
20553
20554   (function() {
20555     var objects = [
20556       { 'a': 'x', 'b': 3 },
20557       { 'a': 'y', 'b': 4 },
20558       { 'a': 'x', 'b': 1 },
20559       { 'a': 'y', 'b': 2 }
20560     ];
20561
20562     QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
20563       assert.expect(1);
20564
20565       var actual = lodashStable.map(_.sortBy(objects, function(object) {
20566         return object.b;
20567       }), 'b');
20568
20569       assert.deepEqual(actual, [1, 2, 3, 4]);
20570     });
20571
20572     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20573       assert.expect(1);
20574
20575       var array = [3, 2, 1],
20576           values = [, null, undefined],
20577           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
20578
20579       var actual = lodashStable.map(values, function(value, index) {
20580         return index ? _.sortBy(array, value) : _.sortBy(array);
20581       });
20582
20583       assert.deepEqual(actual, expected);
20584     });
20585
20586     QUnit.test('should work with `_.property` shorthands', function(assert) {
20587       assert.expect(1);
20588
20589       var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
20590       assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
20591     });
20592
20593     QUnit.test('should work with an object for `collection`', function(assert) {
20594       assert.expect(1);
20595
20596       var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
20597       assert.deepEqual(actual, [3, 1, 2]);
20598     });
20599
20600     QUnit.test('should move symbol, `null`, `undefined`, and `NaN` values to the end', function(assert) {
20601       assert.expect(2);
20602
20603       var symbol1 = Symbol ? Symbol('a') : null,
20604           symbol2 = Symbol ? Symbol('b') : null,
20605           array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
20606           expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20607
20608       assert.deepEqual(_.sortBy(array), expected);
20609
20610       array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
20611       expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20612
20613       assert.deepEqual(_.sortBy(array), expected);
20614     });
20615
20616     QUnit.test('should treat number values for `collection` as empty', function(assert) {
20617       assert.expect(1);
20618
20619       assert.deepEqual(_.sortBy(1), []);
20620     });
20621
20622     QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
20623       assert.expect(1);
20624
20625       var actual = _.sortBy(objects, function(object) {
20626         var result = [object.a, object.b];
20627         result.toString = function() { return String(this[0]); };
20628         return result;
20629       });
20630
20631       assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
20632     });
20633
20634     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20635       assert.expect(1);
20636
20637       var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
20638       assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
20639     });
20640   }());
20641
20642   /*--------------------------------------------------------------------------*/
20643
20644   QUnit.module('sortBy methods');
20645
20646   lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
20647     var func = _[methodName];
20648
20649     function Pair(a, b, c) {
20650       this.a = a;
20651       this.b = b;
20652       this.c = c;
20653     }
20654
20655     var objects = [
20656       { 'a': 'x', 'b': 3 },
20657       { 'a': 'y', 'b': 4 },
20658       { 'a': 'x', 'b': 1 },
20659       { 'a': 'y', 'b': 2 }
20660     ];
20661
20662     var stableArray = [
20663       new Pair(1, 1, 1), new Pair(1, 2, 1),
20664       new Pair(1, 1, 1), new Pair(1, 2, 1),
20665       new Pair(1, 3, 1), new Pair(1, 4, 1),
20666       new Pair(1, 5, 1), new Pair(1, 6, 1),
20667       new Pair(2, 1, 2), new Pair(2, 2, 2),
20668       new Pair(2, 3, 2), new Pair(2, 4, 2),
20669       new Pair(2, 5, 2), new Pair(2, 6, 2),
20670       new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
20671       new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
20672       new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
20673     ];
20674
20675     var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
20676
20677     QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
20678       assert.expect(1);
20679
20680       var actual = func(objects, ['a', 'b']);
20681       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20682     });
20683
20684     QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
20685       assert.expect(1);
20686
20687       var actual = func(objects, ['a', function(object) { return object.b; }]);
20688       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20689     });
20690
20691     QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
20692       assert.expect(2);
20693
20694       lodashStable.each([stableArray, stableObject], function(value, index) {
20695         var actual = func(value, ['a', 'c']);
20696         assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
20697       });
20698     });
20699
20700     QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
20701       assert.expect(1);
20702
20703       try {
20704         var actual = func(objects.concat(null, undefined), ['a', 'b']);
20705       } catch (e) {}
20706
20707       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
20708     });
20709
20710     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
20711       assert.expect(3);
20712
20713       var objects = [
20714         { 'a': 'x', '0': 3 },
20715         { 'a': 'y', '0': 4 },
20716         { 'a': 'x', '0': 1 },
20717         { 'a': 'y', '0': 2 }
20718       ];
20719
20720       var funcs = [func, lodashStable.partialRight(func, 'bogus')];
20721
20722       lodashStable.each(['a', 0, [0]], function(props, index) {
20723         var expected = lodashStable.map(funcs, lodashStable.constant(
20724           index
20725             ? [objects[2], objects[3], objects[0], objects[1]]
20726             : [objects[0], objects[2], objects[1], objects[3]]
20727         ));
20728
20729         var actual = lodashStable.map(funcs, function(func) {
20730           return lodashStable.reduce([props], func, objects);
20731         });
20732
20733         assert.deepEqual(actual, expected);
20734       });
20735     });
20736   });
20737
20738   /*--------------------------------------------------------------------------*/
20739
20740   QUnit.module('sortedIndex methods');
20741
20742   lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
20743     var func = _[methodName],
20744         isSortedIndex = methodName == 'sortedIndex';
20745
20746     QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
20747       assert.expect(1);
20748
20749       var array = [30, 50],
20750           values = [30, 40, 50],
20751           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20752
20753       var actual = lodashStable.map(values, function(value) {
20754         return func(array, value);
20755       });
20756
20757       assert.deepEqual(actual, expected);
20758     });
20759
20760     QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
20761       assert.expect(1);
20762
20763       var array = ['a', 'c'],
20764           values = ['a', 'b', 'c'],
20765           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20766
20767       var actual = lodashStable.map(values, function(value) {
20768         return func(array, value);
20769       });
20770
20771       assert.deepEqual(actual, expected);
20772     });
20773
20774     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
20775       assert.expect(1);
20776
20777       var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
20778
20779       var actual = lodashStable.map(falsey, function(array) {
20780         return [func(array, 1), func(array, undefined), func(array, NaN)];
20781       });
20782
20783       assert.deepEqual(actual, expected);
20784     });
20785
20786     QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
20787       assert.expect(12);
20788
20789       var symbol1 = Symbol ? Symbol('a') : null,
20790           symbol2 = Symbol ? Symbol('b') : null,
20791           symbol3 = Symbol ? Symbol('c') : null,
20792           expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
20793
20794       lodashStable.each([
20795         [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
20796         ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
20797       ], function(array) {
20798         assert.deepEqual(_.sortBy(array), expected);
20799         assert.strictEqual(func(expected, 3), 2);
20800         assert.strictEqual(func(expected, symbol3), isSortedIndex ? 3 : (Symbol ? 5 : 6));
20801         assert.strictEqual(func(expected, null), isSortedIndex ? (Symbol ? 5 : 3) : 6);
20802         assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
20803         assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
20804       });
20805     });
20806
20807     QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for nulls', function(assert) {
20808       assert.expect(3);
20809
20810       var array = [null, null];
20811
20812       assert.strictEqual(func(array, null), isSortedIndex ? 0 : 2);
20813       assert.strictEqual(func(array, 1), 0);
20814       assert.strictEqual(func(array, 'a'), 0);
20815     });
20816
20817     QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for symbols', function(assert) {
20818       assert.expect(3);
20819
20820       var symbol1 = Symbol ? Symbol('a') : null,
20821           symbol2 = Symbol ? Symbol('b') : null,
20822           symbol3 = Symbol ? Symbol('c') : null,
20823           array = [symbol1, symbol2];
20824
20825       assert.strictEqual(func(array, symbol3), isSortedIndex ? 0 : 2);
20826       assert.strictEqual(func(array, 1), 0);
20827       assert.strictEqual(func(array, 'a'), 0);
20828     });
20829   });
20830
20831   /*--------------------------------------------------------------------------*/
20832
20833   QUnit.module('sortedIndexBy methods');
20834
20835   lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
20836     var func = _[methodName],
20837         isSortedIndexBy = methodName == 'sortedIndexBy';
20838
20839     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
20840       assert.expect(1);
20841
20842       var args;
20843
20844       func([30, 50], 40, function(assert) {
20845         args || (args = slice.call(arguments));
20846       });
20847
20848       assert.deepEqual(args, [40]);
20849     });
20850
20851     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
20852       assert.expect(1);
20853
20854       var objects = [{ 'x': 30 }, { 'x': 50 }],
20855           actual = func(objects, { 'x': 40 }, 'x');
20856
20857       assert.strictEqual(actual, 1);
20858     });
20859
20860     QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
20861       assert.expect(12);
20862
20863       lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
20864         var array = [],
20865             values = [MAX_ARRAY_LENGTH, NaN, undefined];
20866
20867         array.length = length;
20868
20869         lodashStable.each(values, function(value) {
20870           var steps = 0;
20871
20872           var actual = func(array, value, function(value) {
20873             steps++;
20874             return value;
20875           });
20876
20877           var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
20878             ? 0
20879             : Math.min(length, MAX_ARRAY_INDEX);
20880
20881           // Avoid false fails in older Firefox.
20882           if (array.length == length) {
20883             assert.ok(steps == 32 || steps == 33);
20884             assert.strictEqual(actual, expected);
20885           }
20886           else {
20887             skipAssert(assert, 2);
20888           }
20889         });
20890       });
20891     });
20892   });
20893
20894   /*--------------------------------------------------------------------------*/
20895
20896   QUnit.module('sortedIndexOf methods');
20897
20898   lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
20899     var func = _[methodName],
20900         isSortedIndexOf = methodName == 'sortedIndexOf';
20901
20902     QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
20903       assert.expect(1);
20904
20905       var sorted = [4, 4, 5, 5, 6, 6];
20906       assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
20907     });
20908   });
20909
20910   /*--------------------------------------------------------------------------*/
20911
20912   QUnit.module('lodash.sortedUniq');
20913
20914   (function() {
20915     QUnit.test('should return unique values of a sorted array', function(assert) {
20916       assert.expect(3);
20917
20918       var expected = [1, 2, 3];
20919
20920       lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
20921         assert.deepEqual(_.sortedUniq(array), expected);
20922       });
20923     });
20924   }());
20925
20926   /*--------------------------------------------------------------------------*/
20927
20928   QUnit.module('lodash.split');
20929
20930   (function() {
20931     QUnit.test('should split a string by `separator`', function(assert) {
20932       assert.expect(3);
20933
20934       var string = 'abcde';
20935       assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
20936       assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
20937       assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
20938     });
20939
20940     QUnit.test('should return an array containing an empty string for empty values', function(assert) {
20941       assert.expect(1);
20942
20943       var values = [, null, undefined, ''],
20944           expected = lodashStable.map(values, lodashStable.constant(['']));
20945
20946       var actual = lodashStable.map(values, function(value, index) {
20947         return index ? _.split(value) : _.split();
20948       });
20949
20950       assert.deepEqual(actual, expected);
20951     });
20952
20953     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20954       assert.expect(1);
20955
20956       var strings = ['abc', 'def', 'ghi'],
20957           actual = lodashStable.map(strings, _.split);
20958
20959       assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
20960     });
20961
20962     QUnit.test('should allow mixed string and array prototype methods', function(assert) {
20963       assert.expect(1);
20964
20965       if (!isNpm) {
20966         var wrapped = _('abc');
20967         assert.strictEqual(wrapped.split('b').join(','), 'a,c');
20968       }
20969       else {
20970         skipAssert(assert);
20971       }
20972     });
20973   }());
20974
20975   /*--------------------------------------------------------------------------*/
20976
20977   QUnit.module('lodash.spread');
20978
20979   (function() {
20980     function fn(a, b, c) {
20981       return slice.call(arguments);
20982     }
20983
20984     QUnit.test('should spread arguments to `func`', function(assert) {
20985       assert.expect(1);
20986
20987       var spread = _.spread(fn);
20988       assert.deepEqual(spread([4, 2]), [4, 2]);
20989     });
20990
20991     QUnit.test('should accept a falsey `array` argument', function(assert) {
20992       assert.expect(1);
20993
20994       var spread = _.spread(stubTrue),
20995           expected = lodashStable.map(falsey, stubTrue);
20996
20997       var actual = lodashStable.map(falsey, function(array, index) {
20998         try {
20999           return index ? spread(array) : spread();
21000         } catch (e) {}
21001       });
21002
21003       assert.deepEqual(actual, expected);
21004     });
21005
21006     QUnit.test('should provide the correct `func` arguments', function(assert) {
21007       assert.expect(1);
21008
21009       var args;
21010
21011       var spread = _.spread(function() {
21012         args = slice.call(arguments);
21013       });
21014
21015       spread([4, 2], 'ignored');
21016       assert.deepEqual(args, [4, 2]);
21017     });
21018
21019     QUnit.test('should work with `start`', function(assert) {
21020       assert.expect(1);
21021
21022       var spread = _.spread(fn, 1);
21023       assert.deepEqual(spread(1, [2, 3, 4]), [1, 2, 3, 4]);
21024     });
21025
21026     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
21027       assert.expect(1);
21028
21029       var values = [-1, NaN, 'a'],
21030           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
21031
21032       var actual = lodashStable.map(values, function(value) {
21033         var spread = _.spread(fn, value);
21034         return spread([1, 2, 3, 4]);
21035       });
21036
21037       assert.deepEqual(actual, expected);
21038     });
21039
21040     QUnit.test('should coerce `start` to an integer', function(assert) {
21041       assert.expect(1);
21042
21043       var spread = _.spread(fn, 1.6);
21044       assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
21045     });
21046   }());
21047
21048   /*--------------------------------------------------------------------------*/
21049
21050   QUnit.module('lodash.startCase');
21051
21052   (function() {
21053     QUnit.test('should uppercase only the first character of each word', function(assert) {
21054       assert.expect(3);
21055
21056       assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
21057       assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
21058       assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
21059     });
21060   }());
21061
21062   /*--------------------------------------------------------------------------*/
21063
21064   QUnit.module('lodash.startsWith');
21065
21066   (function() {
21067     var string = 'abc';
21068
21069     QUnit.test('should return `true` if a string starts with `target`', function(assert) {
21070       assert.expect(1);
21071
21072       assert.strictEqual(_.startsWith(string, 'a'), true);
21073     });
21074
21075     QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
21076       assert.expect(1);
21077
21078       assert.strictEqual(_.startsWith(string, 'b'), false);
21079     });
21080
21081     QUnit.test('should work with a `position` argument', function(assert) {
21082       assert.expect(1);
21083
21084       assert.strictEqual(_.startsWith(string, 'b', 1), true);
21085     });
21086
21087     QUnit.test('should work with `position` >= `length`', function(assert) {
21088       assert.expect(4);
21089
21090       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
21091         assert.strictEqual(_.startsWith(string, 'a', position), false);
21092       });
21093     });
21094
21095     QUnit.test('should treat falsey `position` values as `0`', function(assert) {
21096       assert.expect(1);
21097
21098       var expected = lodashStable.map(falsey, stubTrue);
21099
21100       var actual = lodashStable.map(falsey, function(position) {
21101         return _.startsWith(string, 'a', position);
21102       });
21103
21104       assert.deepEqual(actual, expected);
21105     });
21106
21107     QUnit.test('should treat a negative `position` as `0`', function(assert) {
21108       assert.expect(6);
21109
21110       lodashStable.each([-1, -3, -Infinity], function(position) {
21111         assert.strictEqual(_.startsWith(string, 'a', position), true);
21112         assert.strictEqual(_.startsWith(string, 'b', position), false);
21113       });
21114     });
21115
21116     QUnit.test('should coerce `position` to an integer', function(assert) {
21117       assert.expect(1);
21118
21119       assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
21120     });
21121
21122     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
21123       assert.expect(1);
21124
21125       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
21126         return _.startsWith(string, '', position, true);
21127       }));
21128     });
21129   }());
21130
21131   /*--------------------------------------------------------------------------*/
21132
21133   QUnit.module('lodash.startsWith and lodash.endsWith');
21134
21135   lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
21136     var func = _[methodName],
21137         isStartsWith = methodName == 'startsWith';
21138
21139     var string = 'abc',
21140         chr = isStartsWith ? 'a' : 'c';
21141
21142     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
21143       assert.expect(2);
21144
21145       assert.strictEqual(func(Object(string), chr), true);
21146       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
21147     });
21148
21149     QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
21150       assert.expect(2);
21151
21152       assert.strictEqual(func(string, Object(chr)), true);
21153       assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
21154     });
21155
21156     QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
21157       assert.expect(2);
21158
21159       var position = isStartsWith ? 1 : 2;
21160       assert.strictEqual(func(string, 'b', Object(position)), true);
21161       assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
21162     });
21163   });
21164
21165   /*--------------------------------------------------------------------------*/
21166
21167   QUnit.module('stub methods');
21168
21169   lodashStable.each(['noop', 'stubTrue', 'stubFalse', 'stubArray', 'stubObject', 'stubString'], function(methodName) {
21170     var func = _[methodName];
21171
21172     var pair = ({
21173       'stubArray': [[], 'an empty array'],
21174       'stubFalse': [false, '`false`'],
21175       'stubObject': [{}, 'an empty object'],
21176       'stubString': ['', 'an empty string'],
21177       'stubTrue': [true, '`true`'],
21178       'noop': [undefined, '`undefined`']
21179     })[methodName];
21180
21181     var values = Array(2).concat(empties, true, 1, 'a'),
21182         expected = lodashStable.map(values, lodashStable.constant(pair[0]));
21183
21184     QUnit.test('`_.' + methodName + '` should return ' + pair[1], function(assert) {
21185       assert.expect(1);
21186
21187       var actual = lodashStable.map(values, function(value, index) {
21188         if (index < 2) {
21189           return index ? func.call({}) : func();
21190         }
21191         return func(value);
21192       });
21193
21194       assert.deepEqual(actual, expected);
21195     });
21196   });
21197
21198   /*--------------------------------------------------------------------------*/
21199
21200   QUnit.module('lodash.subtract');
21201
21202   (function() {
21203     QUnit.test('should subtract two numbers', function(assert) {
21204       assert.expect(3);
21205
21206       assert.strictEqual(_.subtract(6, 4), 2);
21207       assert.strictEqual(_.subtract(-6, 4), -10);
21208       assert.strictEqual(_.subtract(-6, -4), -2);
21209     });
21210
21211     QUnit.test('should coerce arguments to numbers', function(assert) {
21212       assert.expect(2);
21213
21214       assert.strictEqual(_.subtract('6', '4'), 2);
21215       assert.deepEqual(_.subtract('x', 'y'), NaN);
21216     });
21217   }());
21218
21219   /*--------------------------------------------------------------------------*/
21220
21221   QUnit.module('math operator methods');
21222
21223   lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
21224     var func = _[methodName];
21225
21226     QUnit.test('`_.' + methodName + '` should return `0` when no arguments are given', function(assert) {
21227       assert.expect(1);
21228
21229       assert.strictEqual(func(), 0);
21230     });
21231
21232     QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
21233       assert.expect(3);
21234
21235       assert.strictEqual(func(6), 6);
21236       assert.strictEqual(func(6, undefined), 6);
21237       assert.strictEqual(func(undefined, 4), 4);
21238     });
21239
21240     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
21241       assert.expect(2);
21242
21243       var values = [0, '0', -0, '-0'],
21244           expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
21245
21246       lodashStable.times(2, function(index) {
21247         var actual = lodashStable.map(values, function(value) {
21248           var result = index ? func(undefined, value) : func(value);
21249           return [result, 1 / result];
21250         });
21251
21252         assert.deepEqual(actual, expected);
21253       });
21254     });
21255
21256     QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
21257       assert.expect(2);
21258
21259       assert.deepEqual(func(0, {}), NaN);
21260       assert.deepEqual(func({}, 0), NaN);
21261     });
21262
21263     QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
21264       assert.expect(2);
21265
21266       if (Symbol) {
21267         assert.deepEqual(func(0, symbol), NaN);
21268         assert.deepEqual(func(symbol, 0), NaN);
21269       }
21270       else {
21271         skipAssert(assert, 2);
21272       }
21273     });
21274
21275     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
21276       assert.expect(1);
21277
21278       if (!isNpm) {
21279         var actual = _(1)[methodName](2);
21280         assert.notOk(actual instanceof _);
21281       }
21282       else {
21283         skipAssert(assert);
21284       }
21285     });
21286
21287     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
21288       assert.expect(1);
21289
21290       if (!isNpm) {
21291         var actual = _(1).chain()[methodName](2);
21292         assert.ok(actual instanceof _);
21293       }
21294       else {
21295         skipAssert(assert);
21296       }
21297     });
21298   });
21299
21300   /*--------------------------------------------------------------------------*/
21301
21302   QUnit.module('lodash.sumBy');
21303
21304   (function() {
21305     var array = [6, 4, 2],
21306         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
21307
21308     QUnit.test('should work with an `iteratee` argument', function(assert) {
21309       assert.expect(1);
21310
21311       var actual = _.sumBy(objects, function(object) {
21312         return object.a;
21313       });
21314
21315       assert.deepEqual(actual, 6);
21316     });
21317
21318     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
21319       assert.expect(1);
21320
21321       var args;
21322
21323       _.sumBy(array, function() {
21324         args || (args = slice.call(arguments));
21325       });
21326
21327       assert.deepEqual(args, [6]);
21328     });
21329
21330     QUnit.test('should work with `_.property` shorthands', function(assert) {
21331       assert.expect(2);
21332
21333       var arrays = [[2], [3], [1]];
21334       assert.strictEqual(_.sumBy(arrays, 0), 6);
21335       assert.strictEqual(_.sumBy(objects, 'a'), 6);
21336     });
21337   }());
21338
21339   /*--------------------------------------------------------------------------*/
21340
21341   QUnit.module('sum methods');
21342
21343   lodashStable.each(['sum', 'sumBy'], function(methodName) {
21344     var array = [6, 4, 2],
21345         func = _[methodName];
21346
21347     QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
21348       assert.expect(1);
21349
21350       assert.strictEqual(func(array), 12);
21351     });
21352
21353     QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
21354       assert.expect(1);
21355
21356       var expected = lodashStable.map(empties, stubZero);
21357
21358       var actual = lodashStable.map(empties, function(value) {
21359         return func(value);
21360       });
21361
21362       assert.deepEqual(actual, expected);
21363     });
21364
21365     QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
21366       assert.expect(1);
21367
21368       assert.strictEqual(func([1, undefined]), 1);
21369     });
21370
21371     QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
21372       assert.expect(1);
21373
21374       assert.deepEqual(func([1, NaN]), NaN);
21375     });
21376
21377     QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
21378       assert.expect(1);
21379
21380       assert.strictEqual(func(['1', '2']), '12');
21381     });
21382   });
21383
21384   /*--------------------------------------------------------------------------*/
21385
21386   QUnit.module('lodash.tail');
21387
21388   (function() {
21389     var array = [1, 2, 3];
21390
21391     QUnit.test('should accept a falsey `array` argument', function(assert) {
21392       assert.expect(1);
21393
21394       var expected = lodashStable.map(falsey, stubArray);
21395
21396       var actual = lodashStable.map(falsey, function(array, index) {
21397         try {
21398           return index ? _.tail(array) : _.tail();
21399         } catch (e) {}
21400       });
21401
21402       assert.deepEqual(actual, expected);
21403     });
21404
21405     QUnit.test('should exclude the first element', function(assert) {
21406       assert.expect(1);
21407
21408       assert.deepEqual(_.tail(array), [2, 3]);
21409     });
21410
21411     QUnit.test('should return an empty when querying empty arrays', function(assert) {
21412       assert.expect(1);
21413
21414       assert.deepEqual(_.tail([]), []);
21415     });
21416
21417     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21418       assert.expect(1);
21419
21420       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21421           actual = lodashStable.map(array, _.tail);
21422
21423       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
21424     });
21425
21426     QUnit.test('should work in a lazy sequence', function(assert) {
21427       assert.expect(4);
21428
21429       if (!isNpm) {
21430         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21431             values = [];
21432
21433         var actual = _(array).tail().filter(function(value) {
21434           values.push(value);
21435           return false;
21436         })
21437         .value();
21438
21439         assert.deepEqual(actual, []);
21440         assert.deepEqual(values, array.slice(1));
21441
21442         values = [];
21443
21444         actual = _(array).filter(function(value) {
21445           values.push(value);
21446           return isEven(value);
21447         })
21448         .tail()
21449         .value();
21450
21451         assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
21452         assert.deepEqual(values, array);
21453       }
21454       else {
21455         skipAssert(assert, 4);
21456       }
21457     });
21458
21459     QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
21460       assert.expect(4);
21461
21462       if (!isNpm) {
21463         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21464             iteratee = function() { pass = false; },
21465             pass = true,
21466             actual = _(array).slice(0, 1).tail().map(iteratee).value();
21467
21468         assert.ok(pass);
21469         assert.deepEqual(actual, []);
21470
21471         pass = true;
21472         actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
21473
21474         assert.ok(pass);
21475         assert.deepEqual(actual, []);
21476       }
21477       else {
21478         skipAssert(assert, 4);
21479       }
21480     });
21481   }());
21482
21483   /*--------------------------------------------------------------------------*/
21484
21485   QUnit.module('lodash.take');
21486
21487   (function() {
21488     var array = [1, 2, 3];
21489
21490     QUnit.test('should take the first two elements', function(assert) {
21491       assert.expect(1);
21492
21493       assert.deepEqual(_.take(array, 2), [1, 2]);
21494     });
21495
21496     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21497       assert.expect(1);
21498
21499       var expected = lodashStable.map(falsey, function(value) {
21500         return value === undefined ? [1] : [];
21501       });
21502
21503       var actual = lodashStable.map(falsey, function(n) {
21504         return _.take(array, n);
21505       });
21506
21507       assert.deepEqual(actual, expected);
21508     });
21509
21510     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21511       assert.expect(3);
21512
21513       lodashStable.each([0, -1, -Infinity], function(n) {
21514         assert.deepEqual(_.take(array, n), []);
21515       });
21516     });
21517
21518     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21519       assert.expect(4);
21520
21521       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21522         assert.deepEqual(_.take(array, n), array);
21523       });
21524     });
21525
21526     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21527       assert.expect(1);
21528
21529       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21530           actual = lodashStable.map(array, _.take);
21531
21532       assert.deepEqual(actual, [[1], [4], [7]]);
21533     });
21534
21535     QUnit.test('should work in a lazy sequence', function(assert) {
21536       assert.expect(6);
21537
21538       if (!isNpm) {
21539         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
21540             predicate = function(value) { values.push(value); return isEven(value); },
21541             values = [],
21542             actual = _(array).take(2).take().value();
21543
21544         assert.deepEqual(actual, _.take(_.take(array, 2)));
21545
21546         actual = _(array).filter(predicate).take(2).take().value();
21547         assert.deepEqual(values, [1, 2]);
21548         assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
21549
21550         actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
21551         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
21552
21553         values = [];
21554
21555         actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
21556         assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
21557         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
21558       }
21559       else {
21560         skipAssert(assert, 6);
21561       }
21562     });
21563   }());
21564
21565   /*--------------------------------------------------------------------------*/
21566
21567   QUnit.module('lodash.takeRight');
21568
21569   (function() {
21570     var array = [1, 2, 3];
21571
21572     QUnit.test('should take the last two elements', function(assert) {
21573       assert.expect(1);
21574
21575       assert.deepEqual(_.takeRight(array, 2), [2, 3]);
21576     });
21577
21578     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21579       assert.expect(1);
21580
21581       var expected = lodashStable.map(falsey, function(value) {
21582         return value === undefined ? [3] : [];
21583       });
21584
21585       var actual = lodashStable.map(falsey, function(n) {
21586         return _.takeRight(array, n);
21587       });
21588
21589       assert.deepEqual(actual, expected);
21590     });
21591
21592     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21593       assert.expect(3);
21594
21595       lodashStable.each([0, -1, -Infinity], function(n) {
21596         assert.deepEqual(_.takeRight(array, n), []);
21597       });
21598     });
21599
21600     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21601       assert.expect(4);
21602
21603       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21604         assert.deepEqual(_.takeRight(array, n), array);
21605       });
21606     });
21607
21608     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21609       assert.expect(1);
21610
21611       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21612           actual = lodashStable.map(array, _.takeRight);
21613
21614       assert.deepEqual(actual, [[3], [6], [9]]);
21615     });
21616
21617     QUnit.test('should work in a lazy sequence', function(assert) {
21618       assert.expect(6);
21619
21620       if (!isNpm) {
21621         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21622             predicate = function(value) { values.push(value); return isEven(value); },
21623             values = [],
21624             actual = _(array).takeRight(2).takeRight().value();
21625
21626         assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
21627
21628         actual = _(array).filter(predicate).takeRight(2).takeRight().value();
21629         assert.deepEqual(values, array);
21630         assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
21631
21632         actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
21633         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
21634
21635         values = [];
21636
21637         actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
21638         assert.deepEqual(values, array);
21639         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
21640       }
21641       else {
21642         skipAssert(assert, 6);
21643       }
21644     });
21645   }());
21646
21647   /*--------------------------------------------------------------------------*/
21648
21649   QUnit.module('lodash.takeRightWhile');
21650
21651   (function() {
21652     var array = [1, 2, 3, 4];
21653
21654     var objects = [
21655       { 'a': 0, 'b': 0 },
21656       { 'a': 1, 'b': 1 },
21657       { 'a': 2, 'b': 2 }
21658     ];
21659
21660     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21661       assert.expect(1);
21662
21663       var actual = _.takeRightWhile(array, function(n) {
21664         return n > 2;
21665       });
21666
21667       assert.deepEqual(actual, [3, 4]);
21668     });
21669
21670     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21671       assert.expect(1);
21672
21673       var args;
21674
21675       _.takeRightWhile(array, function() {
21676         args = slice.call(arguments);
21677       });
21678
21679       assert.deepEqual(args, [4, 3, array]);
21680     });
21681
21682     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21683       assert.expect(1);
21684
21685       assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
21686     });
21687
21688     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21689       assert.expect(1);
21690
21691       assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
21692     });
21693
21694     QUnit.test('should work with `_.property` shorthands', function(assert) {
21695       assert.expect(1);
21696
21697       assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
21698     });
21699
21700     QUnit.test('should work in a lazy sequence', function(assert) {
21701       assert.expect(3);
21702
21703       if (!isNpm) {
21704         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21705             predicate = function(n) { return n > 2; },
21706             expected = _.takeRightWhile(array, predicate),
21707             wrapped = _(array).takeRightWhile(predicate);
21708
21709         assert.deepEqual(wrapped.value(), expected);
21710         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21711         assert.strictEqual(wrapped.last(), _.last(expected));
21712       }
21713       else {
21714         skipAssert(assert, 3);
21715       }
21716     });
21717
21718     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21719       assert.expect(5);
21720
21721       if (!isNpm) {
21722         var args,
21723             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21724             expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
21725
21726         _(array).slice(1).takeRightWhile(function(value, index, array) {
21727           args = slice.call(arguments);
21728         }).value();
21729
21730         assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
21731
21732         _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
21733           args = slice.call(arguments);
21734         }).value();
21735
21736         assert.deepEqual(args, expected);
21737
21738         _(array).slice(1).map(square).takeRightWhile(function(value, index) {
21739           args = slice.call(arguments);
21740         }).value();
21741
21742         assert.deepEqual(args, expected);
21743
21744         _(array).slice(1).map(square).takeRightWhile(function(index) {
21745           args = slice.call(arguments);
21746         }).value();
21747
21748         assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
21749
21750         _(array).slice(1).map(square).takeRightWhile(function() {
21751           args = slice.call(arguments);
21752         }).value();
21753
21754         assert.deepEqual(args, expected);
21755       }
21756       else {
21757         skipAssert(assert, 5);
21758       }
21759     });
21760   }());
21761
21762   /*--------------------------------------------------------------------------*/
21763
21764   QUnit.module('lodash.takeWhile');
21765
21766   (function() {
21767     var array = [1, 2, 3, 4];
21768
21769     var objects = [
21770       { 'a': 2, 'b': 2 },
21771       { 'a': 1, 'b': 1 },
21772       { 'a': 0, 'b': 0 }
21773     ];
21774
21775     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21776       assert.expect(1);
21777
21778       var actual = _.takeWhile(array, function(n) {
21779         return n < 3;
21780       });
21781
21782       assert.deepEqual(actual, [1, 2]);
21783     });
21784
21785     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21786       assert.expect(1);
21787
21788       var args;
21789
21790       _.takeWhile(array, function() {
21791         args = slice.call(arguments);
21792       });
21793
21794       assert.deepEqual(args, [1, 0, array]);
21795     });
21796
21797     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21798       assert.expect(1);
21799
21800       assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
21801     });
21802
21803     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21804       assert.expect(1);
21805
21806       assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
21807     });
21808     QUnit.test('should work with `_.property` shorthands', function(assert) {
21809       assert.expect(1);
21810
21811       assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
21812     });
21813
21814     QUnit.test('should work in a lazy sequence', function(assert) {
21815       assert.expect(3);
21816
21817       if (!isNpm) {
21818         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21819             predicate = function(n) { return n < 3; },
21820             expected = _.takeWhile(array, predicate),
21821             wrapped = _(array).takeWhile(predicate);
21822
21823         assert.deepEqual(wrapped.value(), expected);
21824         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21825         assert.strictEqual(wrapped.last(), _.last(expected));
21826       }
21827       else {
21828         skipAssert(assert, 3);
21829       }
21830     });
21831
21832     QUnit.test('should work in a lazy sequence with `take`', function(assert) {
21833       assert.expect(1);
21834
21835       if (!isNpm) {
21836         var array = lodashStable.range(LARGE_ARRAY_SIZE);
21837
21838         var actual = _(array)
21839           .takeWhile(function(n) { return n < 4; })
21840           .take(2)
21841           .takeWhile(function(n) { return n == 0; })
21842           .value();
21843
21844         assert.deepEqual(actual, [0]);
21845       }
21846       else {
21847         skipAssert(assert);
21848       }
21849     });
21850
21851     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21852       assert.expect(5);
21853
21854       if (!isNpm) {
21855         var args,
21856             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21857             expected = [1, 0, lodashStable.map(array.slice(1), square)];
21858
21859         _(array).slice(1).takeWhile(function(value, index, array) {
21860           args = slice.call(arguments);
21861         }).value();
21862
21863         assert.deepEqual(args, [1, 0, array.slice(1)]);
21864
21865         _(array).slice(1).map(square).takeWhile(function(value, index, array) {
21866           args = slice.call(arguments);
21867         }).value();
21868
21869         assert.deepEqual(args, expected);
21870
21871         _(array).slice(1).map(square).takeWhile(function(value, index) {
21872           args = slice.call(arguments);
21873         }).value();
21874
21875         assert.deepEqual(args, expected);
21876
21877         _(array).slice(1).map(square).takeWhile(function(value) {
21878           args = slice.call(arguments);
21879         }).value();
21880
21881         assert.deepEqual(args, [1]);
21882
21883         _(array).slice(1).map(square).takeWhile(function() {
21884           args = slice.call(arguments);
21885         }).value();
21886
21887         assert.deepEqual(args, expected);
21888       }
21889       else {
21890         skipAssert(assert, 5);
21891       }
21892     });
21893   }());
21894
21895   /*--------------------------------------------------------------------------*/
21896
21897   QUnit.module('lodash.tap');
21898
21899   (function() {
21900     QUnit.test('should intercept and return the given value', function(assert) {
21901       assert.expect(2);
21902
21903       if (!isNpm) {
21904         var intercepted,
21905             array = [1, 2, 3];
21906
21907         var actual = _.tap(array, function(value) {
21908           intercepted = value;
21909         });
21910
21911         assert.strictEqual(actual, array);
21912         assert.strictEqual(intercepted, array);
21913       }
21914       else {
21915         skipAssert(assert, 2);
21916       }
21917     });
21918
21919     QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
21920       assert.expect(2);
21921
21922       if (!isNpm) {
21923         var intercepted,
21924             array = [1, 2, 3];
21925
21926         var wrapped = _(array).tap(function(value) {
21927           intercepted = value;
21928           value.pop();
21929         });
21930
21931         assert.ok(wrapped instanceof _);
21932
21933         wrapped.value();
21934         assert.strictEqual(intercepted, array);
21935       }
21936       else {
21937         skipAssert(assert, 2);
21938       }
21939     });
21940   }());
21941
21942   /*--------------------------------------------------------------------------*/
21943
21944   QUnit.module('lodash.template');
21945
21946   (function() {
21947     QUnit.test('should escape values in "escape" delimiters', function(assert) {
21948       assert.expect(1);
21949
21950       var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
21951           expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
21952           data = { 'value': '&<>"\'`\/' };
21953
21954       var actual = lodashStable.map(strings, function(string) {
21955         return _.template(string)(data);
21956       });
21957
21958       assert.deepEqual(actual, expected);
21959     });
21960
21961     QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
21962       assert.expect(1);
21963
21964       var compiled = _.template('<%= typeof __e %>');
21965       assert.strictEqual(compiled({}), 'undefined');
21966     });
21967
21968     QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
21969       assert.expect(1);
21970
21971       var compiled = _.template(
21972         '<ul><%\
21973         for (var key in collection) {\
21974           %><li><%= collection[key] %></li><%\
21975         } %></ul>'
21976       );
21977
21978       var data = { 'collection': { 'a': 'A', 'b': 'B' } },
21979           actual = compiled(data);
21980
21981       assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
21982     });
21983
21984     QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
21985       assert.expect(1);
21986
21987       var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
21988           data = { 'value': true };
21989
21990       assert.strictEqual(compiled(data), 'yap');
21991     });
21992
21993     QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
21994       assert.expect(1);
21995
21996       var compiled = _.template('<% var b = a; %><%= b.value %>'),
21997           data = { 'a': { 'value': 1 } };
21998
21999       assert.strictEqual(compiled(data), '1');
22000     });
22001
22002     QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
22003       assert.expect(1);
22004
22005       var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
22006           expected = lodashStable.map(strings, lodashStable.constant('ABC')),
22007           data = { 'a': 'A' };
22008
22009       var actual = lodashStable.map(strings, function(string) {
22010         return _.template(string)(data);
22011       });
22012
22013       assert.deepEqual(actual, expected);
22014     });
22015
22016     QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
22017       assert.expect(1);
22018
22019       var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
22020           data = { 'a': true };
22021
22022       assert.strictEqual(compiled(data), 'a="A"');
22023     });
22024
22025     QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
22026       assert.expect(1);
22027
22028       var compiled = _.template('<%= value ? value : "b" %>'),
22029           data = { 'value': 'a' };
22030
22031       assert.strictEqual(compiled(data), 'a');
22032     });
22033
22034     QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
22035       assert.expect(1);
22036
22037       var compiled = _.template('<%= typeof Math.abs %>');
22038
22039       try {
22040         var actual = compiled();
22041       } catch (e) {}
22042
22043       assert.strictEqual(actual, 'function');
22044     });
22045
22046     QUnit.test('should support complex "interpolate" delimiters', function(assert) {
22047       assert.expect(22);
22048
22049       lodashStable.forOwn({
22050         '<%= a + b %>': '3',
22051         '<%= b - a %>': '1',
22052         '<%= a = b %>': '2',
22053         '<%= !a %>': 'false',
22054         '<%= ~a %>': '-2',
22055         '<%= a * b %>': '2',
22056         '<%= a / b %>': '0.5',
22057         '<%= a % b %>': '1',
22058         '<%= a >> b %>': '0',
22059         '<%= a << b %>': '4',
22060         '<%= a & b %>': '0',
22061         '<%= a ^ b %>': '3',
22062         '<%= a | b %>': '3',
22063         '<%= {}.toString.call(0) %>': numberTag,
22064         '<%= a.toFixed(2) %>': '1.00',
22065         '<%= obj["a"] %>': '1',
22066         '<%= delete a %>': 'true',
22067         '<%= "a" in obj %>': 'true',
22068         '<%= obj instanceof Object %>': 'true',
22069         '<%= new Boolean %>': 'false',
22070         '<%= typeof a %>': 'number',
22071         '<%= void a %>': ''
22072       },
22073       function(value, key) {
22074         var compiled = _.template(key),
22075             data = { 'a': 1, 'b': 2 };
22076
22077         assert.strictEqual(compiled(data), value, key);
22078       });
22079     });
22080
22081     QUnit.test('should support ES6 template delimiters', function(assert) {
22082       assert.expect(2);
22083
22084       var data = { 'value': 2 };
22085       assert.strictEqual(_.template('1${value}3')(data), '123');
22086       assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
22087     });
22088
22089     QUnit.test('should support the "imports" option', function(assert) {
22090       assert.expect(1);
22091
22092       var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
22093       assert.strictEqual(compiled({}), '1');
22094     });
22095
22096     QUnit.test('should support the "variable" options', function(assert) {
22097       assert.expect(1);
22098
22099       var compiled = _.template(
22100         '<% _.each( data.a, function( value ) { %>' +
22101             '<%= value.valueOf() %>' +
22102         '<% }) %>', { 'variable': 'data' }
22103       );
22104
22105       var data = { 'a': [1, 2, 3] };
22106
22107       try {
22108         assert.strictEqual(compiled(data), '123');
22109       } catch (e) {
22110         assert.ok(false, e.message);
22111       }
22112     });
22113
22114     QUnit.test('should support custom delimiters', function(assert) {
22115       assert.expect(2);
22116
22117       lodashStable.times(2, function(index) {
22118         var settingsClone = lodashStable.clone(_.templateSettings);
22119
22120         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22121           'escape': /\{\{-([\s\S]+?)\}\}/g,
22122           'evaluate': /\{\{([\s\S]+?)\}\}/g,
22123           'interpolate': /\{\{=([\s\S]+?)\}\}/g
22124         });
22125
22126         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22127             compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
22128             data = { 'collection': ['a & A', 'b & B'] };
22129
22130         assert.strictEqual(compiled(data), expected);
22131         lodashStable.assign(_.templateSettings, settingsClone);
22132       });
22133     });
22134
22135     QUnit.test('should support custom delimiters containing special characters', function(assert) {
22136       assert.expect(2);
22137
22138       lodashStable.times(2, function(index) {
22139         var settingsClone = lodashStable.clone(_.templateSettings);
22140
22141         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22142           'escape': /<\?-([\s\S]+?)\?>/g,
22143           'evaluate': /<\?([\s\S]+?)\?>/g,
22144           'interpolate': /<\?=([\s\S]+?)\?>/g
22145         });
22146
22147         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22148             compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
22149             data = { 'collection': ['a & A', 'b & B'] };
22150
22151         assert.strictEqual(compiled(data), expected);
22152         lodashStable.assign(_.templateSettings, settingsClone);
22153       });
22154     });
22155
22156     QUnit.test('should use a `with` statement by default', function(assert) {
22157       assert.expect(1);
22158
22159       var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
22160           actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
22161
22162       assert.strictEqual(actual, '1b012');
22163     });
22164
22165     QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
22166       assert.expect(1);
22167
22168       var lodash = _.templateSettings.imports._,
22169           settingsClone = lodashStable.clone(lodash.templateSettings);
22170
22171       lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
22172         'interpolate': /\{\{=([\s\S]+?)\}\}/g
22173       });
22174
22175       var compiled = _.template('{{= a }}');
22176       assert.strictEqual(compiled({ 'a': 1 }), '1');
22177
22178       if (settingsClone) {
22179         lodashStable.assign(lodash.templateSettings, settingsClone);
22180       } else {
22181         delete lodash.templateSettings;
22182       }
22183     });
22184
22185     QUnit.test('should fallback to `_.templateSettings`', function(assert) {
22186       assert.expect(1);
22187
22188       var lodash = _.templateSettings.imports._,
22189           delimiter = _.templateSettings.interpolate;
22190
22191       _.templateSettings.imports._ = { 'escape': lodashStable.escape };
22192       _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
22193
22194       var compiled = _.template('{{= a }}');
22195       assert.strictEqual(compiled({ 'a': 1 }), '1');
22196
22197       _.templateSettings.imports._ = lodash;
22198       _.templateSettings.interpolate = delimiter;
22199     });
22200
22201     QUnit.test('should ignore `null` delimiters', function(assert) {
22202       assert.expect(3);
22203
22204       var delimiter = {
22205         'escape': /\{\{-([\s\S]+?)\}\}/g,
22206         'evaluate': /\{\{([\s\S]+?)\}\}/g,
22207         'interpolate': /\{\{=([\s\S]+?)\}\}/g
22208       };
22209
22210       lodashStable.forOwn({
22211         'escape': '{{- a }}',
22212         'evaluate': '{{ print(a) }}',
22213         'interpolate': '{{= a }}'
22214       },
22215       function(value, key) {
22216         var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
22217         settings[key] = delimiter[key];
22218
22219         var expected = '1 <%- a %> <% print(a) %> <%= a %>',
22220             compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
22221             data = { 'a': 1 };
22222
22223         assert.strictEqual(compiled(data), expected);
22224       });
22225     });
22226
22227     QUnit.test('should work without delimiters', function(assert) {
22228       assert.expect(1);
22229
22230       var expected = 'abc';
22231       assert.strictEqual(_.template(expected)({}), expected);
22232     });
22233
22234     QUnit.test('should work with `this` references', function(assert) {
22235       assert.expect(2);
22236
22237       var compiled = _.template('a<%= this.String("b") %>c');
22238       assert.strictEqual(compiled(), 'abc');
22239
22240       var object = { 'b': 'B' };
22241       object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
22242       assert.strictEqual(object.compiled(), 'ABC');
22243     });
22244
22245     QUnit.test('should work with backslashes', function(assert) {
22246       assert.expect(1);
22247
22248       var compiled = _.template('<%= a %> \\b'),
22249           data = { 'a': 'A' };
22250
22251       assert.strictEqual(compiled(data), 'A \\b');
22252     });
22253
22254     QUnit.test('should work with escaped characters in string literals', function(assert) {
22255       assert.expect(2);
22256
22257       var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
22258       assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
22259
22260       var data = { 'a': 'A' };
22261       compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
22262       assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
22263     });
22264
22265     QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
22266       assert.expect(1);
22267
22268       var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
22269       assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
22270     });
22271
22272     QUnit.test('should work with statements containing quotes', function(assert) {
22273       assert.expect(1);
22274
22275       var compiled = _.template("<%\
22276         if (a == 'A' || a == \"a\") {\
22277           %>'a',\"A\"<%\
22278         } %>"
22279       );
22280
22281       var data = { 'a': 'A' };
22282       assert.strictEqual(compiled(data), "'a',\"A\"");
22283     });
22284
22285     QUnit.test('should work with templates containing newlines and comments', function(assert) {
22286       assert.expect(1);
22287
22288       var compiled = _.template('<%\n\
22289         // A code comment.\n\
22290         if (value) { value += 3; }\n\
22291         %><p><%= value %></p>'
22292       );
22293
22294       assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
22295     });
22296
22297     QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
22298       assert.expect(1);
22299
22300       var compiled = _.template(''),
22301           pass = true;
22302
22303       /*@cc_on @*/
22304       try {
22305         compiled();
22306       } catch (e) {
22307         pass = false;
22308       }
22309       assert.ok(pass);
22310     });
22311
22312     QUnit.test('should tokenize delimiters', function(assert) {
22313       assert.expect(1);
22314
22315       var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
22316           data = { 'type': 1 };
22317
22318       assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
22319     });
22320
22321     QUnit.test('should evaluate delimiters once', function(assert) {
22322       assert.expect(1);
22323
22324       var actual = [],
22325           compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
22326           data = { 'func': function(value) { actual.push(value); } };
22327
22328       compiled(data);
22329       assert.deepEqual(actual, ['a', 'b', 'c']);
22330     });
22331
22332     QUnit.test('should match delimiters before escaping text', function(assert) {
22333       assert.expect(1);
22334
22335       var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
22336       assert.strictEqual(compiled(), '<<\n a \n>>');
22337     });
22338
22339     QUnit.test('should resolve nullish values to an empty string', function(assert) {
22340       assert.expect(3);
22341
22342       var compiled = _.template('<%= a %><%- a %>'),
22343           data = { 'a': null };
22344
22345       assert.strictEqual(compiled(data), '');
22346
22347       data = { 'a': undefined };
22348       assert.strictEqual(compiled(data), '');
22349
22350       data = { 'a': {} };
22351       compiled = _.template('<%= a.b %><%- a.b %>');
22352       assert.strictEqual(compiled(data), '');
22353     });
22354
22355     QUnit.test('should return an empty string for empty values', function(assert) {
22356       assert.expect(1);
22357
22358       var values = [, null, undefined, ''],
22359           expected = lodashStable.map(values, stubString),
22360           data = { 'a': 1 };
22361
22362       var actual = lodashStable.map(values, function(value, index) {
22363         var compiled = index ? _.template(value) : _.template();
22364         return compiled(data);
22365       });
22366
22367       assert.deepEqual(actual, expected);
22368     });
22369
22370     QUnit.test('should parse delimiters without newlines', function(assert) {
22371       assert.expect(1);
22372
22373       var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
22374           compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
22375           data = { 'value': true };
22376
22377       assert.strictEqual(compiled(data), expected);
22378     });
22379
22380     QUnit.test('should support recursive calls', function(assert) {
22381       assert.expect(1);
22382
22383       var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
22384           data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
22385
22386       assert.strictEqual(compiled(data), 'AB');
22387     });
22388
22389     QUnit.test('should coerce `text` argument to a string', function(assert) {
22390       assert.expect(1);
22391
22392       var object = { 'toString': lodashStable.constant('<%= a %>') },
22393           data = { 'a': 1 };
22394
22395       assert.strictEqual(_.template(object)(data), '1');
22396     });
22397
22398     QUnit.test('should not modify the `options` object', function(assert) {
22399       assert.expect(1);
22400
22401       var options = {};
22402       _.template('', options);
22403       assert.deepEqual(options, {});
22404     });
22405
22406     QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
22407       assert.expect(2);
22408
22409       var data = { 'a': 1 };
22410
22411       assert.notOk('a' in _.templateSettings);
22412       _.template('', {}, data);
22413       assert.notOk('a' in _.templateSettings);
22414
22415       delete _.templateSettings.a;
22416     });
22417
22418     QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
22419       assert.expect(2);
22420
22421       var pass = true;
22422
22423       try {
22424         _.template('')(1);
22425       } catch (e) {
22426         pass = false;
22427       }
22428       assert.ok(pass, '`data` value');
22429
22430       pass = true;
22431
22432       try {
22433         _.template('', 1)(1);
22434       } catch (e) {
22435         pass = false;
22436       }
22437       assert.ok(pass, '`options` value');
22438     });
22439
22440     QUnit.test('should expose the source on compiled templates', function(assert) {
22441       assert.expect(1);
22442
22443       var compiled = _.template('x'),
22444           values = [String(compiled), compiled.source],
22445           expected = lodashStable.map(values, stubTrue);
22446
22447       var actual = lodashStable.map(values, function(value) {
22448         return lodashStable.includes(value, '__p');
22449       });
22450
22451       assert.deepEqual(actual, expected);
22452     });
22453
22454     QUnit.test('should expose the source on SyntaxErrors', function(assert) {
22455       assert.expect(1);
22456
22457       try {
22458         _.template('<% if x %>');
22459       } catch (e) {
22460         var source = e.source;
22461       }
22462       assert.ok(lodashStable.includes(source, '__p'));
22463     });
22464
22465     QUnit.test('should not include sourceURLs in the source', function(assert) {
22466       assert.expect(1);
22467
22468       var options = { 'sourceURL': '/a/b/c' },
22469           compiled = _.template('x', options),
22470           values = [compiled.source, undefined];
22471
22472       try {
22473         _.template('<% if x %>', options);
22474       } catch (e) {
22475         values[1] = e.source;
22476       }
22477       var expected = lodashStable.map(values, stubFalse);
22478
22479       var actual = lodashStable.map(values, function(value) {
22480         return lodashStable.includes(value, 'sourceURL');
22481       });
22482
22483       assert.deepEqual(actual, expected);
22484     });
22485
22486     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22487       assert.expect(1);
22488
22489       var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
22490           compiles = lodashStable.map(array, _.template),
22491           data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
22492
22493       var actual = lodashStable.map(compiles, function(compiled) {
22494         return compiled(data);
22495       });
22496
22497       assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
22498     });
22499   }());
22500
22501   /*--------------------------------------------------------------------------*/
22502
22503   QUnit.module('lodash.truncate');
22504
22505   (function() {
22506     var string = 'hi-diddly-ho there, neighborino';
22507
22508     QUnit.test('should use a default `length` of `30`', function(assert) {
22509       assert.expect(1);
22510
22511       assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
22512     });
22513
22514     QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
22515       assert.expect(2);
22516
22517       assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
22518       assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
22519     });
22520
22521     QUnit.test('should truncate string the given length', function(assert) {
22522       assert.expect(1);
22523
22524       assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
22525     });
22526
22527     QUnit.test('should support a `omission` option', function(assert) {
22528       assert.expect(1);
22529
22530       assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
22531     });
22532
22533     QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
22534       assert.expect(2);
22535
22536       assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
22537       assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
22538     });
22539
22540     QUnit.test('should support a `length` option', function(assert) {
22541       assert.expect(1);
22542
22543       assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
22544     });
22545
22546     QUnit.test('should support a `separator` option', function(assert) {
22547       assert.expect(3);
22548
22549       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
22550       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
22551       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
22552     });
22553
22554     QUnit.test('should treat negative `length` as `0`', function(assert) {
22555       assert.expect(2);
22556
22557       lodashStable.each([0, -2], function(length) {
22558         assert.strictEqual(_.truncate(string, { 'length': length }), '...');
22559       });
22560     });
22561
22562     QUnit.test('should coerce `length` to an integer', function(assert) {
22563       assert.expect(4);
22564
22565       lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
22566         var actual = index > 1 ? 'h...' : '...';
22567         assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
22568       });
22569     });
22570
22571     QUnit.test('should coerce `string` to a string', function(assert) {
22572       assert.expect(2);
22573
22574       assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
22575       assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
22576     });
22577
22578     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22579       assert.expect(1);
22580
22581       var actual = lodashStable.map([string, string, string], _.truncate),
22582           truncated = 'hi-diddly-ho there, neighbo...';
22583
22584       assert.deepEqual(actual, [truncated, truncated, truncated]);
22585     });
22586   }());
22587
22588   /*--------------------------------------------------------------------------*/
22589
22590   QUnit.module('lodash.throttle');
22591
22592   (function() {
22593     QUnit.test('should throttle a function', function(assert) {
22594       assert.expect(2);
22595
22596       var done = assert.async();
22597
22598       var callCount = 0,
22599           throttled = _.throttle(function() { callCount++; }, 32);
22600
22601       throttled();
22602       throttled();
22603       throttled();
22604
22605       var lastCount = callCount;
22606       assert.ok(callCount);
22607
22608       setTimeout(function() {
22609         assert.ok(callCount > lastCount);
22610         done();
22611       }, 64);
22612     });
22613
22614     QUnit.test('subsequent calls should return the result of the first call', function(assert) {
22615       assert.expect(5);
22616
22617       var done = assert.async();
22618
22619       var throttled = _.throttle(identity, 32),
22620           results = [throttled('a'), throttled('b')];
22621
22622       assert.deepEqual(results, ['a', 'a']);
22623
22624       setTimeout(function() {
22625         var results = [throttled('c'), throttled('d')];
22626         assert.notEqual(results[0], 'a');
22627         assert.notStrictEqual(results[0], undefined);
22628
22629         assert.notEqual(results[1], 'd');
22630         assert.notStrictEqual(results[1], undefined);
22631         done();
22632       }, 64);
22633     });
22634
22635     QUnit.test('should clear timeout when `func` is called', function(assert) {
22636       assert.expect(1);
22637
22638       var done = assert.async();
22639
22640       if (!isModularize) {
22641         var callCount = 0,
22642             dateCount = 0;
22643
22644         var lodash = _.runInContext({
22645           'Date': {
22646             'now': function() {
22647               return ++dateCount == 5 ? Infinity : +new Date;
22648             }
22649           }
22650         });
22651
22652         var throttled = lodash.throttle(function() { callCount++; }, 32);
22653
22654         throttled();
22655         throttled();
22656
22657         setTimeout(function() {
22658           assert.strictEqual(callCount, 2);
22659           done();
22660         }, 64);
22661       }
22662       else {
22663         skipAssert(assert);
22664         done();
22665       }
22666     });
22667
22668     QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
22669       assert.expect(2);
22670
22671       var done = assert.async();
22672
22673       var callCount = 0,
22674           throttled = _.throttle(function() { callCount++; }, 32);
22675
22676       throttled();
22677       assert.strictEqual(callCount, 1);
22678
22679       setTimeout(function() {
22680         assert.strictEqual(callCount, 1);
22681         done();
22682       }, 64);
22683     });
22684
22685     lodashStable.times(2, function(index) {
22686       QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
22687         assert.expect(1);
22688
22689         var done = assert.async();
22690
22691         var callCount = 0,
22692             limit = (argv || isPhantom) ? 1000 : 320,
22693             options = index ? { 'leading': false } : {},
22694             throttled = _.throttle(function() { callCount++; }, 32, options);
22695
22696         var start = +new Date;
22697         while ((new Date - start) < limit) {
22698           throttled();
22699         }
22700         var actual = callCount > 1;
22701         setTimeout(function() {
22702           assert.ok(actual);
22703           done();
22704         }, 1);
22705       });
22706     });
22707
22708     QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
22709       assert.expect(3);
22710
22711       var done = assert.async();
22712
22713       var callCount = 0;
22714
22715       var throttled = _.throttle(function() {
22716         callCount++;
22717       }, 128, { 'leading': false });
22718
22719       throttled();
22720
22721       setTimeout(function() {
22722         assert.strictEqual(callCount, 1);
22723         throttled();
22724       }, 192);
22725
22726       setTimeout(function() {
22727         assert.strictEqual(callCount, 1);
22728       }, 254);
22729
22730       setTimeout(function() {
22731         assert.strictEqual(callCount, 2);
22732         done();
22733       }, 384);
22734     });
22735
22736     QUnit.test('should apply default options', function(assert) {
22737       assert.expect(2);
22738
22739       var done = assert.async();
22740
22741       var callCount = 0,
22742           throttled = _.throttle(function() { callCount++; }, 32, {});
22743
22744       throttled();
22745       throttled();
22746       assert.strictEqual(callCount, 1);
22747
22748       setTimeout(function() {
22749         assert.strictEqual(callCount, 2);
22750         done();
22751       }, 128);
22752     });
22753
22754     QUnit.test('should support a `leading` option', function(assert) {
22755       assert.expect(2);
22756
22757       var withLeading = _.throttle(identity, 32, { 'leading': true });
22758       assert.strictEqual(withLeading('a'), 'a');
22759
22760       var withoutLeading = _.throttle(identity, 32, { 'leading': false });
22761       assert.strictEqual(withoutLeading('a'), undefined);
22762     });
22763
22764     QUnit.test('should support a `trailing` option', function(assert) {
22765       assert.expect(6);
22766
22767       var done = assert.async();
22768
22769       var withCount = 0,
22770           withoutCount = 0;
22771
22772       var withTrailing = _.throttle(function(value) {
22773         withCount++;
22774         return value;
22775       }, 64, { 'trailing': true });
22776
22777       var withoutTrailing = _.throttle(function(value) {
22778         withoutCount++;
22779         return value;
22780       }, 64, { 'trailing': false });
22781
22782       assert.strictEqual(withTrailing('a'), 'a');
22783       assert.strictEqual(withTrailing('b'), 'a');
22784
22785       assert.strictEqual(withoutTrailing('a'), 'a');
22786       assert.strictEqual(withoutTrailing('b'), 'a');
22787
22788       setTimeout(function() {
22789         assert.strictEqual(withCount, 2);
22790         assert.strictEqual(withoutCount, 1);
22791         done();
22792       }, 256);
22793     });
22794
22795     QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
22796       assert.expect(1);
22797
22798       var done = assert.async();
22799
22800       var callCount = 0;
22801
22802       var throttled = _.throttle(function() {
22803         callCount++;
22804       }, 64, { 'trailing': false });
22805
22806       throttled();
22807       throttled();
22808
22809       setTimeout(function() {
22810         throttled();
22811         throttled();
22812       }, 96);
22813
22814       setTimeout(function() {
22815         assert.ok(callCount > 1);
22816         done();
22817       }, 192);
22818     });
22819
22820     QUnit.test('should work with a system time of `0`', function(assert) {
22821       assert.expect(3);
22822
22823       var done = assert.async();
22824
22825       if (!isModularize) {
22826         var callCount = 0,
22827             dateCount = 0;
22828
22829         var lodash = _.runInContext({
22830           'Date': {
22831             'now': function() {
22832               return ++dateCount < 4 ? 0 : +new Date;
22833             }
22834           }
22835         });
22836
22837         var throttled = lodash.throttle(function(value) {
22838           callCount++;
22839           return value;
22840         }, 32);
22841
22842         var results = [throttled('a'), throttled('b'), throttled('c')];
22843         assert.deepEqual(results, ['a', 'a', 'a']);
22844         assert.strictEqual(callCount, 1);
22845
22846         setTimeout(function() {
22847           assert.strictEqual(callCount, 2);
22848           done();
22849         }, 64);
22850       }
22851       else {
22852         skipAssert(assert, 3);
22853         done();
22854       }
22855     });
22856   }());
22857
22858   /*--------------------------------------------------------------------------*/
22859
22860   QUnit.module('lodash.debounce and lodash.throttle');
22861
22862   lodashStable.each(['debounce', 'throttle'], function(methodName) {
22863     var func = _[methodName],
22864         isDebounce = methodName == 'debounce';
22865
22866     QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
22867       assert.expect(1);
22868
22869       var pass = true;
22870
22871       try {
22872         func(noop, 32, 1);
22873       } catch (e) {
22874         pass = false;
22875       }
22876       assert.ok(pass);
22877     });
22878
22879     QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
22880       assert.expect(1);
22881
22882       var done = assert.async();
22883
22884       var callCount = 0,
22885           funced = func(function() { callCount++; });
22886
22887       funced();
22888
22889       setTimeout(function() {
22890         funced();
22891         assert.strictEqual(callCount, isDebounce ? 1 : 2);
22892         done();
22893       }, 32);
22894     });
22895
22896     QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
22897       assert.expect(1);
22898
22899       var done = assert.async();
22900
22901       var actual = [],
22902           object = { 'funced': func(function() { actual.push(this); }, 32) },
22903           expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
22904
22905       object.funced();
22906       if (!isDebounce) {
22907         object.funced();
22908       }
22909       setTimeout(function() {
22910         assert.deepEqual(actual, expected);
22911         done();
22912       }, 64);
22913     });
22914
22915     QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
22916       assert.expect(2);
22917
22918       var done = assert.async();
22919
22920       var actual = [],
22921           args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
22922           expected = args.slice(),
22923           queue = args.slice();
22924
22925       var funced = func(function() {
22926         var current = [this];
22927         push.apply(current, arguments);
22928         actual.push(current);
22929
22930         var next = queue.shift();
22931         if (next) {
22932           funced.call(next[0], next[1]);
22933         }
22934       }, 32);
22935
22936       var next = queue.shift();
22937       funced.call(next[0], next[1]);
22938       assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
22939
22940       setTimeout(function() {
22941         assert.deepEqual(actual, expected.slice(0, actual.length));
22942         done();
22943       }, 256);
22944     });
22945
22946     QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
22947       assert.expect(1);
22948
22949       var done = assert.async();
22950
22951       if (!isModularize) {
22952         var callCount = 0,
22953             dateCount = 0;
22954
22955         var lodash = _.runInContext({
22956           'Date': {
22957             'now': function() {
22958               return ++dateCount == 4
22959                 ? +new Date(2012, 3, 23, 23, 27, 18)
22960                 : +new Date;
22961             }
22962           }
22963         });
22964
22965         var funced = lodash[methodName](function() {
22966           callCount++;
22967         }, 32);
22968
22969         funced();
22970
22971         setTimeout(function() {
22972           funced();
22973           assert.strictEqual(callCount, isDebounce ? 1 : 2);
22974           done();
22975         }, 64);
22976       }
22977       else {
22978         skipAssert(assert);
22979         done();
22980       }
22981     });
22982
22983     QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
22984       assert.expect(1);
22985
22986       var done = assert.async();
22987
22988       var callCount = 0;
22989
22990       var funced = func(function() {
22991         callCount++;
22992       }, 32, { 'leading': false });
22993
22994       funced();
22995       funced.cancel();
22996
22997       setTimeout(function() {
22998         assert.strictEqual(callCount, 0);
22999         done();
23000       }, 64);
23001     });
23002
23003     QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
23004       assert.expect(3);
23005
23006       var done = assert.async();
23007
23008       var callCount = 0;
23009
23010       var funced = func(function() {
23011         return ++callCount;
23012       }, 32, { 'leading': true });
23013
23014       assert.strictEqual(funced(), 1);
23015       funced.cancel();
23016
23017       assert.strictEqual(funced(), 2);
23018       funced();
23019
23020       setTimeout(function() {
23021         assert.strictEqual(callCount, 3);
23022         done();
23023       }, 64);
23024     });
23025
23026     QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
23027       assert.expect(2);
23028
23029       var done = assert.async();
23030
23031       var callCount = 0;
23032
23033       var funced = func(function() {
23034         return ++callCount;
23035       }, 32, { 'leading': false });
23036
23037       funced();
23038       assert.strictEqual(funced.flush(), 1);
23039
23040       setTimeout(function() {
23041         assert.strictEqual(callCount, 1);
23042         done();
23043       }, 64);
23044     });
23045
23046     QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
23047       assert.expect(2);
23048
23049       var done = assert.async();
23050
23051       var callCount = 0,
23052           funced = func(function() { callCount++; }, 32);
23053
23054       funced.cancel();
23055       assert.strictEqual(funced.flush(), undefined);
23056
23057       setTimeout(function() {
23058         assert.strictEqual(callCount, 0);
23059         done();
23060       }, 64);
23061     });
23062   });
23063
23064   /*--------------------------------------------------------------------------*/
23065
23066   QUnit.module('lodash.times');
23067
23068   (function() {
23069     QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
23070       assert.expect(3);
23071
23072       lodashStable.each([-Infinity, NaN, Infinity], function(n) {
23073         assert.deepEqual(_.times(n), []);
23074       });
23075     });
23076
23077     QUnit.test('should coerce `n` to an integer', function(assert) {
23078       assert.expect(1);
23079
23080       var actual = _.times(2.6, _.indentify);
23081       assert.deepEqual(actual, [0, 1]);
23082     });
23083
23084     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23085       assert.expect(1);
23086
23087       var args;
23088
23089       _.times(1, function(assert) {
23090         args || (args = slice.call(arguments));
23091       });
23092
23093       assert.deepEqual(args, [0]);
23094     });
23095
23096     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
23097       assert.expect(1);
23098
23099       var values = [, null, undefined],
23100           expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
23101
23102       var actual = lodashStable.map(values, function(value, index) {
23103         return index ? _.times(3, value) : _.times(3);
23104       });
23105
23106       assert.deepEqual(actual, expected);
23107     });
23108
23109     QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
23110       assert.expect(1);
23111
23112       assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
23113     });
23114
23115     QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
23116       assert.expect(1);
23117
23118       var values = falsey.concat(-1, -Infinity),
23119           expected = lodashStable.map(values, stubArray);
23120
23121       var actual = lodashStable.map(values, function(value, index) {
23122         return index ? _.times(value) : _.times();
23123       });
23124
23125       assert.deepEqual(actual, expected);
23126     });
23127
23128     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
23129       assert.expect(1);
23130
23131       if (!isNpm) {
23132         assert.deepEqual(_(3).times(), [0, 1, 2]);
23133       }
23134       else {
23135         skipAssert(assert);
23136       }
23137     });
23138
23139     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
23140       assert.expect(1);
23141
23142       if (!isNpm) {
23143         assert.ok(_(3).chain().times() instanceof _);
23144       }
23145       else {
23146         skipAssert(assert);
23147       }
23148     });
23149   }());
23150
23151   /*--------------------------------------------------------------------------*/
23152
23153   QUnit.module('lodash.toArray');
23154
23155   (function() {
23156     QUnit.test('should convert objects to arrays', function(assert) {
23157       assert.expect(1);
23158
23159       assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
23160     });
23161
23162     QUnit.test('should convert iterables to arrays', function(assert) {
23163       assert.expect(1);
23164
23165       if (!isNpm && Symbol && Symbol.iterator) {
23166         var object = { '0': 'a', 'length': 1 };
23167         object[Symbol.iterator] = arrayProto[Symbol.iterator];
23168
23169         assert.deepEqual(_.toArray(object), ['a']);
23170       }
23171       else {
23172         skipAssert(assert);
23173       }
23174     });
23175
23176     QUnit.test('should convert maps to arrays', function(assert) {
23177       assert.expect(1);
23178
23179       if (Map) {
23180         var map = new Map;
23181         map.set('a', 1);
23182         map.set('b', 2);
23183         assert.deepEqual(_.toArray(map), [['a', 1], ['b', 2]]);
23184       }
23185       else {
23186         skipAssert(assert);
23187       }
23188     });
23189
23190     QUnit.test('should convert strings to arrays', function(assert) {
23191       assert.expect(3);
23192
23193       assert.deepEqual(_.toArray(''), []);
23194       assert.deepEqual(_.toArray('ab'), ['a', 'b']);
23195       assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
23196     });
23197
23198     QUnit.test('should work in a lazy sequence', function(assert) {
23199       assert.expect(2);
23200
23201       if (!isNpm) {
23202         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
23203             actual = _(array).slice(1).map(String).toArray().value();
23204
23205         assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
23206
23207         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
23208           return ['key' + index, index];
23209         }));
23210
23211         actual = _(object).toArray().slice(1).map(String).value();
23212         assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
23213       }
23214       else {
23215         skipAssert(assert, 2);
23216       }
23217     });
23218   }());
23219
23220   /*--------------------------------------------------------------------------*/
23221
23222   QUnit.module('lodash.toLower');
23223
23224   (function() {
23225     QUnit.test('should convert whole string to lower case', function(assert) {
23226       assert.expect(3);
23227
23228       assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
23229       assert.deepEqual(_.toLower('fooBar'), 'foobar');
23230       assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
23231     });
23232   }());
23233
23234   /*--------------------------------------------------------------------------*/
23235
23236   QUnit.module('lodash.toUpper');
23237
23238   (function() {
23239     QUnit.test('should convert whole string to upper case', function(assert) {
23240       assert.expect(3);
23241
23242       assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
23243       assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
23244       assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
23245     });
23246   }());
23247
23248   /*--------------------------------------------------------------------------*/
23249
23250   QUnit.module('lodash.slice and lodash.toArray');
23251
23252   lodashStable.each(['slice', 'toArray'], function(methodName) {
23253     var args = (function() { return arguments; }(1, 2, 3)),
23254         array = [1, 2, 3],
23255         func = _[methodName];
23256
23257     QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
23258       assert.expect(3);
23259
23260       var sparse = Array(3);
23261       sparse[1] = 2;
23262
23263       var actual = func(sparse);
23264
23265       assert.ok('0' in actual);
23266       assert.ok('2' in actual);
23267       assert.deepEqual(actual, sparse);
23268     });
23269
23270     QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
23271       assert.expect(2);
23272
23273       var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
23274       assert.deepEqual(func(object), ['a', 'b', 'c']);
23275       assert.deepEqual(func(args), array);
23276     });
23277
23278     QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
23279       assert.expect(2);
23280
23281       var actual = func(array);
23282       assert.deepEqual(actual, array);
23283       assert.notStrictEqual(actual, array);
23284     });
23285
23286     QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
23287       assert.expect(1);
23288
23289       if (document) {
23290         try {
23291           var actual = func(document.getElementsByTagName('body'));
23292         } catch (e) {}
23293
23294         assert.deepEqual(actual, [body]);
23295       }
23296       else {
23297         skipAssert(assert);
23298       }
23299     });
23300   });
23301
23302   /*--------------------------------------------------------------------------*/
23303
23304   QUnit.module('toInteger methods');
23305
23306   lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
23307     var func = _[methodName],
23308         isSafe = methodName == 'toSafeInteger';
23309
23310     QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
23311       assert.expect(6);
23312
23313       assert.strictEqual(func(-5.6), -5);
23314       assert.strictEqual(func('5.6'), 5);
23315       assert.strictEqual(func(), 0);
23316       assert.strictEqual(func(NaN), 0);
23317
23318       var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
23319       assert.strictEqual(func(Infinity), expected);
23320       assert.strictEqual(func(-Infinity), -expected);
23321     });
23322
23323     QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
23324       assert.expect(1);
23325
23326       assert.strictEqual(1 / func(-0), -Infinity);
23327     });
23328   });
23329
23330   /*--------------------------------------------------------------------------*/
23331
23332   QUnit.module('lodash.toLength');
23333
23334   (function() {
23335     QUnit.test('should return a valid length', function(assert) {
23336       assert.expect(4);
23337
23338       assert.strictEqual(_.toLength(-1), 0);
23339       assert.strictEqual(_.toLength('1'), 1);
23340       assert.strictEqual(_.toLength(1.1), 1);
23341       assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
23342     });
23343
23344     QUnit.test('should return `value` if a valid length', function(assert) {
23345       assert.expect(3);
23346
23347       assert.strictEqual(_.toLength(0), 0);
23348       assert.strictEqual(_.toLength(3), 3);
23349       assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
23350     });
23351
23352     QUnit.test('should convert `-0` to `0`', function(assert) {
23353       assert.expect(1);
23354
23355       assert.strictEqual(1 / _.toLength(-0), Infinity);
23356     });
23357   }());
23358
23359   /*--------------------------------------------------------------------------*/
23360
23361   QUnit.module('number coercion methods');
23362
23363   lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
23364     var func = _[methodName];
23365
23366     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
23367       assert.expect(2);
23368
23369       var values = [0, '0', -0, '-0'],
23370           expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
23371
23372       lodashStable.times(2, function(index) {
23373         var others = lodashStable.map(values, index ? Object : identity);
23374
23375         var actual = lodashStable.map(others, function(value) {
23376           var result = func(value);
23377           return [result, 1 / result];
23378         });
23379
23380         assert.deepEqual(actual, expected);
23381       });
23382     });
23383   });
23384
23385   lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
23386     var func = _[methodName],
23387         isToFinite = methodName == 'toFinite',
23388         isToLength = methodName == 'toLength',
23389         isToNumber = methodName == 'toNumber',
23390         isToSafeInteger = methodName == 'toSafeInteger';
23391
23392     function negative(string) {
23393       return '-' + string;
23394     }
23395
23396     function pad(string) {
23397       return whitespace + string + whitespace;
23398     }
23399
23400     function positive(string) {
23401       return '+' + string;
23402     }
23403
23404     QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
23405       assert.expect(1);
23406
23407       var values = [0, 1, NaN];
23408
23409       var expected = lodashStable.map(values, function(value) {
23410         return (!isToNumber && value !== value) ? 0 : value;
23411       });
23412
23413       var actual = lodashStable.map(values, func);
23414
23415       assert.deepEqual(actual, expected);
23416     });
23417
23418     QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
23419       assert.expect(1);
23420
23421       var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
23422
23423       var expected = lodashStable.map(values, function(value) {
23424         if (!isToNumber) {
23425           if (!isToFinite && value == 1.2) {
23426             value = 1;
23427           }
23428           else if (value == Infinity) {
23429             value = MAX_INTEGER;
23430           }
23431           else if (value !== value) {
23432             value = 0;
23433           }
23434           if (isToLength || isToSafeInteger) {
23435             value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23436           }
23437         }
23438         var neg = isToLength ? 0 : -value;
23439         return [value, value, neg, neg];
23440       });
23441
23442       var actual = lodashStable.map(values, function(value) {
23443         return [func(value), func(Object(value)), func(-value), func(Object(-value))];
23444       });
23445
23446       assert.deepEqual(actual, expected);
23447     });
23448
23449     QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
23450       assert.expect(1);
23451
23452       var transforms = [identity, pad, positive, negative];
23453
23454       var values = [
23455         '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
23456         '1e+308', '1e308', '1E+308', '1E308',
23457         '5e-324', '5E-324',
23458         'Infinity', 'NaN'
23459       ];
23460
23461       var expected = lodashStable.map(values, function(value) {
23462         var n = +value;
23463         if (!isToNumber) {
23464           if (!isToFinite && n == 1.234567890) {
23465             n = 1;
23466           }
23467           else if (n == Infinity) {
23468             n = MAX_INTEGER;
23469           }
23470           else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) {
23471             n = 0;
23472           }
23473           if (isToLength || isToSafeInteger) {
23474             n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23475           }
23476         }
23477         var neg = isToLength ? 0 : -n;
23478         return [n, n, n, n, n, n, neg, neg];
23479       });
23480
23481       var actual = lodashStable.map(values, function(value) {
23482         return lodashStable.flatMap(transforms, function(mod) {
23483           return [func(mod(value)), func(Object(mod(value)))];
23484         });
23485       });
23486
23487       assert.deepEqual(actual, expected);
23488     });
23489
23490     QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
23491       assert.expect(1);
23492
23493       var numbers = [42, 5349, 1715004],
23494           transforms = [identity, pad],
23495           values = ['0b101010', '0o12345', '0x1a2b3c'];
23496
23497       var expected = lodashStable.map(numbers, function(n) {
23498         return lodashStable.times(8, lodashStable.constant(n));
23499       });
23500
23501       var actual = lodashStable.map(values, function(value) {
23502         var upper = value.toUpperCase();
23503         return lodashStable.flatMap(transforms, function(mod) {
23504           return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
23505         });
23506       });
23507
23508       assert.deepEqual(actual, expected);
23509     });
23510
23511     QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23512       assert.expect(1);
23513
23514       var transforms = [identity, pad, positive, negative],
23515           values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
23516
23517       var expected = lodashStable.map(values, function(n) {
23518         return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
23519       });
23520
23521       var actual = lodashStable.map(values, function(value) {
23522         return lodashStable.flatMap(transforms, function(mod) {
23523           return [func(mod(value)), func(Object(mod(value)))];
23524         });
23525       });
23526
23527       assert.deepEqual(actual, expected);
23528     });
23529
23530     QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23531       assert.expect(1);
23532
23533       if (Symbol) {
23534         var object1 = Object(symbol),
23535             object2 = Object(symbol),
23536             values = [symbol, object1, object2],
23537             expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
23538
23539         object2.valueOf = undefined;
23540         var actual = lodashStable.map(values, func);
23541
23542         assert.deepEqual(actual, expected);
23543       }
23544       else {
23545         skipAssert(assert);
23546       }
23547     });
23548
23549     QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
23550       assert.expect(1);
23551
23552       var values = falsey.concat(whitespace);
23553
23554       var expected = lodashStable.map(values, function(value) {
23555         return (isToNumber && value !== whitespace) ? Number(value) : 0;
23556       });
23557
23558       var actual = lodashStable.map(values, function(value, index) {
23559         return index ? func(value) : func();
23560       });
23561
23562       assert.deepEqual(actual, expected);
23563     });
23564
23565     QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
23566       assert.expect(1);
23567
23568       var values = [
23569         {},
23570         [],
23571         [1],
23572         [1, 2],
23573         { 'valueOf': '1.1' },
23574         { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
23575         { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
23576         { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
23577         { 'valueOf': lodashStable.constant('-0x1a2b3c') },
23578         { 'toString': lodashStable.constant('-0x1a2b3c') },
23579         { 'valueOf': lodashStable.constant('0o12345') },
23580         { 'toString': lodashStable.constant('0o12345') },
23581         { 'valueOf': lodashStable.constant('0b101010') },
23582         { 'toString': lodashStable.constant('0b101010') }
23583       ];
23584
23585       var expected = [
23586         NaN,  0,   1,   NaN,
23587         NaN,  2.2, 1.1, 1.1,
23588         NaN,  NaN,
23589         5349, 5349,
23590         42,   42
23591       ];
23592
23593       if (isToFinite) {
23594         expected = [
23595           0,    0,    1,   0,
23596           0,    2.2,  1.1, 1.1,
23597           0,    0,
23598           5349, 5349,
23599           42,   42
23600         ];
23601       }
23602       else if (!isToNumber) {
23603         expected = [
23604           0,    0,    1, 0,
23605           0,    2,    1, 1,
23606           0,    0,
23607           5349, 5349,
23608           42,   42
23609         ];
23610       }
23611       var actual = lodashStable.map(values, func);
23612
23613       assert.deepEqual(actual, expected);
23614     });
23615   });
23616
23617   /*--------------------------------------------------------------------------*/
23618
23619   QUnit.module('lodash.toPairs');
23620
23621   (function() {
23622     QUnit.test('should be aliased', function(assert) {
23623       assert.expect(1);
23624
23625       assert.strictEqual(_.entries, _.toPairs);
23626     });
23627   }());
23628
23629   /*--------------------------------------------------------------------------*/
23630
23631   QUnit.module('lodash.toPairsIn');
23632
23633   (function() {
23634     QUnit.test('should be aliased', function(assert) {
23635       assert.expect(1);
23636
23637       assert.strictEqual(_.entriesIn, _.toPairsIn);
23638     });
23639   }());
23640
23641   /*--------------------------------------------------------------------------*/
23642
23643   QUnit.module('toPairs methods');
23644
23645   lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
23646     var func = _[methodName],
23647         isToPairs = methodName == 'toPairs';
23648
23649     QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
23650       assert.expect(1);
23651
23652       var object = { 'a': 1, 'b': 2 },
23653           actual = lodashStable.sortBy(func(object), 0);
23654
23655       assert.deepEqual(actual, [['a', 1], ['b', 2]]);
23656     });
23657
23658     QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
23659       assert.expect(1);
23660
23661       function Foo() {
23662         this.a = 1;
23663       }
23664       Foo.prototype.b = 2;
23665
23666       var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
23667           actual = lodashStable.sortBy(func(new Foo), 0);
23668
23669       assert.deepEqual(actual, expected);
23670     });
23671
23672     QUnit.test('`_.' + methodName + '` should convert objects with a `length` property', function(assert) {
23673       assert.expect(1);
23674
23675       var object = { '0': 'a', '1': 'b', 'length': 2 },
23676           actual = lodashStable.sortBy(func(object), 0);
23677
23678       assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
23679     });
23680
23681     QUnit.test('`_.' + methodName + '` should convert maps', function(assert) {
23682       assert.expect(1);
23683
23684       if (Map) {
23685         var map = new Map;
23686         map.set('a', 1);
23687         map.set('b', 2);
23688         assert.deepEqual(func(map), [['a', 1], ['b', 2]]);
23689       }
23690       else {
23691         skipAssert(assert);
23692       }
23693     });
23694
23695     QUnit.test('`_.' + methodName + '` should convert sets', function(assert) {
23696       assert.expect(1);
23697
23698       if (Set) {
23699         var set = new Set;
23700         set.add(1);
23701         set.add(2);
23702         assert.deepEqual(func(set), [[1, 1], [2, 2]]);
23703       }
23704       else {
23705         skipAssert(assert);
23706       }
23707     });
23708
23709     QUnit.test('`_.' + methodName + '` should convert strings', function(assert) {
23710       assert.expect(2);
23711
23712       lodashStable.each(['xo', Object('xo')], function(string) {
23713         var actual = lodashStable.sortBy(func(string), 0);
23714         assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
23715       });
23716     });
23717   });
23718
23719   /*--------------------------------------------------------------------------*/
23720
23721   QUnit.module('lodash.toPath');
23722
23723   (function() {
23724     QUnit.test('should convert a string to a path', function(assert) {
23725       assert.expect(2);
23726
23727       assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
23728       assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
23729     });
23730
23731     QUnit.test('should coerce array elements to strings', function(assert) {
23732       assert.expect(4);
23733
23734       var array = ['a', 'b', 'c'];
23735
23736       lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
23737         var actual = _.toPath(value);
23738         assert.deepEqual(actual, array);
23739         assert.notStrictEqual(actual, array);
23740       });
23741     });
23742
23743     QUnit.test('should a new path array', function(assert) {
23744       assert.expect(1);
23745
23746       assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
23747     });
23748
23749     QUnit.test('should not coerce symbols to strings', function(assert) {
23750       assert.expect(4);
23751
23752       if (Symbol) {
23753         var object = Object(symbol);
23754         lodashStable.each([symbol, object, [symbol], [object]], function(value) {
23755           var actual = _.toPath(value);
23756           assert.ok(lodashStable.isSymbol(actual[0]));
23757         });
23758       }
23759       else {
23760         skipAssert(assert, 4);
23761       }
23762     });
23763
23764     QUnit.test('should handle complex paths', function(assert) {
23765       assert.expect(1);
23766
23767       var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
23768       assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
23769     });
23770
23771     QUnit.test('should not ignore consecutive brackets and dots', function(assert) {
23772       assert.expect(4);
23773
23774       var expected = ['a', ''];
23775       assert.deepEqual(_.toPath('a.'), expected);
23776       assert.deepEqual(_.toPath('a[]'), expected);
23777
23778       expected = ['a', '', 'b'];
23779       assert.deepEqual(_.toPath('a..b'), expected);
23780       assert.deepEqual(_.toPath('a[][]b'), expected);
23781     });
23782   }());
23783
23784   /*--------------------------------------------------------------------------*/
23785
23786   QUnit.module('lodash.toPlainObject');
23787
23788   (function() {
23789     var args = arguments;
23790
23791     QUnit.test('should flatten inherited string keyed properties', function(assert) {
23792       assert.expect(1);
23793
23794       function Foo() {
23795         this.b = 2;
23796       }
23797       Foo.prototype.c = 3;
23798
23799       var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
23800       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
23801     });
23802
23803     QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
23804       assert.expect(1);
23805
23806       var actual = _.toPlainObject(args),
23807           expected = { '0': 1, '1': 2, '2': 3 };
23808
23809       assert.deepEqual(actual, expected);
23810     });
23811
23812     QUnit.test('should convert arrays to plain objects', function(assert) {
23813       assert.expect(1);
23814
23815       var actual = _.toPlainObject(['a', 'b', 'c']),
23816           expected = { '0': 'a', '1': 'b', '2': 'c' };
23817
23818       assert.deepEqual(actual, expected);
23819     });
23820   }(1, 2, 3));
23821
23822   /*--------------------------------------------------------------------------*/
23823
23824   QUnit.module('lodash.toString');
23825
23826   (function() {
23827     QUnit.test('should treat nullish values as empty strings', function(assert) {
23828       assert.expect(1);
23829
23830       var values = [, null, undefined],
23831           expected = lodashStable.map(values, stubString);
23832
23833       var actual = lodashStable.map(values, function(value, index) {
23834         return index ? _.toString(value) : _.toString();
23835       });
23836
23837       assert.deepEqual(actual, expected);
23838     });
23839
23840     QUnit.test('should preserve the sign of `0`', function(assert) {
23841       assert.expect(1);
23842
23843       var values = [-0, Object(-0), 0, Object(0)],
23844           expected = ['-0', '-0', '0', '0'],
23845           actual = lodashStable.map(values, _.toString);
23846
23847       assert.deepEqual(actual, expected);
23848     });
23849
23850     QUnit.test('should not error on symbols', function(assert) {
23851       assert.expect(1);
23852
23853       if (Symbol) {
23854         try {
23855           assert.strictEqual(_.toString(symbol), 'Symbol(a)');
23856         } catch (e) {
23857           assert.ok(false, e.message);
23858         }
23859       }
23860       else {
23861         skipAssert(assert);
23862       }
23863     });
23864
23865     QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
23866       assert.expect(1);
23867
23868       if (!isNpm) {
23869         var wrapped = _([1, 2, 3]);
23870         assert.strictEqual(wrapped.toString(), '1,2,3');
23871       }
23872       else {
23873         skipAssert(assert);
23874       }
23875     });
23876   }());
23877
23878   /*--------------------------------------------------------------------------*/
23879
23880   QUnit.module('lodash.transform');
23881
23882   (function() {
23883     function Foo() {
23884       this.a = 1;
23885       this.b = 2;
23886       this.c = 3;
23887     }
23888
23889     QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
23890       assert.expect(4);
23891
23892       var accumulators = [, null, undefined],
23893           object = new Foo,
23894           expected = lodashStable.map(accumulators, stubTrue);
23895
23896       var iteratee = function(result, value, key) {
23897         result[key] = square(value);
23898       };
23899
23900       var mapper = function(accumulator, index) {
23901         return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
23902       };
23903
23904       var results = lodashStable.map(accumulators, mapper);
23905
23906       var actual = lodashStable.map(results, function(result) {
23907         return result instanceof Foo;
23908       });
23909
23910       assert.deepEqual(actual, expected);
23911
23912       expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
23913       actual = lodashStable.map(results, lodashStable.toPlainObject);
23914
23915       assert.deepEqual(actual, expected);
23916
23917       object = { 'a': 1, 'b': 2, 'c': 3 };
23918       actual = lodashStable.map(accumulators, mapper);
23919
23920       assert.deepEqual(actual, expected);
23921
23922       object = [1, 2, 3];
23923       expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
23924       actual = lodashStable.map(accumulators, mapper);
23925
23926       assert.deepEqual(actual, expected);
23927     });
23928
23929     QUnit.test('should create regular arrays from typed arrays', function(assert) {
23930       assert.expect(1);
23931
23932       var expected = lodashStable.map(typedArrays, stubTrue);
23933
23934       var actual = lodashStable.map(typedArrays, function(type) {
23935         var Ctor = root[type],
23936             array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
23937
23938         return lodashStable.isArray(_.transform(array, noop));
23939       });
23940
23941       assert.deepEqual(actual, expected);
23942     });
23943
23944     QUnit.test('should support an `accumulator` value', function(assert) {
23945       assert.expect(6);
23946
23947       var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
23948           expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
23949
23950       var actual = lodashStable.map(values, function(value) {
23951         return _.transform(value, function(result, value) {
23952           result.push(square(value));
23953         }, []);
23954       });
23955
23956       assert.deepEqual(actual, expected);
23957
23958       var object = { 'a': 1, 'b': 4, 'c': 9 },
23959       expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
23960
23961       actual = lodashStable.map(values, function(value) {
23962         return _.transform(value, function(result, value, key) {
23963           result[key] = square(value);
23964         }, {});
23965       });
23966
23967       assert.deepEqual(actual, expected);
23968
23969       lodashStable.each([[], {}], function(accumulator) {
23970         var actual = lodashStable.map(values, function(value) {
23971           return _.transform(value, noop, accumulator);
23972         });
23973
23974         assert.ok(lodashStable.every(actual, function(result) {
23975           return result === accumulator;
23976         }));
23977
23978         assert.strictEqual(_.transform(null, null, accumulator), accumulator);
23979       });
23980     });
23981
23982     QUnit.test('should treat sparse arrays as dense', function(assert) {
23983       assert.expect(1);
23984
23985       var actual = _.transform(Array(1), function(result, value, index) {
23986         result[index] = String(value);
23987       });
23988
23989       assert.deepEqual(actual, ['undefined']);
23990     });
23991
23992     QUnit.test('should work without an `iteratee` argument', function(assert) {
23993       assert.expect(1);
23994
23995       assert.ok(_.transform(new Foo) instanceof Foo);
23996     });
23997
23998     QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
23999       assert.expect(2);
24000
24001       var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
24002           values = [false, true, 0, 1, NaN, '', 'a'],
24003           expected = lodashStable.map(values, stubObject);
24004
24005       var results = lodashStable.map(values, function(value) {
24006         return _.transform(value);
24007       });
24008
24009       assert.deepEqual(results, expected);
24010
24011       expected = lodashStable.map(values, stubFalse);
24012
24013       var actual = lodashStable.map(results, function(value, index) {
24014         return value instanceof Ctors[index];
24015       });
24016
24017       assert.deepEqual(actual, expected);
24018     });
24019
24020     QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
24021       assert.expect(1);
24022
24023       Foo.prototype.constructor = null;
24024       assert.notOk(_.transform(new Foo) instanceof Foo);
24025       Foo.prototype.constructor = Foo;
24026     });
24027
24028     QUnit.test('should create an empty object when given a falsey `object` argument', function(assert) {
24029       assert.expect(1);
24030
24031       var expected = lodashStable.map(falsey, stubObject);
24032
24033       var actual = lodashStable.map(falsey, function(object, index) {
24034         return index ? _.transform(object) : _.transform();
24035       });
24036
24037       assert.deepEqual(actual, expected);
24038     });
24039
24040     lodashStable.each({
24041       'array': [1, 2, 3],
24042       'object': { 'a': 1, 'b': 2, 'c': 3 }
24043     },
24044     function(object, key) {
24045       QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
24046         assert.expect(2);
24047
24048         var args;
24049
24050         _.transform(object, function() {
24051           args || (args = slice.call(arguments));
24052         });
24053
24054         var first = args[0];
24055         if (key == 'array') {
24056           assert.ok(first !== object && lodashStable.isArray(first));
24057           assert.deepEqual(args, [first, 1, 0, object]);
24058         } else {
24059           assert.ok(first !== object && lodashStable.isPlainObject(first));
24060           assert.deepEqual(args, [first, 1, 'a', object]);
24061         }
24062       });
24063     });
24064
24065     QUnit.test('should create an object from the same realm as `object`', function(assert) {
24066       assert.expect(1);
24067
24068       var objects = lodashStable.filter(realm, function(value) {
24069         return lodashStable.isObject(value) && !lodashStable.isElement(value);
24070       });
24071
24072       var expected = lodashStable.map(objects, stubTrue);
24073
24074       var actual = lodashStable.map(objects, function(object) {
24075         var Ctor = object.constructor,
24076             result = _.transform(object);
24077
24078         if (result === object) {
24079           return false;
24080         }
24081         if (lodashStable.isTypedArray(object)) {
24082           return result instanceof Array;
24083         }
24084         return result instanceof Ctor || !(new Ctor instanceof Ctor);
24085       });
24086
24087       assert.deepEqual(actual, expected);
24088     });
24089   }());
24090
24091   /*--------------------------------------------------------------------------*/
24092
24093   QUnit.module('trim methods');
24094
24095   lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
24096     var func = _[methodName],
24097         parts = [];
24098
24099     if (index != 2) {
24100       parts.push('leading');
24101     }
24102     if (index != 1) {
24103       parts.push('trailing');
24104     }
24105     parts = parts.join(' and ');
24106
24107     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
24108       assert.expect(1);
24109
24110       var string = whitespace + 'a b c' + whitespace,
24111           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24112
24113       assert.strictEqual(func(string), expected);
24114     });
24115
24116     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
24117       assert.expect(1);
24118
24119       var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
24120           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24121
24122       assert.strictEqual(func(object), expected);
24123     });
24124
24125     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
24126       assert.expect(1);
24127
24128       var string = '-_-a-b-c-_-',
24129           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24130
24131       assert.strictEqual(func(string, '_-'), expected);
24132     });
24133
24134     QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
24135       assert.expect(1);
24136
24137       var object = { 'toString': lodashStable.constant('_-') },
24138           string = '-_-a-b-c-_-',
24139           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24140
24141       assert.strictEqual(func(string, object), expected);
24142     });
24143
24144     QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
24145       assert.expect(6);
24146
24147       lodashStable.each([null, '_-'], function(chars) {
24148         assert.strictEqual(func(null, chars), '');
24149         assert.strictEqual(func(undefined, chars), '');
24150         assert.strictEqual(func('', chars), '');
24151       });
24152     });
24153
24154     QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
24155       assert.expect(2);
24156
24157       var string = whitespace + 'a b c' + whitespace,
24158           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24159
24160       assert.strictEqual(func(string, undefined), expected);
24161       assert.strictEqual(func(string, ''), string);
24162     });
24163
24164     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
24165       assert.expect(1);
24166
24167       var string = Object(whitespace + 'a b c' + whitespace),
24168           trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
24169           actual = lodashStable.map([string, string, string], func);
24170
24171       assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
24172     });
24173
24174     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
24175       assert.expect(1);
24176
24177       if (!isNpm) {
24178         var string = whitespace + 'a b c' + whitespace,
24179             expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24180
24181         assert.strictEqual(_(string)[methodName](), expected);
24182       }
24183       else {
24184         skipAssert(assert);
24185       }
24186     });
24187
24188     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
24189       assert.expect(1);
24190
24191       if (!isNpm) {
24192         var string = whitespace + 'a b c' + whitespace;
24193         assert.ok(_(string).chain()[methodName]() instanceof _);
24194       }
24195       else {
24196         skipAssert(assert);
24197       }
24198     });
24199   });
24200
24201   /*--------------------------------------------------------------------------*/
24202
24203   QUnit.module('uncommon symbols');
24204
24205   (function() {
24206     var flag = '\ud83c\uddfa\ud83c\uddf8',
24207         heart = '\u2764' + emojiVar,
24208         hearts = '\ud83d\udc95',
24209         comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
24210         hashKeycap = '#' + emojiVar + '\u20e3',
24211         leafs = '\ud83c\udf42',
24212         mic = '\ud83c\udf99',
24213         noMic = mic + '\u20e0',
24214         raisedHand = '\u270B' + emojiVar,
24215         rocket = '\ud83d\ude80',
24216         thumbsUp = '\ud83d\udc4d';
24217
24218     QUnit.test('should account for astral symbols', function(assert) {
24219       assert.expect(34);
24220
24221       var allHearts = _.repeat(hearts, 10),
24222           chars = hearts + comboGlyph,
24223           string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
24224           trimChars = comboGlyph + hearts,
24225           trimString = trimChars + string + trimChars;
24226
24227       assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
24228       assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
24229       assert.strictEqual(_.capitalize(rocket), rocket);
24230
24231       assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
24232       assert.strictEqual(_.padStart(string, 16), '   ' + string);
24233       assert.strictEqual(_.padEnd(string, 16), string + '   ');
24234
24235       assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
24236       assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
24237       assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
24238
24239       assert.strictEqual(_.size(string), 13);
24240       assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
24241       assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
24242       assert.deepEqual(_.split(string, undefined), [string]);
24243       assert.deepEqual(_.split(string, undefined, -1), [string]);
24244       assert.deepEqual(_.split(string, undefined, 0), []);
24245
24246       var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
24247
24248       assert.deepEqual(_.split(string, ''), expected);
24249       assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
24250       assert.deepEqual(_.toArray(string), expected);
24251
24252       assert.strictEqual(_.trim(trimString, chars), string);
24253       assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
24254       assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
24255
24256       assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
24257       assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
24258
24259       assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
24260       assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
24261       assert.deepEqual(_.toArray(noMic), [noMic]);
24262
24263       lodashStable.times(2, function(index) {
24264         var separator = index ? RegExp(hearts) : hearts,
24265             options = { 'length': 4, 'separator': separator },
24266             actual = _.truncate(string, options);
24267
24268         assert.strictEqual(actual, 'A...');
24269         assert.strictEqual(actual.length, 4);
24270
24271         actual = _.truncate(allHearts, options);
24272         assert.strictEqual(actual, hearts + '...');
24273         assert.strictEqual(actual.length, 5);
24274       });
24275     });
24276
24277     QUnit.test('should account for combining diacritical marks', function(assert) {
24278       assert.expect(1);
24279
24280       var values = lodashStable.map(comboMarks, function(mark) {
24281         return 'o' + mark;
24282       });
24283
24284       var expected = lodashStable.map(values, function(value) {
24285         return [1, [value], [value]];
24286       });
24287
24288       var actual = lodashStable.map(values, function(value) {
24289         return [_.size(value), _.toArray(value), _.words(value)];
24290       });
24291
24292       assert.deepEqual(actual, expected);
24293     });
24294
24295     QUnit.test('should account for fitzpatrick modifiers', function(assert) {
24296       assert.expect(1);
24297
24298       var values = lodashStable.map(fitzModifiers, function(modifier) {
24299         return thumbsUp + modifier;
24300       });
24301
24302       var expected = lodashStable.map(values, function(value) {
24303         return [1, [value], [value]];
24304       });
24305
24306       var actual = lodashStable.map(values, function(value) {
24307         return [_.size(value), _.toArray(value), _.words(value)];
24308       });
24309
24310       assert.deepEqual(actual, expected);
24311     });
24312
24313     QUnit.test('should account for regional symbols', function(assert) {
24314       assert.expect(6);
24315
24316       var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
24317           regionals = pair.join(' ');
24318
24319       assert.strictEqual(_.size(flag), 1);
24320       assert.strictEqual(_.size(regionals), 3);
24321
24322       assert.deepEqual(_.toArray(flag), [flag]);
24323       assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
24324
24325       assert.deepEqual(_.words(flag), [flag]);
24326       assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
24327     });
24328
24329     QUnit.test('should account for variation selectors', function(assert) {
24330       assert.expect(3);
24331
24332       assert.strictEqual(_.size(heart), 1);
24333       assert.deepEqual(_.toArray(heart), [heart]);
24334       assert.deepEqual(_.words(heart), [heart]);
24335     });
24336
24337     QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
24338       assert.expect(1);
24339
24340       var values = lodashStable.map(fitzModifiers, function(modifier) {
24341         return raisedHand + modifier;
24342       });
24343
24344       var expected = lodashStable.map(values, function(value) {
24345         return [1, [value], [value]];
24346       });
24347
24348       var actual = lodashStable.map(values, function(value) {
24349         return [_.size(value), _.toArray(value), _.words(value)];
24350       });
24351
24352       assert.deepEqual(actual, expected);
24353     });
24354
24355     QUnit.test('should match lone surrogates', function(assert) {
24356       assert.expect(3);
24357
24358       var pair = hearts.split(''),
24359           surrogates = pair[0] + ' ' + pair[1];
24360
24361       assert.strictEqual(_.size(surrogates), 3);
24362       assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
24363       assert.deepEqual(_.words(surrogates), []);
24364     });
24365
24366     QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
24367       assert.expect(1);
24368
24369       var string = fitzModifiers[0] + fitzModifiers[0];
24370       assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
24371     });
24372   }());
24373
24374   /*--------------------------------------------------------------------------*/
24375
24376   QUnit.module('lodash.unary');
24377
24378   (function() {
24379     function fn() {
24380       return slice.call(arguments);
24381     }
24382
24383     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
24384       assert.expect(1);
24385
24386       var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
24387       assert.deepEqual(actual, [6, 8, 10]);
24388     });
24389
24390     QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
24391       assert.expect(1);
24392
24393       var capped = _.unary(fn);
24394       assert.deepEqual(capped(), []);
24395     });
24396   }());
24397
24398   /*--------------------------------------------------------------------------*/
24399
24400   QUnit.module('lodash.unescape');
24401
24402   (function() {
24403     var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
24404         unescaped = '&<>"\'\/';
24405
24406     escaped += escaped;
24407     unescaped += unescaped;
24408
24409     QUnit.test('should unescape entities in order', function(assert) {
24410       assert.expect(1);
24411
24412       assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
24413     });
24414
24415     QUnit.test('should unescape the proper entities', function(assert) {
24416       assert.expect(1);
24417
24418       assert.strictEqual(_.unescape(escaped), unescaped);
24419     });
24420
24421     QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
24422       assert.expect(1);
24423
24424       assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
24425     });
24426
24427     QUnit.test('should handle strings with nothing to unescape', function(assert) {
24428       assert.expect(1);
24429
24430       assert.strictEqual(_.unescape('abc'), 'abc');
24431     });
24432
24433     QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
24434       assert.expect(1);
24435
24436       assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
24437     });
24438   }());
24439
24440   /*--------------------------------------------------------------------------*/
24441
24442   QUnit.module('union methods');
24443
24444   lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
24445     var args = (function() { return arguments; }(1, 2, 3)),
24446         func = _[methodName];
24447
24448     QUnit.test('`_.' + methodName + '` should return the union of two arrays', function(assert) {
24449       assert.expect(1);
24450
24451       var actual = func([2], [1, 2]);
24452       assert.deepEqual(actual, [2, 1]);
24453     });
24454
24455     QUnit.test('`_.' + methodName + '` should return the union of multiple arrays', function(assert) {
24456       assert.expect(1);
24457
24458       var actual = func([2], [1, 2], [2, 3]);
24459       assert.deepEqual(actual, [2, 1, 3]);
24460     });
24461
24462     QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
24463       assert.expect(1);
24464
24465       var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
24466       assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
24467     });
24468
24469     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24470       assert.expect(3);
24471
24472       var array = [0];
24473       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24474       assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
24475       assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
24476     });
24477   });
24478
24479   /*--------------------------------------------------------------------------*/
24480
24481   QUnit.module('lodash.unionBy');
24482
24483   (function() {
24484     QUnit.test('should accept an `iteratee` argument', function(assert) {
24485       assert.expect(2);
24486
24487       var actual = _.unionBy([2.1], [1.2, 2.3], Math.floor);
24488       assert.deepEqual(actual, [2.1, 1.2]);
24489
24490       actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
24491       assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
24492     });
24493
24494     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24495       assert.expect(1);
24496
24497       var args;
24498
24499       _.unionBy([2.1], [1.2, 2.3], function() {
24500         args || (args = slice.call(arguments));
24501       });
24502
24503       assert.deepEqual(args, [2.1]);
24504     });
24505   }());
24506
24507   /*--------------------------------------------------------------------------*/
24508
24509   QUnit.module('lodash.unionWith');
24510
24511   (function() {
24512     QUnit.test('should work with a `comparator` argument', function(assert) {
24513       assert.expect(1);
24514
24515       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
24516           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
24517           actual = _.unionWith(objects, others, lodashStable.isEqual);
24518
24519       assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
24520     });
24521   }());
24522
24523   /*--------------------------------------------------------------------------*/
24524
24525   QUnit.module('uniq methods');
24526
24527   lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
24528     var func = _[methodName],
24529         isSorted = /^sorted/.test(methodName),
24530         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24531
24532     if (isSorted) {
24533       objects = _.sortBy(objects, 'a');
24534     }
24535     else {
24536       QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
24537         assert.expect(1);
24538
24539         var array = [2, 1, 2];
24540         assert.deepEqual(func(array), [2, 1]);
24541       });
24542     }
24543     QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
24544       assert.expect(1);
24545
24546       var array = [1, 2, 2];
24547       assert.deepEqual(func(array), [1, 2]);
24548     });
24549
24550     QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
24551       assert.expect(1);
24552
24553       assert.deepEqual(func(objects), objects);
24554     });
24555
24556     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
24557       assert.expect(1);
24558
24559       var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
24560       assert.deepEqual(actual, ['0']);
24561     });
24562
24563     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
24564       assert.expect(1);
24565
24566       assert.deepEqual(func([NaN, NaN]), [NaN]);
24567     });
24568
24569     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
24570       assert.expect(1);
24571
24572       var largeArray = [],
24573           expected = [0, {}, 'a'],
24574           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24575
24576       lodashStable.each(expected, function(value) {
24577         lodashStable.times(count, function() {
24578           largeArray.push(value);
24579         });
24580       });
24581
24582       assert.deepEqual(func(largeArray), expected);
24583     });
24584
24585     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
24586       assert.expect(1);
24587
24588       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24589         return isEven(index) ? -0 : 0;
24590       });
24591
24592       var actual = lodashStable.map(func(largeArray), lodashStable.toString);
24593       assert.deepEqual(actual, ['0']);
24594     });
24595
24596     QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
24597       assert.expect(1);
24598
24599       var largeArray = [],
24600           expected = [null, undefined, false, true, NaN],
24601           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24602
24603       lodashStable.each(expected, function(value) {
24604         lodashStable.times(count, function() {
24605           largeArray.push(value);
24606         });
24607       });
24608
24609       assert.deepEqual(func(largeArray), expected);
24610     });
24611
24612     QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
24613       assert.expect(1);
24614
24615       if (Symbol) {
24616         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
24617         assert.deepEqual(func(largeArray), largeArray);
24618       }
24619       else {
24620         skipAssert(assert);
24621       }
24622     });
24623
24624     QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
24625       assert.expect(1);
24626
24627       // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
24628       if (Symbol) {
24629         var expected = [
24630           Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
24631           Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
24632           Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
24633         ];
24634
24635         var largeArray = [],
24636             count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24637
24638         expected = lodashStable.map(expected, function(symbol) {
24639           return symbol || {};
24640         });
24641
24642         lodashStable.each(expected, function(value) {
24643           lodashStable.times(count, function() {
24644             largeArray.push(value);
24645           });
24646         });
24647
24648         assert.deepEqual(func(largeArray), expected);
24649       }
24650       else {
24651         skipAssert(assert);
24652       }
24653     });
24654
24655     QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
24656       assert.expect(1);
24657
24658       var largeArray = [],
24659           expected = ['2', 2, Object('2'), Object(2)],
24660           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24661
24662       lodashStable.each(expected, function(value) {
24663         lodashStable.times(count, function() {
24664           largeArray.push(value);
24665         });
24666       });
24667
24668       assert.deepEqual(func(largeArray), expected);
24669     });
24670   });
24671
24672   /*--------------------------------------------------------------------------*/
24673
24674   QUnit.module('lodash.uniq');
24675
24676   (function() {
24677     QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
24678       assert.expect(1);
24679
24680       var array = [[2, 1, 2], [1, 2, 1]],
24681           actual = lodashStable.map(array, lodashStable.uniq);
24682
24683       assert.deepEqual(actual, [[2, 1], [1, 2]]);
24684     });
24685   }());
24686
24687   /*--------------------------------------------------------------------------*/
24688
24689   QUnit.module('uniqBy methods');
24690
24691   lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
24692     var func = _[methodName],
24693         isSorted = methodName == 'sortedUniqBy',
24694         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24695
24696     if (isSorted) {
24697       objects = _.sortBy(objects, 'a');
24698     }
24699     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
24700       assert.expect(1);
24701
24702       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
24703
24704       var actual = func(objects, function(object) {
24705         return object.a;
24706       });
24707
24708       assert.deepEqual(actual, expected);
24709     });
24710
24711     QUnit.test('should work with large arrays', function(assert) {
24712       assert.expect(2);
24713
24714       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
24715         return [1, 2];
24716       });
24717
24718       var actual = func(largeArray, String);
24719       assert.strictEqual(actual[0], largeArray[0]);
24720       assert.deepEqual(actual, [[1, 2]]);
24721     });
24722
24723     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
24724       assert.expect(1);
24725
24726       var args;
24727
24728       func(objects, function() {
24729         args || (args = slice.call(arguments));
24730       });
24731
24732       assert.deepEqual(args, [objects[0]]);
24733     });
24734
24735     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
24736       assert.expect(2);
24737
24738       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
24739           actual = func(objects, 'a');
24740
24741       assert.deepEqual(actual, expected);
24742
24743       var arrays = [[2], [3], [1], [2], [3], [1]];
24744       if (isSorted) {
24745         arrays = lodashStable.sortBy(arrays, 0);
24746       }
24747       expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
24748       actual = func(arrays, 0);
24749
24750       assert.deepEqual(actual, expected);
24751     });
24752
24753     lodashStable.each({
24754       'an array': [0, 'a'],
24755       'an object': { '0': 'a' },
24756       'a number': 0,
24757       'a string': '0'
24758     },
24759     function(iteratee, key) {
24760       QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
24761         assert.expect(1);
24762
24763         var actual = func([['a'], ['a'], ['b']], iteratee);
24764         assert.deepEqual(actual, [['a'], ['b']]);
24765       });
24766     });
24767   });
24768
24769   /*--------------------------------------------------------------------------*/
24770
24771   QUnit.module('lodash.uniqWith');
24772
24773   (function() {
24774     QUnit.test('should work with a `comparator` argument', function(assert) {
24775       assert.expect(1);
24776
24777       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }],
24778           actual = _.uniqWith(objects, lodashStable.isEqual);
24779
24780       assert.deepEqual(actual, [objects[0], objects[1]]);
24781     });
24782
24783     QUnit.test('should preserve the sign of `0`', function(assert) {
24784       assert.expect(1);
24785
24786       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24787         return isEven(index) ? -0 : 0;
24788       });
24789
24790       var arrays = [[-0, 0], largeArray],
24791           expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
24792
24793       var actual = lodashStable.map(arrays, function(array) {
24794         return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
24795       });
24796
24797       assert.deepEqual(actual, expected);
24798     });
24799   }());
24800
24801   /*--------------------------------------------------------------------------*/
24802
24803   QUnit.module('lodash.uniqueId');
24804
24805   (function() {
24806     QUnit.test('should generate unique ids', function(assert) {
24807       assert.expect(1);
24808
24809       var actual = lodashStable.times(1000, function(assert) {
24810         return _.uniqueId();
24811       });
24812
24813       assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
24814     });
24815
24816     QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
24817       assert.expect(1);
24818
24819       assert.strictEqual(typeof _.uniqueId(), 'string');
24820     });
24821
24822     QUnit.test('should coerce the prefix argument to a string', function(assert) {
24823       assert.expect(1);
24824
24825       var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
24826       assert.ok(/3\d+,2\d+,1\d+/.test(actual));
24827     });
24828   }());
24829
24830   /*--------------------------------------------------------------------------*/
24831
24832   QUnit.module('lodash.unset');
24833
24834   (function() {
24835     QUnit.test('should unset property values', function(assert) {
24836       assert.expect(4);
24837
24838       lodashStable.each(['a', ['a']], function(path) {
24839         var object = { 'a': 1, 'c': 2 };
24840         assert.strictEqual(_.unset(object, path), true);
24841         assert.deepEqual(object, { 'c': 2 });
24842       });
24843     });
24844
24845     QUnit.test('should preserve the sign of `0`', function(assert) {
24846       assert.expect(1);
24847
24848       var props = [-0, Object(-0), 0, Object(0)],
24849           expected = lodashStable.map(props, lodashStable.constant([true, false]));
24850
24851       var actual = lodashStable.map(props, function(key) {
24852         var object = { '-0': 'a', '0': 'b' };
24853         return [_.unset(object, key), lodashStable.toString(key) in object];
24854       });
24855
24856       assert.deepEqual(actual, expected);
24857     });
24858
24859     QUnit.test('should unset symbol keyed property values', function(assert) {
24860       assert.expect(2);
24861
24862       if (Symbol) {
24863         var object = {};
24864         object[symbol] = 1;
24865
24866         assert.strictEqual(_.unset(object, symbol), true);
24867         assert.notOk(symbol in object);
24868       }
24869       else {
24870         skipAssert(assert, 2);
24871       }
24872     });
24873
24874     QUnit.test('should unset deep property values', function(assert) {
24875       assert.expect(4);
24876
24877       lodashStable.each(['a.b', ['a', 'b']], function(path) {
24878         var object = { 'a': { 'b': null } };
24879         assert.strictEqual(_.unset(object, path), true);
24880         assert.deepEqual(object, { 'a': {} });
24881       });
24882     });
24883
24884     QUnit.test('should handle complex paths', function(assert) {
24885       assert.expect(4);
24886
24887       var paths = [
24888         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
24889         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
24890       ];
24891
24892       lodashStable.each(paths, function(path) {
24893         var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
24894         assert.strictEqual(_.unset(object, path), true);
24895         assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
24896       });
24897     });
24898
24899     QUnit.test('should return `true` for nonexistent paths', function(assert) {
24900       assert.expect(5);
24901
24902       var object = { 'a': { 'b': { 'c': null } } };
24903
24904       lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
24905         assert.strictEqual(_.unset(object, path), true);
24906       });
24907
24908       assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
24909     });
24910
24911     QUnit.test('should not error when `object` is nullish', function(assert) {
24912       assert.expect(1);
24913
24914       var values = [null, undefined],
24915           expected = [[true, true], [true, true]];
24916
24917       var actual = lodashStable.map(values, function(value) {
24918         try {
24919           return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
24920         } catch (e) {
24921           return e.message;
24922         }
24923       });
24924
24925       assert.deepEqual(actual, expected);
24926     });
24927
24928     QUnit.test('should follow `path` over non-plain objects', function(assert) {
24929       assert.expect(8);
24930
24931       var object = { 'a': '' },
24932           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
24933
24934       lodashStable.each(paths, function(path) {
24935         numberProto.a = 1;
24936
24937         var actual = _.unset(0, path);
24938         assert.strictEqual(actual, true);
24939         assert.notOk('a' in numberProto);
24940
24941         delete numberProto.a;
24942       });
24943
24944       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
24945         stringProto.replace.b = 1;
24946
24947         var actual = _.unset(object, path);
24948         assert.strictEqual(actual, true);
24949         assert.notOk('a' in stringProto.replace);
24950
24951         delete stringProto.replace.b;
24952       });
24953     });
24954
24955     QUnit.test('should return `false` for non-configurable properties', function(assert) {
24956       assert.expect(1);
24957
24958       var object = {};
24959
24960       if (!isStrict) {
24961         defineProperty(object, 'a', {
24962           'configurable': false,
24963           'enumerable': true,
24964           'writable': true,
24965           'value': 1,
24966         });
24967         assert.strictEqual(_.unset(object, 'a'), false);
24968       }
24969       else {
24970         skipAssert(assert);
24971       }
24972     });
24973   }());
24974
24975   /*--------------------------------------------------------------------------*/
24976
24977   QUnit.module('lodash.unzipWith');
24978
24979   (function() {
24980     QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
24981       assert.expect(1);
24982
24983       var array = [[1, 4], [2, 5], [3, 6]];
24984
24985       var actual = _.unzipWith(array, function(a, b, c) {
24986         return a + b + c;
24987       });
24988
24989       assert.deepEqual(actual, [6, 15]);
24990     });
24991
24992     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24993       assert.expect(1);
24994
24995       var args;
24996
24997       _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
24998         args || (args = slice.call(arguments));
24999       });
25000
25001       assert.deepEqual(args, [1, 2]);
25002     });
25003
25004     QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
25005       assert.expect(1);
25006
25007       var array = [[1, 3], [2, 4]],
25008           values = [, null, undefined],
25009           expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
25010
25011       var actual = lodashStable.map(values, function(value, index) {
25012         return index ? _.unzipWith(array, value) : _.unzipWith(array);
25013       });
25014
25015       assert.deepEqual(actual, expected);
25016     });
25017   }());
25018
25019   /*--------------------------------------------------------------------------*/
25020
25021   QUnit.module('lodash.updateWith');
25022
25023   (function() {
25024     QUnit.test('should work with a `customizer` callback', function(assert) {
25025       assert.expect(1);
25026
25027       var actual = _.updateWith({ '0': {} }, '[0][1][2]', stubThree, function(value) {
25028         return lodashStable.isObject(value) ? undefined : {};
25029       });
25030
25031       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
25032     });
25033
25034     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
25035       assert.expect(1);
25036
25037       var actual = _.updateWith({}, 'a[0].b.c', stubFour, noop);
25038       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
25039     });
25040   }());
25041
25042   /*--------------------------------------------------------------------------*/
25043
25044   QUnit.module('update methods');
25045
25046   lodashStable.each(['update', 'updateWith'], function(methodName) {
25047     var func = _[methodName],
25048         oldValue = 1;
25049
25050     QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
25051       assert.expect(4);
25052
25053       var object = { 'a': [{ 'b': { 'c': oldValue } }] },
25054           expected = oldValue + 1;
25055
25056       lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
25057         func(object, path, function(n) {
25058           assert.strictEqual(n, oldValue);
25059           return ++n;
25060         });
25061
25062         assert.strictEqual(object.a[0].b.c, expected);
25063         object.a[0].b.c = oldValue;
25064       });
25065     });
25066   });
25067
25068   /*--------------------------------------------------------------------------*/
25069
25070   QUnit.module('lodash.upperCase');
25071
25072   (function() {
25073     QUnit.test('should uppercase as space-separated words', function(assert) {
25074       assert.expect(3);
25075
25076       assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
25077       assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
25078       assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
25079     });
25080   }());
25081
25082   /*--------------------------------------------------------------------------*/
25083
25084   QUnit.module('lodash.upperFirst');
25085
25086   (function() {
25087     QUnit.test('should uppercase only the first character', function(assert) {
25088       assert.expect(3);
25089
25090       assert.strictEqual(_.upperFirst('fred'), 'Fred');
25091       assert.strictEqual(_.upperFirst('Fred'), 'Fred');
25092       assert.strictEqual(_.upperFirst('FRED'), 'FRED');
25093     });
25094   }());
25095
25096   /*--------------------------------------------------------------------------*/
25097
25098   QUnit.module('values methods');
25099
25100   lodashStable.each(['values', 'valuesIn'], function(methodName) {
25101     var args = (function() { return arguments; }(1, 2, 3)),
25102         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
25103         func = _[methodName],
25104         isValues = methodName == 'values';
25105
25106     QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
25107       assert.expect(1);
25108
25109       var object = { 'a': 1, 'b': 2 },
25110           actual = func(object).sort();
25111
25112       assert.deepEqual(actual, [1, 2]);
25113     });
25114
25115     QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
25116       assert.expect(1);
25117
25118       var object = { '0': 'a', '1': 'b', 'length': 2 },
25119           actual = func(object).sort();
25120
25121       assert.deepEqual(actual, [2, 'a', 'b']);
25122     });
25123
25124     QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
25125       assert.expect(1);
25126
25127       function Foo() {
25128         this.a = 1;
25129       }
25130       Foo.prototype.b = 2;
25131
25132       var expected = isValues ? [1] : [1, 2],
25133           actual = func(new Foo).sort();
25134
25135       assert.deepEqual(actual, expected);
25136     });
25137
25138     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
25139       assert.expect(1);
25140
25141       var values = [args, strictArgs],
25142           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
25143
25144       var actual = lodashStable.map(values, function(value) {
25145         return func(value).sort();
25146       });
25147
25148       assert.deepEqual(actual, expected);
25149     });
25150   });
25151
25152   /*--------------------------------------------------------------------------*/
25153
25154   QUnit.module('lodash.without');
25155
25156   (function() {
25157     QUnit.test('should return the difference of values', function(assert) {
25158       assert.expect(1);
25159
25160       var actual = _.without([2, 1, 2, 3], 1, 2);
25161       assert.deepEqual(actual, [3]);
25162     });
25163
25164     QUnit.test('should use strict equality to determine the values to reject', function(assert) {
25165       assert.expect(2);
25166
25167       var object1 = { 'a': 1 },
25168           object2 = { 'b': 2 },
25169           array = [object1, object2];
25170
25171       assert.deepEqual(_.without(array, { 'a': 1 }), array);
25172       assert.deepEqual(_.without(array, object1), [object2]);
25173     });
25174
25175     QUnit.test('should remove all occurrences of each value from an array', function(assert) {
25176       assert.expect(1);
25177
25178       var array = [1, 2, 3, 1, 2, 3];
25179       assert.deepEqual(_.without(array, 1, 2), [3, 3]);
25180     });
25181   }(1, 2, 3));
25182
25183   /*--------------------------------------------------------------------------*/
25184
25185   QUnit.module('lodash.words');
25186
25187   (function() {
25188     QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
25189       assert.expect(1);
25190
25191       var expected = lodashStable.map(burredLetters, function(letter) {
25192         return [letter];
25193       });
25194
25195       var actual = lodashStable.map(burredLetters, function(letter) {
25196         return _.words(letter);
25197       });
25198
25199       assert.deepEqual(actual, expected);
25200     });
25201
25202     QUnit.test('should not treat mathematical operators as words', function(assert) {
25203       assert.expect(1);
25204
25205       var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
25206           expected = lodashStable.map(operators, stubArray),
25207           actual = lodashStable.map(operators, _.words);
25208
25209       assert.deepEqual(actual, expected);
25210     });
25211
25212     QUnit.test('should not treat punctuation as words', function(assert) {
25213       assert.expect(1);
25214
25215       var marks = [
25216         '\u2012', '\u2013', '\u2014', '\u2015',
25217         '\u2024', '\u2025', '\u2026',
25218         '\u205d', '\u205e'
25219       ];
25220
25221       var expected = lodashStable.map(marks, stubArray),
25222           actual = lodashStable.map(marks, _.words);
25223
25224       assert.deepEqual(actual, expected);
25225     });
25226
25227     QUnit.test('should support a `pattern` argument', function(assert) {
25228       assert.expect(2);
25229
25230       assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
25231       assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
25232     });
25233
25234     QUnit.test('should work with compound words', function(assert) {
25235       assert.expect(12);
25236
25237       assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
25238       assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
25239       assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
25240       assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
25241       assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
25242       assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
25243       assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
25244       assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
25245       assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
25246       assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
25247       assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
25248       assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
25249     });
25250
25251     QUnit.test('should work with compound words containing diacritical marks', function(assert) {
25252       assert.expect(3);
25253
25254       assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
25255       assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
25256       assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
25257     });
25258
25259     QUnit.test('should work with contractions', function(assert) {
25260       assert.expect(2);
25261
25262       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
25263
25264       lodashStable.each(["'", '\u2019'], function(apos) {
25265         var actual = lodashStable.map(postfixes, function(postfix) {
25266           return _.words('a b' + apos + postfix +  ' c');
25267         });
25268
25269         var expected = lodashStable.map(postfixes, function(postfix) {
25270           return ['a', 'b' + apos + postfix, 'c'];
25271         });
25272
25273         assert.deepEqual(actual, expected);
25274       });
25275     });
25276
25277     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
25278       assert.expect(1);
25279
25280       var strings = lodashStable.map(['a', 'b', 'c'], Object),
25281           actual = lodashStable.map(strings, _.words);
25282
25283       assert.deepEqual(actual, [['a'], ['b'], ['c']]);
25284     });
25285   }());
25286
25287   /*--------------------------------------------------------------------------*/
25288
25289   QUnit.module('lodash.wrap');
25290
25291   (function() {
25292     QUnit.test('should create a wrapped function', function(assert) {
25293       assert.expect(1);
25294
25295       var p = _.wrap(_.escape, function(func, text) {
25296         return '<p>' + func(text) + '</p>';
25297       });
25298
25299       assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
25300     });
25301
25302     QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
25303       assert.expect(1);
25304
25305       var args;
25306
25307       var wrapped = _.wrap(noop, function() {
25308         args || (args = slice.call(arguments));
25309       });
25310
25311       wrapped(1, 2, 3);
25312       assert.deepEqual(args, [noop, 1, 2, 3]);
25313     });
25314
25315     QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
25316       assert.expect(1);
25317
25318       var values = [, null, undefined],
25319           expected = lodashStable.map(values, stubA);
25320
25321       var actual = lodashStable.map(values, function(value, index) {
25322         var wrapped = index ? _.wrap('a', value) : _.wrap('a');
25323         return wrapped('b', 'c');
25324       });
25325
25326       assert.deepEqual(actual, expected);
25327     });
25328
25329     QUnit.test('should not set a `this` binding', function(assert) {
25330       assert.expect(1);
25331
25332       var p = _.wrap(_.escape, function(func) {
25333         return '<p>' + func(this.text) + '</p>';
25334       });
25335
25336       var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
25337       assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
25338     });
25339   }());
25340
25341   /*--------------------------------------------------------------------------*/
25342
25343   QUnit.module('xor methods');
25344
25345   lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
25346     var args = (function() { return arguments; }(1, 2, 3)),
25347         func = _[methodName];
25348
25349     QUnit.test('`_.' + methodName + '` should return the symmetric difference of two arrays', function(assert) {
25350       assert.expect(1);
25351
25352       var actual = func([2, 1], [2, 3]);
25353       assert.deepEqual(actual, [1, 3]);
25354     });
25355
25356     QUnit.test('`_.' + methodName + '` should return the symmetric difference of multiple arrays', function(assert) {
25357       assert.expect(1);
25358
25359       var actual = func([2, 1], [2, 3], [3, 4]);
25360       assert.deepEqual(actual, [1, 4]);
25361     });
25362
25363     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
25364       assert.expect(2);
25365
25366       var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
25367       assert.deepEqual(actual, [1, 4, 5]);
25368
25369       actual = func([1, 1]);
25370       assert.deepEqual(actual, [1]);
25371     });
25372
25373     QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
25374       assert.expect(1);
25375
25376       var array = [1];
25377       assert.notStrictEqual(func(array), array);
25378     });
25379
25380     QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
25381       assert.expect(1);
25382
25383       var array = [0];
25384       assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
25385     });
25386
25387     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25388       assert.expect(3);
25389
25390       var array = [1, 2];
25391       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
25392       assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
25393       assert.deepEqual(func(array, null, args, null), [3]);
25394     });
25395
25396     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
25397       assert.expect(1);
25398
25399       if (!isNpm) {
25400         var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
25401         assert.ok(wrapped instanceof _);
25402       }
25403       else {
25404         skipAssert(assert);
25405       }
25406     });
25407
25408     QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
25409       assert.expect(1);
25410
25411       if (!isNpm) {
25412         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
25413             wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
25414
25415         var actual = lodashStable.map(['head', 'last'], function(methodName) {
25416           return wrapped[methodName]();
25417         });
25418
25419         assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
25420       }
25421       else {
25422         skipAssert(assert);
25423       }
25424     });
25425   });
25426
25427   /*--------------------------------------------------------------------------*/
25428
25429   QUnit.module('lodash.xorBy');
25430
25431   (function() {
25432     QUnit.test('should accept an `iteratee` argument', function(assert) {
25433       assert.expect(2);
25434
25435       var actual = _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
25436       assert.deepEqual(actual, [1.2, 3.4]);
25437
25438       actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
25439       assert.deepEqual(actual, [{ 'x': 2 }]);
25440     });
25441
25442     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
25443       assert.expect(1);
25444
25445       var args;
25446
25447       _.xorBy([2.1, 1.2], [2.3, 3.4], function() {
25448         args || (args = slice.call(arguments));
25449       });
25450
25451       assert.deepEqual(args, [2.3]);
25452     });
25453   }());
25454
25455   /*--------------------------------------------------------------------------*/
25456
25457   QUnit.module('lodash.xorWith');
25458
25459   (function() {
25460     QUnit.test('should work with a `comparator` argument', function(assert) {
25461       assert.expect(1);
25462
25463       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
25464           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
25465           actual = _.xorWith(objects, others, lodashStable.isEqual);
25466
25467       assert.deepEqual(actual, [objects[1], others[0]]);
25468     });
25469   }());
25470
25471   /*--------------------------------------------------------------------------*/
25472
25473   QUnit.module('zipObject methods');
25474
25475   lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
25476     var func = _[methodName],
25477         object = { 'barney': 36, 'fred': 40 },
25478         isDeep = methodName == 'zipObjectDeep';
25479
25480     QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
25481       assert.expect(1);
25482
25483       var actual = func(['barney', 'fred'], [36, 40]);
25484       assert.deepEqual(actual, object);
25485     });
25486
25487     QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
25488       assert.expect(1);
25489
25490       assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
25491     });
25492
25493     QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
25494       assert.expect(1);
25495
25496       assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
25497     });
25498
25499     QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
25500       assert.expect(2);
25501
25502       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
25503         var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
25504         assert.deepEqual(func([path], [1]), expected);
25505       });
25506     });
25507
25508     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
25509       assert.expect(1);
25510
25511       if (!isNpm) {
25512         var values = lodashStable.range(LARGE_ARRAY_SIZE),
25513             props = lodashStable.map(values, function(value) { return 'key' + value; }),
25514             actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
25515
25516         assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
25517       }
25518       else {
25519         skipAssert(assert);
25520       }
25521     });
25522   });
25523
25524   /*--------------------------------------------------------------------------*/
25525
25526   QUnit.module('lodash.zipWith');
25527
25528   (function() {
25529     QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
25530       assert.expect(2);
25531
25532       var array1 = [1, 2, 3],
25533           array2 = [4, 5, 6],
25534           array3 = [7, 8, 9];
25535
25536       var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
25537         return a + b + c;
25538       });
25539
25540       assert.deepEqual(actual, [12, 15, 18]);
25541
25542       var actual = _.zipWith(array1, [], function(a, b) {
25543         return a + (b || 0);
25544       });
25545
25546       assert.deepEqual(actual, [1, 2, 3]);
25547     });
25548
25549     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
25550       assert.expect(1);
25551
25552       var args;
25553
25554       _.zipWith([1, 2], [3, 4], [5, 6], function() {
25555         args || (args = slice.call(arguments));
25556       });
25557
25558       assert.deepEqual(args, [1, 3, 5]);
25559     });
25560
25561     QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
25562       assert.expect(1);
25563
25564       var array1 = [1, 2],
25565           array2 = [3, 4],
25566           values = [, null, undefined],
25567           expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
25568
25569       var actual = lodashStable.map(values, function(value, index) {
25570         return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
25571       });
25572
25573       assert.deepEqual(actual, expected);
25574     });
25575   }());
25576
25577   /*--------------------------------------------------------------------------*/
25578
25579   QUnit.module('lodash.unzip and lodash.zip');
25580
25581   lodashStable.each(['unzip', 'zip'], function(methodName, index) {
25582     var func = _[methodName];
25583     func = lodashStable.bind(index ? func.apply : func.call, func, null);
25584
25585     var object = {
25586       'an empty array': [
25587         [],
25588         []
25589       ],
25590       '0-tuples': [
25591         [[], []],
25592         []
25593       ],
25594       '2-tuples': [
25595         [['barney', 'fred'], [36, 40]],
25596         [['barney', 36], ['fred', 40]]
25597       ],
25598       '3-tuples': [
25599         [['barney', 'fred'], [36, 40], [false, true]],
25600         [['barney', 36, false], ['fred', 40, true]]
25601       ]
25602     };
25603
25604     lodashStable.forOwn(object, function(pair, key) {
25605       QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
25606         assert.expect(2);
25607
25608         var actual = func(pair[0]);
25609         assert.deepEqual(actual, pair[1]);
25610         assert.deepEqual(func(actual), actual.length ? pair[0] : []);
25611       });
25612     });
25613
25614     QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
25615       assert.expect(4);
25616
25617       var pair = [
25618         [['barney', 36], ['fred', 40, false]],
25619         [['barney', 'fred'], [36, 40], [undefined, false]]
25620       ];
25621
25622       var actual = func(pair[0]);
25623       assert.ok('0' in actual[2]);
25624       assert.deepEqual(actual, pair[1]);
25625
25626       actual = func(actual);
25627       assert.ok('2' in actual[0]);
25628       assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
25629     });
25630
25631     QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
25632       assert.expect(1);
25633
25634       var expected = lodashStable.map(falsey, stubArray);
25635
25636       var actual = lodashStable.map(falsey, function(value) {
25637         return func([value, value, value]);
25638       });
25639
25640       assert.deepEqual(actual, expected);
25641     });
25642
25643     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25644       assert.expect(1);
25645
25646       var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
25647       assert.deepEqual(func(array), [[1, 3], [2, 4]]);
25648     });
25649
25650     QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
25651       assert.expect(1);
25652
25653       var expected = [['barney', 'fred'], [36, 40]];
25654       assert.deepEqual(func(func(func(func(expected)))), expected);
25655     });
25656   });
25657
25658   /*--------------------------------------------------------------------------*/
25659
25660   QUnit.module('lodash(...).commit');
25661
25662   (function() {
25663     QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
25664       assert.expect(4);
25665
25666       if (!isNpm) {
25667         var array = [1],
25668             wrapped = _(array).push(2).push(3);
25669
25670         assert.deepEqual(array, [1]);
25671
25672         var otherWrapper = wrapped.commit();
25673         assert.ok(otherWrapper instanceof _);
25674         assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
25675         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25676       }
25677       else {
25678         skipAssert(assert, 4);
25679       }
25680     });
25681
25682     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
25683       assert.expect(2);
25684
25685       if (!isNpm) {
25686         var wrapped = _([1]).chain().commit().head();
25687         assert.ok(wrapped instanceof _);
25688         assert.strictEqual(wrapped.value(), 1);
25689       }
25690       else {
25691         skipAssert(assert, 2);
25692       }
25693     });
25694   }());
25695
25696   /*--------------------------------------------------------------------------*/
25697
25698   QUnit.module('lodash(...).next');
25699
25700   lodashStable.each([false, true], function(implict) {
25701     function chain(value) {
25702       return implict ? _(value) : _.chain(value);
25703     }
25704
25705     var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
25706
25707     QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
25708       assert.expect(3);
25709
25710       if (!isNpm) {
25711         var wrapped = chain([1, 2]);
25712
25713         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
25714         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
25715         assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
25716       }
25717       else {
25718         skipAssert(assert, 3);
25719       }
25720     });
25721
25722     QUnit.test('should act as an iterable ' + chainType, function(assert) {
25723       assert.expect(2);
25724
25725       if (!isNpm && Symbol && Symbol.iterator) {
25726         var array = [1, 2],
25727             wrapped = chain(array);
25728
25729         assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
25730         assert.deepEqual(lodashStable.toArray(wrapped), array);
25731       }
25732       else {
25733         skipAssert(assert, 2);
25734       }
25735     });
25736
25737     QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
25738       assert.expect(3);
25739
25740       if (!isNpm && Array.from) {
25741         var hearts = '\ud83d\udc95',
25742             values = [[1], { 'a': 1 }, hearts];
25743
25744         lodashStable.each(values, function(value) {
25745           var wrapped = chain(value);
25746           assert.deepEqual(Array.from(wrapped), _.toArray(value));
25747         });
25748       }
25749       else {
25750         skipAssert(assert, 3);
25751       }
25752     });
25753
25754     QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
25755       assert.expect(4);
25756
25757       if (!isNpm && Symbol && Symbol.iterator) {
25758         var array = [1, 2],
25759             wrapped = chain(array);
25760
25761         assert.deepEqual(lodashStable.toArray(wrapped), array);
25762         assert.deepEqual(lodashStable.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
25763
25764         var other = wrapped.filter();
25765         assert.deepEqual(lodashStable.toArray(other), array, 'reset for new chain segments');
25766         assert.deepEqual(lodashStable.toArray(wrapped), [], 'iterator is still exhausted');
25767       }
25768       else {
25769         skipAssert(assert, 4);
25770       }
25771     });
25772
25773     QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
25774       assert.expect(3);
25775
25776       if (!isNpm && Symbol && Symbol.iterator) {
25777         var array = lodashStable.range(LARGE_ARRAY_SIZE),
25778             predicate = function(value) { values.push(value); return isEven(value); },
25779             values = [],
25780             wrapped = chain(array);
25781
25782         assert.deepEqual(lodashStable.toArray(wrapped), array);
25783
25784         wrapped = wrapped.filter(predicate);
25785         assert.deepEqual(lodashStable.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
25786         assert.deepEqual(values, array, 'memoizes iterator values');
25787       }
25788       else {
25789         skipAssert(assert, 3);
25790       }
25791     });
25792   });
25793
25794   /*--------------------------------------------------------------------------*/
25795
25796   QUnit.module('lodash(...).plant');
25797
25798   (function() {
25799     QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
25800       assert.expect(2);
25801
25802       if (!isNpm) {
25803         var array1 = [5, null, 3, null, 1],
25804             array2 = [10, null, 8, null, 6],
25805             wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
25806             wrapped2 = wrapped1.plant(array2);
25807
25808         assert.deepEqual(wrapped2.value(), [36, 64]);
25809         assert.deepEqual(wrapped1.value(), [1, 9]);
25810       }
25811       else {
25812         skipAssert(assert, 2);
25813       }
25814     });
25815
25816     QUnit.test('should clone `chainAll` settings', function(assert) {
25817       assert.expect(1);
25818
25819       if (!isNpm) {
25820         var array1 = [2, 4],
25821             array2 = [6, 8],
25822             wrapped1 = _(array1).chain().map(square),
25823             wrapped2 = wrapped1.plant(array2);
25824
25825         assert.deepEqual(wrapped2.head().value(), 36);
25826       }
25827       else {
25828         skipAssert(assert);
25829       }
25830     });
25831
25832     QUnit.test('should reset iterator data on cloned sequences', function(assert) {
25833       assert.expect(3);
25834
25835       if (!isNpm && Symbol && Symbol.iterator) {
25836         var array1 = [2, 4],
25837             array2 = [6, 8],
25838             wrapped1 = _(array1).map(square);
25839
25840         assert.deepEqual(lodashStable.toArray(wrapped1), [4, 16]);
25841         assert.deepEqual(lodashStable.toArray(wrapped1), []);
25842
25843         var wrapped2 = wrapped1.plant(array2);
25844         assert.deepEqual(lodashStable.toArray(wrapped2), [36, 64]);
25845       }
25846       else {
25847         skipAssert(assert, 3);
25848       }
25849     });
25850   }());
25851
25852   /*--------------------------------------------------------------------------*/
25853
25854   QUnit.module('lodash(...).pop');
25855
25856   (function() {
25857     QUnit.test('should remove elements from the end of `array`', function(assert) {
25858       assert.expect(5);
25859
25860       if (!isNpm) {
25861         var array = [1, 2],
25862             wrapped = _(array);
25863
25864         assert.strictEqual(wrapped.pop(), 2);
25865         assert.deepEqual(wrapped.value(), [1]);
25866         assert.strictEqual(wrapped.pop(), 1);
25867
25868         var actual = wrapped.value();
25869         assert.strictEqual(actual, array);
25870         assert.deepEqual(actual, []);
25871       }
25872       else {
25873         skipAssert(assert, 5);
25874       }
25875     });
25876
25877     QUnit.test('should accept falsey arguments', function(assert) {
25878       assert.expect(1);
25879
25880       if (!isNpm) {
25881         var expected = lodashStable.map(falsey, stubTrue);
25882
25883         var actual = lodashStable.map(falsey, function(value, index) {
25884           try {
25885             var result = index ? _(value).pop() : _().pop();
25886             return result === undefined;
25887           } catch (e) {}
25888         });
25889
25890         assert.deepEqual(actual, expected);
25891       }
25892       else {
25893         skipAssert(assert);
25894       }
25895     });
25896   }());
25897
25898   /*--------------------------------------------------------------------------*/
25899
25900   QUnit.module('lodash(...).push');
25901
25902   (function() {
25903     QUnit.test('should append elements to `array`', function(assert) {
25904       assert.expect(2);
25905
25906       if (!isNpm) {
25907         var array = [1],
25908             wrapped = _(array).push(2, 3),
25909             actual = wrapped.value();
25910
25911         assert.strictEqual(actual, array);
25912         assert.deepEqual(actual, [1, 2, 3]);
25913       }
25914       else {
25915         skipAssert(assert, 2);
25916       }
25917     });
25918
25919     QUnit.test('should accept falsey arguments', function(assert) {
25920       assert.expect(1);
25921
25922       if (!isNpm) {
25923         var expected = lodashStable.map(falsey, stubTrue);
25924
25925         var actual = lodashStable.map(falsey, function(value, index) {
25926           try {
25927             var result = index ? _(value).push(1).value() : _().push(1).value();
25928             return lodashStable.eq(result, value);
25929           } catch (e) {}
25930         });
25931
25932         assert.deepEqual(actual, expected);
25933       }
25934       else {
25935         skipAssert(assert);
25936       }
25937     });
25938   }());
25939
25940   /*--------------------------------------------------------------------------*/
25941
25942   QUnit.module('lodash(...).shift');
25943
25944   (function() {
25945     QUnit.test('should remove elements from the front of `array`', function(assert) {
25946       assert.expect(5);
25947
25948       if (!isNpm) {
25949         var array = [1, 2],
25950             wrapped = _(array);
25951
25952         assert.strictEqual(wrapped.shift(), 1);
25953         assert.deepEqual(wrapped.value(), [2]);
25954         assert.strictEqual(wrapped.shift(), 2);
25955
25956         var actual = wrapped.value();
25957         assert.strictEqual(actual, array);
25958         assert.deepEqual(actual, []);
25959       }
25960       else {
25961         skipAssert(assert, 5);
25962       }
25963     });
25964
25965     QUnit.test('should accept falsey arguments', function(assert) {
25966       assert.expect(1);
25967
25968       if (!isNpm) {
25969         var expected = lodashStable.map(falsey, stubTrue);
25970
25971         var actual = lodashStable.map(falsey, function(value, index) {
25972           try {
25973             var result = index ? _(value).shift() : _().shift();
25974             return result === undefined;
25975           } catch (e) {}
25976         });
25977
25978         assert.deepEqual(actual, expected);
25979       }
25980       else {
25981         skipAssert(assert);
25982       }
25983     });
25984   }());
25985
25986   /*--------------------------------------------------------------------------*/
25987
25988   QUnit.module('lodash(...).sort');
25989
25990   (function() {
25991     QUnit.test('should return the wrapped sorted `array`', function(assert) {
25992       assert.expect(2);
25993
25994       if (!isNpm) {
25995         var array = [3, 1, 2],
25996             wrapped = _(array).sort(),
25997             actual = wrapped.value();
25998
25999         assert.strictEqual(actual, array);
26000         assert.deepEqual(actual, [1, 2, 3]);
26001       }
26002       else {
26003         skipAssert(assert, 2);
26004       }
26005     });
26006
26007     QUnit.test('should accept falsey arguments', function(assert) {
26008       assert.expect(1);
26009
26010       if (!isNpm) {
26011         var expected = lodashStable.map(falsey, stubTrue);
26012
26013         var actual = lodashStable.map(falsey, function(value, index) {
26014           try {
26015             var result = index ? _(value).sort().value() : _().sort().value();
26016             return lodashStable.eq(result, value);
26017           } catch (e) {}
26018         });
26019
26020         assert.deepEqual(actual, expected);
26021       }
26022       else {
26023         skipAssert(assert);
26024       }
26025     });
26026   }());
26027
26028   /*--------------------------------------------------------------------------*/
26029
26030   QUnit.module('lodash(...).splice');
26031
26032   (function() {
26033     QUnit.test('should support removing and inserting elements', function(assert) {
26034       assert.expect(5);
26035
26036       if (!isNpm) {
26037         var array = [1, 2],
26038             wrapped = _(array);
26039
26040         assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
26041         assert.deepEqual(wrapped.value(), [1, 3]);
26042         assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
26043
26044         var actual = wrapped.value();
26045         assert.strictEqual(actual, array);
26046         assert.deepEqual(actual, []);
26047       }
26048       else {
26049         skipAssert(assert, 5);
26050       }
26051     });
26052
26053     QUnit.test('should accept falsey arguments', function(assert) {
26054       assert.expect(1);
26055
26056       if (!isNpm) {
26057         var expected = lodashStable.map(falsey, stubTrue);
26058
26059         var actual = lodashStable.map(falsey, function(value, index) {
26060           try {
26061             var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
26062             return lodashStable.isEqual(result, []);
26063           } catch (e) {}
26064         });
26065
26066         assert.deepEqual(actual, expected);
26067       }
26068       else {
26069         skipAssert(assert);
26070       }
26071     });
26072   }());
26073
26074   /*--------------------------------------------------------------------------*/
26075
26076   QUnit.module('lodash(...).unshift');
26077
26078   (function() {
26079     QUnit.test('should prepend elements to `array`', function(assert) {
26080       assert.expect(2);
26081
26082       if (!isNpm) {
26083         var array = [3],
26084             wrapped = _(array).unshift(1, 2),
26085             actual = wrapped.value();
26086
26087         assert.strictEqual(actual, array);
26088         assert.deepEqual(actual, [1, 2, 3]);
26089       }
26090       else {
26091         skipAssert(assert, 2);
26092       }
26093     });
26094
26095     QUnit.test('should accept falsey arguments', function(assert) {
26096       assert.expect(1);
26097
26098       if (!isNpm) {
26099         var expected = lodashStable.map(falsey, stubTrue);
26100
26101         var actual = lodashStable.map(falsey, function(value, index) {
26102           try {
26103             var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
26104             return lodashStable.eq(result, value);
26105           } catch (e) {}
26106         });
26107
26108         assert.deepEqual(actual, expected);
26109       }
26110       else {
26111         skipAssert(assert);
26112       }
26113     });
26114   }());
26115
26116   /*--------------------------------------------------------------------------*/
26117
26118   QUnit.module('lodash(...).value');
26119
26120   (function() {
26121     QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
26122       assert.expect(4);
26123
26124       if (!isNpm) {
26125         var array = [1],
26126             wrapped = _(array).push(2).push(3);
26127
26128         assert.deepEqual(array, [1]);
26129         assert.deepEqual(wrapped.value(), [1, 2, 3]);
26130         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
26131         assert.deepEqual(array, [1, 2, 3, 2, 3]);
26132       }
26133       else {
26134         skipAssert(assert, 4);
26135       }
26136     });
26137
26138     QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
26139       assert.expect(1);
26140
26141       if (!isNpm) {
26142         var wrapped = _(123);
26143         assert.strictEqual(Number(wrapped), 123);
26144       }
26145       else {
26146         skipAssert(assert);
26147       }
26148     });
26149
26150     QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
26151       assert.expect(1);
26152
26153       if (!isNpm && JSON) {
26154         var wrapped = _([1, 2, 3]);
26155         assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
26156       }
26157       else {
26158         skipAssert(assert);
26159       }
26160     });
26161
26162     QUnit.test('should be aliased', function(assert) {
26163       assert.expect(2);
26164
26165       if (!isNpm) {
26166         var expected = _.prototype.value;
26167         assert.strictEqual(_.prototype.toJSON, expected);
26168         assert.strictEqual(_.prototype.valueOf, expected);
26169       }
26170       else {
26171         skipAssert(assert, 2);
26172       }
26173     });
26174   }());
26175
26176   /*--------------------------------------------------------------------------*/
26177
26178   QUnit.module('lodash(...) methods that return the wrapped modified array');
26179
26180   (function() {
26181     var funcs = [
26182       'push',
26183       'reverse',
26184       'sort',
26185       'unshift'
26186     ];
26187
26188     lodashStable.each(funcs, function(methodName) {
26189       QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
26190         assert.expect(2);
26191
26192         if (!isNpm) {
26193           var array = [1, 2, 3],
26194               wrapped = _(array),
26195               actual = wrapped[methodName]();
26196
26197           assert.ok(actual instanceof _);
26198           assert.notStrictEqual(actual, wrapped);
26199         }
26200         else {
26201           skipAssert(assert, 2);
26202         }
26203       });
26204     });
26205   }());
26206
26207   /*--------------------------------------------------------------------------*/
26208
26209   QUnit.module('lodash(...) methods that return new wrapped values');
26210
26211   (function() {
26212     var funcs = [
26213       'castArray',
26214       'concat',
26215       'difference',
26216       'differenceBy',
26217       'differenceWith',
26218       'intersection',
26219       'intersectionBy',
26220       'intersectionWith',
26221       'pull',
26222       'pullAll',
26223       'pullAt',
26224       'sampleSize',
26225       'shuffle',
26226       'slice',
26227       'splice',
26228       'split',
26229       'toArray',
26230       'union',
26231       'unionBy',
26232       'unionWith',
26233       'uniq',
26234       'uniqBy',
26235       'uniqWith',
26236       'words',
26237       'xor',
26238       'xorBy',
26239       'xorWith'
26240     ];
26241
26242     lodashStable.each(funcs, function(methodName) {
26243       QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
26244         assert.expect(2);
26245
26246         if (!isNpm) {
26247           var value = methodName == 'split' ? 'abc' : [1, 2, 3],
26248               wrapped = _(value),
26249               actual = wrapped[methodName]();
26250
26251           assert.ok(actual instanceof _);
26252           assert.notStrictEqual(actual, wrapped);
26253         }
26254         else {
26255           skipAssert(assert, 2);
26256         }
26257       });
26258     });
26259   }());
26260
26261   /*--------------------------------------------------------------------------*/
26262
26263   QUnit.module('lodash(...) methods that return unwrapped values');
26264
26265   (function() {
26266     var funcs = [
26267       'add',
26268       'camelCase',
26269       'capitalize',
26270       'ceil',
26271       'clone',
26272       'deburr',
26273       'divide',
26274       'endsWith',
26275       'escape',
26276       'escapeRegExp',
26277       'every',
26278       'find',
26279       'floor',
26280       'has',
26281       'hasIn',
26282       'head',
26283       'includes',
26284       'isArguments',
26285       'isArray',
26286       'isArrayBuffer',
26287       'isArrayLike',
26288       'isBoolean',
26289       'isBuffer',
26290       'isDate',
26291       'isElement',
26292       'isEmpty',
26293       'isEqual',
26294       'isError',
26295       'isFinite',
26296       'isFunction',
26297       'isInteger',
26298       'isMap',
26299       'isNaN',
26300       'isNative',
26301       'isNil',
26302       'isNull',
26303       'isNumber',
26304       'isObject',
26305       'isObjectLike',
26306       'isPlainObject',
26307       'isRegExp',
26308       'isSafeInteger',
26309       'isSet',
26310       'isString',
26311       'isUndefined',
26312       'isWeakMap',
26313       'isWeakSet',
26314       'join',
26315       'kebabCase',
26316       'last',
26317       'lowerCase',
26318       'lowerFirst',
26319       'max',
26320       'maxBy',
26321       'min',
26322       'minBy',
26323       'multiply',
26324       'nth',
26325       'pad',
26326       'padEnd',
26327       'padStart',
26328       'parseInt',
26329       'pop',
26330       'random',
26331       'reduce',
26332       'reduceRight',
26333       'repeat',
26334       'replace',
26335       'round',
26336       'sample',
26337       'shift',
26338       'size',
26339       'snakeCase',
26340       'some',
26341       'startCase',
26342       'startsWith',
26343       'subtract',
26344       'sum',
26345       'toFinite',
26346       'toInteger',
26347       'toLower',
26348       'toNumber',
26349       'toSafeInteger',
26350       'toString',
26351       'toUpper',
26352       'trim',
26353       'trimEnd',
26354       'trimStart',
26355       'truncate',
26356       'unescape',
26357       'upperCase',
26358       'upperFirst'
26359     ];
26360
26361     lodashStable.each(funcs, function(methodName) {
26362       QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
26363         assert.expect(1);
26364
26365         if (!isNpm) {
26366           var actual = _()[methodName]();
26367           assert.notOk(actual instanceof _);
26368         }
26369         else {
26370           skipAssert(assert);
26371         }
26372       });
26373
26374       QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
26375         assert.expect(1);
26376
26377         if (!isNpm) {
26378           var actual = _().chain()[methodName]();
26379           assert.ok(actual instanceof _);
26380         }
26381         else {
26382           skipAssert(assert);
26383         }
26384       });
26385     });
26386   }());
26387
26388   /*--------------------------------------------------------------------------*/
26389
26390   QUnit.module('"Arrays" category methods');
26391
26392   (function() {
26393     var args = (function() { return arguments; }(1, null, [3], null, 5)),
26394         sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
26395         array = [1, 2, 3, 4, 5, 6];
26396
26397     QUnit.test('should work with `arguments` objects', function(assert) {
26398       assert.expect(30);
26399
26400       function message(methodName) {
26401         return '`_.' + methodName + '` should work with `arguments` objects';
26402       }
26403
26404       assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
26405       assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
26406
26407       assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
26408       assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
26409
26410       assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
26411       assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
26412       assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
26413       assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
26414       assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
26415       assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
26416       assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
26417       assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
26418       assert.deepEqual(_.head(args), 1, message('head'));
26419       assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
26420       assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
26421       assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
26422       assert.deepEqual(_.last(args), 5, message('last'));
26423       assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
26424       assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
26425       assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
26426       assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
26427       assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
26428       assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
26429       assert.deepEqual(_.take(args, 2), [1, null], message('take'));
26430       assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
26431       assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
26432       assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
26433       assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
26434       assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
26435       assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
26436     });
26437
26438     QUnit.test('should accept falsey primary arguments', function(assert) {
26439       assert.expect(4);
26440
26441       function message(methodName) {
26442         return '`_.' + methodName + '` should accept falsey primary arguments';
26443       }
26444
26445       assert.deepEqual(_.difference(null, array), [], message('difference'));
26446       assert.deepEqual(_.intersection(null, array), [], message('intersection'));
26447       assert.deepEqual(_.union(null, array), array, message('union'));
26448       assert.deepEqual(_.xor(null, array), array, message('xor'));
26449     });
26450
26451     QUnit.test('should accept falsey secondary arguments', function(assert) {
26452       assert.expect(3);
26453
26454       function message(methodName) {
26455         return '`_.' + methodName + '` should accept falsey secondary arguments';
26456       }
26457
26458       assert.deepEqual(_.difference(array, null), array, message('difference'));
26459       assert.deepEqual(_.intersection(array, null), [], message('intersection'));
26460       assert.deepEqual(_.union(array, null), array, message('union'));
26461     });
26462   }());
26463
26464   /*--------------------------------------------------------------------------*/
26465
26466   QUnit.module('"Strings" category methods');
26467
26468   (function() {
26469     var stringMethods = [
26470       'camelCase',
26471       'capitalize',
26472       'escape',
26473       'kebabCase',
26474       'lowerCase',
26475       'lowerFirst',
26476       'pad',
26477       'padEnd',
26478       'padStart',
26479       'repeat',
26480       'snakeCase',
26481       'toLower',
26482       'toUpper',
26483       'trim',
26484       'trimEnd',
26485       'trimStart',
26486       'truncate',
26487       'unescape',
26488       'upperCase',
26489       'upperFirst'
26490     ];
26491
26492     lodashStable.each(stringMethods, function(methodName) {
26493       var func = _[methodName];
26494
26495       QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
26496         assert.expect(1);
26497
26498         var values = [, null, undefined, ''],
26499             expected = lodashStable.map(values, stubString);
26500
26501         var actual = lodashStable.map(values, function(value, index) {
26502           return index ? func(value) : func();
26503         });
26504
26505         assert.deepEqual(actual, expected);
26506       });
26507     });
26508   }());
26509
26510   /*--------------------------------------------------------------------------*/
26511
26512   QUnit.module('lodash methods');
26513
26514   (function() {
26515     var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
26516       return lodashStable.startsWith(methodName, '_');
26517     });
26518
26519     var checkFuncs = [
26520       'after',
26521       'ary',
26522       'before',
26523       'bind',
26524       'curry',
26525       'curryRight',
26526       'debounce',
26527       'defer',
26528       'delay',
26529       'flip',
26530       'flow',
26531       'flowRight',
26532       'memoize',
26533       'negate',
26534       'once',
26535       'partial',
26536       'partialRight',
26537       'rearg',
26538       'rest',
26539       'spread',
26540       'throttle',
26541       'unary'
26542     ];
26543
26544     var noBinding = [
26545       'flip',
26546       'memoize',
26547       'negate',
26548       'once',
26549       'overArgs',
26550       'partial',
26551       'partialRight',
26552       'rearg',
26553       'rest',
26554       'spread'
26555     ];
26556
26557     var rejectFalsey = [
26558       'tap',
26559       'thru'
26560     ].concat(checkFuncs);
26561
26562     var returnArrays = [
26563       'at',
26564       'chunk',
26565       'compact',
26566       'difference',
26567       'drop',
26568       'filter',
26569       'flatten',
26570       'functions',
26571       'initial',
26572       'intersection',
26573       'invokeMap',
26574       'keys',
26575       'map',
26576       'orderBy',
26577       'pull',
26578       'pullAll',
26579       'pullAt',
26580       'range',
26581       'rangeRight',
26582       'reject',
26583       'remove',
26584       'shuffle',
26585       'sortBy',
26586       'tail',
26587       'take',
26588       'times',
26589       'toArray',
26590       'toPairs',
26591       'toPairsIn',
26592       'union',
26593       'uniq',
26594       'values',
26595       'without',
26596       'xor',
26597       'zip'
26598     ];
26599
26600     var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
26601
26602     QUnit.test('should accept falsey arguments', function(assert) {
26603       assert.expect(314);
26604
26605       var arrays = lodashStable.map(falsey, stubArray);
26606
26607       lodashStable.each(acceptFalsey, function(methodName) {
26608         var expected = arrays,
26609             func = _[methodName],
26610             pass = true;
26611
26612         var actual = lodashStable.map(falsey, function(value, index) {
26613           try {
26614             return index ? func(value) : func();
26615           } catch (e) {
26616             pass = false;
26617           }
26618         });
26619
26620         if (methodName == 'noConflict') {
26621           root._ = oldDash;
26622         }
26623         else if (methodName == 'pull' || methodName == 'pullAll') {
26624           expected = falsey;
26625         }
26626         if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
26627           assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
26628         }
26629         assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
26630       });
26631
26632       // Skip tests for missing methods of modularized builds.
26633       lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
26634         if (!_[methodName]) {
26635           skipAssert(assert);
26636         }
26637       });
26638     });
26639
26640     QUnit.test('should return an array', function(assert) {
26641       assert.expect(70);
26642
26643       var array = [1, 2, 3];
26644
26645       lodashStable.each(returnArrays, function(methodName) {
26646         var actual,
26647             func = _[methodName];
26648
26649         switch (methodName) {
26650           case 'invokeMap':
26651             actual = func(array, 'toFixed');
26652             break;
26653           case 'sample':
26654             actual = func(array, 1);
26655             break;
26656           default:
26657             actual = func(array);
26658         }
26659         assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
26660
26661         var isPull = methodName == 'pull' || methodName == 'pullAll';
26662         assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
26663       });
26664     });
26665
26666     QUnit.test('should throw an error for falsey arguments', function(assert) {
26667       assert.expect(24);
26668
26669       lodashStable.each(rejectFalsey, function(methodName) {
26670         var expected = lodashStable.map(falsey, stubTrue),
26671             func = _[methodName];
26672
26673         var actual = lodashStable.map(falsey, function(value, index) {
26674           var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
26675
26676           try {
26677             index ? func(value) : func();
26678           } catch (e) {
26679             pass = !pass && (e instanceof TypeError) &&
26680               (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
26681           }
26682           return pass;
26683         });
26684
26685         assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
26686       });
26687     });
26688
26689     QUnit.test('should not set a `this` binding', function(assert) {
26690       assert.expect(30);
26691
26692       lodashStable.each(noBinding, function(methodName) {
26693         var fn = function() { return this.a; },
26694             func = _[methodName],
26695             isNegate = methodName == 'negate',
26696             object = { 'a': 1 },
26697             expected = isNegate ? false : 1;
26698
26699         var wrapper = func(_.bind(fn, object));
26700         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
26701
26702         wrapper = _.bind(func(fn), object);
26703         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
26704
26705         object.wrapper = func(fn);
26706         assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
26707       });
26708     });
26709
26710     QUnit.test('should not contain minified method names (test production builds)', function(assert) {
26711       assert.expect(1);
26712
26713       var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
26714       assert.ok(lodashStable.every(_.functions(_), function(methodName) {
26715         return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
26716       }));
26717     });
26718   }());
26719
26720   /*--------------------------------------------------------------------------*/
26721
26722   QUnit.config.asyncRetries = 10;
26723   QUnit.config.hidepassed = true;
26724
26725   if (!document) {
26726     QUnit.config.noglobals = true;
26727     QUnit.load();
26728   }
26729 }.call(this));