Built motion from commit fd239ea.|0.0.31
[motion.git] / public / bower_components / lodash / test / test.js
1 ;(function() {
2
3   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
4   var undefined;
5
6   /** Used to detect when a function becomes hot. */
7   var HOT_COUNT = 150;
8
9   /** Used as the size to cover large array optimizations. */
10   var LARGE_ARRAY_SIZE = 200;
11
12   /** Used as the `TypeError` message for "Functions" methods. */
13   var FUNC_ERROR_TEXT = 'Expected a function';
14
15   /** Used as references for various `Number` constants. */
16   var MAX_SAFE_INTEGER = 9007199254740991,
17       MAX_INTEGER = 1.7976931348623157e+308;
18
19   /** Used as references for the maximum length and index of an array. */
20   var MAX_ARRAY_LENGTH = 4294967295,
21       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
22
23   /** `Object#toString` result references. */
24   var funcTag = '[object Function]',
25       numberTag = '[object Number]',
26       objectTag = '[object Object]';
27
28   /** Used as a reference to the global object. */
29   var root = (typeof global == 'object' && global) || this;
30
31   /** Used to store lodash to test for bad extensions/shims. */
32   var lodashBizarro = root.lodashBizarro;
33
34   /** Used for native method references. */
35   var arrayProto = Array.prototype,
36       errorProto = Error.prototype,
37       funcProto = Function.prototype,
38       objectProto = Object.prototype,
39       numberProto = Number.prototype,
40       stringProto = String.prototype;
41
42   /** Method and object shortcuts. */
43   var phantom = root.phantom,
44       amd = root.define && define.amd,
45       argv = root.process && process.argv,
46       ArrayBuffer = root.ArrayBuffer,
47       defineProperty = Object.defineProperty,
48       document = !phantom && root.document,
49       body = root.document && root.document.body,
50       create = Object.create,
51       fnToString = funcProto.toString,
52       freeze = Object.freeze,
53       identity = function(value) { return value; },
54       JSON = root.JSON,
55       Map = root.Map,
56       noop = function() {},
57       objToString = objectProto.toString,
58       params = argv,
59       push = arrayProto.push,
60       realm = {},
61       Set = root.Set,
62       slice = arrayProto.slice,
63       Symbol = root.Symbol,
64       symbol = Symbol ? Symbol('a') : undefined,
65       Uint8Array = root.Uint8Array,
66       WeakMap = root.WeakMap;
67
68   /** Math helpers. */
69   var add = function(x, y) { return x + y; },
70       doubled = function(n) { return n * 2; },
71       isEven = function(n) { return n % 2 == 0; },
72       square = function(n) { return n * n; };
73
74   /** Constant functions. */
75   var alwaysA = function() { return 'a'; },
76       alwaysB = function() { return 'b'; },
77       alwaysC = function() { return 'c'; };
78
79   var alwaysTrue = function() { return true; },
80       alwaysFalse = function() { return false; };
81
82   var alwaysNaN = function() { return NaN; },
83       alwaysNull = function() { return null; },
84       alwaysUndefined = function() { return undefined; };
85
86   var alwaysZero = function() { return 0; },
87       alwaysOne = function() { return 1; },
88       alwaysTwo = function() { return 2; },
89       alwaysThree = function() { return 3; },
90       alwaysFour = function() { return 4; };
91
92   var alwaysEmptyArray = function() { return []; },
93       alwaysEmptyObject = function() { return {}; },
94       alwaysEmptyString = function() { return ''; };
95
96   /** The file path of the lodash file to test. */
97   var filePath = (function() {
98     var min = 2,
99         result = params || [];
100
101     if (phantom) {
102       min = 0;
103       result = params = phantom.args || require('system').args;
104     }
105     var last = result[result.length - 1];
106     result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
107
108     if (!amd) {
109       try {
110         result = require('fs').realpathSync(result);
111       } catch (e) {}
112
113       try {
114         result = require.resolve(result);
115       } catch (e) {}
116     }
117     return result;
118   }());
119
120   /** The `ui` object. */
121   var ui = root.ui || (root.ui = {
122     'buildPath': filePath,
123     'loaderPath': '',
124     'isModularize': /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test(filePath),
125     'isStrict': /\bes6?\b/.test(filePath),
126     'urlParams': {}
127   });
128
129   /** The basename of the lodash file to test. */
130   var basename = /[\w.-]+$/.exec(filePath)[0];
131
132   /** Used to indicate testing a modularized build. */
133   var isModularize = ui.isModularize;
134
135   /** Detect if testing `npm` modules. */
136   var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
137
138   /** Detect if running in PhantomJS. */
139   var isPhantom = phantom || (typeof callPhantom == 'function');
140
141   /** Detect if lodash is in strict mode. */
142   var isStrict = ui.isStrict;
143
144   /*--------------------------------------------------------------------------*/
145
146   // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
147   root.msWDfn = undefined;
148
149   // Exit early if going to run tests in a PhantomJS web page.
150   if (phantom && isModularize) {
151     var page = require('webpage').create();
152
153     page.onCallback = function(details) {
154       var coverage = details.coverage;
155       if (coverage) {
156         var fs = require('fs'),
157             cwd = fs.workingDirectory,
158             sep = fs.separator;
159
160         fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
161       }
162       phantom.exit(details.failed ? 1 : 0);
163     };
164
165     page.onConsoleMessage = function(message) {
166       console.log(message);
167     };
168
169     page.onInitialized = function() {
170       page.evaluate(function() {
171         document.addEventListener('DOMContentLoaded', function() {
172           QUnit.done(function(details) {
173             details.coverage = window.__coverage__;
174             callPhantom(details);
175           });
176         });
177       });
178     };
179
180     page.open(filePath, function(status) {
181       if (status != 'success') {
182         console.log('PhantomJS failed to load page: ' + filePath);
183         phantom.exit(1);
184       }
185     });
186
187     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
188     return;
189   }
190
191   /*--------------------------------------------------------------------------*/
192
193   /** Used to test Web Workers. */
194   var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
195     (document && document.origin != 'null') && root.Worker;
196
197   /** Used to test host objects in IE. */
198   try {
199     var xml = new ActiveXObject('Microsoft.XMLDOM');
200   } catch (e) {}
201
202   /** Poison the free variable `root` in Node.js */
203   try {
204     defineProperty(global.root, 'root', {
205       'configurable': false,
206       'enumerable': false,
207       'get': function() { throw new ReferenceError; }
208     });
209   } catch (e) {}
210
211   /** Use a single "load" function. */
212   var load = (!amd && typeof require == 'function')
213     ? require
214     : noop;
215
216   /** The unit testing framework. */
217   var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qunit.js'));
218
219   /** Load stable Lodash and QUnit Extras. */
220   var lodashStable = root.lodashStable || load('../node_modules/lodash/index.js');
221   if (lodashStable) {
222     lodashStable = lodashStable.runInContext(root);
223   }
224   var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
225   if (QUnitExtras) {
226     QUnitExtras.runInContext(root);
227   }
228
229   /** The `lodash` function to test. */
230   var _ = root._ || (root._ = (
231     _ = load(filePath),
232     _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default']) || _,
233     (_.runInContext ? _.runInContext(root) : _)
234   ));
235
236   /** Used to detect instrumented istanbul code coverage runs. */
237   var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
238     return /^(?:\$\$cov_\d+\$\$)$/.test(key);
239   })];
240
241   /** Used to restore the `_` reference. */
242   var oldDash = root._;
243
244   /** Used to test generator functions. */
245   var generator = lodashStable.attempt(function() {
246     return Function('return function*(){}');
247   });
248
249   /** List of latin-1 supplementary letters to basic latin letters. */
250   var burredLetters = [
251     '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce',
252     '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
253     '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
254     '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
255   ];
256
257   /** List of combining diacritical marks. */
258   var comboMarks = [
259     '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
260     '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
261     '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
262     '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
263     '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
264     '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
265     '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
266     '\ufe20', '\ufe21', '\ufe22', '\ufe23'
267   ];
268
269   /** List of `burredLetters` translated to basic latin letters. */
270   var deburredLetters = [
271     'A',  'A', 'A', 'A', 'A', 'A', 'Ae', 'C',  'E', 'E', 'E', 'E', 'I', 'I', 'I',
272     'I',  'D', 'N', 'O', 'O', 'O', 'O',  'O',  'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
273     'ss', 'a', 'a', 'a', 'a', 'a', 'a',  'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i',  'i',
274     'i',  'd', 'n', 'o', 'o', 'o', 'o',  'o',  'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y'
275   ];
276
277   /** List of emoji modifiers. */
278   var emojiModifiers = [
279     '\ud83c\udffb',
280     '\ud83c\udffc',
281     '\ud83c\udffd',
282     '\ud83c\udffe',
283     '\ud83c\udfff'
284   ];
285
286   /** Used to specify the emoji style glyph variant of characters. */
287   var emojiVar = '\ufe0f';
288
289   /** Used to provide falsey values to methods. */
290   var falsey = [, '', 0, false, NaN, null, undefined];
291
292   /** Used to provide empty values to methods. */
293   var empties = [[], {}].concat(falsey.slice(1));
294
295   /** Used to test error objects. */
296   var errors = [
297     new Error,
298     new EvalError,
299     new RangeError,
300     new ReferenceError,
301     new SyntaxError,
302     new TypeError,
303     new URIError
304   ];
305
306   /** Used to check whether methods support typed arrays. */
307   var typedArrays = [
308     'Float32Array',
309     'Float64Array',
310     'Int8Array',
311     'Int16Array',
312     'Int32Array',
313     'Uint8Array',
314     'Uint8ClampedArray',
315     'Uint16Array',
316     'Uint32Array'
317   ];
318
319   /**
320    * Used to check for problems removing whitespace. For a whitespace reference,
321    * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
322    */
323   var whitespace = lodashStable.filter([
324     // Basic whitespace characters.
325     ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
326
327     // Line terminators.
328     '\n', '\r', '\u2028', '\u2029',
329
330     // Unicode category "Zs" space separators.
331     '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
332     '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
333   ],
334   function(chr) { return /\s/.exec(chr); })
335   .join('');
336
337   /**
338    * Extracts the unwrapped value from its wrapper.
339    *
340    * @private
341    * @param {Object} wrapper The wrapper to unwrap.
342    * @returns {*} Returns the unwrapped value.
343    */
344   function getUnwrappedValue(wrapper) {
345     var index = -1,
346         actions = wrapper.__actions__,
347         length = actions.length,
348         result = wrapper.__wrapped__;
349
350     while (++index < length) {
351       var args = [result],
352           action = actions[index];
353
354       push.apply(args, action.args);
355       result = action.func.apply(action.thisArg, args);
356     }
357     return result;
358   }
359
360   /**
361    * Removes all own enumerable properties from a given object.
362    *
363    * @private
364    * @param {Object} object The object to empty.
365    */
366   function emptyObject(object) {
367     lodashStable.forOwn(object, function(value, key, object) {
368       delete object[key];
369     });
370   }
371
372   /**
373    * Sets a non-enumerable property value on `object`.
374    *
375    * Note: This function is used to avoid a bug in older versions of V8 where
376    * overwriting non-enumerable built-ins makes them enumerable.
377    * See https://code.google.com/p/v8/issues/detail?id=1623
378    *
379    * @private
380    * @param {Object} object The object modify.
381    * @param {string} key The name of the property to set.
382    * @param {*} value The property value.
383    */
384   function setProperty(object, key, value) {
385     try {
386       defineProperty(object, key, {
387         'configurable': true,
388         'enumerable': false,
389         'writable': true,
390         'value': value
391       });
392     } catch (e) {
393       object[key] = value;
394     }
395     return object;
396   }
397
398   /**
399    * Skips a given number of tests with a passing result.
400    *
401    * @private
402    * @param {Object} assert The QUnit assert object.
403    * @param {number} [count=1] The number of tests to skip.
404    */
405   function skipTest(assert, count) {
406     count || (count = 1);
407     while (count--) {
408       assert.ok(true, 'test skipped');
409     }
410   }
411
412   /*--------------------------------------------------------------------------*/
413
414   // Add bizarro values.
415   (function() {
416     if (document || (typeof require != 'function')) {
417       return;
418     }
419     var nativeString = fnToString.call(toString),
420         reToString = /toString/g;
421
422     function createToString(funcName) {
423       return lodashStable.constant(nativeString.replace(reToString, funcName));
424     }
425
426     // Allow bypassing native checks.
427     setProperty(funcProto, 'toString', function wrapper() {
428       setProperty(funcProto, 'toString', fnToString);
429       var result = _.has(this, 'toString') ? this.toString() : fnToString.call(this);
430       setProperty(funcProto, 'toString', wrapper);
431       return result;
432     });
433
434     // Add prototype extensions.
435     funcProto._method = noop;
436
437     // Set bad shims.
438     var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
439     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
440       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
441     });
442
443     if (Map) {
444       setProperty(root, 'Map', (function() {
445         var count = 0;
446         return function() {
447           if (count++) {
448             return new Map;
449           }
450           var result = {};
451           setProperty(root, 'Map', Map);
452           return result;
453         };
454       }()));
455
456       setProperty(root.Map, 'toString', createToString('Map'));
457     }
458     setProperty(Object, 'create', noop);
459
460     var _getOwnPropertySymbols = Object.getOwnPropertySymbols;
461     setProperty(Object, 'getOwnPropertySymbols', undefined);
462
463     setProperty(root, 'Set', noop);
464     setProperty(root, 'Symbol', undefined);
465     setProperty(root, 'WeakMap', noop);
466
467     // Fake `WinRTError`.
468     setProperty(root, 'WinRTError', Error);
469
470     // Clear cache so lodash can be reloaded.
471     emptyObject(require.cache);
472
473     // Load lodash and expose it to the bad extensions/shims.
474     lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
475     root._ = oldDash;
476
477     // Restore built-in methods.
478     if (_getOwnPropertySymbols) {
479       Object.getOwnPropertySymbols = _getOwnPropertySymbols;
480     } else {
481       delete Object.getOwnPropertySymbols;
482     }
483     if (Map) {
484       setProperty(root, 'Map', Map);
485     } else {
486       delete root.Map;
487     }
488     if (Set) {
489       setProperty(root, 'Set', Set);
490     } else {
491       delete root.Set;
492     }
493     if (Symbol) {
494       setProperty(root, 'Symbol', Symbol);
495     } else {
496       delete root.Symbol;
497     }
498     if (WeakMap) {
499       setProperty(root, 'WeakMap', WeakMap);
500     } else {
501       delete root.WeakMap;
502     }
503     setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
504     setProperty(Object, 'create', create);
505
506     delete root.WinRTError;
507     delete funcProto._method;
508   }());
509
510   // Add other realm values from the `vm` module.
511   lodashStable.attempt(function() {
512     lodashStable.assign(realm, require('vm').runInNewContext([
513       '(function() {',
514       '  var noop = function() {},',
515       '      root = this;',
516       '',
517       '  var object = {',
518       "    'arguments': (function() { return arguments; }(1, 2, 3)),",
519       "    'array': [1, 2, 3],",
520       "    'arrayBuffer': new (root.ArrayBuffer || noop),",
521       "    'boolean': Object(false),",
522       "    'date': new Date,",
523       "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
524       "    'function': noop,",
525       "    'map': new (root.Map || noop),",
526       "    'nan': NaN,",
527       "    'null': null,",
528       "    'number': Object(0),",
529       "    'object': { 'a': 1, 'b': 2, 'c': 3 },",
530       "    'regexp': /x/,",
531       "    'set': new (root.Set || noop),",
532       "    'string': Object('a'),",
533       "    'symbol': Object((root.Symbol || noop)()),",
534       "    'undefined': undefined",
535       '  };',
536       '',
537       "  ['" + typedArrays.join("', '") + "'].forEach(function(type) {",
538       "    var Ctor = root[type]",
539       '    if (Ctor) {',
540       "      object[type.toLowerCase()] = new Ctor(new ArrayBuffer(24));",
541       '    }',
542       "  });",
543       '',
544       '  return object;',
545       '}())'
546     ].join('\n')));
547   });
548
549   // Add other realm values from an iframe.
550   lodashStable.attempt(function() {
551     _._realm = realm;
552
553     var iframe = document.createElement('iframe');
554     iframe.frameBorder = iframe.height = iframe.width = 0;
555     body.appendChild(iframe);
556
557     var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
558     idoc.write([
559       '<script>',
560       'var _ = parent._;',
561       '',
562       '  var noop = function() {},',
563       '      root = this;',
564       '',
565       'var object = {',
566       "  'arguments': (function() { return arguments; }(1, 2, 3)),",
567       "  'array': [1, 2, 3],",
568       "  'arrayBuffer': new (root.ArrayBuffer || noop),",
569       "  'boolean': Object(false),",
570       "  'date': new Date,",
571       "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
572       "  'function': noop,",
573       "  'map': new (root.Map || noop),",
574       "  'nan': NaN,",
575       "  'null': null,",
576       "  'number': Object(0),",
577       "  'object': { 'a': 1, 'b': 2, 'c': 3 },",
578       "  'regexp': /x/,",
579       "  'set': new (root.Set || noop),",
580       "  'string': Object('a'),",
581       "  'symbol': Object((root.Symbol || noop)()),",
582       "  'undefined': undefined",
583       '};',
584       '',
585       "_.each(['" + typedArrays.join("', '") + "'], function(type) {",
586       '  var Ctor = root[type];',
587       '  if (Ctor) {',
588       "    object[type.toLowerCase()] = new Ctor(new ArrayBuffer(24));",
589       '  }',
590       '});',
591       '',
592       '_.assign(_._realm, object);',
593       '<\/script>'
594     ].join('\n'));
595
596     idoc.close();
597     delete _._realm;
598   });
599
600   // Add a web worker.
601   lodashStable.attempt(function() {
602     var worker = new Worker('./asset/worker.js?t=' + (+new Date));
603     worker.addEventListener('message', function(e) {
604       _._VERSION = e.data || '';
605     }, false);
606
607     worker.postMessage(ui.buildPath);
608   });
609
610   // Expose internal modules for better code coverage.
611   lodashStable.attempt(function() {
612     var path = require('path'),
613         basePath = path.dirname(filePath);
614
615     if (isModularize && !(amd || isNpm)) {
616       lodashStable.each([
617         'internal/baseEach',
618         'internal/isIndex',
619         'internal/isIterateeCall'
620       ], function(relPath) {
621         var func = require(path.join(basePath, relPath)),
622             funcName = path.basename(relPath);
623
624         _['_' + funcName] = func[funcName] || func['default'] || func;
625       });
626     }
627   });
628
629   /*--------------------------------------------------------------------------*/
630
631   if (params) {
632     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
633   }
634
635   QUnit.module(basename);
636
637   (function() {
638     QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
639       assert.expect(1);
640
641       if (amd) {
642         assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
643       }
644       else {
645         skipTest(assert);
646       }
647     });
648
649     QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
650       assert.expect(1);
651
652       if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
653         assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
654       } else {
655         skipTest(assert);
656       }
657     });
658
659     QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
660       assert.expect(1);
661
662       if (amd) {
663         assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
664       }
665       else {
666         skipTest(assert);
667       }
668     });
669
670     QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
671       assert.expect(1);
672
673       var done = assert.async();
674
675       if (Worker) {
676         var limit = 30000 / QUnit.config.asyncRetries,
677             start = +new Date;
678
679         var attempt = function() {
680           var actual = _._VERSION;
681           if ((new Date - start) < limit && typeof actual != 'string') {
682             setTimeout(attempt, 16);
683             return;
684           }
685           assert.strictEqual(actual, _.VERSION);
686           done();
687         };
688
689         attempt();
690       }
691       else {
692         skipTest(assert);
693         done();
694       }
695     });
696
697     QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
698       assert.expect(1);
699
700       if (lodashBizarro) {
701         assert.notOk('_method' in lodashBizarro);
702       }
703       else {
704         skipTest(assert);
705       }
706     });
707
708     QUnit.test('should avoid overwritten native methods', function(assert) {
709       assert.expect(6);
710
711       function message(lodashMethod, nativeMethod) {
712         return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
713       }
714
715       function Foo() { this.a = 1; }
716       Foo.prototype.b = 2;
717
718       var object = { 'a': 1 },
719           otherObject = { 'b': 2 },
720           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
721
722       if (lodashBizarro) {
723         try {
724           var actual = lodashBizarro.keysIn(new Foo).sort();
725         } catch (e) {
726           actual = null;
727         }
728         var label = message('_.keysIn', 'Object#propertyIsEnumerable');
729         assert.deepEqual(actual, ['a', 'b'], label);
730
731         try {
732           actual = [
733             lodashBizarro.difference([object, otherObject], largeArray),
734             lodashBizarro.intersection(largeArray, [object]),
735             lodashBizarro.uniq(largeArray)
736           ];
737         } catch (e) {
738           actual = null;
739         }
740         label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
741         assert.deepEqual(actual, [[otherObject], [object], [object]], label);
742
743         try {
744           if (Symbol) {
745             object[symbol] = {};
746           }
747           actual = [
748             lodashBizarro.clone(object),
749             lodashBizarro.cloneDeep(object)
750           ];
751         } catch (e) {
752           actual = null;
753         }
754         label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
755         assert.deepEqual(actual, [object, object], label);
756
757         try {
758           var symObject = Object(symbol);
759           symObject.constructor = Object;
760           actual = [
761             Symbol ? lodashBizarro.clone(symObject) : {},
762             Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
763             Symbol ? lodashBizarro.toString(symObject) : ''
764           ];
765         } catch (e) {
766           actual = null;
767         }
768         label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
769         assert.deepEqual(actual, [{}, false, ''], label);
770
771         try {
772           var map = new lodashBizarro.memoize.Cache;
773           actual = map.set('a', 1).get('a');
774         } catch (e) {
775           actual = null;
776         }
777         label = message('_.memoize.Cache', 'Map');
778         assert.deepEqual(actual, 1, label);
779
780         try {
781           map = new (Map || Object);
782           if (Symbol && Symbol.iterator) {
783             map[Symbol.iterator] = null;
784           }
785           actual = lodashBizarro.toArray(map);
786         } catch (e) {
787           actual = null;
788         }
789         label = message('_.toArray', 'Map');
790         assert.deepEqual(actual, [], label);
791       }
792       else {
793         skipTest(assert, 6);
794       }
795     });
796   }());
797
798   /*--------------------------------------------------------------------------*/
799
800   QUnit.module('isIndex');
801
802   (function() {
803     var func = _._isIndex;
804
805     QUnit.test('should return `true` for indexes', function(assert) {
806       assert.expect(1);
807
808       if (func) {
809         var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
810             expected = lodashStable.map(values, alwaysTrue);
811
812         var actual = lodashStable.map(values, function(args) {
813           return func.apply(undefined, args);
814         });
815
816         assert.deepEqual(actual, expected);
817       }
818       else {
819         skipTest(assert);
820       }
821     });
822
823     QUnit.test('should return `false` for non-indexes', function(assert) {
824       assert.expect(1);
825
826       if (func) {
827         var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
828             expected = lodashStable.map(values, alwaysFalse);
829
830         var actual = lodashStable.map(values, function(args) {
831           return func.apply(undefined, args);
832         });
833
834         assert.deepEqual(actual, expected);
835       }
836       else {
837         skipTest(assert);
838       }
839     });
840   }());
841
842   /*--------------------------------------------------------------------------*/
843
844   QUnit.module('isIterateeCall');
845
846   (function() {
847     var array = [1],
848         func = _._isIterateeCall,
849         object =  { 'a': 1 };
850
851     QUnit.test('should return `true` for iteratee calls', function(assert) {
852       assert.expect(3);
853
854       function Foo() {}
855       Foo.prototype.a = 1;
856
857       if (func) {
858         assert.strictEqual(func(1, 0, array), true);
859         assert.strictEqual(func(1, 'a', object), true);
860         assert.strictEqual(func(1, 'a', new Foo), true);
861       }
862       else {
863         skipTest(assert, 3);
864       }
865     });
866
867     QUnit.test('should return `false` for non-iteratee calls', function(assert) {
868       assert.expect(4);
869
870       if (func) {
871         assert.strictEqual(func(2, 0, array), false);
872         assert.strictEqual(func(1, 1.1, array), false);
873         assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
874         assert.strictEqual(func(1, 'b', object), false);
875       }
876       else {
877         skipTest(assert, 4);
878       }
879     });
880
881     QUnit.test('should work with `NaN` values', function(assert) {
882       assert.expect(2);
883
884       if (func) {
885         assert.strictEqual(func(NaN, 0, [NaN]), true);
886         assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
887       }
888       else {
889         skipTest(assert, 2);
890       }
891     });
892
893     QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
894       assert.expect(1);
895
896       if (func) {
897         try {
898           var actual = func(1, { 'toString': null }, [1]);
899         } catch (e) {
900           var message = e.message;
901         }
902         assert.strictEqual(actual, false, message || '');
903       }
904       else {
905         skipTest(assert);
906       }
907     });
908   }());
909
910   /*--------------------------------------------------------------------------*/
911
912   QUnit.module('lodash constructor');
913
914   (function() {
915     var values = empties.concat(true, 1, 'a'),
916         expected = lodashStable.map(values, alwaysTrue);
917
918     QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
919       assert.expect(1);
920
921       if (!isNpm) {
922         var actual = lodashStable.map(values, function(value) {
923           return _(value) instanceof _;
924         });
925
926         assert.deepEqual(actual, expected);
927       }
928       else {
929         skipTest(assert);
930       }
931     });
932
933     QUnit.test('should return provided `lodash` instances', function(assert) {
934       assert.expect(1);
935
936       if (!isNpm) {
937         var actual = lodashStable.map(values, function(value) {
938           var wrapped = _(value);
939           return _(wrapped) === wrapped;
940         });
941
942         assert.deepEqual(actual, expected);
943       }
944       else {
945         skipTest(assert);
946       }
947     });
948
949     QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
950       assert.expect(1);
951
952       if (!isNpm && lodashBizarro) {
953         var actual = lodashStable.map(values, function(value) {
954           var wrapped = _(lodashBizarro(value)),
955               unwrapped = wrapped.value();
956
957           return wrapped instanceof _ &&
958             ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
959         });
960
961         assert.deepEqual(actual, expected);
962       }
963       else {
964         skipTest(assert);
965       }
966     });
967   }());
968
969   /*--------------------------------------------------------------------------*/
970
971   QUnit.module('lodash.add');
972
973   (function() {
974     QUnit.test('should add two numbers', function(assert) {
975       assert.expect(3);
976
977       assert.strictEqual(_.add(6, 4), 10);
978       assert.strictEqual(_.add(-6, 4), -2);
979       assert.strictEqual(_.add(-6, -4), -10);
980     });
981
982     QUnit.test('should not coerce arguments to numbers', function(assert) {
983       assert.expect(2);
984
985       assert.strictEqual(_.add('6', '4'), '64');
986       assert.strictEqual(_.add('x', 'y'), 'xy');
987     });
988
989     QUnit.test('should work with only an `augend` or `addend`', function(assert) {
990       assert.expect(3);
991
992       assert.strictEqual(_.add(6), 6);
993       assert.strictEqual(_.add(6, undefined), 6);
994       assert.strictEqual(_.add(undefined, 4), 4);
995     });
996
997     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
998       assert.expect(1);
999
1000       if (!isNpm) {
1001         assert.strictEqual(_(1).add(2), 3);
1002       }
1003       else {
1004         skipTest(assert);
1005       }
1006     });
1007
1008     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1009       assert.expect(1);
1010
1011       if (!isNpm) {
1012         assert.ok(_(1).chain().add(2) instanceof _);
1013       }
1014       else {
1015         skipTest(assert);
1016       }
1017     });
1018   }());
1019
1020   /*--------------------------------------------------------------------------*/
1021
1022   QUnit.module('lodash.after');
1023
1024   (function() {
1025     function after(n, times) {
1026       var count = 0;
1027       lodashStable.times(times, _.after(n, function() { count++; }));
1028       return count;
1029     }
1030
1031     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1032       assert.expect(4);
1033
1034       assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1035       assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1036       assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1037       assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1038     });
1039
1040     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1041       assert.expect(1);
1042
1043       assert.strictEqual(after(NaN, 1), 1);
1044     });
1045
1046     QUnit.test('should not set a `this` binding', function(assert) {
1047       assert.expect(2);
1048
1049       var after = _.after(1, function(assert) { return ++this.count; }),
1050           object = { 'after': after, 'count': 0 };
1051
1052       object.after();
1053       assert.strictEqual(object.after(), 2);
1054       assert.strictEqual(object.count, 2);
1055     });
1056   }());
1057
1058   /*--------------------------------------------------------------------------*/
1059
1060   QUnit.module('lodash.ary');
1061
1062   (function() {
1063     function fn(a, b, c) {
1064       return slice.call(arguments);
1065     }
1066
1067     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1068       assert.expect(2);
1069
1070       var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1071       assert.deepEqual(actual, [6, 8, 10]);
1072
1073       var capped = _.ary(fn, 2);
1074       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1075     });
1076
1077     QUnit.test('should use `func.length` if `n` is not provided', function(assert) {
1078       assert.expect(1);
1079
1080       var capped = _.ary(fn);
1081       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1082     });
1083
1084     QUnit.test('should treat a negative `n` as `0`', function(assert) {
1085       assert.expect(1);
1086
1087       var capped = _.ary(fn, -1);
1088
1089       try {
1090         var actual = capped('a');
1091       } catch (e) {}
1092
1093       assert.deepEqual(actual, []);
1094     });
1095
1096     QUnit.test('should coerce `n` to an integer', function(assert) {
1097       assert.expect(1);
1098
1099       var values = ['1', 1.6, 'xyz'],
1100           expected = [['a'], ['a'], []];
1101
1102       var actual = lodashStable.map(values, function(n) {
1103         var capped = _.ary(fn, n);
1104         return capped('a', 'b');
1105       });
1106
1107       assert.deepEqual(actual, expected);
1108     });
1109
1110     QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
1111       assert.expect(1);
1112
1113       var capped = _.ary(fn, 3);
1114       assert.deepEqual(capped('a'), ['a']);
1115     });
1116
1117     QUnit.test('should use the existing `ary` if smaller', function(assert) {
1118       assert.expect(1);
1119
1120       var capped = _.ary(_.ary(fn, 1), 2);
1121       assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1122     });
1123
1124     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1125       assert.expect(1);
1126
1127       var funcs = lodashStable.map([fn], _.ary),
1128           actual = funcs[0]('a', 'b', 'c');
1129
1130       assert.deepEqual(actual, ['a', 'b', 'c']);
1131     });
1132
1133     QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1134       assert.expect(2);
1135
1136       var array = ['a', 'b', 'c'],
1137           includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1138
1139       assert.strictEqual(includes('b')(array, 2), true);
1140
1141       if (!isNpm) {
1142         includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1143         assert.strictEqual(includes('b')(array, 2), true);
1144       }
1145       else {
1146         skipTest(assert);
1147       }
1148     });
1149   }());
1150
1151   /*--------------------------------------------------------------------------*/
1152
1153   QUnit.module('lodash.assignIn');
1154
1155   (function() {
1156     QUnit.test('should be aliased', function(assert) {
1157       assert.expect(1);
1158
1159       assert.strictEqual(_.extend, _.assignIn);
1160     });
1161   }());
1162
1163   /*--------------------------------------------------------------------------*/
1164
1165   QUnit.module('lodash.assign and lodash.assignIn');
1166
1167   lodashStable.each(['assign', 'assignIn'], function(methodName) {
1168     var func = _[methodName];
1169
1170     QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1171       assert.expect(1);
1172
1173       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1174     });
1175
1176     QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1177       assert.expect(2);
1178
1179       var expected = { 'a': 1, 'b': 2, 'c': 3 };
1180       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1181       assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1182     });
1183
1184     QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1185       assert.expect(1);
1186
1187       var expected = { 'a': 3, 'b': 2, 'c': 1 };
1188       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1189     });
1190
1191     QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1192       assert.expect(1);
1193
1194       var expected = { 'a': null, 'b': undefined, 'c': null };
1195       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1196     });
1197
1198     QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1199       assert.expect(1);
1200
1201       var object = {};
1202
1203       var descriptor = {
1204         'configurable': true,
1205         'enumerable': true,
1206         'set': function() { throw new Error; }
1207       };
1208
1209       var source = {
1210         'a': 1,
1211         'b': undefined,
1212         'c': NaN,
1213         'd': undefined,
1214         'constructor': Object,
1215         'toString': lodashStable.constant('source')
1216       };
1217
1218       defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1219         'get': alwaysOne
1220       }));
1221
1222       defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1223         'get': alwaysUndefined
1224       }));
1225
1226       defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1227         'get': alwaysNaN
1228       }));
1229
1230       defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1231         'get': lodashStable.constant(Object)
1232       }));
1233
1234       try {
1235         var actual = func(object, source);
1236       } catch (e) {}
1237
1238       assert.deepEqual(actual, source);
1239     });
1240   });
1241
1242   /*--------------------------------------------------------------------------*/
1243
1244   QUnit.module('lodash.assignInWith');
1245
1246   (function() {
1247     QUnit.test('should be aliased', function(assert) {
1248       assert.expect(1);
1249
1250       assert.strictEqual(_.extendWith, _.assignInWith);
1251     });
1252   }());
1253
1254   /*--------------------------------------------------------------------------*/
1255
1256   QUnit.module('lodash.assignWith and lodash.assignInWith');
1257
1258   lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1259     var func = _[methodName];
1260
1261     QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1262       assert.expect(1);
1263
1264       var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1265         return a === undefined ? b : a;
1266       });
1267
1268       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1269     });
1270
1271     QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1272       assert.expect(1);
1273
1274       var expected = { 'a': undefined };
1275       assert.deepEqual(func({}, expected, alwaysUndefined), expected);
1276     });
1277   });
1278
1279   /*--------------------------------------------------------------------------*/
1280
1281   QUnit.module('lodash.at');
1282
1283   (function() {
1284     var args = arguments,
1285         array = ['a', 'b', 'c'],
1286         object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1287
1288     QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1289       assert.expect(1);
1290
1291       var actual = _.at(array, [0, 2]);
1292       assert.deepEqual(actual, ['a', 'c']);
1293     });
1294
1295     QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1296       assert.expect(1);
1297
1298       var actual = _.at(array, [2, 4, 0]);
1299       assert.deepEqual(actual, ['c', undefined, 'a']);
1300     });
1301
1302     QUnit.test('should work with non-index keys on array values', function(assert) {
1303       assert.expect(1);
1304
1305       var values = lodashStable.reject(empties, function(value) {
1306         return (value === 0) || lodashStable.isArray(value);
1307       }).concat(-1, 1.1);
1308
1309       var array = lodashStable.transform(values, function(result, value) {
1310         result[value] = 1;
1311       }, []);
1312
1313       var expected = lodashStable.map(values, alwaysOne),
1314           actual = _.at(array, values);
1315
1316       assert.deepEqual(actual, expected);
1317     });
1318
1319     QUnit.test('should return an empty array when no keys are provided', function(assert) {
1320       assert.expect(2);
1321
1322       assert.deepEqual(_.at(array), []);
1323       assert.deepEqual(_.at(array, [], []), []);
1324     });
1325
1326     QUnit.test('should accept multiple key arguments', function(assert) {
1327       assert.expect(1);
1328
1329       var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1330       assert.deepEqual(actual, ['d', 'a', 'c']);
1331     });
1332
1333     QUnit.test('should work with a falsey `object` argument when keys are provided', function(assert) {
1334       assert.expect(1);
1335
1336       var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1337
1338       var actual = lodashStable.map(falsey, function(object) {
1339         try {
1340           return _.at(object, 0, 1, 'pop', 'push');
1341         } catch (e) {}
1342       });
1343
1344       assert.deepEqual(actual, expected);
1345     });
1346
1347     QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1348       assert.expect(1);
1349
1350       var actual = _.at(args, [2, 0]);
1351       assert.deepEqual(actual, [3, 1]);
1352     });
1353
1354     QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1355       assert.expect(1);
1356
1357       var actual = _.at([1, 2, 3, 4, 5], args);
1358       assert.deepEqual(actual, [2, 3, 4]);
1359     });
1360
1361     QUnit.test('should work with an object for `object`', function(assert) {
1362       assert.expect(1);
1363
1364       var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1365       assert.deepEqual(actual, [3, 4]);
1366     });
1367
1368     QUnit.test('should pluck inherited property values', function(assert) {
1369       assert.expect(1);
1370
1371       function Foo() { this.a = 1; }
1372       Foo.prototype.b = 2;
1373
1374       var actual = _.at(new Foo, 'b');
1375       assert.deepEqual(actual, [2]);
1376     });
1377
1378     QUnit.test('should work in a lazy sequence', function(assert) {
1379       assert.expect(6);
1380
1381       if (!isNpm) {
1382         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1383             smallArray = array;
1384
1385         lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1386           lodashStable.times(2, function(index) {
1387             var array = index ? largeArray : smallArray,
1388                 wrapped = _(array).map(identity).at(paths);
1389
1390             assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1391           });
1392         });
1393       }
1394       else {
1395         skipTest(assert, 6);
1396       }
1397     });
1398
1399     QUnit.test('should support shortcut fusion', function(assert) {
1400       assert.expect(8);
1401
1402       if (!isNpm) {
1403         var array = lodashStable.range(LARGE_ARRAY_SIZE),
1404             count = 0,
1405             iteratee = function(value) { count++; return square(value); },
1406             lastIndex = LARGE_ARRAY_SIZE - 1;
1407
1408         lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1409           count = 0;
1410           var actual = _(array).map(iteratee).at(n).value(),
1411               expected = index < 2 ? 1 : 0;
1412
1413           assert.strictEqual(count, expected);
1414
1415           expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1416           assert.deepEqual(actual, expected);
1417         });
1418       }
1419       else {
1420         skipTest(assert, 8);
1421       }
1422     });
1423
1424     QUnit.test('work with an object for `object` when chaining', function(assert) {
1425       assert.expect(1);
1426
1427       if (!isNpm) {
1428         var paths = ['a[0].b.c', 'a[1]'],
1429             wrapped = _(object).map(identity).at(paths);
1430
1431         assert.deepEqual(wrapped.value(), _.at(_.map(object, identity), paths));
1432       }
1433       else {
1434         skipTest(assert);
1435       }
1436     });
1437   }(1, 2, 3));
1438
1439   /*--------------------------------------------------------------------------*/
1440
1441   QUnit.module('lodash.attempt');
1442
1443   (function() {
1444     QUnit.test('should return the result of `func`', function(assert) {
1445       assert.expect(1);
1446
1447       assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1448     });
1449
1450     QUnit.test('should provide additional arguments to `func`', function(assert) {
1451       assert.expect(1);
1452
1453       var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1454       assert.deepEqual(actual, [1, 2]);
1455     });
1456
1457     QUnit.test('should return the caught error', function(assert) {
1458       assert.expect(1);
1459
1460       var expected = lodashStable.map(errors, alwaysTrue);
1461
1462       var actual = lodashStable.map(errors, function(error) {
1463         return _.attempt(function() { throw error; }) === error;
1464       });
1465
1466       assert.deepEqual(actual, expected);
1467     });
1468
1469     QUnit.test('should coerce errors to error objects', function(assert) {
1470       assert.expect(1);
1471
1472       var actual = _.attempt(function() { throw 'x'; });
1473       assert.ok(lodashStable.isEqual(actual, Error('x')));
1474     });
1475
1476     QUnit.test('should work with an error object from another realm', function(assert) {
1477       assert.expect(1);
1478
1479       if (realm.errors) {
1480         var expected = lodashStable.map(realm.errors, alwaysTrue);
1481
1482         var actual = lodashStable.map(realm.errors, function(error) {
1483           return _.attempt(function() { throw error; }) === error;
1484         });
1485
1486         assert.deepEqual(actual, expected);
1487       }
1488       else {
1489         skipTest(assert);
1490       }
1491     });
1492
1493     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1494       assert.expect(1);
1495
1496       if (!isNpm) {
1497         assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1498       }
1499       else {
1500         skipTest(assert);
1501       }
1502     });
1503
1504     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1505       assert.expect(1);
1506
1507       if (!isNpm) {
1508         assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1509       }
1510       else {
1511         skipTest(assert);
1512       }
1513     });
1514   }());
1515
1516   /*--------------------------------------------------------------------------*/
1517
1518   QUnit.module('lodash.before');
1519
1520   (function() {
1521     function before(n, times) {
1522       var count = 0;
1523       lodashStable.times(times, _.before(n, function() { count++; }));
1524       return count;
1525     }
1526
1527     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1528       assert.expect(4);
1529
1530       assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1531       assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1532       assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1533       assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1534     });
1535
1536     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1537       assert.expect(1);
1538
1539       assert.strictEqual(before(NaN, 1), 0);
1540     });
1541
1542     QUnit.test('should not set a `this` binding', function(assert) {
1543       assert.expect(2);
1544
1545       var before = _.before(2, function(assert) { return ++this.count; }),
1546           object = { 'before': before, 'count': 0 };
1547
1548       object.before();
1549       assert.strictEqual(object.before(), 1);
1550       assert.strictEqual(object.count, 1);
1551     });
1552   }());
1553
1554   /*--------------------------------------------------------------------------*/
1555
1556   QUnit.module('lodash.bind');
1557
1558   (function() {
1559     function fn() {
1560       var result = [this];
1561       push.apply(result, arguments);
1562       return result;
1563     }
1564
1565     QUnit.test('should bind a function to an object', function(assert) {
1566       assert.expect(1);
1567
1568       var object = {},
1569           bound = _.bind(fn, object);
1570
1571       assert.deepEqual(bound('a'), [object, 'a']);
1572     });
1573
1574     QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
1575       assert.expect(1);
1576
1577       var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1578           expected = lodashStable.map(values, function(value) { return [value]; });
1579
1580       var actual = lodashStable.map(values, function(value) {
1581         try {
1582           var bound = _.bind(fn, value);
1583           return bound();
1584         } catch (e) {}
1585       });
1586
1587       assert.ok(lodashStable.every(actual, function(value, index) {
1588         return lodashStable.isEqual(value, expected[index]);
1589       }));
1590     });
1591
1592     QUnit.test('should bind a function to nullish values', function(assert) {
1593       assert.expect(6);
1594
1595       var bound = _.bind(fn, null),
1596           actual = bound('a');
1597
1598       assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1599       assert.strictEqual(actual[1], 'a');
1600
1601       lodashStable.times(2, function(index) {
1602         bound = index ? _.bind(fn, undefined) : _.bind(fn);
1603         actual = bound('b');
1604
1605         assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1606         assert.strictEqual(actual[1], 'b');
1607       });
1608     });
1609
1610     QUnit.test('should partially apply arguments ', function(assert) {
1611       assert.expect(4);
1612
1613       var object = {},
1614           bound = _.bind(fn, object, 'a');
1615
1616       assert.deepEqual(bound(), [object, 'a']);
1617
1618       bound = _.bind(fn, object, 'a');
1619       assert.deepEqual(bound('b'), [object, 'a', 'b']);
1620
1621       bound = _.bind(fn, object, 'a', 'b');
1622       assert.deepEqual(bound(), [object, 'a', 'b']);
1623       assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1624     });
1625
1626     QUnit.test('should support placeholders', function(assert) {
1627       assert.expect(4);
1628
1629       var object = {},
1630           ph = _.bind.placeholder,
1631           bound = _.bind(fn, object, ph, 'b', ph);
1632
1633       assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1634       assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1635       assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1636       assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1637     });
1638
1639     QUnit.test('should create a function with a `length` of `0`', function(assert) {
1640       assert.expect(2);
1641
1642       var fn = function(a, b, c) {},
1643           bound = _.bind(fn, {});
1644
1645       assert.strictEqual(bound.length, 0);
1646
1647       bound = _.bind(fn, {}, 1);
1648       assert.strictEqual(bound.length, 0);
1649     });
1650
1651     QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1652       assert.expect(3);
1653
1654       function Foo() {
1655         return this;
1656       }
1657
1658       var bound = _.bind(Foo, { 'a': 1 }),
1659           newBound = new bound;
1660
1661       assert.strictEqual(bound().a, 1);
1662       assert.strictEqual(newBound.a, undefined);
1663       assert.ok(newBound instanceof Foo);
1664     });
1665
1666     QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1667       assert.expect(1);
1668
1669       function Foo() {
1670         return this;
1671       }
1672
1673       function Bar() {}
1674
1675       var thisArg = { 'a': 1 },
1676           boundFoo = _.bind(Foo, thisArg),
1677           boundBar = _.bind(Bar, thisArg),
1678           count = 9,
1679           expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1680
1681       var actual = lodashStable.times(count, function(index) {
1682         try {
1683           switch (index) {
1684             case 0: return [new boundFoo().a, new boundBar().a];
1685             case 1: return [new boundFoo(1).a, new boundBar(1).a];
1686             case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1687             case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1688             case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1689             case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1690             case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1691             case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1692             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];
1693           }
1694         } catch (e) {}
1695       });
1696
1697       assert.deepEqual(actual, expected);
1698     });
1699
1700     QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1701       assert.expect(2);
1702
1703       function Foo(value) {
1704         return value && object;
1705       }
1706
1707       var bound = _.bind(Foo),
1708           object = {};
1709
1710       assert.ok(new bound instanceof Foo);
1711       assert.strictEqual(new bound(true), object);
1712     });
1713
1714     QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1715       assert.expect(1);
1716
1717       var object = {},
1718           bound = _.bind(fn, object, 'a');
1719
1720       assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1721     });
1722
1723     QUnit.test('should not rebind functions', function(assert) {
1724       assert.expect(3);
1725
1726       var object1 = {},
1727           object2 = {},
1728           object3 = {};
1729
1730       var bound1 = _.bind(fn, object1),
1731           bound2 = _.bind(bound1, object2, 'a'),
1732           bound3 = _.bind(bound1, object3, 'b');
1733
1734       assert.deepEqual(bound1(), [object1]);
1735       assert.deepEqual(bound2(), [object1, 'a']);
1736       assert.deepEqual(bound3(), [object1, 'b']);
1737     });
1738
1739     QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1740       assert.expect(2);
1741
1742       var Ctor = _.bind(Date, null),
1743           expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1744
1745       try {
1746         var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1747       } catch (e) {}
1748
1749       assert.deepEqual(actual, expected);
1750
1751       Ctor = _.bind(Date, null, 2012, 4, 23);
1752
1753       try {
1754         actual = new Ctor(0, 0, 0, 0);
1755       } catch (e) {}
1756
1757       assert.deepEqual(actual, expected);
1758     });
1759
1760     QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
1761       assert.expect(1);
1762
1763       var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
1764
1765       if (typeof createCtor == 'function') {
1766         var bound = _.bind(createCtor()),
1767             count = 8,
1768             expected = lodashStable.times(count, alwaysTrue);
1769
1770         var actual = lodashStable.times(count, function(index) {
1771           try {
1772             switch (index) {
1773               case 0: return !!(new bound);
1774               case 1: return !!(new bound(1));
1775               case 2: return !!(new bound(1, 2));
1776               case 3: return !!(new bound(1, 2, 3));
1777               case 4: return !!(new bound(1, 2, 3, 4));
1778               case 5: return !!(new bound(1, 2, 3, 4, 5));
1779               case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
1780               case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
1781             }
1782           } catch (e) {}
1783         });
1784
1785         assert.deepEqual(actual, expected);
1786       }
1787       else {
1788         skipTest(assert);
1789       }
1790     });
1791
1792     QUnit.test('should return a wrapped value when chaining', function(assert) {
1793       assert.expect(2);
1794
1795       if (!isNpm) {
1796         var object = {},
1797             bound = _(fn).bind({}, 'a', 'b');
1798
1799         assert.ok(bound instanceof _);
1800
1801         var actual = bound.value()('c');
1802         assert.deepEqual(actual, [object, 'a', 'b', 'c']);
1803       }
1804       else {
1805         skipTest(assert, 2);
1806       }
1807     });
1808   }());
1809
1810   /*--------------------------------------------------------------------------*/
1811
1812   QUnit.module('lodash.bindAll');
1813
1814   (function() {
1815     var args = arguments;
1816
1817     var source = {
1818       '_a': 1,
1819       '_b': 2,
1820       '_c': 3,
1821       '_d': 4,
1822       'a': function() { return this._a; },
1823       'b': function() { return this._b; },
1824       'c': function() { return this._c; },
1825       'd': function() { return this._d; }
1826     };
1827
1828     QUnit.test('should accept individual method names', function(assert) {
1829       assert.expect(1);
1830
1831       var object = lodashStable.cloneDeep(source);
1832       _.bindAll(object, 'a', 'b');
1833
1834       var actual = lodashStable.map(['a', 'b', 'c'], function(methodName) {
1835         return object[methodName].call({});
1836       });
1837
1838       assert.deepEqual(actual, [1, 2, undefined]);
1839     });
1840
1841     QUnit.test('should accept arrays of method names', function(assert) {
1842       assert.expect(1);
1843
1844       var object = lodashStable.cloneDeep(source);
1845       _.bindAll(object, ['a', 'b'], ['c']);
1846
1847       var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(methodName) {
1848         return object[methodName].call({});
1849       });
1850
1851       assert.deepEqual(actual, [1, 2, 3, undefined]);
1852     });
1853
1854     QUnit.test('should work with an array `object` argument', function(assert) {
1855       assert.expect(1);
1856
1857       var array = ['push', 'pop'];
1858       _.bindAll(array);
1859       assert.strictEqual(array.pop, arrayProto.pop);
1860     });
1861
1862     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
1863       assert.expect(1);
1864
1865       var object = lodashStable.cloneDeep(source);
1866       _.bindAll(object, args);
1867
1868       var actual = lodashStable.map(args, function(methodName) {
1869         return object[methodName].call({});
1870       });
1871
1872       assert.deepEqual(actual, [1]);
1873     });
1874   }('a'));
1875
1876   /*--------------------------------------------------------------------------*/
1877
1878   QUnit.module('lodash.bindKey');
1879
1880   (function() {
1881     QUnit.test('should work when the target function is overwritten', function(assert) {
1882       assert.expect(2);
1883
1884       var object = {
1885         'user': 'fred',
1886         'greet': function(greeting) {
1887           return this.user + ' says: ' + greeting;
1888         }
1889       };
1890
1891       var bound = _.bindKey(object, 'greet', 'hi');
1892       assert.strictEqual(bound(), 'fred says: hi');
1893
1894       object.greet = function(greeting) {
1895         return this.user + ' says: ' + greeting + '!';
1896       };
1897
1898       assert.strictEqual(bound(), 'fred says: hi!');
1899     });
1900
1901     QUnit.test('should support placeholders', function(assert) {
1902       assert.expect(4);
1903
1904       var object = {
1905         'fn': function() {
1906           return slice.call(arguments);
1907         }
1908       };
1909
1910       var ph = _.bindKey.placeholder,
1911           bound = _.bindKey(object, 'fn', ph, 'b', ph);
1912
1913       assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
1914       assert.deepEqual(bound('a'), ['a', 'b', undefined]);
1915       assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
1916       assert.deepEqual(bound(), [undefined, 'b', undefined]);
1917     });
1918
1919     QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
1920       assert.expect(2);
1921
1922       function Foo(value) {
1923         return value && object;
1924       }
1925
1926       var object = { 'Foo': Foo },
1927           bound = _.bindKey(object, 'Foo');
1928
1929       assert.ok(new bound instanceof Foo);
1930       assert.strictEqual(new bound(true), object);
1931     });
1932   }());
1933
1934   /*--------------------------------------------------------------------------*/
1935
1936   QUnit.module('case methods');
1937
1938   lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
1939     var methodName = caseName + 'Case',
1940         func = _[methodName];
1941
1942     var strings = [
1943       'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
1944       'FOO BAR', 'fooBar', '--foo-bar', '__foo_bar__'
1945     ];
1946
1947     var converted = (function() {
1948       switch (caseName) {
1949         case 'camel': return 'fooBar';
1950         case 'kebab': return 'foo-bar';
1951         case 'lower': return 'foo bar';
1952         case 'snake': return 'foo_bar';
1953         case 'start': return 'Foo Bar';
1954         case 'upper': return 'FOO BAR';
1955       }
1956     }());
1957
1958     QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
1959       assert.expect(1);
1960
1961       var actual = lodashStable.map(strings, function(string) {
1962         return func(string) === converted;
1963       });
1964
1965       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
1966     });
1967
1968     QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
1969       assert.expect(1);
1970
1971       var actual = lodashStable.map(strings, function(string) {
1972         return func(func(string)) === converted;
1973       });
1974
1975       assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
1976     });
1977
1978     QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
1979       assert.expect(1);
1980
1981       var actual = lodashStable.map(burredLetters, function(burred, index) {
1982         var letter = deburredLetters[index];
1983         if (caseName == 'start') {
1984           letter = lodashStable.capitalize(letter);
1985         } else if (caseName == 'upper') {
1986           letter = letter.toUpperCase();
1987         } else {
1988           letter = letter.toLowerCase();
1989         }
1990         return func(burred) === letter;
1991       });
1992
1993       assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue));
1994     });
1995
1996     QUnit.test('`_.' + methodName + '` should trim latin-1 mathematical operators', function(assert) {
1997       assert.expect(1);
1998
1999       var actual = lodashStable.map(['\xd7', '\xf7'], func);
2000       assert.deepEqual(actual, ['', '']);
2001     });
2002
2003     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2004       assert.expect(2);
2005
2006       var string = 'foo bar';
2007       assert.strictEqual(func(Object(string)), converted);
2008       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2009     });
2010
2011     QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2012       assert.expect(1);
2013
2014       if (!isNpm) {
2015         assert.strictEqual(_('foo bar')[methodName](), converted);
2016       }
2017       else {
2018         skipTest(assert);
2019       }
2020     });
2021
2022     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2023       assert.expect(1);
2024
2025       if (!isNpm) {
2026         assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2027       }
2028       else {
2029         skipTest(assert);
2030       }
2031     });
2032   });
2033
2034   (function() {
2035     QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2036       assert.expect(1);
2037
2038       var funcs = [_.camelCase, _.kebabCase, _.snakeCase, _.startCase, _.camelCase];
2039
2040       var actual = lodashStable.reduce(funcs, function(result, func) {
2041         return func(result);
2042       }, 'enable 24h format');
2043
2044       assert.strictEqual(actual, 'enable24hFormat');
2045     });
2046   }());
2047
2048   /*--------------------------------------------------------------------------*/
2049
2050   QUnit.module('lodash.camelCase');
2051
2052   (function() {
2053     QUnit.test('should work with numbers', function(assert) {
2054       assert.expect(5);
2055
2056       assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2057       assert.strictEqual(_.camelCase('enable 24h format'), 'enable24hFormat');
2058       assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2059       assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2060       assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2061     });
2062
2063     QUnit.test('should handle acronyms', function(assert) {
2064       assert.expect(6);
2065
2066       lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2067         assert.strictEqual(_.camelCase(string), 'safeHtml');
2068       });
2069
2070       lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2071         assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2072       });
2073
2074       lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2075         assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2076       });
2077     });
2078   }());
2079
2080   /*--------------------------------------------------------------------------*/
2081
2082   QUnit.module('lodash.capitalize');
2083
2084   (function() {
2085     QUnit.test('should capitalize the first character of a string', function(assert) {
2086       assert.expect(3);
2087
2088       assert.strictEqual(_.capitalize('fred'), 'Fred');
2089       assert.strictEqual(_.capitalize('Fred'), 'Fred');
2090       assert.strictEqual(_.capitalize(' fred'), ' fred');
2091     });
2092   }());
2093
2094   /*--------------------------------------------------------------------------*/
2095
2096   QUnit.module('lodash.chain');
2097
2098   (function() {
2099     QUnit.test('should return a wrapped value', function(assert) {
2100       assert.expect(1);
2101
2102       if (!isNpm) {
2103         var actual = _.chain({ 'a': 0 });
2104         assert.ok(actual instanceof _);
2105       }
2106       else {
2107         skipTest(assert);
2108       }
2109     });
2110
2111     QUnit.test('should return existing wrapped values', function(assert) {
2112       assert.expect(2);
2113
2114       if (!isNpm) {
2115         var wrapped = _({ 'a': 0 });
2116         assert.strictEqual(_.chain(wrapped), wrapped);
2117         assert.strictEqual(wrapped.chain(), wrapped);
2118       }
2119       else {
2120         skipTest(assert, 2);
2121       }
2122     });
2123
2124     QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2125       assert.expect(6);
2126
2127       if (!isNpm) {
2128         var array = ['c', 'b', 'a'];
2129
2130         assert.ok(_.chain(array).head() instanceof _);
2131         assert.ok(_(array).chain().head() instanceof _);
2132
2133         assert.ok(_.chain(array).isArray() instanceof _);
2134         assert.ok(_(array).chain().isArray() instanceof _);
2135
2136         assert.ok(_.chain(array).sortBy().head() instanceof _);
2137         assert.ok(_(array).chain().sortBy().head() instanceof _);
2138       }
2139       else {
2140         skipTest(assert, 6);
2141       }
2142     });
2143
2144     QUnit.test('should chain multiple methods', function(assert) {
2145       assert.expect(6);
2146
2147       if (!isNpm) {
2148         lodashStable.times(2, function(index) {
2149           var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2150               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 },
2151               wrapped = index ? _(array).chain() : _.chain(array);
2152
2153           var actual = wrapped
2154             .chain()
2155             .map(function(value) { return value.split(''); })
2156             .flatten()
2157             .reduce(function(object, chr) {
2158               object[chr] || (object[chr] = 0);
2159               object[chr]++;
2160               return object;
2161             }, {})
2162             .value();
2163
2164           assert.deepEqual(actual, expected);
2165
2166           array = [1, 2, 3, 4, 5, 6];
2167           wrapped = index ? _(array).chain() : _.chain(array);
2168           actual = wrapped
2169             .chain()
2170             .filter(function(n) { return n % 2 != 0; })
2171             .reject(function(n) { return n % 3 == 0; })
2172             .sortBy(function(n) { return -n; })
2173             .value();
2174
2175           assert.deepEqual(actual, [5, 1]);
2176
2177           array = [3, 4];
2178           wrapped = index ? _(array).chain() : _.chain(array);
2179           actual = wrapped
2180             .reverse()
2181             .concat([2, 1])
2182             .unshift(5)
2183             .tap(function(value) { value.pop(); })
2184             .map(square)
2185             .value();
2186
2187           assert.deepEqual(actual, [25, 16, 9, 4]);
2188         });
2189       }
2190       else {
2191         skipTest(assert, 6);
2192       }
2193     });
2194   }());
2195
2196   /*--------------------------------------------------------------------------*/
2197
2198   QUnit.module('lodash.chunk');
2199
2200   (function() {
2201     var array = [0, 1, 2, 3, 4, 5];
2202
2203     QUnit.test('should return chunked arrays', function(assert) {
2204       assert.expect(1);
2205
2206       var actual = _.chunk(array, 3);
2207       assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2208     });
2209
2210     QUnit.test('should return the last chunk as remaining elements', function(assert) {
2211       assert.expect(1);
2212
2213       var actual = _.chunk(array, 4);
2214       assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2215     });
2216
2217     QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2218       assert.expect(1);
2219
2220       var values = falsey.concat(-1, -Infinity),
2221           expected = lodashStable.map(values, alwaysEmptyArray);
2222
2223       var actual = lodashStable.map(values, function(value, index) {
2224         return index ? _.chunk(array, value) : _.chunk(array);
2225       });
2226
2227       assert.deepEqual(actual, expected);
2228     });
2229
2230     QUnit.test('should coerce `size` to an integer', function(assert) {
2231       assert.expect(1);
2232
2233       assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2234     });
2235   }());
2236
2237   /*--------------------------------------------------------------------------*/
2238
2239   QUnit.module('lodash.clamp');
2240
2241   (function() {
2242     QUnit.test('should work with a `max` argument', function(assert) {
2243       assert.expect(2);
2244
2245       assert.strictEqual(_.clamp(5, 3), 3);
2246       assert.strictEqual(_.clamp(1, 3), 1);
2247     });
2248
2249     QUnit.test('should clamp negative numbers', function(assert) {
2250       assert.expect(3);
2251
2252       assert.strictEqual(_.clamp(-10, -5, 5), -5);
2253       assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2254       assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2255     });
2256
2257     QUnit.test('should clamp positive numbers', function(assert) {
2258       assert.expect(3);
2259
2260       assert.strictEqual(_.clamp(10, -5, 5), 5);
2261       assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2262       assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2263     });
2264
2265     QUnit.test('should not alter negative numbers in range', function(assert) {
2266       assert.expect(3);
2267
2268       assert.strictEqual(_.clamp(-4, -5, 5), -4);
2269       assert.strictEqual(_.clamp(-5, -5, 5), -5);
2270       assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2271     });
2272
2273     QUnit.test('should not alter positive numbers in range', function(assert) {
2274       assert.expect(3);
2275
2276       assert.strictEqual(_.clamp(4, -5, 5), 4);
2277       assert.strictEqual(_.clamp(5, -5, 5), 5);
2278       assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2279     });
2280
2281     QUnit.test('should not alter `0` in range', function(assert) {
2282       assert.expect(1);
2283
2284       assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2285     });
2286
2287     QUnit.test('should clamp to `0`', function(assert) {
2288       assert.expect(1);
2289
2290       assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2291     });
2292
2293     QUnit.test('should not alter `-0` in range', function(assert) {
2294       assert.expect(1);
2295
2296       assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2297     });
2298
2299     QUnit.test('should clamp to `-0`', function(assert) {
2300       assert.expect(1);
2301
2302       assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2303     });
2304
2305     QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2306       assert.expect(1);
2307
2308       assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2309     });
2310
2311     QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2312       assert.expect(2);
2313
2314       assert.deepEqual(_.clamp(1, -5, NaN), 0);
2315       assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2316     });
2317   }());
2318
2319   /*--------------------------------------------------------------------------*/
2320
2321   QUnit.module('clone methods');
2322
2323   (function() {
2324     function Foo() { this.a = 1; }
2325     Foo.prototype.b = 1;
2326     Foo.c = function() {};
2327
2328     if (Map) {
2329       var map = new Map;
2330       map.set('a', 1);
2331       map.set('b', 2);
2332     }
2333     if (Set) {
2334       var set = new Set;
2335       set.add(1);
2336       set.add(2);
2337     }
2338     var objects = {
2339       '`arguments` objects': arguments,
2340       'arrays': ['a', ''],
2341       'array-like-objects': { '0': 'a', '1': '', 'length': 3 },
2342       'booleans': false,
2343       'boolean objects': Object(false),
2344       'date objects': new Date,
2345       'Foo instances': new Foo,
2346       'objects': { 'a': 0, 'b': 1, 'c': 2 },
2347       'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2348       'objects from another document': realm.object || {},
2349       'maps': map,
2350       'null values': null,
2351       'numbers': 0,
2352       'number objects': Object(0),
2353       'regexes': /a/gim,
2354       'sets': set,
2355       'strings': 'a',
2356       'string objects': Object('a'),
2357       'undefined values': undefined
2358     };
2359
2360     objects['arrays'].length = 3;
2361
2362     var uncloneable = {
2363       'DOM elements': body,
2364       'functions': Foo,
2365       'generators': generator
2366     };
2367
2368     lodashStable.each(errors, function(error) {
2369       uncloneable[error.name + 's'] = error;
2370     });
2371
2372     QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2373       assert.expect(2);
2374
2375       var array = [{ 'a': 0 }, { 'b': 1 }],
2376           actual = _.clone(array);
2377
2378       assert.deepEqual(actual, array);
2379       assert.ok(actual !== array && actual[0] === array[0]);
2380     });
2381
2382     QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2383       assert.expect(1);
2384
2385       var object = {
2386         'foo': { 'b': { 'c': { 'd': {} } } },
2387         'bar': {}
2388       };
2389
2390       object.foo.b.c.d = object;
2391       object.bar.b = object.foo.b;
2392
2393       var actual = _.cloneDeep(object);
2394       assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2395     });
2396
2397     QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2398       assert.expect(2);
2399
2400       var cyclical = {};
2401       lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2402         cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2403       });
2404
2405       var clone = _.cloneDeep(cyclical),
2406           actual = clone['v' + LARGE_ARRAY_SIZE][0];
2407
2408       assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2409       assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2410     });
2411
2412     QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2413       assert.expect(164);
2414
2415       var Stack,
2416           keys = [true, false, 1, -Infinity, NaN, {}, null, 'a', symbol || {}, undefined];
2417
2418       var pairs = lodashStable.map(keys, function(key, index) {
2419         var lastIndex = keys.length - 1;
2420         return [key, keys[lastIndex - index]];
2421       });
2422
2423       _.cloneDeepWith({ 'a': 1 }, function() {
2424         if (arguments.length > 1) {
2425           Stack || (Stack = _.last(arguments).constructor);
2426         }
2427       });
2428
2429       var stacks = [new Stack(pairs), new Stack(pairs)];
2430
2431       lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
2432         stacks[1].set({}, {});
2433       });
2434
2435       lodashStable.each(stacks, function(stack) {
2436         lodashStable.each(keys, function(key, index) {
2437           var value = pairs[index][1];
2438
2439           assert.deepEqual(stack.get(key), value);
2440           assert.strictEqual(stack.has(key), true);
2441           assert.strictEqual(stack['delete'](key), true);
2442           assert.strictEqual(stack.has(key), false);
2443           assert.strictEqual(stack.get(key), undefined);
2444           assert.strictEqual(stack['delete'](key), false);
2445           assert.strictEqual(stack.set(key, value), stack);
2446           assert.strictEqual(stack.has(key), true);
2447         });
2448
2449         assert.strictEqual(stack.clear(), undefined);
2450         assert.ok(lodashStable.every(keys, function(key) {
2451           return !stack.has(key);
2452         }));
2453       });
2454     });
2455
2456     lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2457       var func = _[methodName],
2458           isDeep = methodName == 'cloneDeep';
2459
2460       lodashStable.forOwn(objects, function(object, key) {
2461         QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
2462           assert.expect(2);
2463
2464           var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
2465               actual = func(object);
2466
2467           assert.ok(isEqual(actual, object));
2468
2469           if (lodashStable.isObject(object)) {
2470             assert.notStrictEqual(actual, object);
2471           } else {
2472             assert.strictEqual(actual, object);
2473           }
2474         });
2475       });
2476
2477       QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2478         assert.expect(2);
2479
2480         if (ArrayBuffer) {
2481           var buffer = new ArrayBuffer(10),
2482               actual = func(buffer);
2483
2484           assert.strictEqual(actual.byteLength, buffer.byteLength);
2485           assert.notStrictEqual(actual, buffer);
2486         }
2487         else {
2488           skipTest(assert, 2);
2489         }
2490       });
2491
2492       QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2493         assert.expect(2);
2494
2495         var array = /x/.exec('vwxyz'),
2496             actual = func(array);
2497
2498         assert.strictEqual(actual.index, 2);
2499         assert.strictEqual(actual.input, 'vwxyz');
2500       });
2501
2502       QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2503         assert.expect(1);
2504
2505         // Avoid a regexp literal for older Opera and use `exec` for older Safari.
2506         var regexp = RegExp('x', 'g');
2507         regexp.exec('vwxyz');
2508
2509         var actual = func(regexp);
2510         assert.strictEqual(actual.lastIndex, 3);
2511       });
2512
2513       QUnit.test('`_.' + methodName + '` should create clone with the same `[[Prototype]]` as `value`', function(assert) {
2514         assert.expect(1);
2515
2516         assert.ok(func(new Foo) instanceof Foo);
2517       });
2518
2519       QUnit.test('should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2520         assert.expect(1);
2521
2522         Foo.prototype.constructor = null;
2523         assert.notOk(func(new Foo) instanceof Foo);
2524         Foo.prototype.constructor = Foo;
2525       });
2526
2527       QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2528         assert.expect(2);
2529
2530         var object = {
2531           'constructor': objectProto.constructor,
2532           'hasOwnProperty': objectProto.hasOwnProperty,
2533           'isPrototypeOf': objectProto.isPrototypeOf,
2534           'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2535           'toLocaleString': objectProto.toLocaleString,
2536           'toString': objectProto.toString,
2537           'valueOf': objectProto.valueOf
2538         };
2539
2540         var actual = func(object);
2541
2542         assert.deepEqual(actual, object);
2543         assert.notStrictEqual(actual, object);
2544       });
2545
2546       QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2547         assert.expect(2);
2548
2549         if (Symbol) {
2550           var object = {};
2551           object[symbol] = {};
2552           assert.strictEqual(func(object)[symbol], object[symbol]);
2553
2554           if (isDeep) {
2555             object = { 'a': { 'b': {} } };
2556             object.a.b[symbol] = {};
2557             assert.strictEqual(func(object).a.b[symbol], object.a.b[symbol]);
2558           }
2559           else {
2560             skipTest(assert);
2561           }
2562         }
2563         else {
2564           skipTest(assert, 2);
2565         }
2566       });
2567
2568       QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2569         assert.expect(4);
2570
2571         if (Symbol) {
2572           assert.strictEqual(func(symbol), symbol);
2573
2574           var object = Object(symbol),
2575               actual = func(object);
2576
2577           assert.strictEqual(typeof actual, 'object');
2578           assert.strictEqual(typeof actual.valueOf(), 'symbol');
2579           assert.notStrictEqual(actual, object);
2580         }
2581         else {
2582           skipTest(assert, 4);
2583         }
2584       });
2585
2586       QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2587         assert.expect(1);
2588
2589         if (Symbol) {
2590           assert.strictEqual(func(symbol), symbol);
2591         }
2592         else {
2593           skipTest(assert);
2594         }
2595       });
2596
2597       QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2598         assert.expect(1);
2599
2600         if (document) {
2601           var element = document.createElement('div');
2602
2603           try {
2604             assert.deepEqual(func(element), {});
2605           } catch (e) {
2606             assert.ok(false, e.message);
2607           }
2608         }
2609         else {
2610           skipTest(assert);
2611         }
2612       });
2613
2614       QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
2615         assert.expect(2);
2616
2617         var expected = [{ 'a': [0] }, { 'b': [1] }],
2618             actual = lodashStable.map(expected, func);
2619
2620         assert.deepEqual(actual, expected);
2621
2622         if (isDeep) {
2623           assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
2624         } else {
2625           assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
2626         }
2627       });
2628
2629       QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
2630         assert.expect(1);
2631
2632         var props = [];
2633
2634         var objects = lodashStable.transform(_, function(result, value, key) {
2635           if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) && !lodashStable.isArguments(value) && !lodashStable.isElement(value) && !lodashStable.isFunction(value)) {
2636             props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
2637             result.push(value);
2638           }
2639         }, []);
2640
2641         var expected = lodashStable.map(objects, alwaysTrue);
2642
2643         var actual = lodashStable.map(objects, function(object) {
2644           var Ctor = object.constructor,
2645               result = func(object);
2646
2647           return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
2648         });
2649
2650         assert.deepEqual(actual, expected, props.join(', '));
2651       });
2652
2653       QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
2654         assert.expect(2);
2655
2656         if (!isNpm) {
2657           var object = objects['objects'],
2658               actual = _(object)[methodName]();
2659
2660           assert.deepEqual(actual, object);
2661           assert.notStrictEqual(actual, object);
2662         }
2663         else {
2664           skipTest(assert, 2);
2665         }
2666       });
2667
2668       lodashStable.each(typedArrays, function(type) {
2669         QUnit.test('`_.' + methodName + '` should clone ' + type + ' arrays', function(assert) {
2670           assert.expect(10);
2671
2672           var Ctor = root[type];
2673
2674           lodashStable.times(2, function(index) {
2675             if (Ctor) {
2676               var buffer = new ArrayBuffer(24),
2677                   array = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
2678                   actual = func(array);
2679
2680               assert.deepEqual(actual, array);
2681               assert.notStrictEqual(actual, array);
2682               assert.strictEqual(actual.buffer === array.buffer, !isDeep);
2683               assert.strictEqual(actual.byteOffset, array.byteOffset);
2684               assert.strictEqual(actual.length, array.length);
2685             }
2686             else {
2687               skipTest(assert, 5);
2688             }
2689           });
2690         });
2691       });
2692
2693       lodashStable.forOwn(uncloneable, function(value, key) {
2694         QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
2695           assert.expect(3);
2696
2697           if (value) {
2698             var object = { 'a': value, 'b': { 'c': value } },
2699                 actual = func(object),
2700                 expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
2701
2702             assert.deepEqual(actual, object);
2703             assert.notStrictEqual(actual, object);
2704             assert.deepEqual(func(value), expected);
2705           }
2706           else {
2707             skipTest(assert, 3);
2708           }
2709         });
2710       });
2711     });
2712
2713     lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
2714       var func = _[methodName],
2715           isDeep = methodName == 'cloneDeepWith';
2716
2717       QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
2718         assert.expect(1);
2719
2720         var argsList = [],
2721             foo = new Foo;
2722
2723         func(foo, function() {
2724           var length = arguments.length,
2725               args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
2726
2727           argsList.push(args);
2728         });
2729
2730         assert.deepEqual(argsList, isDeep ? [[foo], [1, 'a', foo]] : [[foo]]);
2731       });
2732
2733       QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` returns `undefined`', function(assert) {
2734         assert.expect(1);
2735
2736         var actual = func({ 'a': { 'b': 'c' } }, noop);
2737         assert.deepEqual(actual, { 'a': { 'b': 'c' } });
2738       });
2739
2740       lodashStable.forOwn(uncloneable, function(value, key) {
2741         QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
2742           assert.expect(4);
2743
2744           var customizer = function(value) {
2745             return lodashStable.isPlainObject(value) ? undefined : value;
2746           };
2747
2748           var actual = func(value, customizer);
2749
2750           assert.deepEqual(actual, value);
2751           assert.strictEqual(actual, value);
2752
2753           var object = { 'a': value, 'b': { 'c': value } };
2754           actual = func(object, customizer);
2755
2756           assert.deepEqual(actual, object);
2757           assert.notStrictEqual(actual, object);
2758         });
2759       });
2760     });
2761   }(1, 2, 3));
2762
2763   /*--------------------------------------------------------------------------*/
2764
2765   QUnit.module('lodash.compact');
2766
2767   (function() {
2768     QUnit.test('should filter falsey values', function(assert) {
2769       assert.expect(1);
2770
2771       var array = ['0', '1', '2'];
2772       assert.deepEqual(_.compact(falsey.concat(array)), array);
2773     });
2774
2775     QUnit.test('should work when in-between lazy operators', function(assert) {
2776       assert.expect(2);
2777
2778       if (!isNpm) {
2779         var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
2780         assert.deepEqual(actual, []);
2781
2782         actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
2783         assert.deepEqual(actual, [true, 1, 'a']);
2784       }
2785       else {
2786         skipTest(assert, 2);
2787       }
2788     });
2789
2790     QUnit.test('should work in a lazy sequence', function(assert) {
2791       assert.expect(1);
2792
2793       if (!isNpm) {
2794         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
2795             actual = _(array).slice(1).compact().reverse().take().value();
2796
2797         assert.deepEqual(actual, _.take(_.compact(_.slice(array, 1)).reverse()));
2798       }
2799       else {
2800         skipTest(assert);
2801       }
2802     });
2803   }());
2804
2805   /*--------------------------------------------------------------------------*/
2806
2807   QUnit.module('lodash.concat');
2808
2809   (function() {
2810     QUnit.test('should concat arrays and values', function(assert) {
2811       assert.expect(2);
2812
2813       var array = [1],
2814           actual = _.concat(array, 2, [3], [[4]]);
2815
2816       assert.deepEqual(actual, [1, 2, 3, [4]]);
2817       assert.deepEqual(array, [1]);
2818     });
2819
2820     QUnit.test('should treat sparse arrays as dense', function(assert) {
2821       assert.expect(3);
2822
2823       var expected = [],
2824           actual = _.concat(Array(1), Array(1));
2825
2826       expected.push(undefined, undefined);
2827
2828       assert.ok('0'in actual);
2829       assert.ok('1' in actual);
2830       assert.deepEqual(actual, expected);
2831     });
2832
2833     QUnit.test('should return a new wrapped array', function(assert) {
2834       assert.expect(2);
2835
2836       if (!isNpm) {
2837         var array = [1],
2838             wrapped = _(array).concat([2, 3]),
2839             actual = wrapped.value();
2840
2841         assert.deepEqual(array, [1]);
2842         assert.deepEqual(actual, [1, 2, 3]);
2843       }
2844       else {
2845         skipTest(assert, 2);
2846       }
2847     });
2848   }());
2849
2850   /*--------------------------------------------------------------------------*/
2851
2852   QUnit.module('lodash.cond');
2853
2854   (function() {
2855     QUnit.test('should create a conditional function', function(assert) {
2856       assert.expect(3);
2857
2858       var cond = _.cond([
2859         [lodashStable.matches({ 'a': 1 }),     alwaysA],
2860         [lodashStable.matchesProperty('b', 1), alwaysB],
2861         [lodashStable.property('c'),           alwaysC]
2862       ]);
2863
2864       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
2865       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
2866       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
2867     });
2868
2869     QUnit.test('should provide arguments to functions', function(assert) {
2870       assert.expect(2);
2871
2872       var args1,
2873           args2,
2874           expected = ['a', 'b', 'c'];
2875
2876       var cond = _.cond([[
2877         function() { args1 || (args1 = slice.call(arguments)); return true; },
2878         function() { args2 || (args2 = slice.call(arguments)); }
2879       ]]);
2880
2881       cond('a', 'b', 'c');
2882
2883       assert.deepEqual(args1, expected);
2884       assert.deepEqual(args2, expected);
2885     });
2886
2887     QUnit.test('should work with predicate shorthands', function(assert) {
2888       assert.expect(3);
2889
2890       var cond = _.cond([
2891         [{ 'a': 1 }, alwaysA],
2892         [['b', 1],   alwaysB],
2893         ['c',        alwaysC]
2894       ]);
2895
2896       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
2897       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
2898       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
2899     });
2900
2901     QUnit.test('should return `undefined` when no condition is met', function(assert) {
2902       assert.expect(1);
2903
2904       var cond = _.cond([[alwaysFalse, alwaysA]]);
2905       assert.strictEqual(cond({ 'a': 1 }), undefined);
2906     });
2907
2908     QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
2909       assert.expect(2);
2910
2911       lodashStable.each([true, false], function(value) {
2912         assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError);
2913       });
2914     });
2915
2916     QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
2917       assert.expect(1);
2918
2919       var cond = _.cond([
2920         [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
2921       ]);
2922
2923       var object = { 'cond': cond, 'a': 1, 'b': 2 };
2924       assert.strictEqual(object.cond('a', 'b'), 2);
2925     });
2926   }());
2927
2928   /*--------------------------------------------------------------------------*/
2929
2930   QUnit.module('lodash.conforms');
2931
2932   (function() {
2933     var objects = [
2934       { 'a': 1, 'b': 8 },
2935       { 'a': 2, 'b': 4 },
2936       { 'a': 3, 'b': 16 }
2937     ];
2938
2939     QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
2940       assert.expect(2);
2941
2942       var conforms = _.conforms({
2943         'b': function(value) { return value > 4; }
2944       });
2945
2946       var actual = lodashStable.filter(objects, conforms);
2947       assert.deepEqual(actual, [objects[0], objects[2]]);
2948
2949       conforms = _.conforms({
2950         'b': function(value) { return value > 8; },
2951         'a': function(value) { return value > 1; }
2952       });
2953
2954       actual = lodashStable.filter(objects, conforms);
2955       assert.deepEqual(actual, [objects[2]]);
2956     });
2957
2958     QUnit.test('should not match by inherited `source` properties', function(assert) {
2959       assert.expect(1);
2960
2961       function Foo() {
2962         this.a = function(value) {
2963           return value > 1;
2964         };
2965       }
2966
2967       Foo.prototype.b = function(value) {
2968         return value > 8;
2969       };
2970
2971       var conforms = _.conforms(new Foo),
2972           actual = lodashStable.filter(objects, conforms);
2973
2974       assert.deepEqual(actual, [objects[1], objects[2]]);
2975     });
2976
2977     QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
2978       assert.expect(2);
2979
2980       var count = 0;
2981
2982       var conforms = _.conforms({
2983         'a': function() { count++; return true; }
2984       });
2985
2986       assert.strictEqual(conforms({}), false);
2987       assert.strictEqual(count, 0);
2988     });
2989
2990     QUnit.test('should work with a function for `object`', function(assert) {
2991       assert.expect(2);
2992
2993       function Foo() {}
2994       Foo.a = 1;
2995
2996       function Bar() {}
2997       Bar.a = 2;
2998
2999       var conforms = _.conforms({
3000         'a': function(value) { return value > 1; }
3001       });
3002
3003       assert.strictEqual(conforms(Foo), false);
3004       assert.strictEqual(conforms(Bar), true);
3005     });
3006
3007     QUnit.test('should work with a function for `source`', function(assert) {
3008       assert.expect(1);
3009
3010       function Foo() {}
3011       Foo.a = function(value) { return value > 1; };
3012
3013       var objects = [{ 'a': 1 }, { 'a': 2 }],
3014           actual = lodashStable.filter(objects, _.conforms(Foo));
3015
3016       assert.deepEqual(actual, [objects[1]]);
3017     });
3018
3019     QUnit.test('should work with a non-plain `object`', function(assert) {
3020       assert.expect(1);
3021
3022       function Foo() {
3023         this.a = 1;
3024       }
3025       Foo.prototype.b = 2;
3026
3027       var conforms = _.conforms({
3028         'b': function(value) { return value > 1; }
3029       });
3030
3031       assert.strictEqual(conforms(new Foo), true);
3032     });
3033
3034     QUnit.test('should return `false` when `object` is nullish', function(assert) {
3035       assert.expect(1);
3036
3037       var values = [, null, undefined],
3038           expected = lodashStable.map(values, alwaysFalse);
3039
3040       var conforms = _.conforms({
3041         'a': function(value) { return value > 1; }
3042       });
3043
3044       var actual = lodashStable.map(values, function(value, index) {
3045         try {
3046           return index ? conforms(value) : conforms();
3047         } catch (e) {}
3048       });
3049
3050       assert.deepEqual(actual, expected);
3051     });
3052
3053     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3054       assert.expect(1);
3055
3056       var values = [, null, undefined],
3057           expected = lodashStable.map(values, alwaysTrue),
3058           conforms = _.conforms({});
3059
3060       var actual = lodashStable.map(values, function(value, index) {
3061         try {
3062           return index ? conforms(value) : conforms();
3063         } catch (e) {}
3064       });
3065
3066       assert.deepEqual(actual, expected);
3067     });
3068
3069     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
3070       assert.expect(1);
3071
3072       var object = { 'a': 1 },
3073           expected = lodashStable.map(empties, alwaysTrue);
3074
3075       var actual = lodashStable.map(empties, function(value) {
3076         var conforms = _.conforms(value);
3077         return conforms(object);
3078       });
3079
3080       assert.deepEqual(actual, expected);
3081     });
3082
3083     QUnit.test('should not change behavior if `source` is modified', function(assert) {
3084       assert.expect(2);
3085
3086       var source = {
3087         'a': function(value) { return value > 1; }
3088       };
3089
3090       var object = { 'a': 2 },
3091           conforms = _.conforms(source);
3092
3093       assert.strictEqual(conforms(object), true);
3094
3095       source.a = function(value) { return value < 2; };
3096       assert.strictEqual(conforms(object), true);
3097     });
3098   }());
3099
3100   /*--------------------------------------------------------------------------*/
3101
3102   QUnit.module('lodash.constant');
3103
3104   (function() {
3105     QUnit.test('should create a function that returns `value`', function(assert) {
3106       assert.expect(1);
3107
3108       var object = { 'a': 1 },
3109           values = Array(2).concat(empties, true, 1, 'a'),
3110           constant = _.constant(object),
3111           expected = lodashStable.map(values, function() { return true; });
3112
3113       var actual = lodashStable.map(values, function(value, index) {
3114         if (index == 0) {
3115           var result = constant();
3116         } else if (index == 1) {
3117           result = constant.call({});
3118         } else {
3119           result = constant(value);
3120         }
3121         return result === object;
3122       });
3123
3124       assert.deepEqual(actual, expected);
3125     });
3126
3127     QUnit.test('should work with falsey values', function(assert) {
3128       assert.expect(1);
3129
3130       var expected = lodashStable.map(falsey, function() { return true; });
3131
3132       var actual = lodashStable.map(falsey, function(value, index) {
3133         var constant = index ? _.constant(value) : _.constant(),
3134             result = constant();
3135
3136         return (result === value) || (result !== result && value !== value);
3137       });
3138
3139       assert.deepEqual(actual, expected);
3140     });
3141
3142     QUnit.test('should return a wrapped value when chaining', function(assert) {
3143       assert.expect(1);
3144
3145       if (!isNpm) {
3146         var wrapped = _(true).constant();
3147         assert.ok(wrapped instanceof _);
3148       }
3149       else {
3150         skipTest(assert);
3151       }
3152     });
3153   }());
3154
3155   /*--------------------------------------------------------------------------*/
3156
3157   QUnit.module('lodash.countBy');
3158
3159   (function() {
3160     var array = [4.2, 6.1, 6.4];
3161
3162     QUnit.test('should work with an iteratee', function(assert) {
3163       assert.expect(1);
3164
3165       var actual = _.countBy(array, function(num) {
3166         return Math.floor(num);
3167       }, Math);
3168
3169       assert.deepEqual(actual, { '4': 1, '6': 2 });
3170     });
3171
3172     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3173       assert.expect(1);
3174
3175       var array = [4, 6, 6],
3176           values = [, null, undefined],
3177           expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
3178
3179       var actual = lodashStable.map(values, function(value, index) {
3180         return index ? _.countBy(array, value) : _.countBy(array);
3181       });
3182
3183       assert.deepEqual(actual, expected);
3184     });
3185
3186     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
3187       assert.expect(1);
3188
3189       var actual = _.countBy(['one', 'two', 'three'], 'length');
3190       assert.deepEqual(actual, { '3': 2, '5': 1 });
3191     });
3192
3193     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3194       assert.expect(2);
3195
3196       var actual = _.countBy([4.2, 6.1, 6.4], function(num) {
3197         return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
3198       });
3199
3200       assert.deepEqual(actual.constructor, 1);
3201       assert.deepEqual(actual.hasOwnProperty, 2);
3202     });
3203
3204     QUnit.test('should work with a number for `iteratee`', function(assert) {
3205       assert.expect(2);
3206
3207       var array = [
3208         [1, 'a'],
3209         [2, 'a'],
3210         [2, 'b']
3211       ];
3212
3213       assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3214       assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3215     });
3216
3217     QUnit.test('should work with an object for `collection`', function(assert) {
3218       assert.expect(1);
3219
3220       var actual = _.countBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) {
3221         return Math.floor(num);
3222       });
3223
3224       assert.deepEqual(actual, { '4': 1, '6': 2 });
3225     });
3226
3227     QUnit.test('should work in a lazy sequence', function(assert) {
3228       assert.expect(1);
3229
3230       if (!isNpm) {
3231         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3232           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3233           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3234         );
3235
3236         var actual = _(array).countBy().map(square).filter(isEven).take().value();
3237
3238         assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3239       }
3240       else {
3241         skipTest(assert);
3242       }
3243     });
3244   }());
3245
3246   /*--------------------------------------------------------------------------*/
3247
3248   QUnit.module('lodash.create');
3249
3250   (function() {
3251     function Shape() {
3252       this.x = 0;
3253       this.y = 0;
3254     }
3255
3256     function Circle() {
3257       Shape.call(this);
3258     }
3259
3260     QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3261       assert.expect(3);
3262
3263       Circle.prototype = _.create(Shape.prototype);
3264       Circle.prototype.constructor = Circle;
3265
3266       var actual = new Circle;
3267
3268       assert.ok(actual instanceof Circle);
3269       assert.ok(actual instanceof Shape);
3270       assert.notStrictEqual(Circle.prototype, Shape.prototype);
3271     });
3272
3273     QUnit.test('should assign `properties` to the created object', function(assert) {
3274       assert.expect(3);
3275
3276       var expected = { 'constructor': Circle, 'radius': 0 };
3277       Circle.prototype = _.create(Shape.prototype, expected);
3278
3279       var actual = new Circle;
3280
3281       assert.ok(actual instanceof Circle);
3282       assert.ok(actual instanceof Shape);
3283       assert.deepEqual(Circle.prototype, expected);
3284     });
3285
3286     QUnit.test('should assign own properties', function(assert) {
3287       assert.expect(1);
3288
3289       function Foo() {
3290         this.a = 1;
3291         this.c = 3;
3292       }
3293       Foo.prototype.b = 2;
3294
3295       assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3296     });
3297
3298     QUnit.test('should accept a falsey `prototype` argument', function(assert) {
3299       assert.expect(1);
3300
3301       var expected = lodashStable.map(falsey, alwaysEmptyObject);
3302
3303       var actual = lodashStable.map(falsey, function(prototype, index) {
3304         return index ? _.create(prototype) : _.create();
3305       });
3306
3307       assert.deepEqual(actual, expected);
3308     });
3309
3310     QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
3311       assert.expect(1);
3312
3313       var primitives = [true, null, 1, 'a', undefined],
3314           expected = lodashStable.map(primitives, alwaysTrue);
3315
3316       var actual = lodashStable.map(primitives, function(value, index) {
3317         return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3318       });
3319
3320       assert.deepEqual(actual, expected);
3321     });
3322
3323     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3324       assert.expect(1);
3325
3326       var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3327           expected = lodashStable.map(array, alwaysTrue),
3328           objects = lodashStable.map(array, _.create);
3329
3330       var actual = lodashStable.map(objects, function(object) {
3331         return object.a === 1 && !_.keys(object).length;
3332       });
3333
3334       assert.deepEqual(actual, expected);
3335     });
3336   }());
3337
3338   /*--------------------------------------------------------------------------*/
3339
3340   QUnit.module('lodash.curry');
3341
3342   (function() {
3343     function fn(a, b, c, d) {
3344       return slice.call(arguments);
3345     }
3346
3347     QUnit.test('should curry based on the number of arguments provided', function(assert) {
3348       assert.expect(3);
3349
3350       var curried = _.curry(fn),
3351           expected = [1, 2, 3, 4];
3352
3353       assert.deepEqual(curried(1)(2)(3)(4), expected);
3354       assert.deepEqual(curried(1, 2)(3, 4), expected);
3355       assert.deepEqual(curried(1, 2, 3, 4), expected);
3356     });
3357
3358     QUnit.test('should allow specifying `arity`', function(assert) {
3359       assert.expect(3);
3360
3361       var curried = _.curry(fn, 3),
3362           expected = [1, 2, 3];
3363
3364       assert.deepEqual(curried(1)(2, 3), expected);
3365       assert.deepEqual(curried(1, 2)(3), expected);
3366       assert.deepEqual(curried(1, 2, 3), expected);
3367     });
3368
3369     QUnit.test('should coerce `arity` to an integer', function(assert) {
3370       assert.expect(2);
3371
3372       var values = ['0', 0.6, 'xyz'],
3373           expected = lodashStable.map(values, alwaysEmptyArray);
3374
3375       var actual = lodashStable.map(values, function(arity) {
3376         return _.curry(fn, arity)();
3377       });
3378
3379       assert.deepEqual(actual, expected);
3380       assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3381     });
3382
3383     QUnit.test('should support placeholders', function(assert) {
3384       assert.expect(4);
3385
3386       var curried = _.curry(fn),
3387           ph = curried.placeholder;
3388
3389       assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3390       assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3391       assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3392       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3393     });
3394
3395     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3396       assert.expect(3);
3397
3398       var curried = _.curry(fn, 3);
3399       assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3400       assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3401       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3402     });
3403
3404     QUnit.test('should return a function with a `length` of `0`', function(assert) {
3405       assert.expect(6);
3406
3407       lodashStable.times(2, function(index) {
3408         var curried = index ? _.curry(fn, 4) : _.curry(fn);
3409         assert.strictEqual(curried.length, 0);
3410         assert.strictEqual(curried(1).length, 0);
3411         assert.strictEqual(curried(1, 2).length, 0);
3412       });
3413     });
3414
3415     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3416       assert.expect(2);
3417
3418       var Foo = function(value) {
3419         return value && object;
3420       };
3421
3422       var curried = _.curry(Foo),
3423           object = {};
3424
3425       assert.ok(new curried(false) instanceof Foo);
3426       assert.strictEqual(new curried(true), object);
3427     });
3428
3429     QUnit.test('should not set a `this` binding', function(assert) {
3430       assert.expect(9);
3431
3432       var fn = function(a, b, c) {
3433         var value = this || {};
3434         return [value[a], value[b], value[c]];
3435       };
3436
3437       var object = { 'a': 1, 'b': 2, 'c': 3 },
3438           expected = [1, 2, 3];
3439
3440       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3441       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3442       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3443
3444       assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3445       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3446       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3447
3448       object.curried = _.curry(fn);
3449       assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3450       assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3451       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3452     });
3453
3454     QUnit.test('should work with partialed methods', function(assert) {
3455       assert.expect(2);
3456
3457       var curried = _.curry(fn),
3458           expected = [1, 2, 3, 4];
3459
3460       var a = _.partial(curried, 1),
3461           b = _.bind(a, null, 2),
3462           c = _.partialRight(b, 4),
3463           d = _.partialRight(b(3), 4);
3464
3465       assert.deepEqual(c(3), expected);
3466       assert.deepEqual(d(), expected);
3467     });
3468   }());
3469
3470   /*--------------------------------------------------------------------------*/
3471
3472   QUnit.module('lodash.curryRight');
3473
3474   (function() {
3475     function fn(a, b, c, d) {
3476       return slice.call(arguments);
3477     }
3478
3479     QUnit.test('should curry based on the number of arguments provided', function(assert) {
3480       assert.expect(3);
3481
3482       var curried = _.curryRight(fn),
3483           expected = [1, 2, 3, 4];
3484
3485       assert.deepEqual(curried(4)(3)(2)(1), expected);
3486       assert.deepEqual(curried(3, 4)(1, 2), expected);
3487       assert.deepEqual(curried(1, 2, 3, 4), expected);
3488     });
3489
3490     QUnit.test('should allow specifying `arity`', function(assert) {
3491       assert.expect(3);
3492
3493       var curried = _.curryRight(fn, 3),
3494           expected = [1, 2, 3];
3495
3496       assert.deepEqual(curried(3)(1, 2), expected);
3497       assert.deepEqual(curried(2, 3)(1), expected);
3498       assert.deepEqual(curried(1, 2, 3), expected);
3499     });
3500
3501     QUnit.test('should coerce `arity` to an integer', function(assert) {
3502       assert.expect(2);
3503
3504       var values = ['0', 0.6, 'xyz'],
3505           expected = lodashStable.map(values, alwaysEmptyArray);
3506
3507       var actual = lodashStable.map(values, function(arity) {
3508         return _.curryRight(fn, arity)();
3509       });
3510
3511       assert.deepEqual(actual, expected);
3512       assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
3513     });
3514
3515     QUnit.test('should support placeholders', function(assert) {
3516       assert.expect(4);
3517
3518       var curried = _.curryRight(fn),
3519           expected = [1, 2, 3, 4],
3520           ph = curried.placeholder;
3521
3522       assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
3523       assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
3524       assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
3525       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
3526     });
3527
3528     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3529       assert.expect(3);
3530
3531       var curried = _.curryRight(fn, 3);
3532       assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
3533       assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
3534       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3535     });
3536
3537     QUnit.test('should return a function with a `length` of `0`', function(assert) {
3538       assert.expect(6);
3539
3540       lodashStable.times(2, function(index) {
3541         var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
3542         assert.strictEqual(curried.length, 0);
3543         assert.strictEqual(curried(4).length, 0);
3544         assert.strictEqual(curried(3, 4).length, 0);
3545       });
3546     });
3547
3548     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3549       assert.expect(2);
3550
3551       var Foo = function(value) {
3552         return value && object;
3553       };
3554
3555       var curried = _.curryRight(Foo),
3556           object = {};
3557
3558       assert.ok(new curried(false) instanceof Foo);
3559       assert.strictEqual(new curried(true), object);
3560     });
3561
3562     QUnit.test('should not set a `this` binding', function(assert) {
3563       assert.expect(9);
3564
3565       var fn = function(a, b, c) {
3566         var value = this || {};
3567         return [value[a], value[b], value[c]];
3568       };
3569
3570       var object = { 'a': 1, 'b': 2, 'c': 3 },
3571           expected = [1, 2, 3];
3572
3573       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
3574       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
3575       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3576
3577       assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
3578       assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
3579       assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
3580
3581       object.curried = _.curryRight(fn);
3582       assert.deepEqual(object.curried('c')('b')('a'), Array(3));
3583       assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
3584       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3585     });
3586
3587     QUnit.test('should work with partialed methods', function(assert) {
3588       assert.expect(2);
3589
3590       var curried = _.curryRight(fn),
3591           expected = [1, 2, 3, 4];
3592
3593       var a = _.partialRight(curried, 4),
3594           b = _.partialRight(a, 3),
3595           c = _.bind(b, null, 1),
3596           d = _.partial(b(2), 1);
3597
3598       assert.deepEqual(c(2), expected);
3599       assert.deepEqual(d(), expected);
3600     });
3601   }());
3602
3603   /*--------------------------------------------------------------------------*/
3604
3605   QUnit.module('curry methods');
3606
3607   lodashStable.each(['curry', 'curryRight'], function(methodName) {
3608     var func = _[methodName],
3609         fn = function(a, b) { return slice.call(arguments); },
3610         isCurry = methodName == 'curry';
3611
3612     QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
3613       assert.expect(1);
3614
3615       function run(a, b) {
3616         return a + b;
3617       }
3618
3619       var curried = func(run);
3620
3621       try {
3622         var actual = curried(1)(2);
3623       } catch (e) {}
3624
3625       assert.strictEqual(actual, 3);
3626     });
3627
3628     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
3629       assert.expect(2);
3630
3631       var array = [fn, fn, fn],
3632           object = { 'a': fn, 'b': fn, 'c': fn };
3633
3634       lodashStable.each([array, object], function(collection) {
3635         var curries = lodashStable.map(collection, func),
3636             expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
3637
3638         var actual = lodashStable.map(curries, function(curried) {
3639           return curried('a')('b');
3640         });
3641
3642         assert.deepEqual(actual, expected);
3643       });
3644     });
3645   });
3646
3647   /*--------------------------------------------------------------------------*/
3648
3649   QUnit.module('lodash.debounce');
3650
3651   (function() {
3652     QUnit.test('should debounce a function', function(assert) {
3653       assert.expect(2);
3654
3655       var done = assert.async();
3656
3657       var callCount = 0,
3658           debounced = _.debounce(function() { callCount++; }, 32);
3659
3660       debounced();
3661       debounced();
3662       debounced();
3663
3664       assert.strictEqual(callCount, 0);
3665
3666       setTimeout(function() {
3667         assert.strictEqual(callCount, 1);
3668         done();
3669       }, 96);
3670     });
3671
3672     QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
3673       assert.expect(2);
3674
3675       var done = assert.async();
3676
3677       var debounced = _.debounce(identity, 32);
3678       debounced('x');
3679
3680       setTimeout(function() {
3681         assert.notEqual(debounced('y'), 'y');
3682       }, 64);
3683
3684       setTimeout(function() {
3685         assert.notEqual(debounced('z'), 'z');
3686         done();
3687       }, 128);
3688     });
3689
3690     QUnit.test('subsequent "immediate" debounced calls return the last `func` result', function(assert) {
3691       assert.expect(2);
3692
3693       var done = assert.async();
3694
3695       var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
3696           result = [debounced('x'), debounced('y')];
3697
3698       assert.deepEqual(result, ['x', 'x']);
3699
3700       setTimeout(function() {
3701         var result = [debounced('a'), debounced('b')];
3702         assert.deepEqual(result, ['a', 'a']);
3703         done();
3704       }, 64);
3705     });
3706
3707     QUnit.test('should apply default options', function(assert) {
3708       assert.expect(2);
3709
3710       var done = assert.async();
3711
3712       var callCount = 0;
3713
3714       var debounced = _.debounce(function(value) {
3715         callCount++;
3716         return value;
3717       }, 32, {});
3718
3719       assert.strictEqual(debounced('a'), undefined);
3720
3721       setTimeout(function() {
3722         assert.strictEqual(callCount, 1);
3723         done();
3724       }, 64);
3725     });
3726
3727     QUnit.test('should support a `leading` option', function(assert) {
3728       assert.expect(5);
3729
3730       var done = assert.async();
3731
3732       var callCounts = [0, 0];
3733
3734       var withLeading = _.debounce(function(value) {
3735         callCounts[0]++;
3736         return value;
3737       }, 32, { 'leading': true });
3738
3739       assert.strictEqual(withLeading('a'), 'a');
3740
3741       var withoutLeading = _.debounce(identity, 32, { 'leading': false });
3742       assert.strictEqual(withoutLeading('a'), undefined);
3743
3744       var withLeadingAndTrailing = _.debounce(function() {
3745         callCounts[1]++;
3746       }, 32, { 'leading': true });
3747
3748       withLeadingAndTrailing();
3749       withLeadingAndTrailing();
3750
3751       assert.strictEqual(callCounts[1], 1);
3752
3753       setTimeout(function() {
3754         assert.deepEqual(callCounts, [1, 2]);
3755
3756         withLeading('a');
3757         assert.strictEqual(callCounts[0], 2);
3758
3759         done();
3760       }, 64);
3761     });
3762
3763     QUnit.test('should support a `trailing` option', function(assert) {
3764       assert.expect(4);
3765
3766       var done = assert.async();
3767
3768       var withCount = 0,
3769           withoutCount = 0;
3770
3771       var withTrailing = _.debounce(function(value) {
3772         withCount++;
3773         return value;
3774       }, 32, { 'trailing': true });
3775
3776       var withoutTrailing = _.debounce(function(value) {
3777         withoutCount++;
3778         return value;
3779       }, 32, { 'trailing': false });
3780
3781       assert.strictEqual(withTrailing('a'), undefined);
3782       assert.strictEqual(withoutTrailing('a'), undefined);
3783
3784       setTimeout(function() {
3785         assert.strictEqual(withCount, 1);
3786         assert.strictEqual(withoutCount, 0);
3787         done();
3788       }, 64);
3789     });
3790
3791     QUnit.test('should support a `maxWait` option', function(assert) {
3792       assert.expect(1);
3793
3794       var done = assert.async();
3795
3796       var limit = (argv || isPhantom) ? 1000 : 320,
3797           withCount = 0,
3798           withoutCount = 0;
3799
3800       var withMaxWait = _.debounce(function() {
3801         withCount++;
3802       }, 64, { 'maxWait': 128 });
3803
3804       var withoutMaxWait = _.debounce(function() {
3805         withoutCount++;
3806       }, 96);
3807
3808       var start = +new Date;
3809       while ((new Date - start) < limit) {
3810         withMaxWait();
3811         withoutMaxWait();
3812       }
3813       var actual = [Boolean(withCount), Boolean(withoutCount)];
3814
3815       setTimeout(function() {
3816         assert.deepEqual(actual, [true, false]);
3817         done();
3818       }, 1);
3819     });
3820
3821     QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
3822       assert.expect(1);
3823
3824       var done = assert.async();
3825
3826       var callCount = 0;
3827
3828       var debounced = _.debounce(function() {
3829         callCount++;
3830       }, 32, { 'maxWait': 64 });
3831
3832       debounced();
3833
3834       setTimeout(function() {
3835         assert.strictEqual(callCount, 1);
3836         done();
3837       }, 128);
3838     });
3839
3840     QUnit.test('should invoke the `trailing` call with the correct arguments and `this` binding', function(assert) {
3841       assert.expect(2);
3842
3843       var done = assert.async();
3844
3845       var actual,
3846           callCount = 0,
3847           object = {};
3848
3849       var debounced = _.debounce(function(value) {
3850         actual = [this];
3851         push.apply(actual, arguments);
3852         return ++callCount != 2;
3853       }, 32, { 'leading': true, 'maxWait': 64 });
3854
3855       while (true) {
3856         if (!debounced.call(object, 'a')) {
3857           break;
3858         }
3859       }
3860       setTimeout(function() {
3861         assert.strictEqual(callCount, 2);
3862         assert.deepEqual(actual, [object, 'a']);
3863         done();
3864       }, 64);
3865     });
3866   }());
3867
3868   /*--------------------------------------------------------------------------*/
3869
3870   QUnit.module('lodash.deburr');
3871
3872   (function() {
3873     QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
3874       assert.expect(1);
3875
3876       var actual = lodashStable.map(burredLetters, _.deburr);
3877       assert.deepEqual(actual, deburredLetters);
3878     });
3879
3880     QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
3881       assert.expect(1);
3882
3883       var operators = ['\xd7', '\xf7'],
3884           actual = lodashStable.map(operators, _.deburr);
3885
3886       assert.deepEqual(actual, operators);
3887     });
3888
3889     QUnit.test('should deburr combining diacritical marks', function(assert) {
3890       assert.expect(1);
3891
3892       var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
3893
3894       var actual = lodashStable.map(comboMarks, function(chr) {
3895         return _.deburr('e' + chr + 'i');
3896       });
3897
3898       assert.deepEqual(actual, expected);
3899     });
3900   }());
3901
3902   /*--------------------------------------------------------------------------*/
3903
3904   QUnit.module('lodash.defaults');
3905
3906   (function() {
3907     QUnit.test('should assign source properties if missing on `object`', function(assert) {
3908       assert.expect(1);
3909
3910       assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
3911     });
3912
3913     QUnit.test('should accept multiple sources', function(assert) {
3914       assert.expect(2);
3915
3916       var expected = { 'a': 1, 'b': 2, 'c': 3 };
3917       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
3918       assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
3919     });
3920
3921     QUnit.test('should not overwrite `null` values', function(assert) {
3922       assert.expect(1);
3923
3924       var actual = _.defaults({ 'a': null }, { 'a': 1 });
3925       assert.strictEqual(actual.a, null);
3926     });
3927
3928     QUnit.test('should overwrite `undefined` values', function(assert) {
3929       assert.expect(1);
3930
3931       var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
3932       assert.strictEqual(actual.a, 1);
3933     });
3934
3935     QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
3936       assert.expect(2);
3937
3938       var object = {
3939         'constructor': objectProto.constructor,
3940         'hasOwnProperty': objectProto.hasOwnProperty,
3941         'isPrototypeOf': objectProto.isPrototypeOf,
3942         'propertyIsEnumerable': objectProto.propertyIsEnumerable,
3943         'toLocaleString': objectProto.toLocaleString,
3944         'toString': objectProto.toString,
3945         'valueOf': objectProto.valueOf
3946       };
3947
3948       var source = {
3949         'constructor': 1,
3950         'hasOwnProperty': 2,
3951         'isPrototypeOf': 3,
3952         'propertyIsEnumerable': 4,
3953         'toLocaleString': 5,
3954         'toString': 6,
3955         'valueOf': 7
3956       };
3957
3958       assert.deepEqual(_.defaults({}, source), source);
3959       assert.deepEqual(_.defaults({}, object, source), object);
3960     });
3961   }());
3962
3963   /*--------------------------------------------------------------------------*/
3964
3965   QUnit.module('lodash.defaultsDeep');
3966
3967   (function() {
3968     QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
3969       assert.expect(1);
3970
3971       var object = { 'a': { 'b': 2 }, 'd': 4 },
3972           source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 },
3973           expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
3974
3975       assert.deepEqual(_.defaultsDeep(object, source), expected);
3976     });
3977
3978     QUnit.test('should accept multiple sources', function(assert) {
3979       assert.expect(2);
3980
3981       var source1 = { 'a': { 'b': 3 } },
3982           source2 = { 'a': { 'c': 3 } },
3983           source3 = { 'a': { 'b': 3, 'c': 3 } },
3984           source4 = { 'a': { 'c': 4 } },
3985           expected = { 'a': { 'b': 2, 'c': 3 } };
3986
3987       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
3988       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
3989     });
3990
3991     QUnit.test('should not overwrite `null` values', function(assert) {
3992       assert.expect(1);
3993
3994       var object = { 'a': { 'b': null } },
3995           source = { 'a': { 'b': 2 } },
3996           actual = _.defaultsDeep(object, source);
3997
3998       assert.strictEqual(actual.a.b, null);
3999     });
4000
4001     QUnit.test('should overwrite `undefined` values', function(assert) {
4002       assert.expect(1);
4003
4004       var object = { 'a': { 'b': undefined } },
4005           source = { 'a': { 'b': 2 } },
4006           actual = _.defaultsDeep(object, source);
4007
4008       assert.strictEqual(actual.a.b, 2);
4009     });
4010
4011     QUnit.test('should merge sources containing circular references', function(assert) {
4012       assert.expect(1);
4013
4014       var object = {
4015         'foo': { 'b': { 'c': { 'd': {} } } },
4016         'bar': { 'a': 2 }
4017       };
4018
4019       var source = {
4020         'foo': { 'b': { 'c': { 'd': {} } } },
4021         'bar': {}
4022       };
4023
4024       object.foo.b.c.d = object;
4025       source.foo.b.c.d = source;
4026       source.bar.b = source.foo.b;
4027
4028       var actual = _.defaultsDeep(object, source);
4029       assert.ok(actual.bar.b === actual.foo.b && actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
4030     });
4031
4032     QUnit.test('should not modify sources', function(assert) {
4033       assert.expect(3);
4034
4035       var source1 = { 'a': 1, 'b': { 'c': 2 } },
4036           source2 = { 'b': { 'c': 3, 'd': 3 } },
4037           actual = _.defaultsDeep({}, source1, source2);
4038
4039       assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4040       assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4041       assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4042     });
4043
4044     QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4045       assert.expect(1);
4046
4047       var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4048       assert.deepEqual(actual, { 'a': ['abc'] });
4049     });
4050   }());
4051
4052   /*--------------------------------------------------------------------------*/
4053
4054   QUnit.module('lodash.defer');
4055
4056   (function() {
4057     QUnit.test('should defer `func` execution', function(assert) {
4058       assert.expect(1);
4059
4060       var done = assert.async();
4061
4062       var pass = false;
4063       _.defer(function() { pass = true; });
4064
4065       setTimeout(function() {
4066         assert.ok(pass);
4067         done();
4068       }, 32);
4069     });
4070
4071     QUnit.test('should provide additional arguments to `func`', function(assert) {
4072       assert.expect(1);
4073
4074       var done = assert.async();
4075
4076       var args;
4077
4078       _.defer(function() {
4079         args = slice.call(arguments);
4080       }, 1, 2);
4081
4082       setTimeout(function() {
4083         assert.deepEqual(args, [1, 2]);
4084         done();
4085       }, 32);
4086     });
4087
4088     QUnit.test('should be cancelable', function(assert) {
4089       assert.expect(1);
4090
4091       var done = assert.async();
4092
4093       var pass = true;
4094
4095       var timerId = _.defer(function() {
4096         pass = false;
4097       });
4098
4099       clearTimeout(timerId);
4100
4101       setTimeout(function() {
4102         assert.ok(pass);
4103         done();
4104       }, 32);
4105     });
4106   }());
4107
4108   /*--------------------------------------------------------------------------*/
4109
4110   QUnit.module('lodash.delay');
4111
4112   (function() {
4113     QUnit.test('should delay `func` execution', function(assert) {
4114       assert.expect(2);
4115
4116       var done = assert.async();
4117
4118       var pass = false;
4119       _.delay(function() { pass = true; }, 32);
4120
4121       setTimeout(function() {
4122         assert.notOk(pass);
4123       }, 1);
4124
4125       setTimeout(function() {
4126         assert.ok(pass);
4127         done();
4128       }, 64);
4129     });
4130
4131     QUnit.test('should provide additional arguments to `func`', function(assert) {
4132       assert.expect(1);
4133
4134       var done = assert.async();
4135
4136       var args;
4137
4138       _.delay(function() {
4139         args = slice.call(arguments);
4140       }, 32, 1, 2);
4141
4142       setTimeout(function() {
4143         assert.deepEqual(args, [1, 2]);
4144         done();
4145       }, 64);
4146     });
4147
4148     QUnit.test('should use a default `wait` of `0`', function(assert) {
4149       assert.expect(2);
4150
4151       var done = assert.async();
4152
4153       var pass = false;
4154
4155       _.delay(function() {
4156         pass = true;
4157       });
4158
4159       assert.notOk(pass);
4160
4161       setTimeout(function() {
4162         assert.ok(pass);
4163         done();
4164       }, 0);
4165     });
4166
4167     QUnit.test('should be cancelable', function(assert) {
4168       assert.expect(1);
4169
4170       var done = assert.async();
4171
4172       var pass = true;
4173
4174       var timerId = _.delay(function() {
4175         pass = false;
4176       }, 32);
4177
4178       clearTimeout(timerId);
4179
4180       setTimeout(function() {
4181         assert.ok(pass);
4182         done();
4183       }, 64);
4184     });
4185   }());
4186
4187   /*--------------------------------------------------------------------------*/
4188
4189   QUnit.module('difference methods');
4190
4191   lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4192     var args = (function() { return arguments; }(1, 2, 3)),
4193         func = _[methodName];
4194
4195     QUnit.test('`_.' + methodName + '` should return the difference of the given arrays', function(assert) {
4196       assert.expect(2);
4197
4198       var actual = func([1, 2, 3, 4, 5], [5, 2, 10]);
4199       assert.deepEqual(actual, [1, 3, 4]);
4200
4201       actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]);
4202       assert.deepEqual(actual, [1, 3]);
4203     });
4204
4205     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4206       assert.expect(1);
4207
4208       assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4209     });
4210
4211     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4212       assert.expect(1);
4213
4214       var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4215           array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4216           a = {},
4217           b = {},
4218           c = {};
4219
4220       array1.push(a, b, c);
4221       array2.push(b, c, a);
4222
4223       assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4224     });
4225
4226     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4227       assert.expect(1);
4228
4229       var object1 = {},
4230           object2 = {},
4231           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4232
4233       assert.deepEqual(func([object1, object2], largeArray), [object2]);
4234     });
4235
4236     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4237       assert.expect(1);
4238
4239       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
4240       assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4241     });
4242
4243     QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4244       assert.expect(3);
4245
4246       var array = [1, null, 3];
4247       assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4248       assert.deepEqual(func(null, array, 1), []);
4249       assert.deepEqual(func(array, args, null), [null]);
4250     });
4251   });
4252
4253   /*--------------------------------------------------------------------------*/
4254
4255   QUnit.module('lodash.differenceBy');
4256
4257   (function() {
4258     QUnit.test('should accept an `iteratee` argument', function(assert) {
4259       assert.expect(2);
4260
4261       var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
4262       assert.deepEqual(actual, [3.1, 1.3]);
4263
4264       actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4265       assert.deepEqual(actual, [{ 'x': 2 }]);
4266     });
4267
4268     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
4269       assert.expect(1);
4270
4271       var args;
4272
4273       _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() {
4274         args || (args = slice.call(arguments));
4275       });
4276
4277       assert.deepEqual(args, [4.4]);
4278     });
4279   }());
4280
4281   /*--------------------------------------------------------------------------*/
4282
4283   QUnit.module('lodash.differenceWith');
4284
4285   (function() {
4286     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
4287
4288     QUnit.test('should work with a `comparator` argument', function(assert) {
4289       assert.expect(1);
4290
4291       var actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
4292       assert.deepEqual(actual, [{ 'x': 2, 'y': 1 }]);
4293     });
4294   }());
4295
4296   /*--------------------------------------------------------------------------*/
4297
4298   QUnit.module('lodash.drop');
4299
4300   (function() {
4301     var array = [1, 2, 3];
4302
4303     QUnit.test('should drop the first two elements', function(assert) {
4304       assert.expect(1);
4305
4306       assert.deepEqual(_.drop(array, 2), [3]);
4307     });
4308
4309     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4310       assert.expect(1);
4311
4312       var expected = lodashStable.map(falsey, function(value) {
4313         return value === undefined ? [2, 3] : array;
4314       });
4315
4316       var actual = lodashStable.map(falsey, function(n) {
4317         return _.drop(array, n);
4318       });
4319
4320       assert.deepEqual(actual, expected);
4321     });
4322
4323     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4324       assert.expect(3);
4325
4326       lodashStable.each([0, -1, -Infinity], function(n) {
4327         assert.deepEqual(_.drop(array, n), array);
4328       });
4329     });
4330
4331     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4332       assert.expect(4);
4333
4334       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4335         assert.deepEqual(_.drop(array, n), []);
4336       });
4337     });
4338
4339     QUnit.test('should coerce `n` to an integer', function(assert) {
4340       assert.expect(1);
4341
4342       assert.deepEqual(_.drop(array, 1.6), [2, 3]);
4343     });
4344
4345     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4346       assert.expect(1);
4347
4348       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4349           actual = lodashStable.map(array, _.drop);
4350
4351       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
4352     });
4353
4354     QUnit.test('should work in a lazy sequence', function(assert) {
4355       assert.expect(6);
4356
4357       if (!isNpm) {
4358         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4359             predicate = function(value) { values.push(value); return isEven(value); },
4360             values = [],
4361             actual = _(array).drop(2).drop().value();
4362
4363         assert.deepEqual(actual, array.slice(3));
4364
4365         actual = _(array).filter(predicate).drop(2).drop().value();
4366         assert.deepEqual(values, array);
4367         assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
4368
4369         actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
4370         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
4371
4372         values = [];
4373
4374         actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
4375         assert.deepEqual(values, array.slice(1));
4376         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
4377       }
4378       else {
4379         skipTest(assert, 6);
4380       }
4381     });
4382   }());
4383
4384   /*--------------------------------------------------------------------------*/
4385
4386   QUnit.module('lodash.dropRight');
4387
4388   (function() {
4389     var array = [1, 2, 3];
4390
4391     QUnit.test('should drop the last two elements', function(assert) {
4392       assert.expect(1);
4393
4394       assert.deepEqual(_.dropRight(array, 2), [1]);
4395     });
4396
4397     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4398       assert.expect(1);
4399
4400       var expected = lodashStable.map(falsey, function(value) {
4401         return value === undefined ? [1, 2] : array;
4402       });
4403
4404       var actual = lodashStable.map(falsey, function(n) {
4405         return _.dropRight(array, n);
4406       });
4407
4408       assert.deepEqual(actual, expected);
4409     });
4410
4411     QUnit.test('should return all elements when `n` < `1`', function(assert) {
4412       assert.expect(3);
4413
4414       lodashStable.each([0, -1, -Infinity], function(n) {
4415         assert.deepEqual(_.dropRight(array, n), array);
4416       });
4417     });
4418
4419     QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4420       assert.expect(4);
4421
4422       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4423         assert.deepEqual(_.dropRight(array, n), []);
4424       });
4425     });
4426
4427     QUnit.test('should coerce `n` to an integer', function(assert) {
4428       assert.expect(1);
4429
4430       assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
4431     });
4432
4433     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4434       assert.expect(1);
4435
4436       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4437           actual = lodashStable.map(array, _.dropRight);
4438
4439       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
4440     });
4441
4442     QUnit.test('should work in a lazy sequence', function(assert) {
4443       assert.expect(6);
4444
4445       if (!isNpm) {
4446         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4447             predicate = function(value) { values.push(value); return isEven(value); },
4448             values = [],
4449             actual = _(array).dropRight(2).dropRight().value();
4450
4451         assert.deepEqual(actual, array.slice(0, -3));
4452
4453         actual = _(array).filter(predicate).dropRight(2).dropRight().value();
4454         assert.deepEqual(values, array);
4455         assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
4456
4457         actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
4458         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
4459
4460         values = [];
4461
4462         actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
4463         assert.deepEqual(values, array.slice(0, -1));
4464         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
4465       }
4466       else {
4467         skipTest(assert, 6);
4468       }
4469     });
4470   }());
4471
4472   /*--------------------------------------------------------------------------*/
4473
4474   QUnit.module('lodash.dropRightWhile');
4475
4476   (function() {
4477     var array = [1, 2, 3, 4];
4478
4479     var objects = [
4480       { 'a': 0, 'b': 0 },
4481       { 'a': 1, 'b': 1 },
4482       { 'a': 2, 'b': 2 }
4483     ];
4484
4485     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
4486       assert.expect(1);
4487
4488       var actual = _.dropRightWhile(array, function(num) {
4489         return num > 2;
4490       });
4491
4492       assert.deepEqual(actual, [1, 2]);
4493     });
4494
4495     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
4496       assert.expect(1);
4497
4498       var args;
4499
4500       _.dropRightWhile(array, function() {
4501         args = slice.call(arguments);
4502       });
4503
4504       assert.deepEqual(args, [4, 3, array]);
4505     });
4506
4507     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
4508       assert.expect(1);
4509
4510       assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
4511     });
4512
4513     QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
4514       assert.expect(1);
4515
4516       assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
4517     });
4518
4519     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
4520       assert.expect(1);
4521
4522       assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
4523     });
4524
4525     QUnit.test('should return a wrapped value when chaining', function(assert) {
4526       assert.expect(2);
4527
4528       if (!isNpm) {
4529         var wrapped = _(array).dropRightWhile(function(num) {
4530           return num > 2;
4531         });
4532
4533         assert.ok(wrapped instanceof _);
4534         assert.deepEqual(wrapped.value(), [1, 2]);
4535       }
4536       else {
4537         skipTest(assert, 2);
4538       }
4539     });
4540   }());
4541
4542   /*--------------------------------------------------------------------------*/
4543
4544   QUnit.module('lodash.dropWhile');
4545
4546   (function() {
4547     var array = [1, 2, 3, 4];
4548
4549     var objects = [
4550       { 'a': 2, 'b': 2 },
4551       { 'a': 1, 'b': 1 },
4552       { 'a': 0, 'b': 0 }
4553     ];
4554
4555     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
4556       assert.expect(1);
4557
4558       var actual = _.dropWhile(array, function(num) {
4559         return num < 3;
4560       });
4561
4562       assert.deepEqual(actual, [3, 4]);
4563     });
4564
4565     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
4566       assert.expect(1);
4567
4568       var args;
4569
4570       _.dropWhile(array, function() {
4571         args = slice.call(arguments);
4572       });
4573
4574       assert.deepEqual(args, [1, 0, array]);
4575     });
4576
4577     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
4578       assert.expect(1);
4579
4580       assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
4581     });
4582
4583     QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
4584       assert.expect(1);
4585
4586       assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
4587     });
4588
4589     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
4590       assert.expect(1);
4591
4592       assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
4593     });
4594
4595     QUnit.test('should work in a lazy sequence', function(assert) {
4596       assert.expect(3);
4597
4598       if (!isNpm) {
4599         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
4600             predicate = function(num) { return num < 3; },
4601             expected = _.dropWhile(array, predicate),
4602             wrapped = _(array).dropWhile(predicate);
4603
4604         assert.deepEqual(wrapped.value(), expected);
4605         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
4606         assert.strictEqual(wrapped.last(), _.last(expected));
4607       }
4608       else {
4609         skipTest(assert, 3);
4610       }
4611     });
4612
4613     QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
4614       assert.expect(1);
4615
4616       if (!isNpm) {
4617         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
4618
4619         var actual = _(array)
4620           .dropWhile(function(num) { return num == 1; })
4621           .drop()
4622           .dropWhile(function(num) { return num == 3; })
4623           .value();
4624
4625         assert.deepEqual(actual, array.slice(3));
4626       }
4627       else {
4628         skipTest(assert);
4629       }
4630     });
4631   }());
4632
4633   /*--------------------------------------------------------------------------*/
4634
4635   QUnit.module('lodash.endsWith');
4636
4637   (function() {
4638     var string = 'abc';
4639
4640     QUnit.test('should return `true` if a string ends with `target`', function(assert) {
4641       assert.expect(1);
4642
4643       assert.strictEqual(_.endsWith(string, 'c'), true);
4644     });
4645
4646     QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
4647       assert.expect(1);
4648
4649       assert.strictEqual(_.endsWith(string, 'b'), false);
4650     });
4651
4652     QUnit.test('should work with a `position` argument', function(assert) {
4653       assert.expect(1);
4654
4655       assert.strictEqual(_.endsWith(string, 'b', 2), true);
4656     });
4657
4658     QUnit.test('should work with `position` >= `string.length`', function(assert) {
4659       assert.expect(4);
4660
4661       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
4662         assert.strictEqual(_.endsWith(string, 'c', position), true);
4663       });
4664     });
4665
4666     QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
4667       assert.expect(1);
4668
4669       var expected = lodashStable.map(falsey, alwaysTrue);
4670
4671       var actual = lodashStable.map(falsey, function(position) {
4672         return _.endsWith(string, position === undefined ? 'c' : '', position);
4673       });
4674
4675       assert.deepEqual(actual, expected);
4676     });
4677
4678     QUnit.test('should treat a negative `position` as `0`', function(assert) {
4679       assert.expect(6);
4680
4681       lodashStable.each([-1, -3, -Infinity], function(position) {
4682         assert.ok(lodashStable.every(string, function(chr) {
4683           return _.endsWith(string, chr, position) === false;
4684         }));
4685         assert.strictEqual(_.endsWith(string, '', position), true);
4686       });
4687     });
4688
4689     QUnit.test('should coerce `position` to an integer', function(assert) {
4690       assert.expect(1);
4691
4692       assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
4693     });
4694
4695     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
4696       assert.expect(1);
4697
4698       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
4699         return _.endsWith(string, '', position, true);
4700       }));
4701     });
4702   }());
4703
4704   /*--------------------------------------------------------------------------*/
4705
4706   QUnit.module('lodash.eq');
4707
4708   (function() {
4709     QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
4710       assert.expect(11);
4711
4712       assert.strictEqual(_.eq(), true);
4713       assert.strictEqual(_.eq(undefined), true);
4714       assert.strictEqual(_.eq(0, -0), true);
4715       assert.strictEqual(_.eq(NaN, NaN), true);
4716       assert.strictEqual(_.eq(1, 1), true);
4717
4718       assert.strictEqual(_.eq(null, undefined), false);
4719       assert.strictEqual(_.eq(1, Object(1)), false);
4720       assert.strictEqual(_.eq(1, '1'), false);
4721       assert.strictEqual(_.eq(1, '1'), false);
4722
4723       var object = { 'a': 1 };
4724       assert.strictEqual(_.eq(object, object), true);
4725       assert.strictEqual(_.eq(object, { 'a': 1 }), false);
4726     });
4727   }());
4728
4729   /*--------------------------------------------------------------------------*/
4730
4731   QUnit.module('lodash.escape');
4732
4733   (function() {
4734     var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
4735         unescaped = '&<>"\'`\/';
4736
4737     escaped += escaped;
4738     unescaped += unescaped;
4739
4740     QUnit.test('should escape values', function(assert) {
4741       assert.expect(1);
4742
4743       assert.strictEqual(_.escape(unescaped), escaped);
4744     });
4745
4746     QUnit.test('should not escape the "/" character', function(assert) {
4747       assert.expect(1);
4748
4749       assert.strictEqual(_.escape('/'), '/');
4750     });
4751
4752     QUnit.test('should handle strings with nothing to escape', function(assert) {
4753       assert.expect(1);
4754
4755       assert.strictEqual(_.escape('abc'), 'abc');
4756     });
4757
4758     QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
4759       assert.expect(1);
4760
4761       assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
4762     });
4763   }());
4764
4765   /*--------------------------------------------------------------------------*/
4766
4767   QUnit.module('lodash.escapeRegExp');
4768
4769   (function() {
4770     var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
4771         unescaped = '^$.*+?()[]{}|\\';
4772
4773     QUnit.test('should escape values', function(assert) {
4774       assert.expect(1);
4775
4776       assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
4777     });
4778
4779     QUnit.test('should handle strings with nothing to escape', function(assert) {
4780       assert.expect(1);
4781
4782       assert.strictEqual(_.escapeRegExp('ghi'), 'ghi');
4783     });
4784
4785     QUnit.test('should return an empty string for empty values', function(assert) {
4786       assert.expect(1);
4787
4788       var values = [, null, undefined, ''],
4789           expected = lodashStable.map(values, alwaysEmptyString);
4790
4791       var actual = lodashStable.map(values, function(value, index) {
4792         return index ? _.escapeRegExp(value) : _.escapeRegExp();
4793       });
4794
4795       assert.deepEqual(actual, expected);
4796     });
4797   }());
4798
4799   /*--------------------------------------------------------------------------*/
4800
4801   QUnit.module('lodash.every');
4802
4803   (function() {
4804     QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
4805       assert.expect(1);
4806
4807       assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
4808     });
4809
4810     QUnit.test('should return `true` for empty collections', function(assert) {
4811       assert.expect(1);
4812
4813       var expected = lodashStable.map(empties, alwaysTrue);
4814
4815       var actual = lodashStable.map(empties, function(value) {
4816         try {
4817           return _.every(value, identity);
4818         } catch (e) {}
4819       });
4820
4821       assert.deepEqual(actual, expected);
4822     });
4823
4824     QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
4825       assert.expect(2);
4826
4827       var count = 0;
4828
4829       assert.strictEqual(_.every([true, null, true], function(value) {
4830         count++;
4831         return value;
4832       }), false);
4833
4834       assert.strictEqual(count, 2);
4835     });
4836
4837     QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
4838       assert.expect(1);
4839
4840       assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
4841     });
4842
4843     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
4844       assert.expect(2);
4845
4846       var values = [, null, undefined],
4847           expected = lodashStable.map(values, alwaysFalse);
4848
4849       var actual = lodashStable.map(values, function(value, index) {
4850         var array = [0];
4851         return index ? _.every(array, value) : _.every(array);
4852       });
4853
4854       assert.deepEqual(actual, expected);
4855
4856       expected = lodashStable.map(values, alwaysTrue);
4857       actual = lodashStable.map(values, function(value, index) {
4858         var array = [1];
4859         return index ? _.every(array, value) : _.every(array);
4860       });
4861
4862       assert.deepEqual(actual, expected);
4863     });
4864
4865     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
4866       assert.expect(2);
4867
4868       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
4869       assert.strictEqual(_.every(objects, 'a'), false);
4870       assert.strictEqual(_.every(objects, 'b'), true);
4871     });
4872
4873     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
4874       assert.expect(2);
4875
4876       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
4877       assert.strictEqual(_.every(objects, { 'a': 0 }), true);
4878       assert.strictEqual(_.every(objects, { 'b': 1 }), false);
4879     });
4880
4881     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4882       assert.expect(1);
4883
4884       var actual = lodashStable.map([[1]], _.every);
4885       assert.deepEqual(actual, [true]);
4886     });
4887   }());
4888
4889   /*--------------------------------------------------------------------------*/
4890
4891   QUnit.module('strict mode checks');
4892
4893   lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
4894     var func = _[methodName],
4895         isBindAll = methodName == 'bindAll';
4896
4897     QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
4898       assert.expect(1);
4899
4900       if (freeze) {
4901         var object = freeze({ 'a': undefined, 'b': function() {} }),
4902             pass = !isStrict;
4903
4904         try {
4905           func(object, isBindAll ? 'b' : { 'a': 1 });
4906         } catch (e) {
4907           pass = !pass;
4908         }
4909         assert.ok(pass);
4910       }
4911       else {
4912         skipTest(assert);
4913       }
4914     });
4915   });
4916
4917   /*--------------------------------------------------------------------------*/
4918
4919   QUnit.module('lodash.fill');
4920
4921   (function() {
4922     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
4923       assert.expect(1);
4924
4925       var array = [1, 2, 3];
4926       assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
4927     });
4928
4929     QUnit.test('should use `undefined` for `value` if not provided', function(assert) {
4930       assert.expect(2);
4931
4932       var array = [1, 2, 3],
4933           actual = _.fill(array);
4934
4935       assert.deepEqual(actual, Array(3));
4936       assert.ok(lodashStable.every(actual, function(value, index) {
4937         return index in actual;
4938       }));
4939     });
4940
4941     QUnit.test('should work with a positive `start`', function(assert) {
4942       assert.expect(1);
4943
4944       var array = [1, 2, 3];
4945       assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
4946     });
4947
4948     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
4949       assert.expect(4);
4950
4951       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
4952         var array = [1, 2, 3];
4953         assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
4954       });
4955     });
4956
4957     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
4958       assert.expect(1);
4959
4960       var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
4961
4962       var actual = lodashStable.map(falsey, function(start) {
4963         var array = [1, 2, 3];
4964         return _.fill(array, 'a', start);
4965       });
4966
4967       assert.deepEqual(actual, expected);
4968     });
4969
4970     QUnit.test('should work with a negative `start`', function(assert) {
4971       assert.expect(1);
4972
4973       var array = [1, 2, 3];
4974       assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
4975     });
4976
4977     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
4978       assert.expect(3);
4979
4980       lodashStable.each([-3, -4, -Infinity], function(start) {
4981         var array = [1, 2, 3];
4982         assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
4983       });
4984     });
4985
4986     QUnit.test('should work with `start` >= `end`', function(assert) {
4987       assert.expect(2);
4988
4989       lodashStable.each([2, 3], function(start) {
4990         var array = [1, 2, 3];
4991         assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
4992       });
4993     });
4994
4995     QUnit.test('should work with a positive `end`', function(assert) {
4996       assert.expect(1);
4997
4998       var array = [1, 2, 3];
4999       assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5000     });
5001
5002     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
5003       assert.expect(4);
5004
5005       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5006         var array = [1, 2, 3];
5007         assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5008       });
5009     });
5010
5011     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5012       assert.expect(1);
5013
5014       var expected = lodashStable.map(falsey, function(value) {
5015         return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5016       });
5017
5018       var actual = lodashStable.map(falsey, function(end) {
5019         var array = [1, 2, 3];
5020         return _.fill(array, 'a', 0, end);
5021       });
5022
5023       assert.deepEqual(actual, expected);
5024     });
5025
5026     QUnit.test('should work with a negative `end`', function(assert) {
5027       assert.expect(1);
5028
5029       var array = [1, 2, 3];
5030       assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5031     });
5032
5033     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
5034       assert.expect(3);
5035
5036       lodashStable.each([-3, -4, -Infinity], function(end) {
5037         var array = [1, 2, 3];
5038         assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5039       });
5040     });
5041
5042     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5043       assert.expect(1);
5044
5045       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5046
5047       var actual = lodashStable.map(positions, function(pos) {
5048         var array = [1, 2, 3];
5049         return _.fill.apply(_, [array, 'a'].concat(pos));
5050       });
5051
5052       assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5053     });
5054
5055     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5056       assert.expect(1);
5057
5058       var array = [[1, 2], [3, 4]],
5059           actual = lodashStable.map(array, _.fill);
5060
5061       assert.deepEqual(actual, [[0, 0], [1, 1]]);
5062     });
5063
5064     QUnit.test('should return a wrapped value when chaining', function(assert) {
5065       assert.expect(3);
5066
5067       if (!isNpm) {
5068         var array = [1, 2, 3],
5069             wrapped = _(array).fill('a'),
5070             actual = wrapped.value();
5071
5072         assert.ok(wrapped instanceof _);
5073         assert.deepEqual(actual, ['a', 'a', 'a']);
5074         assert.strictEqual(actual, array);
5075       }
5076       else {
5077         skipTest(assert, 3);
5078       }
5079     });
5080   }());
5081
5082   /*--------------------------------------------------------------------------*/
5083
5084   QUnit.module('lodash.filter');
5085
5086   (function() {
5087     var array = [1, 2, 3];
5088
5089     QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5090       assert.expect(1);
5091
5092       assert.deepEqual(_.filter(array, isEven), [2]);
5093     });
5094
5095     QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
5096       assert.expect(1);
5097
5098       // Trigger a Mobile Safari 8 JIT bug.
5099       // See https://github.com/lodash/lodash/issues/799.
5100       var counter = 0,
5101           object = { '1': 'foo', '8': 'bar', '50': 'baz' };
5102
5103       lodashStable.times(1000, function(assert) {
5104         _.filter([], alwaysTrue);
5105       });
5106
5107       _.filter(object, function() {
5108         counter++;
5109         return true;
5110       });
5111
5112       assert.strictEqual(counter, 3);
5113     });
5114   }());
5115
5116   /*--------------------------------------------------------------------------*/
5117
5118   lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
5119     QUnit.module('lodash.' + methodName);
5120
5121     var func = _[methodName],
5122         isFindKey = /Key$/.test(methodName);
5123
5124     (function() {
5125       var objects = [
5126         { 'a': 0, 'b': 0 },
5127         { 'a': 1, 'b': 1 },
5128         { 'a': 2, 'b': 2 }
5129       ];
5130
5131       var expected = ({
5132         'find': [objects[1], undefined, objects[2], objects[1]],
5133         'findLast': [objects[2], undefined, objects[2], objects[2]],
5134         'findIndex': [1, -1, 2, 1],
5135         'findLastIndex': [2, -1, 2, 2],
5136         'findKey': ['1', undefined, '2', '1'],
5137         'findLastKey': ['2', undefined, '2', '2']
5138       })[methodName];
5139
5140       QUnit.test('should return the found value', function(assert) {
5141         assert.expect(1);
5142
5143         assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5144       });
5145
5146       QUnit.test('should return `' + expected[1] + '` if value is not found', function(assert) {
5147         assert.expect(1);
5148
5149         assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5150       });
5151
5152       QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
5153         assert.expect(1);
5154
5155         assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5156       });
5157
5158       QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
5159         assert.expect(1);
5160
5161         assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5162       });
5163
5164       QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
5165         assert.expect(1);
5166
5167         assert.strictEqual(func(objects, 'b'), expected[3]);
5168       });
5169
5170       QUnit.test('should return `' + expected[1] + '` for empty collections', function(assert) {
5171         assert.expect(1);
5172
5173         var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5174             expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5175
5176         var actual = lodashStable.map(emptyValues, function(value) {
5177           try {
5178             return func(value, { 'a': 3 });
5179           } catch (e) {}
5180         });
5181
5182         assert.deepEqual(actual, expecting);
5183       });
5184     }());
5185
5186     (function() {
5187       var array = [1, 2, 3, 4];
5188
5189       var expected = ({
5190         'find': 1,
5191         'findLast': 4,
5192         'findIndex': 0,
5193         'findLastIndex': 3,
5194         'findKey': '0',
5195         'findLastKey': '3'
5196       })[methodName];
5197
5198       QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
5199         assert.expect(1);
5200
5201         if (!isNpm) {
5202           assert.strictEqual(_(array)[methodName](), expected);
5203         }
5204         else {
5205           skipTest(assert);
5206         }
5207       });
5208
5209       QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
5210         assert.expect(1);
5211
5212         if (!isNpm) {
5213           assert.ok(_(array).chain()[methodName]() instanceof _);
5214         }
5215         else {
5216           skipTest(assert);
5217         }
5218       });
5219
5220       QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
5221         assert.expect(1);
5222
5223         if (!isNpm) {
5224           var wrapped = _(array).chain()[methodName]();
5225           assert.strictEqual(wrapped.__wrapped__, array);
5226         }
5227         else {
5228           skipTest(assert);
5229         }
5230       });
5231
5232       QUnit.test('should work in a lazy sequence', function(assert) {
5233         assert.expect(2);
5234
5235         if (!isNpm) {
5236           var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5237               smallArray = array;
5238
5239           lodashStable.times(2, function(index) {
5240             var array = index ? largeArray : smallArray,
5241                 wrapped = _(array).filter(isEven);
5242
5243             assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5244           });
5245         }
5246         else {
5247           skipTest(assert, 2);
5248         }
5249       });
5250     }());
5251
5252     (function() {
5253       var expected = ({
5254         'find': 1,
5255         'findLast': 2,
5256         'findKey': 'a',
5257         'findLastKey': 'b'
5258       })[methodName];
5259
5260       if (expected != null) {
5261         QUnit.test('should work with an object for `collection`', function(assert) {
5262           assert.expect(1);
5263
5264           var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(num) {
5265             return num < 3;
5266           });
5267
5268           assert.strictEqual(actual, expected);
5269         });
5270       }
5271     }());
5272   });
5273
5274   /*--------------------------------------------------------------------------*/
5275
5276   QUnit.module('lodash.find and lodash.findLast');
5277
5278   lodashStable.each(['find', 'findLast'], function(methodName) {
5279     var isFind = methodName == 'find';
5280
5281     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5282       assert.expect(3);
5283
5284       if (!isNpm) {
5285         var findCount = 0,
5286             mapCount = 0,
5287             array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5288             iteratee = function(value) { mapCount++; return square(value); },
5289             predicate = function(value) { findCount++; return isEven(value); },
5290             actual = _(array).map(iteratee)[methodName](predicate);
5291
5292         assert.strictEqual(findCount, isFind ? 2 : 1);
5293         assert.strictEqual(mapCount, isFind ? 2 : 1);
5294         assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
5295       }
5296       else {
5297         skipTest(assert, 3);
5298       }
5299     });
5300   });
5301
5302   /*--------------------------------------------------------------------------*/
5303
5304   QUnit.module('lodash.flip');
5305
5306   (function() {
5307     function fn() {
5308       return slice.call(arguments);
5309     }
5310
5311     QUnit.test('should flip arguments provided to `func`', function(assert) {
5312       assert.expect(1);
5313
5314       var flipped = _.flip(fn);
5315       assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
5316     });
5317   }());
5318
5319   /*--------------------------------------------------------------------------*/
5320
5321   QUnit.module('lodash.flatMap');
5322
5323   (function() {
5324     var array = [1, 2, 3, 4];
5325
5326     function duplicate(n) {
5327       return [n, n];
5328     }
5329
5330     QUnit.test('should map values in `array` to a new flattened array', function(assert) {
5331       assert.expect(1);
5332
5333       var actual = _.flatMap(array, duplicate),
5334           expected = lodashStable.flatten(lodashStable.map(array, duplicate));
5335
5336       assert.deepEqual(actual, expected);
5337     });
5338
5339     QUnit.test('should work in a lazy sequence', function(assert) {
5340       assert.expect(2);
5341
5342       if (!isNpm) {
5343         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
5344             smallArray = array;
5345
5346         lodashStable.times(2, function(index) {
5347           var array = index ? largeArray : smallArray,
5348               actual = _(array).filter(isEven).flatMap(duplicate).take(2).value();
5349
5350           assert.deepEqual(actual, _.take(_.flatMap(_.filter(array, isEven), duplicate), 2));
5351         });
5352       }
5353       else {
5354         skipTest(assert, 2);
5355       }
5356     });
5357   }());
5358
5359   /*--------------------------------------------------------------------------*/
5360
5361   QUnit.module('flatten methods');
5362
5363   (function() {
5364     var args = arguments;
5365
5366     QUnit.test('should perform a shallow flatten', function(assert) {
5367       assert.expect(1);
5368
5369       var array = [[['a']], [['b']]];
5370       assert.deepEqual(_.flatten(array), [['a'], ['b']]);
5371     });
5372
5373     QUnit.test('should flatten `arguments` objects', function(assert) {
5374       assert.expect(2);
5375
5376       var array = [args, [args]];
5377
5378       assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
5379       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
5380     });
5381
5382     QUnit.test('should treat sparse arrays as dense', function(assert) {
5383       assert.expect(6);
5384
5385       var array = [[1, 2, 3], Array(3)],
5386           expected = [1, 2, 3];
5387
5388       expected.push(undefined, undefined, undefined);
5389
5390       lodashStable.each([_.flatten(array), _.flatten(array, true), _.flattenDeep(array)], function(actual) {
5391         assert.deepEqual(actual, expected);
5392         assert.ok('4' in actual);
5393       });
5394     });
5395
5396     QUnit.test('should work with extremely large arrays', function(assert) {
5397       assert.expect(3);
5398
5399       // Test in modern browsers only to avoid browser hangs.
5400       lodashStable.times(3, function(index) {
5401         if (freeze) {
5402           var expected = Array(5e5);
5403
5404           try {
5405             if (index) {
5406               var actual = actual == 1 ? _.flatten([expected], true) : _.flattenDeep([expected]);
5407             } else {
5408               actual = _.flatten(expected);
5409             }
5410             assert.deepEqual(actual, expected);
5411           } catch (e) {
5412             assert.ok(false, e.message);
5413           }
5414         }
5415         else {
5416           skipTest(assert);
5417         }
5418       });
5419     });
5420
5421     QUnit.test('should work with empty arrays', function(assert) {
5422       assert.expect(2);
5423
5424       var array = [[], [[]], [[], [[[]]]]];
5425
5426       assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
5427       assert.deepEqual(_.flattenDeep(array), []);
5428     });
5429
5430     QUnit.test('should support flattening of nested arrays', function(assert) {
5431       assert.expect(2);
5432
5433       var array = [1, [2, 3], 4, [[5]]];
5434
5435       assert.deepEqual(_.flatten(array), [1, 2, 3, 4, [5]]);
5436       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
5437     });
5438
5439     QUnit.test('should return an empty array for non array-like objects', function(assert) {
5440       assert.expect(3);
5441
5442       var expected = [];
5443
5444       assert.deepEqual(_.flatten({ 'a': 1 }), expected);
5445       assert.deepEqual(_.flatten({ 'a': 1 }, true), expected);
5446       assert.deepEqual(_.flattenDeep({ 'a': 1 }), expected);
5447     });
5448
5449     QUnit.test('should return a wrapped value when chaining', function(assert) {
5450       assert.expect(4);
5451
5452       if (!isNpm) {
5453         var wrapped = _([1, [2], [3, [4]]]),
5454             actual = wrapped.flatten();
5455
5456         assert.ok(actual instanceof _);
5457         assert.deepEqual(actual.value(), [1, 2, 3, [4]]);
5458
5459         actual = wrapped.flattenDeep();
5460
5461         assert.ok(actual instanceof _);
5462         assert.deepEqual(actual.value(), [1, 2, 3, 4]);
5463       }
5464       else {
5465         skipTest(assert, 4);
5466       }
5467     });
5468   }(1, 2, 3));
5469
5470   /*--------------------------------------------------------------------------*/
5471
5472   QUnit.module('flow methods');
5473
5474   lodashStable.each(['flow', 'flowRight'], function(methodName) {
5475     var func = _[methodName],
5476         isFlow = methodName == 'flow';
5477
5478     QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
5479       assert.expect(1);
5480
5481       var fixed = function(n) { return n.toFixed(1); },
5482           combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
5483
5484       assert.strictEqual(combined(1, 2), '9.0');
5485     });
5486
5487     QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
5488       assert.expect(1);
5489
5490       assert.notStrictEqual(func(noop), noop);
5491     });
5492
5493     QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are provided', function(assert) {
5494       assert.expect(3);
5495
5496       var combined = func();
5497
5498       try {
5499         assert.strictEqual(combined('a'), 'a');
5500       } catch (e) {
5501         assert.ok(false, e.message);
5502       }
5503       assert.strictEqual(combined.length, 0);
5504       assert.notStrictEqual(combined, identity);
5505     });
5506
5507     QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
5508       assert.expect(1);
5509
5510       var curried = _.curry(identity);
5511
5512       var combined = isFlow
5513         ? func(_.head, curried)
5514         : func(curried, _.head);
5515
5516       assert.strictEqual(combined([1]), 1);
5517     });
5518
5519     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5520       assert.expect(6);
5521
5522       var filterCount,
5523           mapCount,
5524           array = lodashStable.range(LARGE_ARRAY_SIZE),
5525           iteratee = function(value) { mapCount++; return square(value); },
5526           predicate = function(value) { filterCount++; return isEven(value); };
5527
5528       lodashStable.times(2, function(index) {
5529         var filter1 = _.filter,
5530             filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
5531             filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
5532
5533         var map1 = _.map,
5534             map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
5535             map3 = (_.map = index ? map2 : map1, map2(iteratee));
5536
5537         var take1 = _.take,
5538             take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
5539             take3 = (_.take = index ? take2 : take1, take2(2));
5540
5541         var combined = isFlow
5542           ? func(map3, filter3, _.compact, take3)
5543           : func(take3, _.compact, filter3, map3);
5544
5545         filterCount = mapCount = 0;
5546         assert.deepEqual(combined(array), [4, 16]);
5547
5548         if (!isNpm && WeakMap && WeakMap.name) {
5549           assert.strictEqual(filterCount, 5, 'filterCount');
5550           assert.strictEqual(mapCount, 5, 'mapCount');
5551         }
5552         else {
5553           skipTest(assert, 2);
5554         }
5555         _.filter = filter1;
5556         _.map = map1;
5557         _.take = take1;
5558       });
5559     });
5560
5561     QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
5562       assert.expect(1);
5563
5564       var curried = _.curry(_.ary(_.map, 2), 2),
5565           getProp = curried(curried.placeholder, 'a'),
5566           objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
5567
5568       var combined = isFlow
5569         ? func(getProp, _.uniq)
5570         : func(_.uniq, getProp);
5571
5572       assert.deepEqual(combined(objects), [1, 2]);
5573     });
5574
5575     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
5576       assert.expect(1);
5577
5578       if (!isNpm) {
5579         var wrapped = _(noop)[methodName]();
5580         assert.ok(wrapped instanceof _);
5581       }
5582       else {
5583         skipTest(assert);
5584       }
5585     });
5586   });
5587
5588   /*--------------------------------------------------------------------------*/
5589
5590   QUnit.module('lodash.forEach');
5591
5592   (function() {
5593     QUnit.test('should be aliased', function(assert) {
5594       assert.expect(1);
5595
5596       assert.strictEqual(_.each, _.forEach);
5597     });
5598   }());
5599
5600   /*--------------------------------------------------------------------------*/
5601
5602   QUnit.module('lodash.forEachRight');
5603
5604   (function() {
5605     QUnit.test('should be aliased', function(assert) {
5606       assert.expect(1);
5607
5608       assert.strictEqual(_.eachRight, _.forEachRight);
5609     });
5610   }());
5611
5612   /*--------------------------------------------------------------------------*/
5613
5614   QUnit.module('forIn methods');
5615
5616   lodashStable.each(['forIn', 'forInRight'], function(methodName) {
5617     var func = _[methodName];
5618
5619     QUnit.test('`_.' + methodName + '` iterates over inherited properties', function(assert) {
5620       assert.expect(1);
5621
5622       function Foo() { this.a = 1; }
5623       Foo.prototype.b = 2;
5624
5625       var keys = [];
5626       func(new Foo, function(value, key) { keys.push(key); });
5627       assert.deepEqual(keys.sort(), ['a', 'b']);
5628     });
5629   });
5630
5631   /*--------------------------------------------------------------------------*/
5632
5633   QUnit.module('forOwn methods');
5634
5635   lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
5636     var func = _[methodName];
5637
5638     QUnit.test('should iterate over `length` properties', function(assert) {
5639       assert.expect(1);
5640
5641       var object = { '0': 'zero', '1': 'one', 'length': 2 },
5642           props = [];
5643
5644       func(object, function(value, prop) { props.push(prop); });
5645       assert.deepEqual(props.sort(), ['0', '1', 'length']);
5646     });
5647   });
5648
5649   /*--------------------------------------------------------------------------*/
5650
5651   QUnit.module('iteration methods');
5652
5653   (function() {
5654     var methods = [
5655       '_baseEach',
5656       'countBy',
5657       'every',
5658       'filter',
5659       'find',
5660       'findIndex',
5661       'findKey',
5662       'findLast',
5663       'findLastIndex',
5664       'findLastKey',
5665       'forEach',
5666       'forEachRight',
5667       'forIn',
5668       'forInRight',
5669       'forOwn',
5670       'forOwnRight',
5671       'groupBy',
5672       'keyBy',
5673       'map',
5674       'mapKeys',
5675       'mapValues',
5676       'maxBy',
5677       'minBy',
5678       'omitBy',
5679       'partition',
5680       'pickBy',
5681       'reject',
5682       'some'
5683     ];
5684
5685     var arrayMethods = [
5686       'findIndex',
5687       'findLastIndex',
5688       'maxBy',
5689       'minBy'
5690     ];
5691
5692     var collectionMethods = [
5693       '_baseEach',
5694       'countBy',
5695       'every',
5696       'filter',
5697       'find',
5698       'findLast',
5699       'forEach',
5700       'forEachRight',
5701       'groupBy',
5702       'keyBy',
5703       'map',
5704       'partition',
5705       'reduce',
5706       'reduceRight',
5707       'reject',
5708       'some'
5709     ];
5710
5711     var forInMethods = [
5712       'forIn',
5713       'forInRight',
5714       'omitBy',
5715       'pickBy'
5716     ];
5717
5718     var iterationMethods = [
5719       '_baseEach',
5720       'forEach',
5721       'forEachRight',
5722       'forIn',
5723       'forInRight',
5724       'forOwn',
5725       'forOwnRight'
5726     ];
5727
5728     var objectMethods = [
5729       'findKey',
5730       'findLastKey',
5731       'forIn',
5732       'forInRight',
5733       'forOwn',
5734       'forOwnRight',
5735       'mapKeys',
5736       'mapValues',
5737       'omitBy',
5738       'pickBy'
5739     ];
5740
5741     var rightMethods = [
5742       'findLast',
5743       'findLastIndex',
5744       'findLastKey',
5745       'forEachRight',
5746       'forInRight',
5747       'forOwnRight'
5748     ];
5749
5750     var unwrappedMethods = [
5751       'every',
5752       'find',
5753       'findIndex',
5754       'findKey',
5755       'findLast',
5756       'findLastIndex',
5757       'findLastKey',
5758       'forEach',
5759       'forEachRight',
5760       'forIn',
5761       'forInRight',
5762       'forOwn',
5763       'forOwnRight',
5764       'max',
5765       'maxBy',
5766       'min',
5767       'minBy',
5768       'some'
5769     ];
5770
5771     lodashStable.each(methods, function(methodName) {
5772       var array = [1, 2, 3],
5773           func = _[methodName],
5774           isBy = /(^partition|By)$/.test(methodName),
5775           isFind = /^find/.test(methodName),
5776           isSome = methodName == 'some';
5777
5778       QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
5779         assert.expect(1);
5780
5781         if (func) {
5782           var args,
5783               expected = [1, 0, array];
5784
5785           func(array, function() {
5786             args || (args = slice.call(arguments));
5787           });
5788
5789           if (lodashStable.includes(rightMethods, methodName)) {
5790             expected[0] = 3;
5791             expected[1] = 2;
5792           }
5793           if (lodashStable.includes(objectMethods, methodName)) {
5794             expected[1] += '';
5795           }
5796           if (isBy) {
5797             expected.length = 1;
5798           }
5799           assert.deepEqual(args, expected);
5800         }
5801         else {
5802           skipTest(assert);
5803         }
5804       });
5805
5806       QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
5807         assert.expect(1);
5808
5809         if (func) {
5810           var array = [1];
5811           array[2] = 3;
5812
5813           var expected = [[1, 0, array], [undefined, 1, array], [3, 2, array]];
5814
5815           if (isBy) {
5816             expected = lodashStable.map(expected, function(args) {
5817               return args.slice(0, 1);
5818             });
5819           }
5820           else if (lodashStable.includes(objectMethods, methodName)) {
5821             expected = lodashStable.map(expected, function(args) {
5822               args[1] += '';
5823               return args;
5824             });
5825           }
5826           if (lodashStable.includes(rightMethods, methodName)) {
5827             expected.reverse();
5828           }
5829           var argsList = [];
5830           func(array, function() {
5831             argsList.push(slice.call(arguments));
5832             return !(isFind || isSome);
5833           });
5834
5835           assert.deepEqual(argsList, expected);
5836         }
5837         else {
5838           skipTest(assert);
5839         }
5840       });
5841     });
5842
5843     lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
5844       var array = [1, 2, 3],
5845           func = _[methodName],
5846           isEvery = methodName == 'every';
5847
5848       array.a = 1;
5849
5850       QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
5851         assert.expect(1);
5852
5853         if (func) {
5854           var keys = [];
5855           func(array, function(value, key) {
5856             keys.push(key);
5857             return isEvery;
5858           });
5859
5860           assert.notOk(lodashStable.includes(keys, 'a'));
5861         }
5862         else {
5863           skipTest(assert);
5864         }
5865       });
5866     });
5867
5868     lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
5869       var array = [1, 2, 3],
5870           func = _[methodName],
5871           isBaseEach = methodName == '_baseEach';
5872
5873       QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
5874         assert.expect(1);
5875
5876         if (!(isBaseEach || isNpm)) {
5877           var wrapped = _(array)[methodName](noop);
5878           assert.ok(wrapped instanceof _);
5879         }
5880         else {
5881           skipTest(assert);
5882         }
5883       });
5884     });
5885
5886     lodashStable.each(unwrappedMethods, function(methodName) {
5887       var array = [1, 2, 3],
5888           func = _[methodName];
5889
5890       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5891         assert.expect(1);
5892
5893         if (!isNpm) {
5894           var actual = _(array)[methodName](noop);
5895           assert.notOk(actual instanceof _);
5896         }
5897         else {
5898           skipTest(assert);
5899         }
5900       });
5901
5902       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5903         assert.expect(2);
5904
5905         if (!isNpm) {
5906           var wrapped = _(array).chain(),
5907               actual = wrapped[methodName](noop);
5908
5909           assert.ok(actual instanceof _);
5910           assert.notStrictEqual(actual, wrapped);
5911         }
5912         else {
5913           skipTest(assert, 2);
5914         }
5915       });
5916     });
5917
5918     lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
5919       var array = [1, 2, 3],
5920           func = _[methodName];
5921
5922       QUnit.test('`_.' + methodName + '` iterates over own properties of objects', function(assert) {
5923         assert.expect(1);
5924
5925         function Foo() { this.a = 1; }
5926         Foo.prototype.b = 2;
5927
5928         if (func) {
5929           var values = [];
5930           func(new Foo, function(value) { values.push(value); });
5931           assert.deepEqual(values, [1]);
5932         }
5933         else {
5934           skipTest(assert);
5935         }
5936       });
5937     });
5938
5939     lodashStable.each(iterationMethods, function(methodName) {
5940       var array = [1, 2, 3],
5941           func = _[methodName];
5942
5943       QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
5944         assert.expect(1);
5945
5946         if (func) {
5947           assert.strictEqual(func(array, Boolean), array);
5948         }
5949         else {
5950           skipTest(assert);
5951         }
5952       });
5953     });
5954
5955     lodashStable.each(collectionMethods, function(methodName) {
5956       var func = _[methodName];
5957
5958       QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
5959         assert.expect(3);
5960
5961         if (func) {
5962           var isIteratedAsObject = function(object) {
5963             var result = false;
5964             func(object, function() { result = true; }, 0);
5965             return result;
5966           };
5967
5968           var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
5969               expected = lodashStable.map(values, alwaysTrue);
5970
5971           var actual = lodashStable.map(values, function(length) {
5972             return isIteratedAsObject({ 'length': length });
5973           });
5974
5975           var Foo = function(a) {};
5976           Foo.a = 1;
5977
5978           assert.deepEqual(actual, expected);
5979           assert.ok(isIteratedAsObject(Foo));
5980           assert.notOk(isIteratedAsObject({ 'length': 0 }));
5981         }
5982         else {
5983           skipTest(assert, 3);
5984         }
5985       });
5986     });
5987
5988     lodashStable.each(methods, function(methodName) {
5989       var array = [1, 2, 3],
5990           func = _[methodName],
5991           isFind = /^find/.test(methodName),
5992           isSome = methodName == 'some',
5993           isReduce = /^reduce/.test(methodName);
5994
5995       QUnit.test('`_.' + methodName + '` should ignore changes to `array.length`', function(assert) {
5996         assert.expect(1);
5997
5998         if (func) {
5999           var count = 0,
6000               array = [1];
6001
6002           func(array, function() {
6003             if (++count == 1) {
6004               array.push(2);
6005             }
6006             return !(isFind || isSome);
6007           }, isReduce ? array : null);
6008
6009           assert.strictEqual(count, 1);
6010         }
6011         else {
6012           skipTest(assert);
6013         }
6014       });
6015     });
6016
6017     lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
6018       var func = _[methodName],
6019           isFind = /^find/.test(methodName),
6020           isSome = methodName == 'some',
6021           isReduce = /^reduce/.test(methodName);
6022
6023       QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
6024         assert.expect(1);
6025
6026         if (func) {
6027           var count = 0,
6028               object = { 'a': 1 };
6029
6030           func(object, function() {
6031             if (++count == 1) {
6032               object.b = 2;
6033             }
6034             return !(isFind || isSome);
6035           }, isReduce ? object : null);
6036
6037           assert.strictEqual(count, 1);
6038         }
6039         else {
6040           skipTest(assert);
6041         }
6042       });
6043     });
6044   }());
6045
6046   /*--------------------------------------------------------------------------*/
6047
6048   QUnit.module('object assignments');
6049
6050   lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
6051     var func = _[methodName],
6052         isAssign = methodName == 'assign',
6053         isDefaults = methodName == 'defaults';
6054
6055     QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
6056       assert.expect(1);
6057
6058       var expected = lodashStable.map(falsey, alwaysTrue);
6059
6060       var actual = lodashStable.map(falsey, function(object, index) {
6061         var result = index ? func(object) : func();
6062         return lodashStable.isEqual(result, Object(object));
6063       });
6064
6065       assert.deepEqual(actual, expected);
6066     });
6067
6068     QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'source properties', function(assert) {
6069       assert.expect(1);
6070
6071       function Foo() { this.a = 1; }
6072       Foo.prototype.b = 2;
6073
6074       var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
6075       assert.deepEqual(func({}, new Foo), expected);
6076     });
6077
6078     QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
6079       assert.expect(1);
6080
6081       try {
6082         assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
6083       } catch (e) {
6084         assert.ok(false, e.message);
6085       }
6086     });
6087
6088     QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
6089       assert.expect(2);
6090
6091       var source = { 'a': 1 },
6092           values = [null, undefined],
6093           expected = lodashStable.map(values, alwaysTrue);
6094
6095       var actual = lodashStable.map(values, function(value) {
6096         var object = func(value, source);
6097         return object !== source && lodashStable.isEqual(object, source);
6098       });
6099
6100       assert.deepEqual(actual, expected);
6101
6102       actual = lodashStable.map(values, function(value) {
6103         return lodashStable.isEqual(func(value), {});
6104       });
6105
6106       assert.deepEqual(actual, expected);
6107     });
6108
6109     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
6110       assert.expect(2);
6111
6112       var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
6113           expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
6114
6115       assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
6116
6117       var fn = function() {};
6118       fn.a = array[0];
6119       fn.b = array[1];
6120       fn.c = array[2];
6121
6122       assert.deepEqual(_.reduce(fn, func, { 'a': 0 }), expected);
6123     });
6124
6125     QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
6126       assert.expect(1);
6127
6128       if (!isNpm) {
6129         var wrapped = _({ 'a': 1 }),
6130             actual = wrapped[methodName]({ 'b': 2 });
6131
6132         assert.notStrictEqual(actual, wrapped);
6133       }
6134       else {
6135         skipTest(assert);
6136       }
6137     });
6138   });
6139
6140   lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
6141     var func = _[methodName];
6142
6143     QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
6144       assert.expect(1);
6145
6146       function Foo() {}
6147       Foo.prototype.a = 1;
6148
6149       var actual = func(new Foo, { 'b': 2 });
6150       assert.notOk(_.has(actual, 'a'));
6151     });
6152   });
6153
6154   lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
6155     var func = _[methodName];
6156
6157     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
6158       assert.expect(4);
6159
6160       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
6161         if (defineProperty) {
6162           var object = {},
6163               pass = true;
6164
6165           defineProperty(object, 'a', {
6166             'enumerable': true,
6167             'configurable': true,
6168             'get': lodashStable.constant(value),
6169             'set': function() { pass = false; }
6170           });
6171
6172           func(object, { 'a': value });
6173           assert.ok(pass);
6174         }
6175         else {
6176           skipTest(assert);
6177         }
6178       });
6179     });
6180   });
6181
6182   lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
6183     var func = _[methodName],
6184         isMergeWith = methodName == 'mergeWith';
6185
6186     QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
6187       assert.expect(3);
6188
6189       var args,
6190           object = { 'a': 1 },
6191           source = { 'a': 2 },
6192           expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
6193
6194       func(object, source, function() {
6195         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6196       });
6197
6198       assert.deepEqual(args, expected, 'primitive property values');
6199
6200       args = undefined;
6201       object = { 'a': 1 };
6202       source = { 'b': 2 };
6203       expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
6204
6205       func(object, source, function() {
6206         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6207       });
6208
6209       assert.deepEqual(args, expected, 'missing destination property');
6210
6211       var argsList = [],
6212           objectValue = [1, 2],
6213           sourceValue = { 'b': 2 };
6214
6215       object = { 'a': objectValue };
6216       source = { 'a': sourceValue };
6217       expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
6218
6219       if (isMergeWith) {
6220         expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
6221       }
6222       func(object, source, function() {
6223         argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6224       });
6225
6226       assert.deepEqual(argsList, expected, 'object property values');
6227     });
6228
6229     QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
6230       assert.expect(2);
6231
6232       function callback() {}
6233       callback.b = 2;
6234
6235       var actual = func({ 'a': 1 }, callback);
6236       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
6237
6238       actual = func({ 'a': 1 }, callback, { 'c': 3 });
6239       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
6240     });
6241   });
6242
6243   /*--------------------------------------------------------------------------*/
6244
6245   QUnit.module('exit early');
6246
6247   lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
6248     var func = _[methodName];
6249
6250     QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
6251       assert.expect(1);
6252
6253       if (func) {
6254         var array = [1, 2, 3],
6255             values = [];
6256
6257         func(array, function(value, other) {
6258           values.push(lodashStable.isArray(value) ? other : value);
6259           return false;
6260         });
6261
6262         assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
6263       }
6264       else {
6265         skipTest(assert);
6266       }
6267     });
6268
6269     QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
6270       assert.expect(1);
6271
6272       if (func) {
6273         var object = { 'a': 1, 'b': 2, 'c': 3 },
6274             values = [];
6275
6276         func(object, function(value, other) {
6277           values.push(lodashStable.isArray(value) ? other : value);
6278           return false;
6279         });
6280
6281         assert.strictEqual(values.length, 1);
6282       }
6283       else {
6284         skipTest(assert);
6285       }
6286     });
6287   });
6288
6289   /*--------------------------------------------------------------------------*/
6290
6291   QUnit.module('`__proto__` property bugs');
6292
6293   (function() {
6294     QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
6295       assert.expect(4);
6296
6297       var stringLiteral = '__proto__',
6298           stringObject = Object(stringLiteral),
6299           expected = [stringLiteral, stringObject];
6300
6301       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
6302         return isEven(count) ? stringLiteral : stringObject;
6303       });
6304
6305       assert.deepEqual(_.difference(largeArray, largeArray), []);
6306       assert.deepEqual(_.intersection(largeArray, largeArray), expected);
6307       assert.deepEqual(_.uniq(largeArray), expected);
6308       assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
6309     });
6310   }());
6311
6312   /*--------------------------------------------------------------------------*/
6313
6314   QUnit.module('lodash.fromPairs');
6315
6316   (function() {
6317     var object = { 'barney': 36, 'fred': 40 },
6318         array = [['barney', 36], ['fred', 40]];
6319
6320     QUnit.test('should accept a two dimensional array', function(assert) {
6321       assert.expect(1);
6322
6323       var actual = _.fromPairs(array);
6324       assert.deepEqual(actual, object);
6325     });
6326
6327     QUnit.test('should accept a falsey `array` argument', function(assert) {
6328       assert.expect(1);
6329
6330       var expected = lodashStable.map(falsey, alwaysEmptyObject);
6331
6332       var actual = lodashStable.map(falsey, function(array, index) {
6333         try {
6334           return index ? _.fromPairs(array) : _.fromPairs();
6335         } catch (e) {}
6336       });
6337
6338       assert.deepEqual(actual, expected);
6339     });
6340
6341     QUnit.test('should support deep paths', function(assert) {
6342       assert.expect(1);
6343
6344       var actual = _.fromPairs([['a.b.c', 1]]);
6345       assert.deepEqual(actual, { 'a': { 'b': { 'c': 1 } } });
6346     });
6347
6348     QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
6349       assert.expect(1);
6350
6351       assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
6352     });
6353
6354     QUnit.test('should work in a lazy sequence', function(assert) {
6355       assert.expect(1);
6356
6357       if (!isNpm) {
6358         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
6359           return ['key' + index, index];
6360         });
6361
6362         var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
6363
6364         assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
6365       }
6366       else {
6367         skipTest(assert);
6368       }
6369     });
6370   }());
6371
6372   /*--------------------------------------------------------------------------*/
6373
6374   QUnit.module('lodash.functions');
6375
6376   (function() {
6377     QUnit.test('should return the function names of an object', function(assert) {
6378       assert.expect(1);
6379
6380       var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': lodashStable.each };
6381       assert.deepEqual(_.functions(object).sort(), ['b', 'd']);
6382     });
6383
6384     QUnit.test('should not include inherited functions', function(assert) {
6385       assert.expect(1);
6386
6387       function Foo() {
6388         this.a = identity;
6389         this.b = 'b';
6390       }
6391       Foo.prototype.c = noop;
6392       assert.deepEqual(_.functions(new Foo).sort(), ['a']);
6393     });
6394   }());
6395
6396   /*--------------------------------------------------------------------------*/
6397
6398   QUnit.module('lodash.groupBy');
6399
6400   (function() {
6401     var array = [4.2, 6.1, 6.4];
6402
6403     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
6404       assert.expect(1);
6405
6406       var array = [4, 6, 6],
6407           values = [, null, undefined],
6408           expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
6409
6410       var actual = lodashStable.map(values, function(value, index) {
6411         return index ? _.groupBy(array, value) : _.groupBy(array);
6412       });
6413
6414       assert.deepEqual(actual, expected);
6415     });
6416
6417     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
6418       assert.expect(1);
6419
6420       var actual = _.groupBy(['one', 'two', 'three'], 'length');
6421       assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
6422     });
6423
6424     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
6425       assert.expect(2);
6426
6427       var actual = _.groupBy([4.2, 6.1, 6.4], function(num) {
6428         return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
6429       });
6430
6431       assert.deepEqual(actual.constructor, [4.2]);
6432       assert.deepEqual(actual.hasOwnProperty, [6.1, 6.4]);
6433     });
6434
6435     QUnit.test('should work with a number for `iteratee`', function(assert) {
6436       assert.expect(2);
6437
6438       var array = [
6439         [1, 'a'],
6440         [2, 'a'],
6441         [2, 'b']
6442       ];
6443
6444       assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
6445       assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
6446     });
6447
6448     QUnit.test('should work with an object for `collection`', function(assert) {
6449       assert.expect(1);
6450
6451       var actual = _.groupBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) {
6452         return Math.floor(num);
6453       });
6454
6455       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.4] });
6456     });
6457
6458     QUnit.test('should work in a lazy sequence', function(assert) {
6459       assert.expect(1);
6460
6461       if (!isNpm) {
6462         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
6463           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
6464           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
6465         );
6466
6467         var iteratee = function(value) { value.push(value[0]); return value; },
6468             predicate = function(value) { return isEven(value[0]); },
6469             actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
6470
6471         assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
6472       }
6473       else {
6474         skipTest(assert);
6475       }
6476     });
6477   }());
6478
6479   /*--------------------------------------------------------------------------*/
6480
6481   QUnit.module('lodash.gt');
6482
6483   (function() {
6484     QUnit.test('should return `true` if `value` > `other`', function(assert) {
6485       assert.expect(2);
6486
6487       assert.strictEqual(_.gt(3, 1), true);
6488       assert.strictEqual(_.gt('def', 'abc'), true);
6489     });
6490
6491     QUnit.test('should return `false` if `value` is less than or equal to `other`', function(assert) {
6492       assert.expect(4);
6493
6494       assert.strictEqual(_.gt(1, 3), false);
6495       assert.strictEqual(_.gt(3, 3), false);
6496       assert.strictEqual(_.gt('abc', 'def'), false);
6497       assert.strictEqual(_.gt('def', 'def'), false);
6498     });
6499   }());
6500
6501   /*--------------------------------------------------------------------------*/
6502
6503   QUnit.module('lodash.gte');
6504
6505   (function() {
6506     QUnit.test('should return `true` if `value` >= `other`', function(assert) {
6507       assert.expect(4);
6508
6509       assert.strictEqual(_.gte(3, 1), true);
6510       assert.strictEqual(_.gte(3, 3), true);
6511       assert.strictEqual(_.gte('def', 'abc'), true);
6512       assert.strictEqual(_.gte('def', 'def'), true);
6513     });
6514
6515     QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
6516       assert.expect(2);
6517
6518       assert.strictEqual(_.gte(1, 3), false);
6519       assert.strictEqual(_.gte('abc', 'def'), false);
6520     });
6521   }());
6522
6523   /*--------------------------------------------------------------------------*/
6524
6525   QUnit.module('has methods');
6526
6527   lodashStable.each(['has', 'hasIn'], function(methodName) {
6528     var args = (function() { return arguments; }(1, 2, 3)),
6529         func = _[methodName],
6530         isHas = methodName == 'has';
6531
6532     QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
6533       assert.expect(2);
6534
6535       var object = { 'a': 1 };
6536
6537       lodashStable.each(['a', ['a']], function(path) {
6538         assert.strictEqual(func(object, path), true);
6539       });
6540     });
6541
6542     QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
6543       assert.expect(1);
6544
6545       var object = { 'hasOwnProperty': null, 'a': 1 };
6546       assert.strictEqual(func(object, 'a'), true);
6547     });
6548
6549     QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
6550       assert.expect(2);
6551
6552       var object = { 'a': { 'b': { 'c': 3 } } };
6553
6554       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
6555         assert.strictEqual(func(object, path), true);
6556       });
6557     });
6558
6559     QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
6560       assert.expect(1);
6561
6562       function fn() {}
6563       fn.toString = lodashStable.constant('fn');
6564
6565       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
6566           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
6567           values = [null, undefined, fn, {}];
6568
6569       var actual = lodashStable.transform(objects, function(result, object, index) {
6570         var key = values[index];
6571         lodashStable.each([key, [key]], function(path) {
6572           var prop = _.property(key);
6573           result.push(prop(object));
6574         });
6575       });
6576
6577       assert.deepEqual(actual, expected);
6578     });
6579
6580     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
6581       assert.expect(1);
6582
6583       assert.strictEqual(func(args, 1), true);
6584     });
6585
6586     QUnit.test('`_.' + methodName + '` should work with non-string `path` arguments', function(assert) {
6587       assert.expect(2);
6588
6589       var array = [1, 2, 3];
6590
6591       lodashStable.each([1, [1]], function(path) {
6592         assert.strictEqual(func(array, path), true);
6593       });
6594     });
6595
6596     QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
6597       assert.expect(1);
6598
6599       if (create)  {
6600         var object = create(null);
6601         object[1] = 'a';
6602         assert.strictEqual(func(object, 1), true);
6603       }
6604       else {
6605         skipTest(assert);
6606       }
6607     });
6608
6609     QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
6610       assert.expect(2);
6611
6612       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
6613
6614       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
6615         assert.strictEqual(func(object, path), true);
6616       });
6617     });
6618
6619     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
6620       assert.expect(2);
6621
6622       function Foo() {}
6623       Foo.prototype.a = 1;
6624
6625       lodashStable.each(['a', ['a']], function(path) {
6626         assert.strictEqual(func(new Foo, path), !isHas);
6627       });
6628     });
6629
6630     QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
6631       assert.expect(1);
6632
6633       var string = Object('abc');
6634       delete args[0];
6635       delete string[0];
6636
6637       var values = [Array(3), args, string],
6638           expected = lodashStable.map(values, alwaysTrue);
6639
6640       var actual = lodashStable.map(values, function(value) {
6641         return func(value, 0);
6642       });
6643
6644       assert.deepEqual(actual, expected);
6645       args[0] = 1;
6646     });
6647
6648     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
6649       assert.expect(2);
6650
6651       var values = [null, undefined],
6652           expected = lodashStable.map(values, alwaysFalse);
6653
6654       lodashStable.each(['constructor', ['constructor']], function(path) {
6655         var actual = lodashStable.map(values, function(value) {
6656           return func(value, path);
6657         });
6658
6659         assert.deepEqual(actual, expected);
6660       });
6661     });
6662
6663     QUnit.test('`_.' + methodName + '` should return `false` with deep paths when `object` is nullish', function(assert) {
6664       assert.expect(2);
6665
6666       var values = [null, undefined],
6667           expected = lodashStable.map(values, alwaysFalse);
6668
6669       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
6670         var actual = lodashStable.map(values, function(value) {
6671           return func(value, path);
6672         });
6673
6674         assert.deepEqual(actual, expected);
6675       });
6676     });
6677
6678     QUnit.test('`_.' + methodName + '` should return `false` if parts of `path` are missing', function(assert) {
6679       assert.expect(4);
6680
6681       var object = {};
6682
6683       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
6684         assert.strictEqual(func(object, path), false);
6685       });
6686     });
6687   });
6688
6689   /*--------------------------------------------------------------------------*/
6690
6691   QUnit.module('lodash.head');
6692
6693   (function() {
6694     var array = [1, 2, 3, 4];
6695
6696     QUnit.test('should return the first element', function(assert) {
6697       assert.expect(1);
6698
6699       assert.strictEqual(_.head(array), 1);
6700     });
6701
6702     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
6703       assert.expect(1);
6704
6705       var array = [];
6706       array['-1'] = 1;
6707
6708       assert.strictEqual(_.head(array), undefined);
6709     });
6710
6711     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
6712       assert.expect(1);
6713
6714       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
6715           actual = lodashStable.map(array, _.head);
6716
6717       assert.deepEqual(actual, [1, 4, 7]);
6718     });
6719
6720     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
6721       assert.expect(1);
6722
6723       if (!isNpm) {
6724         assert.strictEqual(_(array).head(), 1);
6725       }
6726       else {
6727         skipTest(assert);
6728       }
6729     });
6730
6731     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
6732       assert.expect(1);
6733
6734       if (!isNpm) {
6735         assert.ok(_(array).chain().head() instanceof _);
6736       }
6737       else {
6738         skipTest(assert);
6739       }
6740     });
6741
6742     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
6743       assert.expect(1);
6744
6745       if (!isNpm) {
6746         var wrapped = _(array).chain().head();
6747         assert.strictEqual(wrapped.__wrapped__, array);
6748       }
6749       else {
6750         skipTest(assert);
6751       }
6752     });
6753
6754     QUnit.test('should work in a lazy sequence', function(assert) {
6755       assert.expect(2);
6756
6757       if (!isNpm) {
6758         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
6759             smallArray = array;
6760
6761         lodashStable.times(2, function(index) {
6762           var array = index ? largeArray : smallArray,
6763               wrapped = _(array).filter(isEven);
6764
6765           assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
6766         });
6767       }
6768       else {
6769         skipTest(assert, 2);
6770       }
6771     });
6772
6773     QUnit.test('should be aliased', function(assert) {
6774       assert.expect(1);
6775
6776       assert.strictEqual(_.first, _.head);
6777     });
6778   }());
6779
6780   /*--------------------------------------------------------------------------*/
6781
6782   QUnit.module('lodash.identity');
6783
6784   (function() {
6785     QUnit.test('should return the first argument provided', function(assert) {
6786       assert.expect(1);
6787
6788       var object = { 'name': 'fred' };
6789       assert.strictEqual(_.identity(object), object);
6790     });
6791   }());
6792
6793   /*--------------------------------------------------------------------------*/
6794
6795   QUnit.module('lodash.includes');
6796
6797   (function() {
6798     lodashStable.each({
6799       'an `arguments` object': arguments,
6800       'an array': [1, 2, 3, 4],
6801       'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
6802       'a string': '1234'
6803     },
6804     function(collection, key) {
6805       var isStr = typeof collection == 'string',
6806           values = _.toArray(collection),
6807           length = values.length;
6808
6809       QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
6810         assert.expect(1);
6811
6812         assert.strictEqual(_.includes(collection, 3), true);
6813       });
6814
6815       QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
6816         assert.expect(1);
6817
6818         assert.strictEqual(_.includes(collection, 5), false);
6819       });
6820
6821       QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6822         assert.expect(2);
6823
6824         assert.strictEqual(_.includes(collection, values[2], 2), true);
6825         assert.strictEqual(_.includes(collection, values[1], 2), false);
6826       });
6827
6828       QUnit.test('should work with ' + key + ' and a `fromIndex` >= `collection.length`', function(assert) {
6829         assert.expect(12);
6830
6831         lodashStable.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) {
6832           assert.strictEqual(_.includes(collection, 1, fromIndex), false);
6833           assert.strictEqual(_.includes(collection, undefined, fromIndex), false);
6834           assert.strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length));
6835         });
6836       });
6837
6838       QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
6839         assert.expect(1);
6840
6841         var expected = lodashStable.map(falsey, alwaysTrue);
6842
6843         var actual = lodashStable.map(falsey, function(fromIndex) {
6844           return _.includes(collection, values[0], fromIndex);
6845         });
6846
6847         assert.deepEqual(actual, expected);
6848       });
6849
6850       QUnit.test('should work with ' + key + ' and coerce non-integer `fromIndex` values to integers', function(assert) {
6851         assert.expect(3);
6852
6853         assert.strictEqual(_.includes(collection, values[0], '1'), false);
6854         assert.strictEqual(_.includes(collection, values[0], 0.1), true);
6855         assert.strictEqual(_.includes(collection, values[0], NaN), true);
6856       });
6857
6858       QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6859         assert.expect(2);
6860
6861         assert.strictEqual(_.includes(collection, values[2], -2), true);
6862         assert.strictEqual(_.includes(collection, values[1], -2), false);
6863       });
6864
6865       QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= negative `collection.length`', function(assert) {
6866         assert.expect(3);
6867
6868         lodashStable.each([-4, -6, -Infinity], function(fromIndex) {
6869           assert.strictEqual(_.includes(collection, values[0], fromIndex), true);
6870         });
6871       });
6872
6873       QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
6874         assert.expect(1);
6875
6876         assert.strictEqual(_.includes(collection, 2, 1.2), true);
6877       });
6878
6879       QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
6880         assert.expect(1);
6881
6882         if (!isNpm) {
6883           assert.strictEqual(_(collection).includes(3), true);
6884         }
6885         else {
6886           skipTest(assert);
6887         }
6888       });
6889
6890       QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
6891         assert.expect(1);
6892
6893         if (!isNpm) {
6894           assert.ok(_(collection).chain().includes(3) instanceof _);
6895         }
6896         else {
6897           skipTest(assert);
6898         }
6899       });
6900     });
6901
6902     lodashStable.each({
6903       'literal': 'abc',
6904       'object': Object('abc')
6905     },
6906     function(collection, key) {
6907       QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
6908         assert.expect(2);
6909
6910         assert.strictEqual(_.includes(collection, 'bc'), true);
6911         assert.strictEqual(_.includes(collection, 'd'), false);
6912       });
6913     });
6914
6915     QUnit.test('should return `false` for empty collections', function(assert) {
6916       assert.expect(1);
6917
6918       var expected = lodashStable.map(empties, alwaysFalse);
6919
6920       var actual = lodashStable.map(empties, function(value) {
6921         try {
6922           return _.includes(value);
6923         } catch (e) {}
6924       });
6925
6926       assert.deepEqual(actual, expected);
6927     });
6928
6929     QUnit.test('should match `NaN`', function(assert) {
6930       assert.expect(1);
6931
6932       assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
6933     });
6934
6935     QUnit.test('should match `-0` as `0`', function(assert) {
6936       assert.expect(2);
6937
6938       assert.strictEqual(_.includes([-0], 0), true);
6939       assert.strictEqual(_.includes([0], -0), true);
6940     });
6941
6942     QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
6943       assert.expect(1);
6944
6945       var array1 = [1, 2, 3],
6946           array2 = [2, 3, 1];
6947
6948       assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
6949     });
6950   }(1, 2, 3, 4));
6951
6952   /*--------------------------------------------------------------------------*/
6953
6954   QUnit.module('lodash.indexOf');
6955
6956   (function() {
6957     var array = [1, 2, 3, 1, 2, 3];
6958
6959     QUnit.test('should return the index of the first matched value', function(assert) {
6960       assert.expect(1);
6961
6962       assert.strictEqual(_.indexOf(array, 3), 2);
6963     });
6964
6965     QUnit.test('should work with a positive `fromIndex`', function(assert) {
6966       assert.expect(1);
6967
6968       assert.strictEqual(_.indexOf(array, 1, 2), 3);
6969     });
6970
6971     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
6972       assert.expect(1);
6973
6974       var values = [6, 8, Math.pow(2, 32), Infinity],
6975           expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
6976
6977       var actual = lodashStable.map(values, function(fromIndex) {
6978         return [
6979           _.indexOf(array, undefined, fromIndex),
6980           _.indexOf(array, 1, fromIndex),
6981           _.indexOf(array, '', fromIndex)
6982         ];
6983       });
6984
6985       assert.deepEqual(actual, expected);
6986     });
6987
6988     QUnit.test('should work with a negative `fromIndex`', function(assert) {
6989       assert.expect(1);
6990
6991       assert.strictEqual(_.indexOf(array, 2, -3), 4);
6992     });
6993
6994     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
6995       assert.expect(1);
6996
6997       var values = [-6, -8, -Infinity],
6998           expected = lodashStable.map(values, alwaysZero);
6999
7000       var actual = lodashStable.map(values, function(fromIndex) {
7001         return _.indexOf(array, 1, fromIndex);
7002       });
7003
7004       assert.deepEqual(actual, expected);
7005     });
7006
7007     QUnit.test('should treat falsey `fromIndex` values as `0`', function(assert) {
7008       assert.expect(1);
7009
7010       var expected = lodashStable.map(falsey, alwaysZero);
7011
7012       var actual = lodashStable.map(falsey, function(fromIndex) {
7013         return _.indexOf(array, 1, fromIndex);
7014       });
7015
7016       assert.deepEqual(actual, expected);
7017     });
7018
7019     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
7020       assert.expect(1);
7021
7022       assert.strictEqual(_.indexOf(array, 2, 1.2), 1);
7023     });
7024   }());
7025
7026   /*--------------------------------------------------------------------------*/
7027
7028   QUnit.module('lodash.initial');
7029
7030   (function() {
7031     var array = [1, 2, 3];
7032
7033     QUnit.test('should accept a falsey `array` argument', function(assert) {
7034       assert.expect(1);
7035
7036       var expected = lodashStable.map(falsey, alwaysEmptyArray);
7037
7038       var actual = lodashStable.map(falsey, function(array, index) {
7039         try {
7040           return index ? _.initial(array) : _.initial();
7041         } catch (e) {}
7042       });
7043
7044       assert.deepEqual(actual, expected);
7045     });
7046
7047     QUnit.test('should exclude last element', function(assert) {
7048       assert.expect(1);
7049
7050       assert.deepEqual(_.initial(array), [1, 2]);
7051     });
7052
7053     QUnit.test('should return an empty when querying empty arrays', function(assert) {
7054       assert.expect(1);
7055
7056       assert.deepEqual(_.initial([]), []);
7057     });
7058
7059     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7060       assert.expect(1);
7061
7062       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7063           actual = lodashStable.map(array, _.initial);
7064
7065       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
7066     });
7067
7068     QUnit.test('should work in a lazy sequence', function(assert) {
7069       assert.expect(4);
7070
7071       if (!isNpm) {
7072         var array = lodashStable.range(LARGE_ARRAY_SIZE),
7073             values = [];
7074
7075         var actual = _(array).initial().filter(function(value) {
7076           values.push(value);
7077           return false;
7078         })
7079         .value();
7080
7081         assert.deepEqual(actual, []);
7082         assert.deepEqual(values, _.initial(array));
7083
7084         values = [];
7085
7086         actual = _(array).filter(function(value) {
7087           values.push(value);
7088           return isEven(value);
7089         })
7090         .initial()
7091         .value();
7092
7093         assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
7094         assert.deepEqual(values, array);
7095       }
7096       else {
7097         skipTest(assert, 4);
7098       }
7099     });
7100   }());
7101
7102   /*--------------------------------------------------------------------------*/
7103
7104   QUnit.module('lodash.inRange');
7105
7106   (function() {
7107     QUnit.test('should work with an `end` argument', function(assert) {
7108       assert.expect(3);
7109
7110       assert.strictEqual(_.inRange(3, 5), true);
7111       assert.strictEqual(_.inRange(5, 5), false);
7112       assert.strictEqual(_.inRange(6, 5), false);
7113     });
7114
7115     QUnit.test('should work with `start` and `end` arguments', function(assert) {
7116       assert.expect(4);
7117
7118       assert.strictEqual(_.inRange(1, 1, 5), true);
7119       assert.strictEqual(_.inRange(3, 1, 5), true);
7120       assert.strictEqual(_.inRange(0, 1, 5), false);
7121       assert.strictEqual(_.inRange(5, 1, 5), false);
7122     });
7123
7124     QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
7125       assert.expect(13);
7126
7127       lodashStable.each(falsey, function(value, index) {
7128         if (index) {
7129           assert.strictEqual(_.inRange(0, value), false);
7130           assert.strictEqual(_.inRange(0, value, 1), true);
7131         } else {
7132           assert.strictEqual(_.inRange(0), false);
7133         }
7134       });
7135     });
7136
7137     QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
7138       assert.expect(2);
7139
7140       assert.strictEqual(_.inRange(2, 5, 1), true);
7141       assert.strictEqual(_.inRange(-3, -2, -6), true);
7142     });
7143
7144     QUnit.test('should work with a floating point `n` value', function(assert) {
7145       assert.expect(4);
7146
7147       assert.strictEqual(_.inRange(0.5, 5), true);
7148       assert.strictEqual(_.inRange(1.2, 1, 5), true);
7149       assert.strictEqual(_.inRange(5.2, 5), false);
7150       assert.strictEqual(_.inRange(0.5, 1, 5), false);
7151     });
7152
7153     QUnit.test('should coerce arguments to finite numbers', function(assert) {
7154       assert.expect(1);
7155
7156       var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
7157           expected = lodashStable.map(actual, alwaysTrue);
7158
7159       assert.deepEqual(actual, expected);
7160     });
7161   }());
7162
7163   /*--------------------------------------------------------------------------*/
7164
7165   QUnit.module('intersection methods');
7166
7167   lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
7168     var args = (function() { return arguments; }(1, 2, 3)),
7169         func = _[methodName];
7170
7171     QUnit.test('`_.' + methodName + '` should return the intersection of the given arrays', function(assert) {
7172       assert.expect(1);
7173
7174       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
7175       assert.deepEqual(actual, [1, 2]);
7176     });
7177
7178     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
7179       assert.expect(1);
7180
7181       var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
7182       assert.deepEqual(actual, [1, 2]);
7183     });
7184
7185     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
7186       assert.expect(1);
7187
7188       var actual = func([1, NaN, 3], [NaN, 5, NaN]);
7189       assert.deepEqual(actual, [NaN]);
7190     });
7191
7192     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
7193       assert.expect(2);
7194
7195       var object = {},
7196           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
7197
7198       assert.deepEqual(func([object], largeArray), [object]);
7199       assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
7200     });
7201
7202     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
7203       assert.expect(1);
7204
7205       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
7206       assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
7207     });
7208
7209     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7210       assert.expect(2);
7211
7212       var array = [0, 1, null, 3],
7213           expected = [1, 3];
7214
7215       assert.deepEqual(func(array, args), expected);
7216       assert.deepEqual(func(args, array), expected);
7217     });
7218
7219     QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
7220       assert.expect(1);
7221
7222       var actual = func([1, 1, 3, 2, 2]);
7223       assert.deepEqual(actual, [1, 3, 2]);
7224     });
7225
7226     QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
7227       assert.expect(3);
7228
7229       var array = [0, 1, null, 3];
7230       assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
7231       assert.deepEqual(func(null, array, null, [2, 3]), []);
7232       assert.deepEqual(func(array, null, args, null), []);
7233     });
7234
7235     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
7236       assert.expect(2);
7237
7238       if (!isNpm) {
7239         var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
7240         assert.ok(wrapped instanceof _);
7241         assert.deepEqual(wrapped.value(), [1, 2]);
7242       }
7243       else {
7244         skipTest(assert, 2);
7245       }
7246     });
7247   });
7248
7249   /*--------------------------------------------------------------------------*/
7250
7251   QUnit.module('lodash.intersectionBy');
7252
7253   (function() {
7254     QUnit.test('should accept an `iteratee` argument', function(assert) {
7255       assert.expect(2);
7256
7257       var actual = _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7258       assert.deepEqual(actual, [2.1]);
7259
7260       actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7261       assert.deepEqual(actual, [{ 'x': 1 }]);
7262     });
7263
7264     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
7265       assert.expect(1);
7266
7267       var args;
7268
7269       _.intersectionBy([2.1, 1.2], [4.3, 2.4], function() {
7270         args || (args = slice.call(arguments));
7271       });
7272
7273       assert.deepEqual(args, [4.3]);
7274     });
7275   }());
7276
7277   /*--------------------------------------------------------------------------*/
7278
7279   QUnit.module('lodash.intersectionWith');
7280
7281   (function() {
7282     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7283
7284     QUnit.test('should work with a `comparator` argument', function(assert) {
7285       assert.expect(1);
7286
7287       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
7288           actual = _.intersectionWith(objects, others, lodashStable.isEqual);
7289
7290       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }]);
7291     });
7292   }());
7293
7294   /*--------------------------------------------------------------------------*/
7295
7296   QUnit.module('lodash.invert');
7297
7298   (function() {
7299     QUnit.test('should invert an object', function(assert) {
7300       assert.expect(2);
7301
7302       var object = { 'a': 1, 'b': 2 },
7303           actual = _.invert(object);
7304
7305       assert.deepEqual(actual, { '1': 'a', '2': 'b' });
7306       assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
7307     });
7308
7309     QUnit.test('should work with an object that has a `length` property', function(assert) {
7310       assert.expect(1);
7311
7312       var object = { '0': 'a', '1': 'b', 'length': 2 };
7313       assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
7314     });
7315
7316     QUnit.test('should accept a `multiValue` flag', function(assert) {
7317       assert.expect(1);
7318
7319       var object = { 'a': 1, 'b': 2, 'c': 1 };
7320       assert.deepEqual(_.invert(object, true), { '1': ['a', 'c'], '2': ['b'] });
7321     });
7322
7323     QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
7324       assert.expect(2);
7325
7326       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
7327
7328       assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
7329       assert.ok(lodashStable.isEqual(_.invert(object, true), { 'hasOwnProperty': ['a'], 'constructor': ['b'] }));
7330     });
7331
7332     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7333       assert.expect(2);
7334
7335       var regular = { 'a': 1, 'b': 2, 'c': 1 },
7336           inverted = { '1': 'c', '2': 'b' };
7337
7338       var array = [regular, regular, regular],
7339           object = { 'a': regular, 'b': regular, 'c': regular },
7340           expected = lodashStable.map(array, lodashStable.constant(inverted));
7341
7342       lodashStable.each([array, object], function(collection) {
7343         var actual = lodashStable.map(collection, _.invert);
7344         assert.deepEqual(actual, expected);
7345       });
7346     });
7347
7348     QUnit.test('should return a wrapped value when chaining', function(assert) {
7349       assert.expect(2);
7350
7351       if (!isNpm) {
7352         var object = { 'a': 1, 'b': 2 },
7353             wrapped = _(object).invert();
7354
7355         assert.ok(wrapped instanceof _);
7356         assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
7357       }
7358       else {
7359         skipTest(assert, 2);
7360       }
7361     });
7362   }());
7363
7364   /*--------------------------------------------------------------------------*/
7365
7366   QUnit.module('lodash.invoke');
7367
7368   (function() {
7369     QUnit.test('should invoke a method on `object`', function(assert) {
7370       assert.expect(1);
7371
7372       var object = { 'a': lodashStable.constant('A') },
7373           actual = _.invoke(object, 'a');
7374
7375       assert.strictEqual(actual, 'A');
7376     });
7377
7378     QUnit.test('should support invoking with arguments', function(assert) {
7379       assert.expect(1);
7380
7381       var object = { 'a': function(a, b) { return [a, b]; } },
7382           actual = _.invoke(object, 'a', 1, 2);
7383
7384       assert.deepEqual(actual, [1, 2]);
7385     });
7386
7387     QUnit.test('should not error on nullish elements', function(assert) {
7388       assert.expect(1);
7389
7390       var values = [null, undefined],
7391           expected = lodashStable.map(values, alwaysUndefined);
7392
7393       var actual = lodashStable.map(values, function(value) {
7394         try {
7395           return _.invoke(value, 'a.b.c', 1, 2);
7396         } catch (e) {}
7397       });
7398
7399       assert.deepEqual(actual, expected);
7400     });
7401
7402     QUnit.test('should support deep paths', function(assert) {
7403       assert.expect(2);
7404
7405       var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
7406
7407       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7408         var actual = _.invoke(object, path, 1, 2);
7409         assert.deepEqual(actual, [1, 2]);
7410       });
7411     });
7412
7413     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
7414       assert.expect(2);
7415
7416       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
7417
7418       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7419         assert.deepEqual(_.invoke(object, path), 1);
7420       });
7421     });
7422
7423     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7424       assert.expect(1);
7425
7426       if (!isNpm) {
7427         var object = { 'a': alwaysOne };
7428         assert.strictEqual(_(object).invoke('a'), 1);
7429       }
7430       else {
7431         skipTest(assert);
7432       }
7433     });
7434
7435     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7436       assert.expect(1);
7437
7438       if (!isNpm) {
7439         var object = { 'a': alwaysOne };
7440         assert.ok(_(object).chain().invoke('a') instanceof _);
7441       }
7442       else {
7443         skipTest(assert);
7444       }
7445     });
7446   }());
7447
7448   /*--------------------------------------------------------------------------*/
7449
7450   QUnit.module('lodash.invokeMap');
7451
7452   (function() {
7453     QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
7454       assert.expect(1);
7455
7456       var array = ['a', 'b', 'c'],
7457           actual = _.invokeMap(array, 'toUpperCase');
7458
7459       assert.deepEqual(actual, ['A', 'B', 'C']);
7460     });
7461
7462     QUnit.test('should support invoking with arguments', function(assert) {
7463       assert.expect(1);
7464
7465       var array = [function() { return slice.call(arguments); }],
7466           actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
7467
7468       assert.deepEqual(actual, [['a', 'b', 'c']]);
7469     });
7470
7471     QUnit.test('should work with a function for `methodName`', function(assert) {
7472       assert.expect(1);
7473
7474       var array = ['a', 'b', 'c'];
7475
7476       var actual = _.invokeMap(array, function(left, right) {
7477         return left + this.toUpperCase() + right;
7478       }, '(', ')');
7479
7480       assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
7481     });
7482
7483     QUnit.test('should work with an object for `collection`', function(assert) {
7484       assert.expect(1);
7485
7486       var object = { 'a': 1, 'b': 2, 'c': 3 },
7487           actual = _.invokeMap(object, 'toFixed', 1);
7488
7489       assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
7490     });
7491
7492     QUnit.test('should treat number values for `collection` as empty', function(assert) {
7493       assert.expect(1);
7494
7495       assert.deepEqual(_.invokeMap(1), []);
7496     });
7497
7498     QUnit.test('should not error on nullish elements', function(assert) {
7499       assert.expect(1);
7500
7501       var array = ['a', null, undefined, 'd'];
7502
7503       try {
7504         var actual = _.invokeMap(array, 'toUpperCase');
7505       } catch (e) {}
7506
7507       assert.deepEqual(_.invokeMap(array, 'toUpperCase'), ['A', undefined, undefined, 'D']);
7508     });
7509
7510     QUnit.test('should not error on elements with missing properties', function(assert) {
7511       assert.expect(1);
7512
7513       var objects = lodashStable.map([null, undefined, alwaysOne], function(value) {
7514         return { 'a': value };
7515       });
7516
7517       var expected = lodashStable.map(objects, function(object) {
7518         return object.a ? object.a() : undefined;
7519       });
7520
7521       try {
7522         var actual = _.invokeMap(objects, 'a');
7523       } catch (e) {}
7524
7525       assert.deepEqual(actual, expected);
7526     });
7527
7528     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
7529       assert.expect(2);
7530
7531       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
7532
7533       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7534         assert.deepEqual(_.invokeMap([object], path), [1]);
7535       });
7536     });
7537
7538     QUnit.test('should return a wrapped value when chaining', function(assert) {
7539       assert.expect(4);
7540
7541       if (!isNpm) {
7542         var array = ['a', 'b', 'c'],
7543             wrapped = _(array),
7544             actual = wrapped.invokeMap('toUpperCase');
7545
7546         assert.ok(actual instanceof _);
7547         assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
7548
7549         actual = wrapped.invokeMap(function(left, right) {
7550           return left + this.toUpperCase() + right;
7551         }, '(', ')');
7552
7553         assert.ok(actual instanceof _);
7554         assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
7555       }
7556       else {
7557         skipTest(assert, 4);
7558       }
7559     });
7560
7561     QUnit.test('should support shortcut fusion', function(assert) {
7562       assert.expect(2);
7563
7564       if (!isNpm) {
7565         var count = 0,
7566             method = function() { count++; return this.index; };
7567
7568         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7569           return { 'index': index, 'method': method };
7570         });
7571
7572         var actual = _(array).invokeMap('method').take(1).value();
7573
7574         assert.strictEqual(count, 1);
7575         assert.deepEqual(actual, [0]);
7576       }
7577       else {
7578         skipTest(assert, 2);
7579       }
7580     });
7581   }());
7582
7583   /*--------------------------------------------------------------------------*/
7584
7585   QUnit.module('lodash.isArguments');
7586
7587   (function() {
7588     var args = (function() { return arguments; }(1, 2, 3)),
7589         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
7590
7591     QUnit.test('should return `true` for `arguments` objects', function(assert) {
7592       assert.expect(2);
7593
7594       assert.strictEqual(_.isArguments(args), true);
7595       assert.strictEqual(_.isArguments(strictArgs), true);
7596     });
7597
7598     QUnit.test('should return `false` for non `arguments` objects', function(assert) {
7599       assert.expect(12);
7600
7601       var expected = lodashStable.map(falsey, alwaysFalse);
7602
7603       var actual = lodashStable.map(falsey, function(value, index) {
7604         return index ? _.isArguments(value) : _.isArguments();
7605       });
7606
7607       assert.deepEqual(actual, expected);
7608
7609       assert.strictEqual(_.isArguments([1, 2, 3]), false);
7610       assert.strictEqual(_.isArguments(true), false);
7611       assert.strictEqual(_.isArguments(new Date), false);
7612       assert.strictEqual(_.isArguments(new Error), false);
7613       assert.strictEqual(_.isArguments(_), false);
7614       assert.strictEqual(_.isArguments(slice), false);
7615       assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
7616       assert.strictEqual(_.isArguments(1), false);
7617       assert.strictEqual(_.isArguments(/x/), false);
7618       assert.strictEqual(_.isArguments('a'), false);
7619       assert.strictEqual(_.isArguments(symbol), false);
7620     });
7621
7622     QUnit.test('should work with an `arguments` object from another realm', function(assert) {
7623       assert.expect(1);
7624
7625       if (realm.arguments) {
7626         assert.strictEqual(_.isArguments(realm.arguments), true);
7627       }
7628       else {
7629         skipTest(assert);
7630       }
7631     });
7632   }());
7633
7634   /*--------------------------------------------------------------------------*/
7635
7636   QUnit.module('lodash.isArray');
7637
7638   (function() {
7639     var args = arguments;
7640
7641     QUnit.test('should return `true` for arrays', function(assert) {
7642       assert.expect(1);
7643
7644       assert.strictEqual(_.isArray([1, 2, 3]), true);
7645     });
7646
7647     QUnit.test('should return `false` for non-arrays', function(assert) {
7648       assert.expect(12);
7649
7650       var expected = lodashStable.map(falsey, alwaysFalse);
7651
7652       var actual = lodashStable.map(falsey, function(value, index) {
7653         return index ? _.isArray(value) : _.isArray();
7654       });
7655
7656       assert.deepEqual(actual, expected);
7657
7658       assert.strictEqual(_.isArray(args), false);
7659       assert.strictEqual(_.isArray(true), false);
7660       assert.strictEqual(_.isArray(new Date), false);
7661       assert.strictEqual(_.isArray(new Error), false);
7662       assert.strictEqual(_.isArray(_), false);
7663       assert.strictEqual(_.isArray(slice), false);
7664       assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
7665       assert.strictEqual(_.isArray(1), false);
7666       assert.strictEqual(_.isArray(/x/), false);
7667       assert.strictEqual(_.isArray('a'), false);
7668       assert.strictEqual(_.isArray(symbol), false);
7669     });
7670
7671     QUnit.test('should work with an array from another realm', function(assert) {
7672       assert.expect(1);
7673
7674       if (realm.array) {
7675         assert.strictEqual(_.isArray(realm.array), true);
7676       }
7677       else {
7678         skipTest(assert);
7679       }
7680     });
7681   }(1, 2, 3));
7682
7683   /*--------------------------------------------------------------------------*/
7684
7685   QUnit.module('lodash.isArrayLike');
7686
7687   (function() {
7688     var args = arguments;
7689
7690     QUnit.test('should return `true` for array-like values', function(assert) {
7691       assert.expect(1);
7692
7693       var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
7694           expected = lodashStable.map(values, alwaysTrue),
7695           actual = lodashStable.map(values, _.isArrayLike);
7696
7697       assert.deepEqual(actual, expected);
7698     });
7699
7700     QUnit.test('should return `false` for non-arrays', function(assert) {
7701       assert.expect(11);
7702
7703       var expected = lodashStable.map(falsey, function(value) {
7704         return value === '';
7705       });
7706
7707       var actual = lodashStable.map(falsey, function(value, index) {
7708         return index ? _.isArrayLike(value) : _.isArrayLike();
7709       });
7710
7711       assert.deepEqual(actual, expected);
7712
7713       assert.strictEqual(_.isArrayLike(true), false);
7714       assert.strictEqual(_.isArrayLike(new Date), false);
7715       assert.strictEqual(_.isArrayLike(new Error), false);
7716       assert.strictEqual(_.isArrayLike(_), false);
7717       assert.strictEqual(_.isArrayLike(generator), false);
7718       assert.strictEqual(_.isArrayLike(slice), false);
7719       assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
7720       assert.strictEqual(_.isArrayLike(1), false);
7721       assert.strictEqual(_.isArrayLike(/x/), false);
7722       assert.strictEqual(_.isArrayLike(symbol), false);
7723     });
7724
7725     QUnit.test('should work with an array from another realm', function(assert) {
7726       assert.expect(1);
7727
7728       if (realm.object) {
7729         var values = [realm.arguments, realm.array, realm.string],
7730             expected = lodashStable.map(values, alwaysTrue),
7731             actual = lodashStable.map(values, _.isArrayLike);
7732
7733         assert.deepEqual(actual, expected);
7734       }
7735       else {
7736         skipTest(assert);
7737       }
7738     });
7739   }(1, 2, 3));
7740
7741   /*--------------------------------------------------------------------------*/
7742
7743   QUnit.module('lodash.isBoolean');
7744
7745   (function() {
7746     var args = arguments;
7747
7748     QUnit.test('should return `true` for booleans', function(assert) {
7749       assert.expect(4);
7750
7751       assert.strictEqual(_.isBoolean(true), true);
7752       assert.strictEqual(_.isBoolean(false), true);
7753       assert.strictEqual(_.isBoolean(Object(true)), true);
7754       assert.strictEqual(_.isBoolean(Object(false)), true);
7755     });
7756
7757     QUnit.test('should return `false` for non-booleans', function(assert) {
7758       assert.expect(12);
7759
7760       var expected = lodashStable.map(falsey, function(value) {
7761         return value === false;
7762       });
7763
7764       var actual = lodashStable.map(falsey, function(value, index) {
7765         return index ? _.isBoolean(value) : _.isBoolean();
7766       });
7767
7768       assert.deepEqual(actual, expected);
7769
7770       assert.strictEqual(_.isBoolean(args), false);
7771       assert.strictEqual(_.isBoolean([1, 2, 3]), false);
7772       assert.strictEqual(_.isBoolean(new Date), false);
7773       assert.strictEqual(_.isBoolean(new Error), false);
7774       assert.strictEqual(_.isBoolean(_), false);
7775       assert.strictEqual(_.isBoolean(slice), false);
7776       assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
7777       assert.strictEqual(_.isBoolean(1), false);
7778       assert.strictEqual(_.isBoolean(/x/), false);
7779       assert.strictEqual(_.isBoolean('a'), false);
7780       assert.strictEqual(_.isBoolean(symbol), false);
7781     });
7782
7783     QUnit.test('should work with a boolean from another realm', function(assert) {
7784       assert.expect(1);
7785
7786       if (realm.boolean) {
7787         assert.strictEqual(_.isBoolean(realm.boolean), true);
7788       }
7789       else {
7790         skipTest(assert);
7791       }
7792     });
7793   }(1, 2, 3));
7794
7795   /*--------------------------------------------------------------------------*/
7796
7797   QUnit.module('lodash.isDate');
7798
7799   (function() {
7800     var args = arguments;
7801
7802     QUnit.test('should return `true` for dates', function(assert) {
7803       assert.expect(1);
7804
7805       assert.strictEqual(_.isDate(new Date), true);
7806     });
7807
7808     QUnit.test('should return `false` for non-dates', function(assert) {
7809       assert.expect(12);
7810
7811       var expected = lodashStable.map(falsey, alwaysFalse);
7812
7813       var actual = lodashStable.map(falsey, function(value, index) {
7814         return index ? _.isDate(value) : _.isDate();
7815       });
7816
7817       assert.deepEqual(actual, expected);
7818
7819       assert.strictEqual(_.isDate(args), false);
7820       assert.strictEqual(_.isDate([1, 2, 3]), false);
7821       assert.strictEqual(_.isDate(true), false);
7822       assert.strictEqual(_.isDate(new Error), false);
7823       assert.strictEqual(_.isDate(_), false);
7824       assert.strictEqual(_.isDate(slice), false);
7825       assert.strictEqual(_.isDate({ 'a': 1 }), false);
7826       assert.strictEqual(_.isDate(1), false);
7827       assert.strictEqual(_.isDate(/x/), false);
7828       assert.strictEqual(_.isDate('a'), false);
7829       assert.strictEqual(_.isDate(symbol), false);
7830     });
7831
7832     QUnit.test('should work with a date object from another realm', function(assert) {
7833       assert.expect(1);
7834
7835       if (realm.date) {
7836         assert.strictEqual(_.isDate(realm.date), true);
7837       }
7838       else {
7839         skipTest(assert);
7840       }
7841     });
7842   }(1, 2, 3));
7843
7844   /*--------------------------------------------------------------------------*/
7845
7846   QUnit.module('lodash.isElement');
7847
7848   (function() {
7849     var args = arguments;
7850
7851     function Element() {
7852       this.nodeType = 1;
7853     }
7854
7855     QUnit.test('should return `false` for plain objects', function(assert) {
7856       assert.expect(7);
7857
7858       var element = body || new Element;
7859
7860       assert.strictEqual(_.isElement(element), true);
7861       assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
7862       assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
7863       assert.strictEqual(_.isElement({ 'nodeType': true }), false);
7864       assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
7865       assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
7866       assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
7867     });
7868
7869     QUnit.test('should return `false` for non DOM elements', function(assert) {
7870       assert.expect(13);
7871
7872       var expected = lodashStable.map(falsey, alwaysFalse);
7873
7874       var actual = lodashStable.map(falsey, function(value, index) {
7875         return index ? _.isElement(value) : _.isElement();
7876       });
7877
7878       assert.deepEqual(actual, expected);
7879
7880       assert.strictEqual(_.isElement(args), false);
7881       assert.strictEqual(_.isElement([1, 2, 3]), false);
7882       assert.strictEqual(_.isElement(true), false);
7883       assert.strictEqual(_.isElement(new Date), false);
7884       assert.strictEqual(_.isElement(new Error), false);
7885       assert.strictEqual(_.isElement(_), false);
7886       assert.strictEqual(_.isElement(slice), false);
7887       assert.strictEqual(_.isElement({ 'a': 1 }), false);
7888       assert.strictEqual(_.isElement(1), false);
7889       assert.strictEqual(_.isElement(/x/), false);
7890       assert.strictEqual(_.isElement('a'), false);
7891       assert.strictEqual(_.isElement(symbol), false);
7892     });
7893
7894     QUnit.test('should work with a DOM element from another realm', function(assert) {
7895       assert.expect(1);
7896
7897       if (realm.element) {
7898         assert.strictEqual(_.isElement(realm.element), true);
7899       }
7900       else {
7901         skipTest(assert);
7902       }
7903     });
7904   }(1, 2, 3));
7905
7906   /*--------------------------------------------------------------------------*/
7907
7908   QUnit.module('lodash.isEmpty');
7909
7910   (function() {
7911     var args = arguments;
7912
7913     QUnit.test('should return `true` for empty values', function(assert) {
7914       assert.expect(8);
7915
7916       var expected = lodashStable.map(empties, alwaysTrue),
7917           actual = lodashStable.map(empties, _.isEmpty);
7918
7919       assert.deepEqual(actual, expected);
7920
7921       assert.strictEqual(_.isEmpty(true), true);
7922       assert.strictEqual(_.isEmpty(slice), true);
7923       assert.strictEqual(_.isEmpty(1), true);
7924       assert.strictEqual(_.isEmpty(NaN), true);
7925       assert.strictEqual(_.isEmpty(/x/), true);
7926       assert.strictEqual(_.isEmpty(symbol), true);
7927       assert.strictEqual(_.isEmpty(), true);
7928     });
7929
7930     QUnit.test('should return `false` for non-empty values', function(assert) {
7931       assert.expect(3);
7932
7933       assert.strictEqual(_.isEmpty([0]), false);
7934       assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
7935       assert.strictEqual(_.isEmpty('a'), false);
7936     });
7937
7938     QUnit.test('should work with an object that has a `length` property', function(assert) {
7939       assert.expect(1);
7940
7941       assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
7942     });
7943
7944     QUnit.test('should work with `arguments` objects', function(assert) {
7945       assert.expect(1);
7946
7947       assert.strictEqual(_.isEmpty(args), false);
7948     });
7949
7950     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
7951       assert.expect(1);
7952
7953       function Foo(elements) { push.apply(this, elements); }
7954       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
7955
7956       assert.strictEqual(_.isEmpty(new Foo([])), true);
7957     });
7958
7959     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
7960       assert.expect(1);
7961
7962       function Foo() {}
7963       Foo.prototype.length = -1;
7964
7965       assert.strictEqual(_.isEmpty(new Foo), true);
7966     });
7967
7968     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
7969       assert.expect(1);
7970
7971       function Foo() {}
7972       Foo.prototype.length = MAX_SAFE_INTEGER + 1;
7973
7974       assert.strictEqual(_.isEmpty(new Foo), true);
7975     });
7976
7977     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
7978       assert.expect(1);
7979
7980       assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
7981     });
7982
7983     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7984       assert.expect(1);
7985
7986       if (!isNpm) {
7987         assert.strictEqual(_({}).isEmpty(), true);
7988       }
7989       else {
7990         skipTest(assert);
7991       }
7992     });
7993
7994     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7995       assert.expect(1);
7996
7997       if (!isNpm) {
7998         assert.ok(_({}).chain().isEmpty() instanceof _);
7999       }
8000       else {
8001         skipTest(assert);
8002       }
8003     });
8004   }(1, 2, 3));
8005
8006   /*--------------------------------------------------------------------------*/
8007
8008   QUnit.module('lodash.isEqual');
8009
8010   (function() {
8011     var symbol1 = Symbol ? Symbol('a') : true,
8012         symbol2 = Symbol ? Symbol('b') : false;
8013
8014     QUnit.test('should compare primitives', function(assert) {
8015       assert.expect(1);
8016
8017       var pairs = [
8018         [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
8019         [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
8020         [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
8021         ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
8022         [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
8023         [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
8024         [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
8025         [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
8026         [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
8027       ];
8028
8029       var expected = lodashStable.map(pairs, function(pair) {
8030         return pair[2];
8031       });
8032
8033       var actual = lodashStable.map(pairs, function(pair) {
8034         return _.isEqual(pair[0], pair[1]);
8035       });
8036
8037       assert.deepEqual(actual, expected);
8038     });
8039
8040     QUnit.test('should compare arrays', function(assert) {
8041       assert.expect(6);
8042
8043       var array1 = [true, null, 1, 'a', undefined],
8044           array2 = [true, null, 1, 'a', undefined];
8045
8046       assert.strictEqual(_.isEqual(array1, array2), true);
8047
8048       array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
8049       array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
8050
8051       assert.strictEqual(_.isEqual(array1, array2), true);
8052
8053       array1 = [1];
8054       array1[2] = 3;
8055
8056       array2 = [1];
8057       array2[1] = undefined;
8058       array2[2] = 3;
8059
8060       assert.strictEqual(_.isEqual(array1, array2), true);
8061
8062       array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
8063       array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
8064
8065       assert.strictEqual(_.isEqual(array1, array2), true);
8066
8067       array1 = [1, 2, 3];
8068       array2 = [3, 2, 1];
8069
8070       assert.strictEqual(_.isEqual(array1, array2), false);
8071
8072       array1 = [1, 2];
8073       array2 = [1, 2, 3];
8074
8075       assert.strictEqual(_.isEqual(array1, array2), false);
8076     });
8077
8078     QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
8079       assert.expect(3);
8080
8081       var array1 = [1, 2, 3],
8082           array2 = [1, 2, 3];
8083
8084       array1.every = array1.filter = array1.forEach =
8085       array1.indexOf = array1.lastIndexOf = array1.map =
8086       array1.some = array1.reduce = array1.reduceRight = null;
8087
8088       array2.concat = array2.join = array2.pop =
8089       array2.reverse = array2.shift = array2.slice =
8090       array2.sort = array2.splice = array2.unshift = null;
8091
8092       assert.strictEqual(_.isEqual(array1, array2), true);
8093
8094       array1 = [1, 2, 3];
8095       array1.a = 1;
8096
8097       array2 = [1, 2, 3];
8098       array2.b = 1;
8099
8100       assert.strictEqual(_.isEqual(array1, array2), true);
8101
8102       array1 = /x/.exec('vwxyz');
8103       array2 = ['x'];
8104
8105       assert.strictEqual(_.isEqual(array1, array2), true);
8106     });
8107
8108     QUnit.test('should compare sparse arrays', function(assert) {
8109       assert.expect(3);
8110
8111       var array = Array(1);
8112
8113       assert.strictEqual(_.isEqual(array, Array(1)), true);
8114       assert.strictEqual(_.isEqual(array, [undefined]), true);
8115       assert.strictEqual(_.isEqual(array, Array(2)), false);
8116     });
8117
8118     QUnit.test('should compare plain objects', function(assert) {
8119       assert.expect(5);
8120
8121       var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
8122           object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
8123
8124       assert.strictEqual(_.isEqual(object1, object2), true);
8125
8126       object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
8127       object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
8128
8129       assert.strictEqual(_.isEqual(object1, object2), true);
8130
8131       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8132       object2 = { 'a': 3, 'b': 2, 'c': 1 };
8133
8134       assert.strictEqual(_.isEqual(object1, object2), false);
8135
8136       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8137       object2 = { 'd': 1, 'e': 2, 'f': 3 };
8138
8139       assert.strictEqual(_.isEqual(object1, object2), false);
8140
8141       object1 = { 'a': 1, 'b': 2 };
8142       object2 = { 'a': 1, 'b': 2, 'c': 3 };
8143
8144       assert.strictEqual(_.isEqual(object1, object2), false);
8145     });
8146
8147     QUnit.test('should compare nested objects', function(assert) {
8148       assert.expect(1);
8149
8150       var object1 = {
8151         'a': [1, 2, 3],
8152         'b': true,
8153         'c': Object(1),
8154         'd': 'a',
8155         'e': {
8156           'f': ['a', Object('b'), 'c'],
8157           'g': Object(false),
8158           'h': new Date(2012, 4, 23),
8159           'i': noop,
8160           'j': 'a'
8161         }
8162       };
8163
8164       var object2 = {
8165         'a': [1, Object(2), 3],
8166         'b': Object(true),
8167         'c': 1,
8168         'd': Object('a'),
8169         'e': {
8170           'f': ['a', 'b', 'c'],
8171           'g': false,
8172           'h': new Date(2012, 4, 23),
8173           'i': noop,
8174           'j': 'a'
8175         }
8176       };
8177
8178       assert.strictEqual(_.isEqual(object1, object2), true);
8179     });
8180
8181     QUnit.test('should compare object instances', function(assert) {
8182       assert.expect(4);
8183
8184       function Foo() { this.a = 1; }
8185       Foo.prototype.a = 1;
8186
8187       function Bar() { this.a = 1; }
8188       Bar.prototype.a = 2;
8189
8190       assert.strictEqual(_.isEqual(new Foo, new Foo), true);
8191       assert.strictEqual(_.isEqual(new Foo, new Bar), false);
8192       assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
8193       assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
8194     });
8195
8196     QUnit.test('should compare objects with constructor properties', function(assert) {
8197       assert.expect(5);
8198
8199       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
8200       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
8201       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
8202       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
8203       assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
8204     });
8205
8206     QUnit.test('should compare arrays with circular references', function(assert) {
8207       assert.expect(4);
8208
8209       var array1 = [],
8210           array2 = [];
8211
8212       array1.push(array1);
8213       array2.push(array2);
8214
8215       assert.strictEqual(_.isEqual(array1, array2), true);
8216
8217       array1.push('b');
8218       array2.push('b');
8219
8220       assert.strictEqual(_.isEqual(array1, array2), true);
8221
8222       array1.push('c');
8223       array2.push('d');
8224
8225       assert.strictEqual(_.isEqual(array1, array2), false);
8226
8227       array1 = ['a', 'b', 'c'];
8228       array1[1] = array1;
8229       array2 = ['a', ['a', 'b', 'c'], 'c'];
8230
8231       assert.strictEqual(_.isEqual(array1, array2), false);
8232     });
8233
8234     QUnit.test('should compare objects with circular references', function(assert) {
8235       assert.expect(4);
8236
8237       var object1 = {},
8238           object2 = {};
8239
8240       object1.a = object1;
8241       object2.a = object2;
8242
8243       assert.strictEqual(_.isEqual(object1, object2), true);
8244
8245       object1.b = 0;
8246       object2.b = Object(0);
8247
8248       assert.strictEqual(_.isEqual(object1, object2), true);
8249
8250       object1.c = Object(1);
8251       object2.c = Object(2);
8252
8253       assert.strictEqual(_.isEqual(object1, object2), false);
8254
8255       object1 = { 'a': 1, 'b': 2, 'c': 3 };
8256       object1.b = object1;
8257       object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
8258
8259       assert.strictEqual(_.isEqual(object1, object2), false);
8260     });
8261
8262     QUnit.test('should compare objects with multiple circular references', function(assert) {
8263       assert.expect(3);
8264
8265       var array1 = [{}],
8266           array2 = [{}];
8267
8268       (array1[0].a = array1).push(array1);
8269       (array2[0].a = array2).push(array2);
8270
8271       assert.strictEqual(_.isEqual(array1, array2), true);
8272
8273       array1[0].b = 0;
8274       array2[0].b = Object(0);
8275
8276       assert.strictEqual(_.isEqual(array1, array2), true);
8277
8278       array1[0].c = Object(1);
8279       array2[0].c = Object(2);
8280
8281       assert.strictEqual(_.isEqual(array1, array2), false);
8282     });
8283
8284     QUnit.test('should compare objects with complex circular references', function(assert) {
8285       assert.expect(1);
8286
8287       var object1 = {
8288         'foo': { 'b': { 'c': { 'd': {} } } },
8289         'bar': { 'a': 2 }
8290       };
8291
8292       var object2 = {
8293         'foo': { 'b': { 'c': { 'd': {} } } },
8294         'bar': { 'a': 2 }
8295       };
8296
8297       object1.foo.b.c.d = object1;
8298       object1.bar.b = object1.foo.b;
8299
8300       object2.foo.b.c.d = object2;
8301       object2.bar.b = object2.foo.b;
8302
8303       assert.strictEqual(_.isEqual(object1, object2), true);
8304     });
8305
8306     QUnit.test('should compare objects with shared property values', function(assert) {
8307       assert.expect(1);
8308
8309       var object1 = {
8310         'a': [1, 2]
8311       };
8312
8313       var object2 = {
8314         'a': [1, 2],
8315         'b': [1, 2]
8316       };
8317
8318       object1.b = object1.a;
8319
8320       assert.strictEqual(_.isEqual(object1, object2), true);
8321     });
8322
8323     QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
8324       assert.expect(2);
8325
8326       function Foo() { this.a = 1; }
8327       Foo.prototype.constructor = null;
8328
8329       var object2 = { 'a': 1 };
8330       assert.strictEqual(_.isEqual(new Foo, object2), false);
8331
8332       if (create)  {
8333         var object1 = create(null);
8334         object1.a = 1;
8335         assert.strictEqual(_.isEqual(object1, object2), true);
8336       }
8337       else {
8338         skipTest(assert);
8339       }
8340     });
8341
8342     QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
8343       assert.expect(1);
8344
8345       var primitive,
8346           object = { 'toString': function() { return primitive; } },
8347           values = [true, null, 1, 'a', undefined],
8348           expected = lodashStable.map(values, alwaysFalse);
8349
8350       var actual = lodashStable.map(values, function(value) {
8351         primitive = value;
8352         return _.isEqual(object, value);
8353       });
8354
8355       assert.deepEqual(actual, expected);
8356     });
8357
8358     QUnit.test('should avoid common type coercions', function(assert) {
8359       assert.expect(9);
8360
8361       assert.strictEqual(_.isEqual(true, Object(false)), false);
8362       assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
8363       assert.strictEqual(_.isEqual(false, Object('')), false);
8364       assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
8365       assert.strictEqual(_.isEqual(0, ''), false);
8366       assert.strictEqual(_.isEqual(1, true), false);
8367       assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
8368       assert.strictEqual(_.isEqual('36', 36), false);
8369       assert.strictEqual(_.isEqual(36, '36'), false);
8370     });
8371
8372     QUnit.test('should compare `arguments` objects', function(assert) {
8373       assert.expect(2);
8374
8375       var args1 = (function() { return arguments; }(1, 2, 3)),
8376           args2 = (function() { return arguments; }(1, 2, 3)),
8377           args3 = (function() { return arguments; }(1, 2));
8378
8379       assert.strictEqual(_.isEqual(args1, args2), true);
8380       assert.strictEqual(_.isEqual(args1, args3), false);
8381     });
8382
8383     QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
8384       assert.expect(4);
8385
8386       var args = (function() { return arguments; }(1, 2, 3)),
8387           object = { '0': 1, '1': 2, '2': 3 };
8388
8389       function Foo() {}
8390       Foo.prototype = object;
8391
8392       assert.strictEqual(_.isEqual(args, object), true);
8393       assert.strictEqual(_.isEqual(object, args), true);
8394
8395       assert.strictEqual(_.isEqual(args, new Foo), false);
8396       assert.strictEqual(_.isEqual(new Foo, args), false);
8397     });
8398
8399     QUnit.test('should compare array buffers', function(assert) {
8400       assert.expect(2);
8401
8402       if (ArrayBuffer) {
8403         var buffer1 = new ArrayBuffer(4),
8404             buffer2 = new ArrayBuffer(8);
8405
8406         assert.strictEqual(_.isEqual(buffer1, buffer2), false);
8407
8408         buffer1 = new Int8Array([-1]).buffer;
8409         buffer2 = new Uint8Array([255]).buffer;
8410
8411         assert.strictEqual(_.isEqual(buffer1, buffer2), true);
8412       }
8413       else {
8414         skipTest(assert, 2);
8415       }
8416     });
8417
8418     QUnit.test('should compare date objects', function(assert) {
8419       assert.expect(4);
8420
8421       assert.strictEqual(_.isEqual(new Date(2012, 4, 23), new Date(2012, 4, 23)), true);
8422       assert.strictEqual(_.isEqual(new Date(2012, 4, 23), new Date(2013, 3, 25)), false);
8423       assert.strictEqual(_.isEqual(new Date(2012, 4, 23), { 'getTime': lodashStable.constant(1337756400000) }), false);
8424       assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
8425     });
8426
8427     QUnit.test('should compare error objects', function(assert) {
8428       assert.expect(1);
8429
8430       var pairs = lodashStable.map([
8431         'Error',
8432         'EvalError',
8433         'RangeError',
8434         'ReferenceError',
8435         'SyntaxError',
8436         'TypeError',
8437         'URIError'
8438       ], function(type, index, errorTypes) {
8439         var otherType = errorTypes[++index % errorTypes.length],
8440             CtorA = root[type],
8441             CtorB = root[otherType];
8442
8443         return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
8444       });
8445
8446       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
8447
8448       var actual = lodashStable.map(pairs, function(pair) {
8449         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
8450       });
8451
8452       assert.deepEqual(actual, expected);
8453     });
8454
8455     QUnit.test('should compare functions', function(assert) {
8456       assert.expect(2);
8457
8458       function a() { return 1 + 2; }
8459       function b() { return 1 + 2; }
8460
8461       assert.strictEqual(_.isEqual(a, a), true);
8462       assert.strictEqual(_.isEqual(a, b), false);
8463     });
8464
8465     QUnit.test('should compare maps', function(assert) {
8466       assert.expect(4);
8467
8468       if (Map) {
8469         var map1 = new Map,
8470             map2 = new Map;
8471
8472         map1.set('a', 1);
8473         map2.set('b', 2);
8474         assert.strictEqual(_.isEqual(map1, map2), false);
8475
8476         map1.set('b', 2);
8477         map2.set('a', 1);
8478         assert.strictEqual(_.isEqual(map1, map2), true);
8479
8480         map1['delete']('a');
8481         map1.set('a', 1);
8482         assert.strictEqual(_.isEqual(map1, map2), true);
8483
8484         map2['delete']('a');
8485         assert.strictEqual(_.isEqual(map1, map2), false);
8486       }
8487       else {
8488         skipTest(assert, 4);
8489       }
8490     });
8491
8492     QUnit.test('should compare regexes', function(assert) {
8493       assert.expect(5);
8494
8495       assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
8496       assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
8497       assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
8498       assert.strictEqual(_.isEqual(/x/, /y/), false);
8499       assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
8500     });
8501
8502     QUnit.test('should compare sets', function(assert) {
8503       assert.expect(4);
8504
8505       if (Set) {
8506         var set1 = new Set,
8507             set2 = new Set;
8508
8509         set1.add(1);
8510         set2.add(2);
8511         assert.strictEqual(_.isEqual(set1, set2), false);
8512
8513         set1.add(2);
8514         set2.add(1);
8515         assert.strictEqual(_.isEqual(set1, set2), true);
8516
8517         set1['delete'](1);
8518         set1.add(1);
8519         assert.strictEqual(_.isEqual(set1, set2), true);
8520
8521         set2['delete'](1);
8522         assert.strictEqual(_.isEqual(set1, set2), false);
8523       }
8524       else {
8525         skipTest(assert, 4);
8526       }
8527     });
8528
8529     QUnit.test('should compare typed arrays', function(assert) {
8530       assert.expect(1);
8531
8532       var pairs = lodashStable.map(typedArrays, function(type, index) {
8533         var otherType = typedArrays[(index + 1) % typedArrays.length],
8534             CtorA = root[type] || function(n) { this.n = n; },
8535             CtorB = root[otherType] || function(n) { this.n = n; },
8536             bufferA = root[type] ? new ArrayBuffer(8) : 8,
8537             bufferB = root[otherType] ? new ArrayBuffer(8) : 8,
8538             bufferC = root[otherType] ? new ArrayBuffer(16) : 16;
8539
8540         return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
8541       });
8542
8543       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
8544
8545       var actual = lodashStable.map(pairs, function(pair) {
8546         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
8547       });
8548
8549       assert.deepEqual(actual, expected);
8550     });
8551
8552     QUnit.test('should work as an iteratee for `_.every`', function(assert) {
8553       assert.expect(1);
8554
8555       var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
8556       assert.ok(actual);
8557     });
8558
8559     QUnit.test('should return `true` for like-objects from different documents', function(assert) {
8560       assert.expect(4);
8561
8562       if (realm.object) {
8563         assert.strictEqual(_.isEqual({ 'a': 1, 'b': 2, 'c': 3 }, realm.object), true);
8564         assert.strictEqual(_.isEqual({ 'a': 1, 'b': 2, 'c': 2 }, realm.object), false);
8565         assert.strictEqual(_.isEqual([1, 2, 3], realm.array), true);
8566         assert.strictEqual(_.isEqual([1, 2, 2], realm.array), false);
8567       }
8568       else {
8569         skipTest(assert, 4);
8570       }
8571     });
8572
8573     QUnit.test('should not error on DOM elements', function(assert) {
8574       assert.expect(1);
8575
8576       if (document) {
8577         var element1 = document.createElement('div'),
8578             element2 = element1.cloneNode(true);
8579
8580         try {
8581           assert.strictEqual(_.isEqual(element1, element2), false);
8582         } catch (e) {
8583           assert.ok(false, e.message);
8584         }
8585       }
8586       else {
8587         skipTest(assert);
8588       }
8589     });
8590
8591     QUnit.test('should compare wrapped values', function(assert) {
8592       assert.expect(32);
8593
8594       var stamp = +new Date;
8595
8596       var values = [
8597         [[1, 2], [1, 2], [1, 2, 3]],
8598         [true, true, false],
8599         [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
8600         [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
8601         [1, 1, 2],
8602         [NaN, NaN, Infinity],
8603         [/x/, /x/, /x/i],
8604         ['a', 'a', 'A']
8605       ];
8606
8607       lodashStable.each(values, function(vals) {
8608         if (!isNpm) {
8609           var wrapped1 = _(vals[0]),
8610               wrapped2 = _(vals[1]),
8611               actual = wrapped1.isEqual(wrapped2);
8612
8613           assert.strictEqual(actual, true);
8614           assert.strictEqual(_.isEqual(_(actual), _(true)), true);
8615
8616           wrapped1 = _(vals[0]);
8617           wrapped2 = _(vals[2]);
8618
8619           actual = wrapped1.isEqual(wrapped2);
8620           assert.strictEqual(actual, false);
8621           assert.strictEqual(_.isEqual(_(actual), _(false)), true);
8622         }
8623         else {
8624           skipTest(assert, 4);
8625         }
8626       });
8627     });
8628
8629     QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
8630       assert.expect(4);
8631
8632       if (!isNpm) {
8633         var object1 = _({ 'a': 1, 'b': 2 }),
8634             object2 = { 'a': 1, 'b': 2 };
8635
8636         assert.strictEqual(object1.isEqual(object2), true);
8637         assert.strictEqual(_.isEqual(object1, object2), true);
8638
8639         object1 = _({ 'a': 1, 'b': 2 });
8640         object2 = { 'a': 1, 'b': 1 };
8641
8642         assert.strictEqual(object1.isEqual(object2), false);
8643         assert.strictEqual(_.isEqual(object1, object2), false);
8644       }
8645       else {
8646         skipTest(assert, 4);
8647       }
8648     });
8649
8650     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8651       assert.expect(1);
8652
8653       if (!isNpm) {
8654         assert.strictEqual(_('a').isEqual('a'), true);
8655       }
8656       else {
8657         skipTest(assert);
8658       }
8659     });
8660
8661     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8662       assert.expect(1);
8663
8664       if (!isNpm) {
8665         assert.ok(_('a').chain().isEqual('a') instanceof _);
8666       }
8667       else {
8668         skipTest(assert);
8669       }
8670     });
8671   }());
8672
8673   /*--------------------------------------------------------------------------*/
8674
8675   QUnit.module('lodash.isEqualWith');
8676
8677   (function() {
8678     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
8679       assert.expect(1);
8680
8681       var argsList = [],
8682           object1 = { 'a': [1, 2], 'b': null },
8683           object2 = { 'a': [1, 2], 'b': null };
8684
8685       object1.b = object2;
8686       object2.b = object1;
8687
8688       var expected = [
8689         [object1, object2],
8690         [object1.a, object2.a, 'a', object1, object2],
8691         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
8692         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
8693         [object1.b, object2.b, 'b', object1.b, object2.b],
8694         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
8695         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
8696         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
8697         [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
8698       ];
8699
8700       _.isEqualWith(object1, object2, function(assert) {
8701         var length = arguments.length,
8702             args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
8703
8704         argsList.push(args);
8705       });
8706
8707       assert.deepEqual(argsList, expected);
8708     });
8709
8710     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
8711       assert.expect(3);
8712
8713       assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
8714       assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
8715       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
8716     });
8717
8718     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
8719       assert.expect(3);
8720
8721       var customizer = function(value) {
8722         return _.isString(value) || undefined;
8723       };
8724
8725       assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
8726       assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
8727       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
8728     });
8729
8730     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
8731       assert.expect(3);
8732
8733       var customizer = function(value) {
8734         return _.isString(value) ? false : undefined;
8735       };
8736
8737       assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
8738       assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
8739       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
8740     });
8741
8742     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
8743       assert.expect(2);
8744
8745       var actual = _.isEqualWith('a', 'b', alwaysC);
8746       assert.strictEqual(actual, true);
8747
8748       var values = _.without(falsey, undefined),
8749           expected = lodashStable.map(values, alwaysFalse);
8750
8751       actual = [];
8752       lodashStable.each(values, function(value) {
8753         actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
8754       });
8755
8756       assert.deepEqual(actual, expected);
8757     });
8758
8759     QUnit.test('should ensure `customizer` is a function', function(assert) {
8760       assert.expect(1);
8761
8762       var array = [1, 2, 3],
8763           eq = _.partial(_.isEqualWith, array),
8764           actual = lodashStable.map([array, [1, 0, 3]], eq);
8765
8766       assert.deepEqual(actual, [true, false]);
8767     });
8768
8769     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
8770       assert.expect(2);
8771
8772       var value = { 'a': { 'b': 2 } };
8773
8774       if (Map) {
8775         var map1 = new Map;
8776         map1.set('a', value);
8777
8778         var map2 = new Map;
8779         map2.set('a', value);
8780       }
8781       if (Set) {
8782         var set1 = new Set;
8783         set1.add(value);
8784
8785         var set2 = new Set;
8786         set2.add(value);
8787       }
8788       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
8789         if (pair[0]) {
8790           var argsList = [],
8791               array = _.toArray(pair[0]);
8792
8793           var expected = [
8794             [pair[0], pair[1]],
8795             [array[0], array[0], 0, array, array],
8796             [array[0][0], array[0][0], 0, array[0], array[0]],
8797             [array[0][1], array[0][1], 1, array[0], array[0]]
8798           ];
8799
8800           if (index) {
8801             expected.length = 2;
8802           }
8803           _.isEqualWith(pair[0], pair[1], function() {
8804             var length = arguments.length,
8805                 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
8806
8807             argsList.push(args);
8808           });
8809
8810           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
8811         }
8812         else {
8813           skipTest(assert);
8814         }
8815       });
8816     });
8817   }());
8818
8819   /*--------------------------------------------------------------------------*/
8820
8821   QUnit.module('lodash.isError');
8822
8823   (function() {
8824     var args = arguments;
8825
8826     QUnit.test('should return `true` for error objects', function(assert) {
8827       assert.expect(1);
8828
8829       var expected = lodashStable.map(errors, alwaysTrue);
8830
8831       var actual = lodashStable.map(errors, function(error) {
8832         return _.isError(error) === true;
8833       });
8834
8835       assert.deepEqual(actual, expected);
8836     });
8837
8838     QUnit.test('should return `false` for non error objects', function(assert) {
8839       assert.expect(12);
8840
8841       var expected = lodashStable.map(falsey, alwaysFalse);
8842
8843       var actual = lodashStable.map(falsey, function(value, index) {
8844         return index ? _.isError(value) : _.isError();
8845       });
8846
8847       assert.deepEqual(actual, expected);
8848
8849       assert.strictEqual(_.isError(args), false);
8850       assert.strictEqual(_.isError([1, 2, 3]), false);
8851       assert.strictEqual(_.isError(true), false);
8852       assert.strictEqual(_.isError(new Date), false);
8853       assert.strictEqual(_.isError(_), false);
8854       assert.strictEqual(_.isError(slice), false);
8855       assert.strictEqual(_.isError({ 'a': 1 }), false);
8856       assert.strictEqual(_.isError(1), false);
8857       assert.strictEqual(_.isError(/x/), false);
8858       assert.strictEqual(_.isError('a'), false);
8859       assert.strictEqual(_.isError(symbol), false);
8860     });
8861
8862     QUnit.test('should work with an error object from another realm', function(assert) {
8863       assert.expect(1);
8864
8865       if (realm.errors) {
8866         var expected = lodashStable.map(realm.errors, alwaysTrue);
8867
8868         var actual = lodashStable.map(realm.errors, function(error) {
8869           return _.isError(error) === true;
8870         });
8871
8872         assert.deepEqual(actual, expected);
8873       }
8874       else {
8875         skipTest(assert);
8876       }
8877     });
8878   }(1, 2, 3));
8879
8880   /*--------------------------------------------------------------------------*/
8881
8882   QUnit.module('lodash.isFinite');
8883
8884   (function() {
8885     var args = arguments;
8886
8887     QUnit.test('should return `true` for finite values', function(assert) {
8888       assert.expect(1);
8889
8890       var values = [0, 1, 3.14, -1],
8891           expected = lodashStable.map(values, alwaysTrue),
8892           actual = lodashStable.map(values, _.isFinite);
8893
8894       assert.deepEqual(actual, expected);
8895     });
8896
8897     QUnit.test('should return `false` for non-finite values', function(assert) {
8898       assert.expect(1);
8899
8900       var values = [NaN, Infinity, -Infinity, Object(1)],
8901           expected = lodashStable.map(values, alwaysFalse),
8902           actual = lodashStable.map(values, _.isFinite);
8903
8904       assert.deepEqual(actual, expected);
8905     });
8906
8907     QUnit.test('should return `false` for non-numeric values', function(assert) {
8908       assert.expect(10);
8909
8910       var values = [undefined, [], true, '', ' ', '2px'],
8911           expected = lodashStable.map(values, alwaysFalse),
8912           actual = lodashStable.map(values, _.isFinite);
8913
8914       assert.deepEqual(actual, expected);
8915
8916       assert.strictEqual(_.isFinite(args), false);
8917       assert.strictEqual(_.isFinite([1, 2, 3]), false);
8918       assert.strictEqual(_.isFinite(true), false);
8919       assert.strictEqual(_.isFinite(new Date), false);
8920       assert.strictEqual(_.isFinite(new Error), false);
8921       assert.strictEqual(_.isFinite({ 'a': 1 }), false);
8922       assert.strictEqual(_.isFinite(/x/), false);
8923       assert.strictEqual(_.isFinite('a'), false);
8924       assert.strictEqual(_.isFinite(symbol), false);
8925     });
8926
8927     QUnit.test('should return `false` for numeric string values', function(assert) {
8928       assert.expect(1);
8929
8930       var values = ['2', '0', '08'],
8931           expected = lodashStable.map(values, alwaysFalse),
8932           actual = lodashStable.map(values, _.isFinite);
8933
8934       assert.deepEqual(actual, expected);
8935     });
8936   }(1, 2, 3));
8937
8938   /*--------------------------------------------------------------------------*/
8939
8940   QUnit.module('lodash.isFunction');
8941
8942   (function() {
8943     var args = arguments;
8944
8945     QUnit.test('should return `true` for functions', function(assert) {
8946       assert.expect(2);
8947
8948       assert.strictEqual(_.isFunction(_), true);
8949       assert.strictEqual(_.isFunction(slice), true);
8950     });
8951
8952     QUnit.test('should return `true` for generator functions', function(assert) {
8953       assert.expect(1);
8954
8955       assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
8956     });
8957
8958     QUnit.test('should return `true` for typed array constructors', function(assert) {
8959       assert.expect(1);
8960
8961       var expected = lodashStable.map(typedArrays, function(type) {
8962         return objToString.call(root[type]) == funcTag;
8963       });
8964
8965       var actual = lodashStable.map(typedArrays, function(type) {
8966         return _.isFunction(root[type]);
8967       });
8968
8969       assert.deepEqual(actual, expected);
8970     });
8971
8972     QUnit.test('should return `false` for non-functions', function(assert) {
8973       assert.expect(12);
8974
8975       var expected = lodashStable.map(falsey, alwaysFalse);
8976
8977       var actual = lodashStable.map(falsey, function(value, index) {
8978         return index ? _.isFunction(value) : _.isFunction();
8979       });
8980
8981       assert.deepEqual(actual, expected);
8982
8983       assert.strictEqual(_.isFunction(args), false);
8984       assert.strictEqual(_.isFunction([1, 2, 3]), false);
8985       assert.strictEqual(_.isFunction(true), false);
8986       assert.strictEqual(_.isFunction(new Date), false);
8987       assert.strictEqual(_.isFunction(new Error), false);
8988       assert.strictEqual(_.isFunction({ 'a': 1 }), false);
8989       assert.strictEqual(_.isFunction(1), false);
8990       assert.strictEqual(_.isFunction(/x/), false);
8991       assert.strictEqual(_.isFunction('a'), false);
8992       assert.strictEqual(_.isFunction(symbol), false);
8993
8994       if (document) {
8995         assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
8996       } else {
8997         skipTest(assert);
8998       }
8999     });
9000
9001     QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
9002       assert.expect(2);
9003
9004       // Trigger a Chakra JIT bug.
9005       // See https://github.com/jashkenas/underscore/issues/1621.
9006       lodashStable.each([body, xml], function(object) {
9007         if (object) {
9008           lodashStable.times(100, _.isFunction);
9009           assert.strictEqual(_.isFunction(object), false);
9010         }
9011         else {
9012           skipTest(assert);
9013         }
9014       });
9015     });
9016
9017     QUnit.test('should work with a function from another realm', function(assert) {
9018       assert.expect(1);
9019
9020       if (realm.function) {
9021         assert.strictEqual(_.isFunction(realm.function), true);
9022       }
9023       else {
9024         skipTest(assert);
9025       }
9026     });
9027   }(1, 2, 3));
9028
9029   /*--------------------------------------------------------------------------*/
9030
9031   QUnit.module('isInteger methods');
9032
9033   lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
9034     var args = arguments,
9035         func = _[methodName],
9036         isSafe = methodName == 'isSafeInteger';
9037
9038     QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
9039       assert.expect(2);
9040
9041       var values = [-1, 0, 1],
9042           expected = lodashStable.map(values, alwaysTrue);
9043
9044       var actual = lodashStable.map(values, function(value) {
9045         return func(value);
9046       });
9047
9048       assert.deepEqual(actual, expected);
9049       assert.strictEqual(func(MAX_INTEGER), !isSafe);
9050     });
9051
9052     QUnit.test('should return `false` for non-integer number values', function(assert) {
9053       assert.expect(1);
9054
9055       var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
9056           expected = lodashStable.map(values, alwaysFalse);
9057
9058       var actual = lodashStable.map(values, function(value) {
9059         return func(value);
9060       });
9061
9062       assert.deepEqual(actual, expected);
9063     });
9064
9065     QUnit.test('should return `false` for non-numeric values', function(assert) {
9066       assert.expect(10);
9067
9068       var expected = lodashStable.map(falsey, function(value) {
9069         return value === 0;
9070       });
9071
9072       var actual = lodashStable.map(falsey, function(value, index) {
9073         return index ? func(value) : func();
9074       });
9075
9076       assert.deepEqual(actual, expected);
9077
9078       assert.strictEqual(func(args), false);
9079       assert.strictEqual(func([1, 2, 3]), false);
9080       assert.strictEqual(func(true), false);
9081       assert.strictEqual(func(new Date), false);
9082       assert.strictEqual(func(new Error), false);
9083       assert.strictEqual(func({ 'a': 1 }), false);
9084       assert.strictEqual(func(/x/), false);
9085       assert.strictEqual(func('a'), false);
9086       assert.strictEqual(func(symbol), false);
9087     });
9088   });
9089
9090   /*--------------------------------------------------------------------------*/
9091
9092   QUnit.module('lodash.isLength');
9093
9094   (function() {
9095     QUnit.test('should return `true` for lengths', function(assert) {
9096       assert.expect(1);
9097
9098       var values = [0, 3, MAX_SAFE_INTEGER],
9099           expected = lodashStable.map(values, alwaysTrue),
9100           actual = lodashStable.map(values, _.isLength);
9101
9102       assert.deepEqual(actual, expected);
9103     });
9104
9105     QUnit.test('should return `false` for non-lengths', function(assert) {
9106       assert.expect(1);
9107
9108       var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
9109           expected = lodashStable.map(values, alwaysFalse),
9110           actual = lodashStable.map(values, _.isLength);
9111
9112       assert.deepEqual(actual, expected);
9113     });
9114   }());
9115
9116   /*--------------------------------------------------------------------------*/
9117
9118   QUnit.module('lodash.isMatch');
9119
9120   (function() {
9121     QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
9122       assert.expect(5);
9123
9124       var object = { 'a': 1, 'b': 2, 'c': 3 };
9125       assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
9126       assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
9127       assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
9128       assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
9129
9130       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
9131       assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
9132     });
9133
9134     QUnit.test('should match inherited `object` properties', function(assert) {
9135       assert.expect(1);
9136
9137       function Foo() { this.a = 1; }
9138       Foo.prototype.b = 2;
9139
9140       assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
9141     });
9142
9143     QUnit.test('should not match by inherited `source` properties', function(assert) {
9144       assert.expect(1);
9145
9146       function Foo() { this.a = 1; }
9147       Foo.prototype.b = 2;
9148
9149       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
9150           source = new Foo,
9151           expected = lodashStable.map(objects, alwaysTrue);
9152
9153       var actual = lodashStable.map(objects, function(object) {
9154         return _.isMatch(object, source);
9155       });
9156
9157       assert.deepEqual(actual, expected);
9158     });
9159
9160     QUnit.test('should compare a variety of `source` property values', function(assert) {
9161       assert.expect(2);
9162
9163       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
9164           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
9165
9166       assert.strictEqual(_.isMatch(object1, object1), true);
9167       assert.strictEqual(_.isMatch(object1, object2), false);
9168     });
9169
9170     QUnit.test('should match `-0` as `0`', function(assert) {
9171       assert.expect(2);
9172
9173       var object1 = { 'a': -0 },
9174           object2 = { 'a': 0 };
9175
9176       assert.strictEqual(_.isMatch(object1, object2), true);
9177       assert.strictEqual(_.isMatch(object2, object1), true);
9178     });
9179
9180     QUnit.test('should compare functions by reference', function(assert) {
9181       assert.expect(3);
9182
9183       var object1 = { 'a': lodashStable.noop },
9184           object2 = { 'a': noop },
9185           object3 = { 'a': {} };
9186
9187       assert.strictEqual(_.isMatch(object1, object1), true);
9188       assert.strictEqual(_.isMatch(object2, object1), false);
9189       assert.strictEqual(_.isMatch(object3, object1), false);
9190     });
9191
9192     QUnit.test('should work with a function for `object`', function(assert) {
9193       assert.expect(1);
9194
9195       function Foo() {}
9196       Foo.a = { 'b': 1, 'c': 2 };
9197
9198       assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 1 } }), true);
9199     });
9200
9201     QUnit.test('should work with a function for `source`', function(assert) {
9202       assert.expect(1);
9203
9204       function Foo() {}
9205       Foo.a = 1;
9206       Foo.b = function() {};
9207       Foo.c = 3;
9208
9209       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
9210
9211       var actual = lodashStable.map(objects, function(object) {
9212         return _.isMatch(object, Foo);
9213       });
9214
9215       assert.deepEqual(actual, [false, true]);
9216     });
9217
9218     QUnit.test('should work with a non-plain `object`', function(assert) {
9219       assert.expect(1);
9220
9221       function Foo(object) { lodashStable.assign(this, object); }
9222
9223       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) });
9224       assert.strictEqual(_.isMatch(object, { 'a': { 'b': 1 } }), true);
9225     });
9226
9227     QUnit.test('should partial match arrays', function(assert) {
9228       assert.expect(3);
9229
9230       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
9231           source = { 'a': ['d'] },
9232           predicate = function(object) { return _.isMatch(object, source); },
9233           actual = lodashStable.filter(objects, predicate);
9234
9235       assert.deepEqual(actual, [objects[1]]);
9236
9237       source = { 'a': ['b', 'd'] };
9238       actual = lodashStable.filter(objects, predicate);
9239
9240       assert.deepEqual(actual, []);
9241
9242       source = { 'a': ['d', 'b'] };
9243       actual = lodashStable.filter(objects, predicate);
9244       assert.deepEqual(actual, []);
9245     });
9246
9247     QUnit.test('should partial match arrays of objects', function(assert) {
9248       assert.expect(1);
9249
9250       var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
9251
9252       var objects = [
9253         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
9254         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
9255       ];
9256
9257       var actual = lodashStable.filter(objects, function(object) {
9258         return _.isMatch(object, source);
9259       });
9260
9261       assert.deepEqual(actual, [objects[0]]);
9262     });
9263
9264     QUnit.test('should partial match maps', function(assert) {
9265       assert.expect(3);
9266
9267       if (Map) {
9268         var objects = [{ 'a': new Map }, { 'a': new Map }];
9269         objects[0].a.set('a', 1);
9270         objects[1].a.set('a', 1);
9271         objects[1].a.set('b', 2);
9272
9273         var map = new Map;
9274         map.set('b', 2);
9275
9276         var source = { 'a': map },
9277             predicate = function(object) { return _.isMatch(object, source); },
9278             actual = lodashStable.filter(objects, predicate);
9279
9280         assert.deepEqual(actual, [objects[1]]);
9281
9282         map['delete']('b');
9283         actual = lodashStable.filter(objects, predicate);
9284
9285         assert.deepEqual(actual, objects);
9286
9287         map.set('c', 3);
9288         actual = lodashStable.filter(objects, predicate);
9289
9290         assert.deepEqual(actual, []);
9291       }
9292       else {
9293         skipTest(assert, 3);
9294       }
9295     });
9296
9297     QUnit.test('should partial match sets', function(assert) {
9298       assert.expect(3);
9299
9300       if (Set) {
9301         var objects = [{ 'a': new Set }, { 'a': new Set }];
9302         objects[0].a.add(1);
9303         objects[1].a.add(1);
9304         objects[1].a.add(2);
9305
9306         var set = new Set;
9307         set.add(2);
9308
9309         var source = { 'a': set },
9310             predicate = function(object) { return _.isMatch(object, source); },
9311             actual = lodashStable.filter(objects, predicate);
9312
9313         assert.deepEqual(actual, [objects[1]]);
9314
9315         set['delete'](2);
9316         actual = lodashStable.filter(objects, predicate);
9317
9318         assert.deepEqual(actual, objects);
9319
9320         set.add(3);
9321         actual = lodashStable.filter(objects, predicate);
9322
9323         assert.deepEqual(actual, []);
9324       }
9325       else {
9326         skipTest(assert, 3);
9327       }
9328     });
9329
9330     QUnit.test('should match `undefined` values', function(assert) {
9331       assert.expect(3);
9332
9333       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
9334           source = { 'b': undefined },
9335           predicate = function(object) { return _.isMatch(object, source); },
9336           actual = lodashStable.map(objects, predicate),
9337           expected = [false, false, true];
9338
9339       assert.deepEqual(actual, expected);
9340
9341       source = { 'a': 1, 'b': undefined };
9342       actual = lodashStable.map(objects, predicate);
9343
9344       assert.deepEqual(actual, expected);
9345
9346       objects = [{ 'a': { 'b': 1 } }, { 'a':{ 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
9347       source = { 'a': { 'c': undefined } };
9348       actual = lodashStable.map(objects, predicate);
9349
9350       assert.deepEqual(actual, expected);
9351     });
9352
9353     QUnit.test('should match `undefined` values on primitives', function(assert) {
9354       assert.expect(3);
9355
9356       numberProto.a = 1;
9357       numberProto.b = undefined;
9358
9359       try {
9360         assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
9361       } catch (e) {
9362         assert.ok(false, e.message);
9363       }
9364       try {
9365         assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
9366       } catch (e) {
9367         assert.ok(false, e.message);
9368       }
9369       numberProto.a = { 'b': 1, 'c': undefined };
9370       try {
9371         assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
9372       } catch (e) {
9373         assert.ok(false, e.message);
9374       }
9375       delete numberProto.a;
9376       delete numberProto.b;
9377     });
9378
9379     QUnit.test('should return `false` when `object` is nullish', function(assert) {
9380       assert.expect(1);
9381
9382       var values = [null, undefined],
9383           expected = lodashStable.map(values, alwaysFalse),
9384           source = { 'a': 1 };
9385
9386       var actual = lodashStable.map(values, function(value) {
9387         try {
9388           return _.isMatch(value, source);
9389         } catch (e) {}
9390       });
9391
9392       assert.deepEqual(actual, expected);
9393     });
9394
9395     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
9396       assert.expect(1);
9397
9398       var values = [null, undefined],
9399           expected = lodashStable.map(values, alwaysTrue),
9400           source = {};
9401
9402       var actual = lodashStable.map(values, function(value) {
9403         try {
9404           return _.isMatch(value, source);
9405         } catch (e) {}
9406       });
9407
9408       assert.deepEqual(actual, expected);
9409     });
9410
9411     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
9412       assert.expect(1);
9413
9414       var object = { 'a': 1 },
9415           expected = lodashStable.map(empties, alwaysTrue);
9416
9417       var actual = lodashStable.map(empties, function(value) {
9418         return _.isMatch(object, value);
9419       });
9420
9421       assert.deepEqual(actual, expected);
9422     });
9423
9424     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
9425       assert.expect(1);
9426
9427       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
9428           source = { 'a': [], 'b': {} };
9429
9430       var actual = lodashStable.filter(objects, function(object) {
9431         return _.isMatch(object, source);
9432       });
9433
9434       assert.deepEqual(actual, objects);
9435     });
9436   }());
9437
9438   /*--------------------------------------------------------------------------*/
9439
9440   QUnit.module('lodash.isMatchWith');
9441
9442   (function() {
9443     QUnit.test('should provide the correct `customizer` arguments', function(assert) {
9444       assert.expect(1);
9445
9446       var argsList = [],
9447           object1 = { 'a': [1, 2], 'b': null },
9448           object2 = { 'a': [1, 2], 'b': null };
9449
9450       object1.b = object2;
9451       object2.b = object1;
9452
9453       var expected = [
9454         [object1.a, object2.a, 'a', object1, object2],
9455         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
9456         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
9457         [object1.b, object2.b, 'b', object1, object2],
9458         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
9459         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
9460         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
9461         [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
9462         [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
9463         [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
9464         [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
9465         [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
9466       ];
9467
9468       _.isMatchWith(object1, object2, function(assert) {
9469         argsList.push(slice.call(arguments, 0, -1));
9470       });
9471
9472       assert.deepEqual(argsList, expected);
9473     });
9474
9475     QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
9476       assert.expect(1);
9477
9478       assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
9479     });
9480
9481     QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
9482       assert.expect(2);
9483
9484       var customizer = function(value) {
9485         return _.isString(value) || undefined;
9486       };
9487
9488       assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
9489       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
9490     });
9491
9492     QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
9493       assert.expect(2);
9494
9495       var customizer = function(value) {
9496         return _.isString(value) ? false : undefined;
9497       };
9498
9499       assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
9500       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
9501     });
9502
9503     QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
9504       assert.expect(2);
9505
9506       var object = { 'a': 1 },
9507           actual = _.isMatchWith(object, { 'a': 1 }, alwaysA);
9508
9509       assert.strictEqual(actual, true);
9510
9511       var expected = lodashStable.map(falsey, alwaysFalse);
9512
9513       actual = [];
9514       lodashStable.each(falsey, function(value) {
9515         actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
9516       });
9517
9518       assert.deepEqual(actual, expected);
9519     });
9520
9521     QUnit.test('should ensure `customizer` is a function', function(assert) {
9522       assert.expect(1);
9523
9524       var object = { 'a': 1 },
9525           matches = _.partial(_.isMatchWith, object),
9526           actual = lodashStable.map([object, { 'a': 2 }], matches);
9527
9528       assert.deepEqual(actual, [true, false]);
9529     });
9530
9531     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
9532       assert.expect(2);
9533
9534       var value = { 'a': { 'b': 2 } };
9535
9536       if (Map) {
9537         var map1 = new Map;
9538         map1.set('a', value);
9539
9540         var map2 = new Map;
9541         map2.set('a', value);
9542       }
9543       if (Set) {
9544         var set1 = new Set;
9545         set1.add(value);
9546
9547         var set2 = new Set;
9548         set2.add(value);
9549       }
9550       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
9551         if (pair[0]) {
9552           var argsList = [],
9553               array = _.toArray(pair[0]),
9554               object1 = { 'a': pair[0] },
9555               object2 = { 'a': pair[1] };
9556
9557           var expected = [
9558             [pair[0], pair[1], 'a', object1, object2],
9559             [array[0], array[0], 0, array, array],
9560             [array[0][0], array[0][0], 0, array[0], array[0]],
9561             [array[0][1], array[0][1], 1, array[0], array[0]]
9562           ];
9563
9564           if (index) {
9565             expected.length = 2;
9566           }
9567           _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
9568             argsList.push(slice.call(arguments, 0, -1));
9569           });
9570
9571           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
9572         }
9573         else {
9574           skipTest(assert);
9575         }
9576       });
9577     });
9578   }());
9579
9580   /*--------------------------------------------------------------------------*/
9581
9582   QUnit.module('lodash.isNaN');
9583
9584   (function() {
9585     var args = arguments;
9586
9587     QUnit.test('should return `true` for NaNs', function(assert) {
9588       assert.expect(2);
9589
9590       assert.strictEqual(_.isNaN(NaN), true);
9591       assert.strictEqual(_.isNaN(Object(NaN)), true);
9592     });
9593
9594     QUnit.test('should return `false` for non-NaNs', function(assert) {
9595       assert.expect(14);
9596
9597       var expected = lodashStable.map(falsey, function(value) {
9598         return value !== value;
9599       });
9600
9601       var actual = lodashStable.map(falsey, function(value, index) {
9602         return index ? _.isNaN(value) : _.isNaN();
9603       });
9604
9605       assert.deepEqual(actual, expected);
9606
9607       assert.strictEqual(_.isNaN(args), false);
9608       assert.strictEqual(_.isNaN([1, 2, 3]), false);
9609       assert.strictEqual(_.isNaN(true), false);
9610       assert.strictEqual(_.isNaN(new Date), false);
9611       assert.strictEqual(_.isNaN(new Error), false);
9612       assert.strictEqual(_.isNaN(_), false);
9613       assert.strictEqual(_.isNaN(slice), false);
9614       assert.strictEqual(_.isNaN({ 'a': 1 }), false);
9615       assert.strictEqual(_.isNaN(1), false);
9616       assert.strictEqual(_.isNaN(Object(1)), false);
9617       assert.strictEqual(_.isNaN(/x/), false);
9618       assert.strictEqual(_.isNaN('a'), false);
9619       assert.strictEqual(_.isNaN(symbol), false);
9620     });
9621
9622     QUnit.test('should work with `NaN` from another realm', function(assert) {
9623       assert.expect(1);
9624
9625       if (realm.object) {
9626         assert.strictEqual(_.isNaN(realm.nan), true);
9627       }
9628       else {
9629         skipTest(assert);
9630       }
9631     });
9632   }(1, 2, 3));
9633
9634   /*--------------------------------------------------------------------------*/
9635
9636   QUnit.module('lodash.isNative');
9637
9638   (function() {
9639     var args = arguments;
9640
9641     QUnit.test('should return `true` for native methods', function(assert) {
9642       assert.expect(6);
9643
9644       lodashStable.each([Array, create, root.encodeURI, slice, Uint8Array], function(func) {
9645         if (func) {
9646           assert.strictEqual(_.isNative(func), true);
9647         }
9648         else {
9649           skipTest(assert);
9650         }
9651       });
9652
9653       if (body) {
9654         assert.strictEqual(_.isNative(body.cloneNode), true);
9655       }
9656       else {
9657         skipTest(assert);
9658       }
9659     });
9660
9661     QUnit.test('should return `false` for non-native methods', function(assert) {
9662       assert.expect(12);
9663
9664       var expected = lodashStable.map(falsey, alwaysFalse);
9665
9666       var actual = lodashStable.map(falsey, function(value, index) {
9667         return index ? _.isNative(value) : _.isNative();
9668       });
9669
9670       assert.deepEqual(actual, expected);
9671
9672       assert.strictEqual(_.isNative(args), false);
9673       assert.strictEqual(_.isNative([1, 2, 3]), false);
9674       assert.strictEqual(_.isNative(true), false);
9675       assert.strictEqual(_.isNative(new Date), false);
9676       assert.strictEqual(_.isNative(new Error), false);
9677       assert.strictEqual(_.isNative(_), false);
9678       assert.strictEqual(_.isNative({ 'a': 1 }), false);
9679       assert.strictEqual(_.isNative(1), false);
9680       assert.strictEqual(_.isNative(/x/), false);
9681       assert.strictEqual(_.isNative('a'), false);
9682       assert.strictEqual(_.isNative(symbol), false);
9683     });
9684
9685     QUnit.test('should work with native functions from another realm', function(assert) {
9686       assert.expect(2);
9687
9688       if (realm.element) {
9689         assert.strictEqual(_.isNative(realm.element.cloneNode), true);
9690       }
9691       else {
9692         skipTest(assert);
9693       }
9694       if (realm.object) {
9695         assert.strictEqual(_.isNative(realm.object.valueOf), true);
9696       }
9697       else {
9698         skipTest(assert);
9699       }
9700     });
9701   }(1, 2, 3));
9702
9703   /*--------------------------------------------------------------------------*/
9704
9705   QUnit.module('lodash.isNull');
9706
9707   (function() {
9708     var args = arguments;
9709
9710     QUnit.test('should return `true` for `null` values', function(assert) {
9711       assert.expect(1);
9712
9713       assert.strictEqual(_.isNull(null), true);
9714     });
9715
9716     QUnit.test('should return `false` for non `null` values', function(assert) {
9717       assert.expect(13);
9718
9719       var expected = lodashStable.map(falsey, function(value) {
9720         return value === null;
9721       });
9722
9723       var actual = lodashStable.map(falsey, function(value, index) {
9724         return index ? _.isNull(value) : _.isNull();
9725       });
9726
9727       assert.deepEqual(actual, expected);
9728
9729       assert.strictEqual(_.isNull(args), false);
9730       assert.strictEqual(_.isNull([1, 2, 3]), false);
9731       assert.strictEqual(_.isNull(true), false);
9732       assert.strictEqual(_.isNull(new Date), false);
9733       assert.strictEqual(_.isNull(new Error), false);
9734       assert.strictEqual(_.isNull(_), false);
9735       assert.strictEqual(_.isNull(slice), false);
9736       assert.strictEqual(_.isNull({ 'a': 1 }), false);
9737       assert.strictEqual(_.isNull(1), false);
9738       assert.strictEqual(_.isNull(/x/), false);
9739       assert.strictEqual(_.isNull('a'), false);
9740       assert.strictEqual(_.isNull(symbol), false);
9741     });
9742
9743     QUnit.test('should work with nulls from another realm', function(assert) {
9744       assert.expect(1);
9745
9746       if (realm.object) {
9747         assert.strictEqual(_.isNull(realm.null), true);
9748       }
9749       else {
9750         skipTest(assert);
9751       }
9752     });
9753   }(1, 2, 3));
9754
9755   /*--------------------------------------------------------------------------*/
9756
9757   QUnit.module('lodash.isNil');
9758
9759   (function() {
9760     var args = arguments;
9761
9762     QUnit.test('should return `true` for nullish values', function(assert) {
9763       assert.expect(3);
9764
9765       assert.strictEqual(_.isNil(null), true);
9766       assert.strictEqual(_.isNil(), true);
9767       assert.strictEqual(_.isNil(undefined), true);
9768     });
9769
9770     QUnit.test('should return `false` for non-nullish values', function(assert) {
9771       assert.expect(13);
9772
9773       var expected = lodashStable.map(falsey, function(value) {
9774         return value == null;
9775       });
9776
9777       var actual = lodashStable.map(falsey, function(value, index) {
9778         return index ? _.isNil(value) : _.isNil();
9779       });
9780
9781       assert.deepEqual(actual, expected);
9782
9783       assert.strictEqual(_.isNil(args), false);
9784       assert.strictEqual(_.isNil([1, 2, 3]), false);
9785       assert.strictEqual(_.isNil(true), false);
9786       assert.strictEqual(_.isNil(new Date), false);
9787       assert.strictEqual(_.isNil(new Error), false);
9788       assert.strictEqual(_.isNil(_), false);
9789       assert.strictEqual(_.isNil(slice), false);
9790       assert.strictEqual(_.isNil({ 'a': 1 }), false);
9791       assert.strictEqual(_.isNil(1), false);
9792       assert.strictEqual(_.isNil(/x/), false);
9793       assert.strictEqual(_.isNil('a'), false);
9794
9795       if (Symbol) {
9796         assert.strictEqual(_.isNil(symbol), false);
9797       }
9798       else {
9799         skipTest(assert);
9800       }
9801     });
9802
9803     QUnit.test('should work with nulls from another realm', function(assert) {
9804       assert.expect(2);
9805
9806       if (realm.object) {
9807         assert.strictEqual(_.isNil(realm.null), true);
9808         assert.strictEqual(_.isNil(realm.undefined), true);
9809       }
9810       else {
9811         skipTest(assert, 2);
9812       }
9813     });
9814   }(1, 2, 3));
9815
9816   /*--------------------------------------------------------------------------*/
9817
9818   QUnit.module('lodash.isNumber');
9819
9820   (function() {
9821     var args = arguments;
9822
9823     QUnit.test('should return `true` for numbers', function(assert) {
9824       assert.expect(3);
9825
9826       assert.strictEqual(_.isNumber(0), true);
9827       assert.strictEqual(_.isNumber(Object(0)), true);
9828       assert.strictEqual(_.isNumber(NaN), true);
9829     });
9830
9831     QUnit.test('should return `false` for non-numbers', function(assert) {
9832       assert.expect(12);
9833
9834       var expected = lodashStable.map(falsey, function(value) {
9835         return typeof value == 'number';
9836       });
9837
9838       var actual = lodashStable.map(falsey, function(value, index) {
9839         return index ? _.isNumber(value) : _.isNumber();
9840       });
9841
9842       assert.deepEqual(actual, expected);
9843
9844       assert.strictEqual(_.isNumber(args), false);
9845       assert.strictEqual(_.isNumber([1, 2, 3]), false);
9846       assert.strictEqual(_.isNumber(true), false);
9847       assert.strictEqual(_.isNumber(new Date), false);
9848       assert.strictEqual(_.isNumber(new Error), false);
9849       assert.strictEqual(_.isNumber(_), false);
9850       assert.strictEqual(_.isNumber(slice), false);
9851       assert.strictEqual(_.isNumber({ 'a': 1 }), false);
9852       assert.strictEqual(_.isNumber(/x/), false);
9853       assert.strictEqual(_.isNumber('a'), false);
9854       assert.strictEqual(_.isNumber(symbol), false);
9855     });
9856
9857     QUnit.test('should work with numbers from another realm', function(assert) {
9858       assert.expect(1);
9859
9860       if (realm.number) {
9861         assert.strictEqual(_.isNumber(realm.number), true);
9862       }
9863       else {
9864         skipTest(assert);
9865       }
9866     });
9867
9868     QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
9869       assert.expect(1);
9870
9871       assert.strictEqual(_.isNumber(+'2'), true);
9872     });
9873   }(1, 2, 3));
9874
9875   /*--------------------------------------------------------------------------*/
9876
9877   QUnit.module('lodash.isObject');
9878
9879   (function() {
9880     var args = arguments;
9881
9882     QUnit.test('should return `true` for objects', function(assert) {
9883       assert.expect(13);
9884
9885       assert.strictEqual(_.isObject(args), true);
9886       assert.strictEqual(_.isObject([1, 2, 3]), true);
9887       assert.strictEqual(_.isObject(Object(false)), true);
9888       assert.strictEqual(_.isObject(new Date), true);
9889       assert.strictEqual(_.isObject(new Error), true);
9890       assert.strictEqual(_.isObject(_), true);
9891       assert.strictEqual(_.isObject(slice), true);
9892       assert.strictEqual(_.isObject({ 'a': 1 }), true);
9893       assert.strictEqual(_.isObject(Object(0)), true);
9894       assert.strictEqual(_.isObject(/x/), true);
9895       assert.strictEqual(_.isObject(Object('a')), true);
9896
9897       if (document) {
9898         assert.strictEqual(_.isObject(body), true);
9899       }
9900       else {
9901         skipTest(assert);
9902       }
9903       if (Symbol) {
9904         assert.strictEqual(_.isObject(Object(symbol)), true);
9905       }
9906       else {
9907         skipTest(assert);
9908       }
9909     });
9910
9911     QUnit.test('should return `false` for non-objects', function(assert) {
9912       assert.expect(1);
9913
9914       var values = falsey.concat(true, 1, 'a', symbol),
9915           expected = lodashStable.map(values, alwaysFalse);
9916
9917       var actual = lodashStable.map(values, function(value, index) {
9918         return index ? _.isObject(value) : _.isObject();
9919       });
9920
9921       assert.deepEqual(actual, expected);
9922     });
9923
9924     QUnit.test('should work with objects from another realm', function(assert) {
9925       assert.expect(8);
9926
9927       if (realm.element) {
9928         assert.strictEqual(_.isObject(realm.element), true);
9929       }
9930       else {
9931         skipTest(assert);
9932       }
9933       if (realm.object) {
9934         assert.strictEqual(_.isObject(realm.boolean), true);
9935         assert.strictEqual(_.isObject(realm.date), true);
9936         assert.strictEqual(_.isObject(realm.function), true);
9937         assert.strictEqual(_.isObject(realm.number), true);
9938         assert.strictEqual(_.isObject(realm.object), true);
9939         assert.strictEqual(_.isObject(realm.regexp), true);
9940         assert.strictEqual(_.isObject(realm.string), true);
9941       }
9942       else {
9943         skipTest(assert, 7);
9944       }
9945     });
9946
9947     QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
9948       assert.expect(1);
9949
9950       // Trigger a V8 JIT bug.
9951       // See https://code.google.com/p/v8/issues/detail?id=2291.
9952       var object = {};
9953
9954       // 1: Useless comparison statement, this is half the trigger.
9955       object == object;
9956
9957       // 2: Initial check with object, this is the other half of the trigger.
9958       _.isObject(object);
9959
9960       assert.strictEqual(_.isObject('a'), false);
9961     });
9962   }(1, 2, 3));
9963
9964   /*--------------------------------------------------------------------------*/
9965
9966   QUnit.module('lodash.isObjectLike');
9967
9968   (function() {
9969     var args = arguments;
9970
9971     QUnit.test('should return `true` for objects', function(assert) {
9972       assert.expect(9);
9973
9974       assert.strictEqual(_.isObjectLike(args), true);
9975       assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
9976       assert.strictEqual(_.isObjectLike(Object(false)), true);
9977       assert.strictEqual(_.isObjectLike(new Date), true);
9978       assert.strictEqual(_.isObjectLike(new Error), true);
9979       assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
9980       assert.strictEqual(_.isObjectLike(Object(0)), true);
9981       assert.strictEqual(_.isObjectLike(/x/), true);
9982       assert.strictEqual(_.isObjectLike(Object('a')), true);
9983     });
9984
9985     QUnit.test('should return `false` for non-objects', function(assert) {
9986       assert.expect(1);
9987
9988       var values = falsey.concat(true, _, slice, 1, 'a', symbol),
9989           expected = lodashStable.map(values, alwaysFalse);
9990
9991       var actual = lodashStable.map(values, function(value, index) {
9992         return index ? _.isObjectLike(value) : _.isObjectLike();
9993       });
9994
9995       assert.deepEqual(actual, expected);
9996     });
9997
9998     QUnit.test('should work with objects from another realm', function(assert) {
9999       assert.expect(6);
10000
10001       if (realm.object) {
10002         assert.strictEqual(_.isObjectLike(realm.boolean), true);
10003         assert.strictEqual(_.isObjectLike(realm.date), true);
10004         assert.strictEqual(_.isObjectLike(realm.number), true);
10005         assert.strictEqual(_.isObjectLike(realm.object), true);
10006         assert.strictEqual(_.isObjectLike(realm.regexp), true);
10007         assert.strictEqual(_.isObjectLike(realm.string), true);
10008       }
10009       else {
10010         skipTest(assert, 6);
10011       }
10012     });
10013   }(1, 2, 3));
10014
10015   /*--------------------------------------------------------------------------*/
10016
10017   QUnit.module('lodash.isPlainObject');
10018
10019   (function() {
10020     var element = document && document.createElement('div');
10021
10022     QUnit.test('should detect plain objects', function(assert) {
10023       assert.expect(5);
10024
10025       function Foo(a) {
10026         this.a = 1;
10027       }
10028
10029       assert.strictEqual(_.isPlainObject({}), true);
10030       assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
10031       assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
10032       assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
10033       assert.strictEqual(_.isPlainObject(new Foo(1)), false);
10034     });
10035
10036     QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
10037       assert.expect(2);
10038
10039       if (create) {
10040         var object = create(null);
10041         assert.strictEqual(_.isPlainObject(object), true);
10042
10043         object.constructor = objectProto.constructor;
10044         assert.strictEqual(_.isPlainObject(object), true);
10045       }
10046       else {
10047         skipTest(assert, 2);
10048       }
10049     });
10050
10051     QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
10052       assert.expect(2);
10053
10054       assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
10055
10056       if (element) {
10057         var valueOf = element.valueOf;
10058         element.valueOf = 0;
10059
10060         assert.strictEqual(_.isPlainObject(element), false);
10061         element.valueOf = valueOf;
10062       }
10063       else {
10064         skipTest(assert);
10065       }
10066     });
10067
10068     QUnit.test('should return `false` for DOM elements', function(assert) {
10069       assert.expect(1);
10070
10071       if (element) {
10072         assert.strictEqual(_.isPlainObject(element), false);
10073       } else {
10074         skipTest(assert);
10075       }
10076     });
10077
10078     QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
10079       assert.expect(3);
10080
10081       assert.strictEqual(_.isPlainObject(arguments), false);
10082       assert.strictEqual(_.isPlainObject(Error), false);
10083       assert.strictEqual(_.isPlainObject(Math), false);
10084     });
10085
10086     QUnit.test('should return `false` for non-objects', function(assert) {
10087       assert.expect(4);
10088
10089       var expected = lodashStable.map(falsey, alwaysFalse);
10090
10091       var actual = lodashStable.map(falsey, function(value, index) {
10092         return index ? _.isPlainObject(value) : _.isPlainObject();
10093       });
10094
10095       assert.deepEqual(actual, expected);
10096
10097       assert.strictEqual(_.isPlainObject(true), false);
10098       assert.strictEqual(_.isPlainObject('a'), false);
10099       assert.strictEqual(_.isPlainObject(symbol), false);
10100     });
10101
10102     QUnit.test('should work with objects from another realm', function(assert) {
10103       assert.expect(1);
10104
10105       if (realm.object) {
10106         assert.strictEqual(_.isPlainObject(realm.object), true);
10107       }
10108       else {
10109         skipTest(assert);
10110       }
10111     });
10112   }());
10113
10114   /*--------------------------------------------------------------------------*/
10115
10116   QUnit.module('lodash.isRegExp');
10117
10118   (function() {
10119     var args = arguments;
10120
10121     QUnit.test('should return `true` for regexes', function(assert) {
10122       assert.expect(2);
10123
10124       assert.strictEqual(_.isRegExp(/x/), true);
10125       assert.strictEqual(_.isRegExp(RegExp('x')), true);
10126     });
10127
10128     QUnit.test('should return `false` for non-regexes', function(assert) {
10129       assert.expect(12);
10130
10131       var expected = lodashStable.map(falsey, alwaysFalse);
10132
10133       var actual = lodashStable.map(falsey, function(value, index) {
10134         return index ? _.isRegExp(value) : _.isRegExp();
10135       });
10136
10137       assert.deepEqual(actual, expected);
10138
10139       assert.strictEqual(_.isRegExp(args), false);
10140       assert.strictEqual(_.isRegExp([1, 2, 3]), false);
10141       assert.strictEqual(_.isRegExp(true), false);
10142       assert.strictEqual(_.isRegExp(new Date), false);
10143       assert.strictEqual(_.isRegExp(new Error), false);
10144       assert.strictEqual(_.isRegExp(_), false);
10145       assert.strictEqual(_.isRegExp(slice), false);
10146       assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
10147       assert.strictEqual(_.isRegExp(1), false);
10148       assert.strictEqual(_.isRegExp('a'), false);
10149       assert.strictEqual(_.isRegExp(symbol), false);
10150     });
10151
10152     QUnit.test('should work with regexes from another realm', function(assert) {
10153       assert.expect(1);
10154
10155       if (realm.regexp) {
10156         assert.strictEqual(_.isRegExp(realm.regexp), true);
10157       }
10158       else {
10159         skipTest(assert);
10160       }
10161     });
10162   }(1, 2, 3));
10163
10164   /*--------------------------------------------------------------------------*/
10165
10166   QUnit.module('lodash.isString');
10167
10168   (function() {
10169     var args = arguments;
10170
10171     QUnit.test('should return `true` for strings', function(assert) {
10172       assert.expect(2);
10173
10174       assert.strictEqual(_.isString('a'), true);
10175       assert.strictEqual(_.isString(Object('a')), true);
10176     });
10177
10178     QUnit.test('should return `false` for non-strings', function(assert) {
10179       assert.expect(12);
10180
10181       var expected = lodashStable.map(falsey, function(value) {
10182         return value === '';
10183       });
10184
10185       var actual = lodashStable.map(falsey, function(value, index) {
10186         return index ? _.isString(value) : _.isString();
10187       });
10188
10189       assert.deepEqual(actual, expected);
10190
10191       assert.strictEqual(_.isString(args), false);
10192       assert.strictEqual(_.isString([1, 2, 3]), false);
10193       assert.strictEqual(_.isString(true), false);
10194       assert.strictEqual(_.isString(new Date), false);
10195       assert.strictEqual(_.isString(new Error), false);
10196       assert.strictEqual(_.isString(_), false);
10197       assert.strictEqual(_.isString(slice), false);
10198       assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
10199       assert.strictEqual(_.isString(1), false);
10200       assert.strictEqual(_.isString(/x/), false);
10201       assert.strictEqual(_.isString(symbol), false);
10202     });
10203
10204     QUnit.test('should work with strings from another realm', function(assert) {
10205       assert.expect(1);
10206
10207       if (realm.string) {
10208         assert.strictEqual(_.isString(realm.string), true);
10209       }
10210       else {
10211         skipTest(assert);
10212       }
10213     });
10214   }(1, 2, 3));
10215
10216   /*--------------------------------------------------------------------------*/
10217
10218   QUnit.module('lodash.isSymbol');
10219
10220   (function() {
10221     var args = arguments;
10222
10223     QUnit.test('should return `true` for symbols', function(assert) {
10224       assert.expect(2);
10225
10226       if (Symbol) {
10227         assert.strictEqual(_.isSymbol(symbol), true);
10228         assert.strictEqual(_.isSymbol(Object(symbol)), true);
10229       }
10230       else {
10231         skipTest(assert, 2);
10232       }
10233     });
10234
10235     QUnit.test('should return `false` for non-symbols', function(assert) {
10236       assert.expect(12);
10237
10238       var expected = lodashStable.map(falsey, alwaysFalse);
10239
10240       var actual = lodashStable.map(falsey, function(value, index) {
10241         return index ? _.isSymbol(value) : _.isSymbol();
10242       });
10243
10244       assert.deepEqual(actual, expected);
10245
10246       assert.strictEqual(_.isSymbol(args), false);
10247       assert.strictEqual(_.isSymbol([1, 2, 3]), false);
10248       assert.strictEqual(_.isSymbol(true), false);
10249       assert.strictEqual(_.isSymbol(new Date), false);
10250       assert.strictEqual(_.isSymbol(new Error), false);
10251       assert.strictEqual(_.isSymbol(_), false);
10252       assert.strictEqual(_.isSymbol(slice), false);
10253       assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
10254       assert.strictEqual(_.isSymbol(1), false);
10255       assert.strictEqual(_.isSymbol(/x/), false);
10256       assert.strictEqual(_.isSymbol('a'), false);
10257     });
10258
10259     QUnit.test('should work with symbols from another realm', function(assert) {
10260       assert.expect(1);
10261
10262       if (Symbol && realm.symbol) {
10263         assert.strictEqual(_.isSymbol(realm.symbol), true);
10264       }
10265       else {
10266         skipTest(assert);
10267       }
10268     });
10269   }(1, 2, 3));
10270
10271   /*--------------------------------------------------------------------------*/
10272
10273   QUnit.module('lodash.isTypedArray');
10274
10275   (function() {
10276     var args = arguments;
10277
10278     QUnit.test('should return `true` for typed arrays', function(assert) {
10279       assert.expect(1);
10280
10281       var expected = lodashStable.map(typedArrays, function(type) {
10282         return type in root;
10283       });
10284
10285       var actual = lodashStable.map(typedArrays, function(type) {
10286         var Ctor = root[type];
10287         return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
10288       });
10289
10290       assert.deepEqual(actual, expected);
10291     });
10292
10293     QUnit.test('should return `false` for non typed arrays', function(assert) {
10294       assert.expect(13);
10295
10296       var expected = lodashStable.map(falsey, alwaysFalse);
10297
10298       var actual = lodashStable.map(falsey, function(value, index) {
10299         return index ? _.isTypedArray(value) : _.isTypedArray();
10300       });
10301
10302       assert.deepEqual(actual, expected);
10303
10304       assert.strictEqual(_.isTypedArray(args), false);
10305       assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
10306       assert.strictEqual(_.isTypedArray(true), false);
10307       assert.strictEqual(_.isTypedArray(new Date), false);
10308       assert.strictEqual(_.isTypedArray(new Error), false);
10309       assert.strictEqual(_.isTypedArray(_), false);
10310       assert.strictEqual(_.isTypedArray(slice), false);
10311       assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
10312       assert.strictEqual(_.isTypedArray(1), false);
10313       assert.strictEqual(_.isTypedArray(/x/), false);
10314       assert.strictEqual(_.isTypedArray('a'), false);
10315       assert.strictEqual(_.isTypedArray(symbol), false);
10316     });
10317
10318     QUnit.test('should work with typed arrays from another realm', function(assert) {
10319       assert.expect(1);
10320
10321       if (realm.object) {
10322         var invoke = lodashStable.invokeMap || lodashStable.invoke,
10323             props = invoke(typedArrays, 'toLowerCase');
10324
10325         var expected = lodashStable.map(props, function(key) {
10326           return key in realm;
10327         });
10328
10329         var actual = lodashStable.map(props, function(key) {
10330           var value = realm[key];
10331           return value ? _.isTypedArray(value) : false;
10332         });
10333
10334         assert.deepEqual(actual, expected);
10335       }
10336       else {
10337         skipTest(assert);
10338       }
10339     });
10340   }(1, 2, 3));
10341
10342   /*--------------------------------------------------------------------------*/
10343
10344   QUnit.module('lodash.isUndefined');
10345
10346   (function() {
10347     var args = arguments;
10348
10349     QUnit.test('should return `true` for `undefined` values', function(assert) {
10350       assert.expect(2);
10351
10352       assert.strictEqual(_.isUndefined(), true);
10353       assert.strictEqual(_.isUndefined(undefined), true);
10354     });
10355
10356     QUnit.test('should return `false` for non `undefined` values', function(assert) {
10357       assert.expect(13);
10358
10359       var expected = lodashStable.map(falsey, function(value) {
10360         return value === undefined;
10361       });
10362
10363       var actual = lodashStable.map(falsey, function(value, index) {
10364         return index ? _.isUndefined(value) : _.isUndefined();
10365       });
10366
10367       assert.deepEqual(actual, expected);
10368
10369       assert.strictEqual(_.isUndefined(args), false);
10370       assert.strictEqual(_.isUndefined([1, 2, 3]), false);
10371       assert.strictEqual(_.isUndefined(true), false);
10372       assert.strictEqual(_.isUndefined(new Date), false);
10373       assert.strictEqual(_.isUndefined(new Error), false);
10374       assert.strictEqual(_.isUndefined(_), false);
10375       assert.strictEqual(_.isUndefined(slice), false);
10376       assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
10377       assert.strictEqual(_.isUndefined(1), false);
10378       assert.strictEqual(_.isUndefined(/x/), false);
10379       assert.strictEqual(_.isUndefined('a'), false);
10380
10381       if (Symbol) {
10382         assert.strictEqual(_.isUndefined(symbol), false);
10383       }
10384       else {
10385         skipTest(assert);
10386       }
10387     });
10388
10389     QUnit.test('should work with `undefined` from another realm', function(assert) {
10390       assert.expect(1);
10391
10392       if (realm.object) {
10393         assert.strictEqual(_.isUndefined(realm.undefined), true);
10394       }
10395       else {
10396         skipTest(assert);
10397       }
10398     });
10399   }(1, 2, 3));
10400
10401   /*--------------------------------------------------------------------------*/
10402
10403   QUnit.module('isType checks');
10404
10405   (function() {
10406     QUnit.test('should return `false` for subclassed values', function(assert) {
10407       assert.expect(8);
10408
10409       var funcs = [
10410         'isArray', 'isBoolean', 'isDate', 'isError',
10411         'isFunction', 'isNumber', 'isRegExp', 'isString'
10412       ];
10413
10414       lodashStable.each(funcs, function(methodName) {
10415         function Foo() {}
10416         Foo.prototype = root[methodName.slice(2)].prototype;
10417
10418         var object = new Foo;
10419         if (objToString.call(object) == objectTag) {
10420           assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
10421         } else {
10422           skipTest(assert);
10423         }
10424       });
10425     });
10426
10427     QUnit.test('should not error on host objects (test in IE)', function(assert) {
10428       assert.expect(20);
10429
10430       var funcs = [
10431         'isArguments', 'isArray', 'isArrayLike', 'isBoolean', 'isDate',
10432         'isElement', 'isError', 'isFinite', 'isFunction', 'isInteger', 'isNaN',
10433         'isNil', 'isNull', 'isNumber', 'isObject', 'isObjectLike', 'isRegExp',
10434         'isSafeInteger', 'isString', 'isUndefined'
10435       ];
10436
10437       lodashStable.each(funcs, function(methodName) {
10438         if (xml) {
10439           var pass = true;
10440
10441           try {
10442             _[methodName](xml);
10443           } catch (e) {
10444             pass = false;
10445           }
10446           assert.ok(pass, '`_.' + methodName + '` should not error');
10447         }
10448         else {
10449           skipTest(assert);
10450         }
10451       });
10452     });
10453   }());
10454
10455   /*--------------------------------------------------------------------------*/
10456
10457   QUnit.module('lodash.iteratee');
10458
10459   (function() {
10460     QUnit.test('should provide arguments to `func`', function(assert) {
10461       assert.expect(1);
10462
10463       var fn = function() { return slice.call(arguments); },
10464           iteratee = _.iteratee(fn),
10465           actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
10466
10467       assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
10468     });
10469
10470     QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
10471       assert.expect(1);
10472
10473       var object = {},
10474           values = [, null, undefined],
10475           expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
10476
10477       var actual = lodashStable.map(values, function(value, index) {
10478         var identity = index ? _.iteratee(value) : _.iteratee();
10479         return [!isNpm && identity, identity(object)];
10480       });
10481
10482       assert.deepEqual(actual, expected);
10483     });
10484
10485     QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
10486       assert.expect(2);
10487
10488       var matches = _.iteratee({ 'a': 1, 'b': 2 });
10489       assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
10490       assert.strictEqual(matches({ 'b': 2 }), false);
10491     });
10492
10493     QUnit.test('should not change behavior if `source` is modified', function(assert) {
10494       assert.expect(9);
10495
10496       var sources = [
10497         { 'a': { 'b': 2, 'c': 3 } },
10498         { 'a': 1, 'b': 2 },
10499         { 'a': 1 }
10500       ];
10501
10502       lodashStable.each(sources, function(source, index) {
10503         var object = lodashStable.cloneDeep(source),
10504             matches = _.iteratee(source);
10505
10506         assert.strictEqual(matches(object), true);
10507
10508         if (index) {
10509           source.a = 2;
10510           source.b = 1;
10511           source.c = 3;
10512         } else {
10513           source.a.b = 1;
10514           source.a.c = 2;
10515           source.a.d = 3;
10516         }
10517         assert.strictEqual(matches(object), true);
10518         assert.strictEqual(matches(source), false);
10519       });
10520     });
10521
10522     QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is a number or string and a value is provided', function(assert) {
10523       assert.expect(3);
10524
10525       var array = ['a', undefined],
10526           matches = _.iteratee([0, 'a']);
10527
10528       assert.strictEqual(matches(array), true);
10529
10530       matches = _.iteratee(['0', 'a']);
10531       assert.strictEqual(matches(array), true);
10532
10533       matches = _.iteratee([1, undefined]);
10534       assert.strictEqual(matches(array), true);
10535     });
10536
10537     QUnit.test('should support deep paths for "_.matchesProperty" shorthands', function(assert) {
10538       assert.expect(1);
10539
10540       var object = { 'a': { 'b': { 'c': { 'd': 1, 'e': 2 } } } },
10541           matches = _.iteratee(['a.b.c', { 'e': 2 }]);
10542
10543       assert.strictEqual(matches(object), true);
10544     });
10545
10546     QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
10547       assert.expect(2);
10548
10549       var array = ['a'],
10550           prop = _.iteratee(0);
10551
10552       assert.strictEqual(prop(array), 'a');
10553
10554       prop = _.iteratee('0');
10555       assert.strictEqual(prop(array), 'a');
10556     });
10557
10558     QUnit.test('should support deep paths for "_.property" shorthands', function(assert) {
10559       assert.expect(1);
10560
10561       var object = { 'a': { 'b': { 'c': 3 } } },
10562           prop = _.iteratee('a.b.c');
10563
10564       assert.strictEqual(prop(object), 3);
10565     });
10566
10567     QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
10568       assert.expect(2);
10569
10570       var fn = function() {
10571         var result = [this.a];
10572         push.apply(result, arguments);
10573         return result;
10574       };
10575
10576       var expected = [1, 2, 3],
10577           object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
10578
10579       assert.deepEqual(object.iteratee(3), expected);
10580
10581       object.iteratee = _.iteratee(_.partialRight(fn, 3));
10582       assert.deepEqual(object.iteratee(2), expected);
10583     });
10584
10585     QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
10586       assert.expect(1);
10587
10588       var iteratee = _.iteratee;
10589       delete _.iteratee;
10590
10591       assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
10592
10593       _.iteratee = iteratee;
10594     });
10595
10596     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
10597       assert.expect(1);
10598
10599       var fn = function() { return this instanceof Number; },
10600           array = [fn, fn, fn],
10601           iteratees = lodashStable.map(array, _.iteratee),
10602           expected = lodashStable.map(array, alwaysFalse);
10603
10604       var actual = lodashStable.map(iteratees, function(iteratee) {
10605         return iteratee();
10606       });
10607
10608       assert.deepEqual(actual, expected);
10609     });
10610   }());
10611
10612   /*--------------------------------------------------------------------------*/
10613
10614   QUnit.module('custom `_.iteratee` methods');
10615
10616   (function() {
10617     var array = ['one', 'two', 'three'],
10618         getPropA = _.partial(_.property, 'a'),
10619         getPropB = _.partial(_.property, 'b'),
10620         getLength = _.partial(_.property, 'length'),
10621         iteratee = _.iteratee;
10622
10623     var getSum = function() {
10624       return function(result, object) {
10625         return result + object.a;
10626       };
10627     };
10628
10629     var objects = [
10630       { 'a': 0, 'b': 0 },
10631       { 'a': 1, 'b': 0 },
10632       { 'a': 1, 'b': 1 }
10633     ];
10634
10635     QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
10636       assert.expect(1);
10637
10638       if (!isModularize) {
10639         _.iteratee = getLength;
10640         assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
10641         _.iteratee = iteratee;
10642       }
10643       else {
10644         skipTest(assert);
10645       }
10646     });
10647
10648     QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
10649       assert.expect(1);
10650
10651       if (!isModularize) {
10652         _.iteratee = getPropA;
10653         assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
10654         _.iteratee = iteratee;
10655       }
10656       else {
10657         skipTest(assert);
10658       }
10659     });
10660
10661     QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
10662       assert.expect(1);
10663
10664       if (!isModularize) {
10665         _.iteratee = getPropB;
10666         assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
10667         _.iteratee = iteratee;
10668       }
10669       else {
10670         skipTest(assert);
10671       }
10672     });
10673
10674     QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
10675       assert.expect(1);
10676
10677       if (!isModularize) {
10678         _.iteratee = getPropB;
10679         assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
10680         _.iteratee = iteratee;
10681       }
10682       else {
10683         skipTest(assert);
10684       }
10685     });
10686
10687     QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
10688       assert.expect(1);
10689
10690       if (!isModularize) {
10691         _.iteratee = getPropA;
10692         assert.strictEqual(_.every(objects.slice(1)), true);
10693         _.iteratee = iteratee;
10694       }
10695       else {
10696         skipTest(assert);
10697       }
10698     });
10699
10700     QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
10701       assert.expect(1);
10702
10703       if (!isModularize) {
10704         var objects = [{ 'a': 0 }, { 'a': 1 }];
10705
10706         _.iteratee = getPropA;
10707         assert.deepEqual(_.filter(objects), [objects[1]]);
10708         _.iteratee = iteratee;
10709       }
10710       else {
10711         skipTest(assert);
10712       }
10713     });
10714
10715     QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
10716       assert.expect(1);
10717
10718       if (!isModularize) {
10719         _.iteratee = getPropA;
10720         assert.strictEqual(_.find(objects), objects[1]);
10721         _.iteratee = iteratee;
10722       }
10723       else {
10724         skipTest(assert);
10725       }
10726     });
10727
10728     QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
10729       assert.expect(1);
10730
10731       if (!isModularize) {
10732         _.iteratee = getPropA;
10733         assert.strictEqual(_.findIndex(objects), 1);
10734         _.iteratee = iteratee;
10735       }
10736       else {
10737         skipTest(assert);
10738       }
10739     });
10740
10741     QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
10742       assert.expect(1);
10743
10744       if (!isModularize) {
10745         _.iteratee = getPropA;
10746         assert.strictEqual(_.findLast(objects), objects[2]);
10747         _.iteratee = iteratee;
10748       }
10749       else {
10750         skipTest(assert);
10751       }
10752     });
10753
10754     QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
10755       assert.expect(1);
10756
10757       if (!isModularize) {
10758         _.iteratee = getPropA;
10759         assert.strictEqual(_.findLastIndex(objects), 2);
10760         _.iteratee = iteratee;
10761       }
10762       else {
10763         skipTest(assert);
10764       }
10765     });
10766
10767     QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
10768       assert.expect(1);
10769
10770       if (!isModularize) {
10771         _.iteratee = getPropB;
10772         assert.strictEqual(_.findKey(objects), '2');
10773         _.iteratee = iteratee;
10774       }
10775       else {
10776         skipTest(assert);
10777       }
10778     });
10779
10780     QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
10781       assert.expect(1);
10782
10783       if (!isModularize) {
10784         _.iteratee = getPropB;
10785         assert.strictEqual(_.findLastKey(objects), '2');
10786         _.iteratee = iteratee;
10787       }
10788       else {
10789         skipTest(assert);
10790       }
10791     });
10792
10793     QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
10794       assert.expect(1);
10795
10796       if (!isModularize) {
10797         _.iteratee = getLength;
10798         assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
10799         _.iteratee = iteratee;
10800       }
10801       else {
10802         skipTest(assert);
10803       }
10804     });
10805
10806     QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
10807       assert.expect(1);
10808
10809       if (!isModularize) {
10810         _.iteratee = getPropA;
10811         assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
10812         _.iteratee = iteratee;
10813       }
10814       else {
10815         skipTest(assert);
10816       }
10817     });
10818
10819     QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
10820       assert.expect(1);
10821
10822       if (!isModularize) {
10823         _.iteratee = getLength;
10824         assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
10825         _.iteratee = iteratee;
10826       }
10827       else {
10828         skipTest(assert);
10829       }
10830     });
10831
10832     QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
10833       assert.expect(1);
10834
10835       if (!isModularize) {
10836         _.iteratee = getPropA;
10837         assert.deepEqual(_.map(objects), [0, 1, 1]);
10838         _.iteratee = iteratee;
10839       }
10840       else {
10841         skipTest(assert);
10842       }
10843     });
10844
10845     QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
10846       assert.expect(1);
10847
10848       if (!isModularize) {
10849         _.iteratee = getPropB;
10850         assert.deepEqual(_.mapKeys({ 'a': { 'b': 1 } }), { '1':  { 'b': 1 } });
10851         _.iteratee = iteratee;
10852       }
10853       else {
10854         skipTest(assert);
10855       }
10856     });
10857
10858     QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
10859       assert.expect(1);
10860
10861       if (!isModularize) {
10862         _.iteratee = getPropB;
10863         assert.deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 });
10864         _.iteratee = iteratee;
10865       }
10866       else {
10867         skipTest(assert);
10868       }
10869     });
10870
10871     QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
10872       assert.expect(1);
10873
10874       if (!isModularize) {
10875         _.iteratee = getPropB;
10876         assert.deepEqual(_.maxBy(objects), objects[2]);
10877         _.iteratee = iteratee;
10878       }
10879       else {
10880         skipTest(assert);
10881       }
10882     });
10883
10884     QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
10885       assert.expect(1);
10886
10887       if (!isModularize) {
10888         _.iteratee = getPropB;
10889         assert.deepEqual(_.minBy(objects), objects[0]);
10890         _.iteratee = iteratee;
10891       }
10892       else {
10893         skipTest(assert);
10894       }
10895     });
10896
10897     QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
10898       assert.expect(1);
10899
10900       if (!isModularize) {
10901         var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
10902
10903         _.iteratee = getPropA;
10904         assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
10905         _.iteratee = iteratee;
10906       }
10907       else {
10908         skipTest(assert);
10909       }
10910     });
10911
10912     QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
10913       assert.expect(1);
10914
10915       if (!isModularize) {
10916         _.iteratee = getPropA;
10917         assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
10918         _.iteratee = iteratee;
10919       }
10920       else {
10921         skipTest(assert);
10922       }
10923     });
10924
10925     QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
10926       assert.expect(1);
10927
10928       if (!isModularize) {
10929         _.iteratee = getSum;
10930         assert.strictEqual(_.reduce(objects, undefined, 0), 2);
10931         _.iteratee = iteratee;
10932       }
10933       else {
10934         skipTest(assert);
10935       }
10936     });
10937
10938     QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
10939       assert.expect(1);
10940
10941       if (!isModularize) {
10942         _.iteratee = getSum;
10943         assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
10944         _.iteratee = iteratee;
10945       }
10946       else {
10947         skipTest(assert);
10948       }
10949     });
10950
10951     QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
10952       assert.expect(1);
10953
10954       if (!isModularize) {
10955         var objects = [{ 'a': 0 }, { 'a': 1 }];
10956
10957         _.iteratee = getPropA;
10958         assert.deepEqual(_.reject(objects), [objects[0]]);
10959         _.iteratee = iteratee;
10960       }
10961       else {
10962         skipTest(assert);
10963       }
10964     });
10965
10966     QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
10967       assert.expect(1);
10968
10969       if (!isModularize) {
10970         var objects = [{ 'a': 0 }, { 'a': 1 }];
10971
10972         _.iteratee = getPropA;
10973         _.remove(objects);
10974         assert.deepEqual(objects, [{ 'a': 0 }]);
10975         _.iteratee = iteratee;
10976       }
10977       else {
10978         skipTest(assert);
10979       }
10980     });
10981
10982     QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
10983       assert.expect(1);
10984
10985       if (!isModularize) {
10986         _.iteratee = getPropB;
10987         assert.strictEqual(_.some(objects), true);
10988         _.iteratee = iteratee;
10989       }
10990       else {
10991         skipTest(assert);
10992       }
10993     });
10994
10995     QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
10996       assert.expect(1);
10997
10998       if (!isModularize) {
10999         _.iteratee = getPropA;
11000         assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
11001         _.iteratee = iteratee;
11002       }
11003       else {
11004         skipTest(assert);
11005       }
11006     });
11007
11008     QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
11009       assert.expect(1);
11010
11011       if (!isModularize) {
11012         var objects = [{ 'a': 30 }, { 'a': 50 }];
11013
11014         _.iteratee = getPropA;
11015         assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
11016         _.iteratee = iteratee;
11017       }
11018       else {
11019         skipTest(assert);
11020       }
11021     });
11022
11023     QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
11024       assert.expect(1);
11025
11026       if (!isModularize) {
11027         var objects = [{ 'a': 30 }, { 'a': 50 }];
11028
11029         _.iteratee = getPropA;
11030         assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
11031         _.iteratee = iteratee;
11032       }
11033       else {
11034         skipTest(assert);
11035       }
11036     });
11037
11038     QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
11039       assert.expect(1);
11040
11041       if (!isModularize) {
11042         _.iteratee = getPropB;
11043         assert.strictEqual(_.sumBy(objects), 1);
11044         _.iteratee = iteratee;
11045       }
11046       else {
11047         skipTest(assert);
11048       }
11049     });
11050
11051     QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
11052       assert.expect(1);
11053
11054       if (!isModularize) {
11055         _.iteratee = getPropB;
11056         assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
11057         _.iteratee = iteratee;
11058       }
11059       else {
11060         skipTest(assert);
11061       }
11062     });
11063
11064     QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
11065       assert.expect(1);
11066
11067       if (!isModularize) {
11068         _.iteratee = getPropB;
11069         assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
11070         _.iteratee = iteratee;
11071       }
11072       else {
11073         skipTest(assert);
11074       }
11075     });
11076
11077     QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
11078       assert.expect(1);
11079
11080       if (!isModularize) {
11081         _.iteratee = function() {
11082           return function(result, object) {
11083             result.sum += object.a;
11084           };
11085         };
11086
11087         assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
11088         _.iteratee = iteratee;
11089       }
11090       else {
11091         skipTest(assert);
11092       }
11093     });
11094
11095     QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
11096       assert.expect(1);
11097
11098       if (!isModularize) {
11099         _.iteratee = getPropB;
11100         assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
11101         _.iteratee = iteratee;
11102       }
11103       else {
11104         skipTest(assert);
11105       }
11106     });
11107
11108     QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
11109       assert.expect(1);
11110
11111       if (!isModularize) {
11112         _.iteratee = getPropB;
11113         assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
11114         _.iteratee = iteratee;
11115       }
11116       else {
11117         skipTest(assert);
11118       }
11119     });
11120
11121     QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
11122       assert.expect(1);
11123
11124       if (!isModularize) {
11125         _.iteratee = getPropA;
11126         assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
11127         _.iteratee = iteratee;
11128       }
11129       else {
11130         skipTest(assert);
11131       }
11132     });
11133   }());
11134
11135   /*--------------------------------------------------------------------------*/
11136
11137   QUnit.module('lodash.join');
11138
11139   (function() {
11140     var array = ['a', 'b', 'c'];
11141
11142     QUnit.test('should return join all array elements into a string', function(assert) {
11143       assert.expect(1);
11144
11145       assert.strictEqual(_.join(array, '~'), 'a~b~c');
11146     });
11147
11148     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
11149       assert.expect(2);
11150
11151       if (!isNpm) {
11152         var wrapped = _(array);
11153         assert.strictEqual(wrapped.join('~'), 'a~b~c');
11154         assert.strictEqual(wrapped.value(), array);
11155       }
11156       else {
11157         skipTest(assert, 2);
11158       }
11159     });
11160
11161     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
11162       assert.expect(1);
11163
11164       if (!isNpm) {
11165         assert.ok(_(array).chain().join('~') instanceof _);
11166       }
11167       else {
11168         skipTest(assert);
11169       }
11170     });
11171   }());
11172
11173   /*--------------------------------------------------------------------------*/
11174
11175   QUnit.module('lodash.keyBy');
11176
11177   (function() {
11178     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
11179       assert.expect(1);
11180
11181       var array = [4, 6, 6],
11182           values = [, null, undefined],
11183           expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
11184
11185       var actual = lodashStable.map(values, function(value, index) {
11186         return index ? _.keyBy(array, value) : _.keyBy(array);
11187       });
11188
11189       assert.deepEqual(actual, expected);
11190     });
11191
11192     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
11193       assert.expect(1);
11194
11195       var actual = _.keyBy(['one', 'two', 'three'], 'length');
11196       assert.deepEqual(actual, { '3': 'two', '5': 'three' });
11197     });
11198
11199     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
11200       assert.expect(2);
11201
11202       var actual = _.keyBy([4.2, 6.1, 6.4], function(num) {
11203         return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
11204       });
11205
11206       assert.deepEqual(actual.constructor, 4.2);
11207       assert.deepEqual(actual.hasOwnProperty, 6.4);
11208     });
11209
11210     QUnit.test('should work with a number for `iteratee`', function(assert) {
11211       assert.expect(2);
11212
11213       var array = [
11214         [1, 'a'],
11215         [2, 'a'],
11216         [2, 'b']
11217       ];
11218
11219       assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
11220       assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
11221     });
11222
11223     QUnit.test('should work with an object for `collection`', function(assert) {
11224       assert.expect(1);
11225
11226       var actual = _.keyBy({ 'a': 4.2, 'b': 6.1, 'c': 6.4 }, function(num) {
11227         return Math.floor(num);
11228       });
11229
11230       assert.deepEqual(actual, { '4': 4.2, '6': 6.4 });
11231     });
11232
11233     QUnit.test('should work in a lazy sequence', function(assert) {
11234       assert.expect(1);
11235
11236       if (!isNpm) {
11237         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
11238           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
11239           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
11240         );
11241
11242         var actual = _(array).keyBy().map(square).filter(isEven).take().value();
11243
11244         assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
11245       }
11246       else {
11247         skipTest(assert);
11248       }
11249     });
11250   }());
11251
11252   /*--------------------------------------------------------------------------*/
11253
11254   QUnit.module('keys methods');
11255
11256   lodashStable.each(['keys', 'keysIn'], function(methodName) {
11257     var args = (function() { return arguments; }(1, 2, 3)),
11258         strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
11259         func = _[methodName],
11260         isKeys = methodName == 'keys';
11261
11262     QUnit.test('`_.' + methodName + '` should return the keys of an object', function(assert) {
11263       assert.expect(1);
11264
11265       assert.deepEqual(func({ 'a': 1, 'b': 1 }).sort(), ['a', 'b']);
11266     });
11267
11268     QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
11269       assert.expect(2);
11270
11271       assert.deepEqual(func('abc').sort(), ['0', '1', '2']);
11272
11273       // IE 9 doesn't box numbers in for-in loops.
11274       numberProto.a = 1;
11275       assert.deepEqual(func(0), isKeys ? [] : ['a']);
11276       delete numberProto.a;
11277     });
11278
11279     QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
11280       assert.expect(1);
11281
11282       var array = [1];
11283       array[2] = 3;
11284
11285       assert.deepEqual(func(array).sort(), ['0', '1', '2']);
11286     });
11287
11288     QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
11289       assert.expect(2);
11290
11291       objectProto.a = 1;
11292       lodashStable.each([null, undefined], function(value) {
11293         assert.deepEqual(func(value), []);
11294       });
11295       delete objectProto.a;
11296     });
11297
11298     QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
11299       assert.expect(1);
11300
11301       var array = [1];
11302       array.a = 1;
11303
11304       assert.deepEqual(func(array).sort(), ['0', 'a']);
11305     });
11306
11307     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of arrays', function(assert) {
11308       assert.expect(1);
11309
11310       var expected = isKeys ? ['0'] : ['0', 'a'];
11311
11312       arrayProto.a = 1;
11313       assert.deepEqual(func([1]).sort(), expected);
11314       delete arrayProto.a;
11315     });
11316
11317     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
11318       assert.expect(1);
11319
11320       var values = [args, strictArgs],
11321           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2'])),
11322           actual = lodashStable.map(values, func);
11323
11324       assert.deepEqual(actual, expected);
11325     });
11326
11327     QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
11328       assert.expect(1);
11329
11330       var values = [args, strictArgs],
11331           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
11332
11333       var actual = lodashStable.map(values, function(value) {
11334         value.a = 1;
11335         var result = func(value).sort();
11336         delete value.a;
11337         return result;
11338       });
11339
11340       assert.deepEqual(actual, expected);
11341     });
11342
11343     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of `arguments` objects', function(assert) {
11344       assert.expect(1);
11345
11346       var values = [args, strictArgs],
11347           expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
11348
11349       var actual = lodashStable.map(values, function(value) {
11350         objectProto.a = 1;
11351         var result = func(value).sort();
11352         delete objectProto.a;
11353         return result;
11354       });
11355
11356       assert.deepEqual(actual, expected);
11357     });
11358
11359     QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
11360       assert.expect(1);
11361
11362       assert.deepEqual(func(Object('abc')).sort(), ['0', '1', '2']);
11363     });
11364
11365     QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
11366       assert.expect(1);
11367
11368       var object = Object('a');
11369       object.a = 1;
11370
11371       assert.deepEqual(func(object).sort(), ['0', 'a']);
11372     });
11373
11374     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of string objects', function(assert) {
11375       assert.expect(1);
11376
11377       var expected = isKeys ? ['0'] : ['0', 'a'];
11378
11379       stringProto.a = 1;
11380       assert.deepEqual(func(Object('a')).sort(), expected);
11381       delete stringProto.a;
11382     });
11383
11384     QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
11385       assert.expect(3);
11386
11387       function Foo() {}
11388       Foo.prototype.a = 1;
11389
11390       var expected = ['a'];
11391       assert.deepEqual(func(Foo.prototype), expected);
11392
11393       Foo.prototype = { 'constructor': Foo, 'a': 1 };
11394       assert.deepEqual(func(Foo.prototype), expected);
11395
11396       var Fake = { 'prototype': {} };
11397       Fake.prototype.constructor = Fake;
11398       assert.deepEqual(func(Fake.prototype), ['constructor']);
11399     });
11400
11401     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties', function(assert) {
11402       assert.expect(1);
11403
11404       function Foo() { this.a = 1; }
11405       Foo.prototype.b = 2;
11406
11407       var expected = isKeys ? ['a'] : ['a', 'b'];
11408       assert.deepEqual(func(new Foo).sort(), expected);
11409     });
11410   });
11411
11412   /*--------------------------------------------------------------------------*/
11413
11414   QUnit.module('lodash.last');
11415
11416   (function() {
11417     var array = [1, 2, 3, 4];
11418
11419     QUnit.test('should return the last element', function(assert) {
11420       assert.expect(1);
11421
11422       assert.strictEqual(_.last(array), 4);
11423     });
11424
11425     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
11426       assert.expect(1);
11427
11428       var array = [];
11429       array['-1'] = 1;
11430
11431       assert.strictEqual(_.last([]), undefined);
11432     });
11433
11434     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
11435       assert.expect(1);
11436
11437       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
11438           actual = lodashStable.map(array, _.last);
11439
11440       assert.deepEqual(actual, [3, 6, 9]);
11441     });
11442
11443     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
11444       assert.expect(1);
11445
11446       if (!isNpm) {
11447         assert.strictEqual(_(array).last(), 4);
11448       }
11449       else {
11450         skipTest(assert);
11451       }
11452     });
11453
11454     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
11455       assert.expect(1);
11456
11457       if (!isNpm) {
11458         assert.ok(_(array).chain().last() instanceof _);
11459       }
11460       else {
11461         skipTest(assert);
11462       }
11463     });
11464
11465     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
11466       assert.expect(1);
11467
11468       if (!isNpm) {
11469         var wrapped = _(array).chain().last();
11470         assert.strictEqual(wrapped.__wrapped__, array);
11471       }
11472       else {
11473         skipTest(assert);
11474       }
11475     });
11476
11477     QUnit.test('should work in a lazy sequence', function(assert) {
11478       assert.expect(2);
11479
11480       if (!isNpm) {
11481         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
11482             smallArray = array;
11483
11484         lodashStable.times(2, function(index) {
11485           var array = index ? largeArray : smallArray,
11486               wrapped = _(array).filter(isEven);
11487
11488           assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
11489         });
11490       }
11491       else {
11492         skipTest(assert, 2);
11493       }
11494     });
11495   }());
11496
11497 /*--------------------------------------------------------------------------*/
11498
11499   QUnit.module('lodash.lowerCase');
11500
11501   (function() {
11502     QUnit.test('should lowercase as space-separated words', function(assert) {
11503       assert.expect(3);
11504
11505       assert.strictEqual(_.lowerCase('--Foo-Bar'), 'foo bar');
11506       assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
11507       assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
11508     });
11509   }());
11510
11511 /*--------------------------------------------------------------------------*/
11512
11513   QUnit.module('lodash.lowerFirst');
11514
11515   (function() {
11516     QUnit.test('should lowercase only the first character', function(assert) {
11517       assert.expect(3);
11518
11519       assert.strictEqual(_.lowerFirst('fred'), 'fred');
11520       assert.strictEqual(_.lowerFirst('Fred'), 'fred');
11521       assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
11522     });
11523   }());
11524
11525   /*--------------------------------------------------------------------------*/
11526
11527   QUnit.module('lodash.lt');
11528
11529   (function() {
11530     QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
11531       assert.expect(2);
11532
11533       assert.strictEqual(_.lt(1, 3), true);
11534       assert.strictEqual(_.lt('abc', 'def'), true);
11535     });
11536
11537     QUnit.test('should return `false` if `value` >= `other`', function(assert) {
11538       assert.expect(4);
11539
11540       assert.strictEqual(_.lt(3, 1), false);
11541       assert.strictEqual(_.lt(3, 3), false);
11542       assert.strictEqual(_.lt('def', 'abc'), false);
11543       assert.strictEqual(_.lt('def', 'def'), false);
11544     });
11545   }());
11546
11547   /*--------------------------------------------------------------------------*/
11548
11549   QUnit.module('lodash.lte');
11550
11551   (function() {
11552     QUnit.test('should return `true` if `value` is less than or equal to `other`', function(assert) {
11553       assert.expect(4);
11554
11555       assert.strictEqual(_.lte(1, 3), true);
11556       assert.strictEqual(_.lte(3, 3), true);
11557       assert.strictEqual(_.lte('abc', 'def'), true);
11558       assert.strictEqual(_.lte('def', 'def'), true);
11559     });
11560
11561     QUnit.test('should return `false` if `value` > `other`', function(assert) {
11562       assert.expect(2);
11563
11564       assert.strictEqual(_.lt(3, 1), false);
11565       assert.strictEqual(_.lt('def', 'abc'), false);
11566     });
11567   }());
11568
11569   /*--------------------------------------------------------------------------*/
11570
11571   QUnit.module('lodash.lastIndexOf');
11572
11573   (function() {
11574     var array = [1, 2, 3, 1, 2, 3];
11575
11576     QUnit.test('should return the index of the last matched value', function(assert) {
11577       assert.expect(1);
11578
11579       assert.strictEqual(_.lastIndexOf(array, 3), 5);
11580     });
11581
11582     QUnit.test('should work with a positive `fromIndex`', function(assert) {
11583       assert.expect(1);
11584
11585       assert.strictEqual(_.lastIndexOf(array, 1, 2), 0);
11586     });
11587
11588     QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
11589       assert.expect(1);
11590
11591       var values = [6, 8, Math.pow(2, 32), Infinity],
11592           expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
11593
11594       var actual = lodashStable.map(values, function(fromIndex) {
11595         return [
11596           _.lastIndexOf(array, undefined, fromIndex),
11597           _.lastIndexOf(array, 1, fromIndex),
11598           _.lastIndexOf(array, '', fromIndex)
11599         ];
11600       });
11601
11602       assert.deepEqual(actual, expected);
11603     });
11604
11605     QUnit.test('should work with a negative `fromIndex`', function(assert) {
11606       assert.expect(1);
11607
11608       assert.strictEqual(_.lastIndexOf(array, 2, -3), 1);
11609     });
11610
11611     QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
11612       assert.expect(1);
11613
11614       var values = [-6, -8, -Infinity],
11615           expected = lodashStable.map(values, alwaysZero);
11616
11617       var actual = lodashStable.map(values, function(fromIndex) {
11618         return _.lastIndexOf(array, 1, fromIndex);
11619       });
11620
11621       assert.deepEqual(actual, expected);
11622     });
11623
11624     QUnit.test('should treat falsey `fromIndex` values correctly', function(assert) {
11625       assert.expect(1);
11626
11627       var expected = lodashStable.map(falsey, function(value) {
11628         return value === undefined ? 5 : -1;
11629       });
11630
11631       var actual = lodashStable.map(falsey, function(fromIndex) {
11632         return _.lastIndexOf(array, 3, fromIndex);
11633       });
11634
11635       assert.deepEqual(actual, expected);
11636     });
11637
11638     QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
11639       assert.expect(1);
11640
11641       assert.strictEqual(_.lastIndexOf(array, 2, 4.2), 4);
11642     });
11643   }());
11644
11645   /*--------------------------------------------------------------------------*/
11646
11647   QUnit.module('indexOf methods');
11648
11649   lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
11650     var func = _[methodName],
11651         isIndexOf = !/last/i.test(methodName),
11652         isSorted = /^sorted/.test(methodName);
11653
11654     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
11655       assert.expect(1);
11656
11657       var expected = lodashStable.map(falsey, lodashStable.constant(-1));
11658
11659       var actual = lodashStable.map(falsey, function(array, index) {
11660         try {
11661           return index ? func(array) : func();
11662         } catch (e) {}
11663       });
11664
11665       assert.deepEqual(actual, expected);
11666     });
11667
11668     QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
11669       assert.expect(5);
11670
11671       var array = [1, 2, 3],
11672           empty = [];
11673
11674       assert.strictEqual(func(array, 4), -1);
11675       assert.strictEqual(func(array, 4, true), -1);
11676       assert.strictEqual(func(array, undefined, true), -1);
11677
11678       assert.strictEqual(func(empty, undefined), -1);
11679       assert.strictEqual(func(empty, undefined, true), -1);
11680     });
11681
11682     QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
11683       assert.expect(2);
11684
11685       var array = [];
11686       array[-1] = 0;
11687
11688       assert.strictEqual(func(array, undefined), -1);
11689       assert.strictEqual(func(array, 0, true), -1);
11690     });
11691
11692     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
11693       assert.expect(4);
11694
11695       var array = isSorted
11696         ? [1, 2, NaN, NaN]
11697         : [1, NaN, 3, NaN, 5, NaN];
11698
11699       if (isSorted) {
11700         assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
11701         skipTest(assert, 3);
11702       }
11703       else {
11704         assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
11705         assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
11706         assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
11707         skipTest(assert);
11708       }
11709     });
11710
11711     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
11712       assert.expect(2);
11713
11714       assert.strictEqual(func([-0], 0), 0);
11715       assert.strictEqual(func([0], -0), 0);
11716     });
11717   });
11718
11719   /*--------------------------------------------------------------------------*/
11720
11721   QUnit.module('lodash.map');
11722
11723   (function() {
11724     var array = [1, 2, 3];
11725
11726     QUnit.test('should map values in `collection` to a new array', function(assert) {
11727       assert.expect(2);
11728
11729       var object = { 'a': 1, 'b': 2, 'c': 3 },
11730           expected = ['1', '2', '3'];
11731
11732       assert.deepEqual(_.map(array, String), expected);
11733       assert.deepEqual(_.map(object, String), expected);
11734     });
11735
11736     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
11737       assert.expect(1);
11738
11739       var objects = [{ 'a': 'x' }, { 'a': 'y' }];
11740       assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
11741     });
11742
11743     QUnit.test('should iterate over own properties of objects', function(assert) {
11744       assert.expect(1);
11745
11746       function Foo() { this.a = 1; }
11747       Foo.prototype.b = 2;
11748
11749       var actual = _.map(new Foo, function(value, key) { return key; });
11750       assert.deepEqual(actual, ['a']);
11751     });
11752
11753     QUnit.test('should work on an object with no `iteratee`', function(assert) {
11754       assert.expect(1);
11755
11756       var actual = _.map({ 'a': 1, 'b': 2, 'c': 3 });
11757       assert.deepEqual(actual, array);
11758     });
11759
11760     QUnit.test('should handle object arguments with non-number length properties', function(assert) {
11761       assert.expect(1);
11762
11763       var value = { 'value': 'x' },
11764           object = { 'length': { 'value': 'x' } };
11765
11766       assert.deepEqual(_.map(object, identity), [value]);
11767     });
11768
11769     QUnit.test('should treat a nodelist as an array-like object', function(assert) {
11770       assert.expect(1);
11771
11772       if (document) {
11773         var actual = _.map(document.getElementsByTagName('body'), function(element) {
11774           return element.nodeName.toLowerCase();
11775         });
11776
11777         assert.deepEqual(actual, ['body']);
11778       }
11779       else {
11780         skipTest(assert);
11781       }
11782     });
11783
11784     QUnit.test('should accept a falsey `collection` argument', function(assert) {
11785       assert.expect(1);
11786
11787       var expected = lodashStable.map(falsey, alwaysEmptyArray);
11788
11789       var actual = lodashStable.map(falsey, function(collection, index) {
11790         try {
11791           return index ? _.map(collection) : _.map();
11792         } catch (e) {}
11793       });
11794
11795       assert.deepEqual(actual, expected);
11796     });
11797
11798     QUnit.test('should treat number values for `collection` as empty', function(assert) {
11799       assert.expect(1);
11800
11801       assert.deepEqual(_.map(1), []);
11802     });
11803
11804     QUnit.test('should return a wrapped value when chaining', function(assert) {
11805       assert.expect(1);
11806
11807       if (!isNpm) {
11808         assert.ok(_(array).map(noop) instanceof _);
11809       }
11810       else {
11811         skipTest(assert);
11812       }
11813     });
11814
11815     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
11816       assert.expect(5);
11817
11818       if (!isNpm) {
11819         var args,
11820             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
11821             expected = [1, 0, _.map(array.slice(1), square)];
11822
11823         _(array).slice(1).map(function(value, index, array) {
11824           args || (args = slice.call(arguments));
11825         }).value();
11826
11827         assert.deepEqual(args, [1, 0, array.slice(1)]);
11828
11829         args = undefined;
11830         _(array).slice(1).map(square).map(function(value, index, array) {
11831           args || (args = slice.call(arguments));
11832         }).value();
11833
11834         assert.deepEqual(args, expected);
11835
11836         args = undefined;
11837         _(array).slice(1).map(square).map(function(value, index) {
11838           args || (args = slice.call(arguments));
11839         }).value();
11840
11841         assert.deepEqual(args, expected);
11842
11843         args = undefined;
11844         _(array).slice(1).map(square).map(function(value) {
11845           args || (args = slice.call(arguments));
11846         }).value();
11847
11848         assert.deepEqual(args, [1]);
11849
11850         args = undefined;
11851         _(array).slice(1).map(square).map(function() {
11852           args || (args = slice.call(arguments));
11853         }).value();
11854
11855         assert.deepEqual(args, expected);
11856       }
11857       else {
11858         skipTest(assert, 5);
11859       }
11860     });
11861   }());
11862
11863   /*--------------------------------------------------------------------------*/
11864
11865   QUnit.module('lodash.mapKeys');
11866
11867   (function() {
11868     var array = [1, 2],
11869         object = { 'a': 1, 'b': 2, 'c': 3 };
11870
11871     QUnit.test('should map keys in `object` to a new object', function(assert) {
11872       assert.expect(1);
11873
11874       var actual = _.mapKeys(object, String);
11875       assert.deepEqual(actual, { '1': 1, '2': 2, '3': 3 });
11876     });
11877
11878     QUnit.test('should treat arrays like objects', function(assert) {
11879       assert.expect(1);
11880
11881       var actual = _.mapKeys(array, String);
11882       assert.deepEqual(actual, { '1': 1, '2': 2 });
11883     });
11884
11885     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
11886       assert.expect(1);
11887
11888       var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
11889       assert.deepEqual(actual, { 'c': { 'b': 'c' } });
11890     });
11891
11892     QUnit.test('should work on an object with no `iteratee`', function(assert) {
11893       assert.expect(1);
11894
11895       var actual = _.mapKeys({ 'a': 1, 'b': 2, 'c': 3 });
11896       assert.deepEqual(actual, { '1': 1, '2': 2, '3': 3 });
11897     });
11898   }());
11899
11900   /*--------------------------------------------------------------------------*/
11901
11902   QUnit.module('lodash.mapValues');
11903
11904   (function() {
11905     var array = [1, 2],
11906         object = { 'a': 1, 'b': 2, 'c': 3 };
11907
11908     QUnit.test('should map values in `object` to a new object', function(assert) {
11909       assert.expect(1);
11910
11911       var actual = _.mapValues(object, String);
11912       assert.deepEqual(actual, { 'a': '1', 'b': '2', 'c': '3' });
11913     });
11914
11915     QUnit.test('should treat arrays like objects', function(assert) {
11916       assert.expect(1);
11917
11918       var actual = _.mapValues(array, String);
11919       assert.deepEqual(actual, { '0': '1', '1': '2' });
11920     });
11921
11922     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
11923       assert.expect(1);
11924
11925       var actual = _.mapValues({ 'a': { 'b': 1 } }, 'b');
11926       assert.deepEqual(actual, { 'a': 1 });
11927     });
11928
11929     QUnit.test('should work on an object with no `iteratee`', function(assert) {
11930       assert.expect(2);
11931
11932       var actual = _.mapValues({ 'a': 1, 'b': 2, 'c': 3 });
11933       assert.deepEqual(actual, object);
11934       assert.notStrictEqual(actual, object);
11935     });
11936   }());
11937
11938   /*--------------------------------------------------------------------------*/
11939
11940   QUnit.module('lodash.mapKeys and lodash.mapValues');
11941
11942   lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
11943     var array = [1, 2],
11944         func = _[methodName],
11945         object = { 'a': 1, 'b': 2, 'c': 3 };
11946
11947     QUnit.test('should iterate over own properties of objects', function(assert) {
11948       assert.expect(1);
11949
11950       function Foo() { this.a = 'a'; }
11951       Foo.prototype.b = 'b';
11952
11953       var actual = func(new Foo, function(value, key) { return key; });
11954       assert.deepEqual(actual, { 'a': 'a' });
11955     });
11956
11957     QUnit.test('should accept a falsey `object` argument', function(assert) {
11958       assert.expect(1);
11959
11960       var expected = lodashStable.map(falsey, alwaysEmptyObject);
11961
11962       var actual = lodashStable.map(falsey, function(object, index) {
11963         try {
11964           return index ? func(object) : func();
11965         } catch (e) {}
11966       });
11967
11968       assert.deepEqual(actual, expected);
11969     });
11970
11971     QUnit.test('should return a wrapped value when chaining', function(assert) {
11972       assert.expect(1);
11973
11974       if (!isNpm) {
11975         assert.ok(_(object)[methodName](noop) instanceof _);
11976       }
11977       else {
11978         skipTest(assert);
11979       }
11980     });
11981   });
11982
11983   /*--------------------------------------------------------------------------*/
11984
11985   QUnit.module('lodash.matches');
11986
11987   (function() {
11988     QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
11989       assert.expect(6);
11990
11991       var object = { 'a': 1, 'b': 2, 'c': 3 },
11992           matches = _.matches({ 'a': 1 });
11993
11994       assert.strictEqual(matches.length, 1);
11995       assert.strictEqual(matches(object), true);
11996
11997       matches = _.matches({ 'b': 1 });
11998       assert.strictEqual(matches(object), false);
11999
12000       matches = _.matches({ 'a': 1, 'c': 3 });
12001       assert.strictEqual(matches(object), true);
12002
12003       matches = _.matches({ 'c': 3, 'd': 4 });
12004       assert.strictEqual(matches(object), false);
12005
12006       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
12007       matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
12008
12009       assert.strictEqual(matches(object), true);
12010     });
12011
12012     QUnit.test('should match inherited `object` properties', function(assert) {
12013       assert.expect(1);
12014
12015       function Foo() { this.a = 1; }
12016       Foo.prototype.b = 2;
12017
12018       var object = { 'a': new Foo },
12019           matches = _.matches({ 'a': { 'b': 2 } });
12020
12021       assert.strictEqual(matches(object), true);
12022     });
12023
12024     QUnit.test('should not match by inherited `source` properties', function(assert) {
12025       assert.expect(1);
12026
12027       function Foo() { this.a = 1; }
12028       Foo.prototype.b = 2;
12029
12030       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
12031           source = new Foo,
12032           actual = lodashStable.map(objects, _.matches(source)),
12033           expected = lodashStable.map(objects, alwaysTrue);
12034
12035       assert.deepEqual(actual, expected);
12036     });
12037
12038     QUnit.test('should compare a variety of `source` property values', function(assert) {
12039       assert.expect(2);
12040
12041       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
12042           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
12043           matches = _.matches(object1);
12044
12045       assert.strictEqual(matches(object1), true);
12046       assert.strictEqual(matches(object2), false);
12047     });
12048
12049     QUnit.test('should match `-0` as `0`', function(assert) {
12050       assert.expect(2);
12051
12052       var object1 = { 'a': -0 },
12053           object2 = { 'a': 0 },
12054           matches = _.matches(object1);
12055
12056       assert.strictEqual(matches(object2), true);
12057
12058       matches = _.matches(object2);
12059       assert.strictEqual(matches(object1), true);
12060     });
12061
12062     QUnit.test('should compare functions by reference', function(assert) {
12063       assert.expect(3);
12064
12065       var object1 = { 'a': lodashStable.noop },
12066           object2 = { 'a': noop },
12067           object3 = { 'a': {} },
12068           matches = _.matches(object1);
12069
12070       assert.strictEqual(matches(object1), true);
12071       assert.strictEqual(matches(object2), false);
12072       assert.strictEqual(matches(object3), false);
12073     });
12074
12075     QUnit.test('should work with a function for `object`', function(assert) {
12076       assert.expect(1);
12077
12078       function Foo() {}
12079       Foo.a = { 'b': 1, 'c': 2 };
12080
12081       var matches = _.matches({ 'a': { 'b': 1 } });
12082       assert.strictEqual(matches(Foo), true);
12083     });
12084
12085     QUnit.test('should work with a function for `source`', function(assert) {
12086       assert.expect(1);
12087
12088       function Foo() {}
12089       Foo.a = 1;
12090       Foo.b = function() {};
12091       Foo.c = 3;
12092
12093       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
12094           actual = lodashStable.map(objects, _.matches(Foo));
12095
12096       assert.deepEqual(actual, [false, true]);
12097     });
12098
12099     QUnit.test('should work with a non-plain `object`', function(assert) {
12100       assert.expect(1);
12101
12102       function Foo(object) { lodashStable.assign(this, object); }
12103
12104       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
12105           matches = _.matches({ 'a': { 'b': 1 } });
12106
12107       assert.strictEqual(matches(object), true);
12108     });
12109
12110     QUnit.test('should partial match arrays', function(assert) {
12111       assert.expect(3);
12112
12113       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
12114           actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
12115
12116       assert.deepEqual(actual, [objects[1]]);
12117
12118       actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
12119       assert.deepEqual(actual, []);
12120
12121       actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
12122       assert.deepEqual(actual, []);
12123     });
12124
12125     QUnit.test('should partial match arrays of objects', function(assert) {
12126       assert.expect(1);
12127
12128       var objects = [
12129         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
12130         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
12131       ];
12132
12133       var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
12134       assert.deepEqual(actual, [objects[0]]);
12135     });
12136
12137     QUnit.test('should partial match maps', function(assert) {
12138       assert.expect(3);
12139
12140       if (Map) {
12141         var objects = [{ 'a': new Map }, { 'a': new Map }];
12142         objects[0].a.set('a', 1);
12143         objects[1].a.set('a', 1);
12144         objects[1].a.set('b', 2);
12145
12146         var map = new Map;
12147         map.set('b', 2);
12148         var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
12149
12150         assert.deepEqual(actual, [objects[1]]);
12151
12152         map['delete']('b');
12153         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
12154
12155         assert.deepEqual(actual, objects);
12156
12157         map.set('c', 3);
12158         actual = lodashStable.filter(objects, _.matches({ 'a': map }));
12159
12160         assert.deepEqual(actual, []);
12161       }
12162       else {
12163         skipTest(assert, 3);
12164       }
12165     });
12166
12167     QUnit.test('should partial match sets', function(assert) {
12168       assert.expect(3);
12169
12170       if (Set) {
12171         var objects = [{ 'a': new Set }, { 'a': new Set }];
12172         objects[0].a.add(1);
12173         objects[1].a.add(1);
12174         objects[1].a.add(2);
12175
12176         var set = new Set;
12177         set.add(2);
12178         var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
12179
12180         assert.deepEqual(actual, [objects[1]]);
12181
12182         set['delete'](2);
12183         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
12184
12185         assert.deepEqual(actual, objects);
12186
12187         set.add(3);
12188         actual = lodashStable.filter(objects, _.matches({ 'a': set }));
12189
12190         assert.deepEqual(actual, []);
12191       }
12192       else {
12193         skipTest(assert, 3);
12194       }
12195     });
12196
12197     QUnit.test('should match `undefined` values', function(assert) {
12198       assert.expect(3);
12199
12200       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
12201           actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
12202           expected = [false, false, true];
12203
12204       assert.deepEqual(actual, expected);
12205
12206       actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
12207
12208       assert.deepEqual(actual, expected);
12209
12210       objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
12211       actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
12212
12213       assert.deepEqual(actual, expected);
12214     });
12215
12216     QUnit.test('should match `undefined` values on primitives', function(assert) {
12217       assert.expect(3);
12218
12219       numberProto.a = 1;
12220       numberProto.b = undefined;
12221
12222       try {
12223         var matches = _.matches({ 'b': undefined });
12224         assert.strictEqual(matches(1), true);
12225       } catch (e) {
12226         assert.ok(false, e.message);
12227       }
12228       try {
12229         matches = _.matches({ 'a': 1, 'b': undefined });
12230         assert.strictEqual(matches(1), true);
12231       } catch (e) {
12232         assert.ok(false, e.message);
12233       }
12234       numberProto.a = { 'b': 1, 'c': undefined };
12235       try {
12236         matches = _.matches({ 'a': { 'c': undefined } });
12237         assert.strictEqual(matches(1), true);
12238       } catch (e) {
12239         assert.ok(false, e.message);
12240       }
12241       delete numberProto.a;
12242       delete numberProto.b;
12243     });
12244
12245     QUnit.test('should return `false` when `object` is nullish', function(assert) {
12246       assert.expect(1);
12247
12248       var values = [, null, undefined],
12249           expected = lodashStable.map(values, alwaysFalse),
12250           matches = _.matches({ 'a': 1 });
12251
12252       var actual = lodashStable.map(values, function(value, index) {
12253         try {
12254           return index ? matches(value) : matches();
12255         } catch (e) {}
12256       });
12257
12258       assert.deepEqual(actual, expected);
12259     });
12260
12261     QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
12262       assert.expect(1);
12263
12264       var values = [, null, undefined],
12265           expected = lodashStable.map(values, alwaysTrue),
12266           matches = _.matches({});
12267
12268       var actual = lodashStable.map(values, function(value, index) {
12269         try {
12270           return index ? matches(value) : matches();
12271         } catch (e) {}
12272       });
12273
12274       assert.deepEqual(actual, expected);
12275     });
12276
12277     QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
12278       assert.expect(1);
12279
12280       var object = { 'a': 1 },
12281           expected = lodashStable.map(empties, alwaysTrue);
12282
12283       var actual = lodashStable.map(empties, function(value) {
12284         var matches = _.matches(value);
12285         return matches(object);
12286       });
12287
12288       assert.deepEqual(actual, expected);
12289     });
12290
12291     QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
12292       assert.expect(1);
12293
12294       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
12295           actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
12296
12297       assert.deepEqual(actual, objects);
12298     });
12299
12300     QUnit.test('should not change behavior if `source` is modified', function(assert) {
12301       assert.expect(9);
12302
12303       var sources = [
12304         { 'a': { 'b': 2, 'c': 3 } },
12305         { 'a': 1, 'b': 2 },
12306         { 'a': 1 }
12307       ];
12308
12309       lodashStable.each(sources, function(source, index) {
12310         var object = lodashStable.cloneDeep(source),
12311             matches = _.matches(source);
12312
12313         assert.strictEqual(matches(object), true);
12314
12315         if (index) {
12316           source.a = 2;
12317           source.b = 1;
12318           source.c = 3;
12319         } else {
12320           source.a.b = 1;
12321           source.a.c = 2;
12322           source.a.d = 3;
12323         }
12324         assert.strictEqual(matches(object), true);
12325         assert.strictEqual(matches(source), false);
12326       });
12327     });
12328   }());
12329
12330   /*--------------------------------------------------------------------------*/
12331
12332   QUnit.module('lodash.matchesProperty');
12333
12334   (function() {
12335     QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
12336       assert.expect(6);
12337
12338       var object = { 'a': 1, 'b': 2, 'c': 3 },
12339           matches = _.matchesProperty('a', 1);
12340
12341       assert.strictEqual(matches.length, 1);
12342       assert.strictEqual(matches(object), true);
12343
12344       matches = _.matchesProperty('b', 3);
12345       assert.strictEqual(matches(object), false);
12346
12347       matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
12348       assert.strictEqual(matches({ 'a': object }), true);
12349
12350       matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
12351       assert.strictEqual(matches(object), false);
12352
12353       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
12354       matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
12355
12356       assert.strictEqual(matches(object), true);
12357     });
12358
12359     QUnit.test('should support deep paths', function(assert) {
12360       assert.expect(2);
12361
12362       var object = { 'a': { 'b': { 'c': 3 } } };
12363
12364       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
12365         var matches = _.matchesProperty(path, 3);
12366         assert.strictEqual(matches(object), true);
12367       });
12368     });
12369
12370     QUnit.test('should coerce key to a string', function(assert) {
12371       assert.expect(1);
12372
12373       function fn() {}
12374       fn.toString = lodashStable.constant('fn');
12375
12376       var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
12377           values = [null, undefined, fn, {}];
12378
12379       var expected = lodashStable.transform(values, function(result) {
12380         result.push(true, true);
12381       });
12382
12383       var actual = lodashStable.transform(objects, function(result, object, index) {
12384         var key = values[index];
12385         lodashStable.each([key, [key]], function(path) {
12386           var matches = _.matchesProperty(path, object[key]);
12387           result.push(matches(object));
12388         });
12389       });
12390
12391       assert.deepEqual(actual, expected);
12392     });
12393
12394     QUnit.test('should match a key over a path', function(assert) {
12395       assert.expect(2);
12396
12397       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
12398
12399       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
12400         var matches = _.matchesProperty(path, 3);
12401         assert.strictEqual(matches(object), true);
12402       });
12403     });
12404
12405     QUnit.test('should work with non-string `path` arguments', function(assert) {
12406       assert.expect(2);
12407
12408       var array = [1, 2, 3];
12409
12410       lodashStable.each([1, [1]], function(path) {
12411         var matches = _.matchesProperty(path, 2);
12412         assert.strictEqual(matches(array), true);
12413       });
12414     });
12415
12416     QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
12417       assert.expect(4);
12418
12419       var object = {};
12420
12421       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
12422         var matches = _.matchesProperty(path, 1);
12423         assert.strictEqual(matches(object), false);
12424       });
12425     });
12426
12427     QUnit.test('should return `false` with deep paths when `object` is nullish', function(assert) {
12428       assert.expect(2);
12429
12430       var values = [, null, undefined],
12431           expected = lodashStable.map(values, alwaysFalse);
12432
12433       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
12434         var matches = _.matchesProperty(path, 1);
12435
12436         var actual = lodashStable.map(values, function(value, index) {
12437           try {
12438             return index ? matches(value) : matches();
12439           } catch (e) {}
12440         });
12441
12442         assert.deepEqual(actual, expected);
12443       });
12444     });
12445
12446     QUnit.test('should match inherited `srcValue` properties', function(assert) {
12447       assert.expect(2);
12448
12449       function Foo() {}
12450       Foo.prototype.b = 2;
12451
12452       var object = { 'a': new Foo };
12453
12454       lodashStable.each(['a', ['a']], function(path) {
12455         var matches = _.matchesProperty(path, { 'b': 2 });
12456         assert.strictEqual(matches(object), true);
12457       });
12458     });
12459
12460     QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
12461       assert.expect(2);
12462
12463       function Foo() { this.a = 1; }
12464       Foo.prototype.b = 2;
12465
12466       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
12467           expected = lodashStable.map(objects, alwaysTrue);
12468
12469       lodashStable.each(['a', ['a']], function(path) {
12470         assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
12471       });
12472     });
12473
12474     QUnit.test('should compare a variety of values', function(assert) {
12475       assert.expect(2);
12476
12477       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
12478           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
12479           matches = _.matchesProperty('a', object1);
12480
12481       assert.strictEqual(matches({ 'a': object1 }), true);
12482       assert.strictEqual(matches({ 'a': object2 }), false);
12483     });
12484
12485     QUnit.test('should match `-0` as `0`', function(assert) {
12486       assert.expect(2);
12487
12488       var matches = _.matchesProperty('a', -0);
12489       assert.strictEqual(matches({ 'a': 0 }), true);
12490
12491       matches = _.matchesProperty('a', 0);
12492       assert.strictEqual(matches({ 'a': -0 }), true);
12493     });
12494
12495     QUnit.test('should compare functions by reference', function(assert) {
12496       assert.expect(3);
12497
12498       var object1 = { 'a': lodashStable.noop },
12499           object2 = { 'a': noop },
12500           object3 = { 'a': {} },
12501           matches = _.matchesProperty('a', object1);
12502
12503       assert.strictEqual(matches({ 'a': object1 }), true);
12504       assert.strictEqual(matches({ 'a': object2 }), false);
12505       assert.strictEqual(matches({ 'a': object3 }), false);
12506     });
12507
12508     QUnit.test('should work with a function for `srcValue`', function(assert) {
12509       assert.expect(1);
12510
12511       function Foo() {}
12512       Foo.a = 1;
12513       Foo.b = function() {};
12514       Foo.c = 3;
12515
12516       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
12517           actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
12518
12519       assert.deepEqual(actual, [false, true]);
12520     });
12521
12522     QUnit.test('should work with a non-plain `srcValue`', function(assert) {
12523       assert.expect(1);
12524
12525       function Foo(object) { lodashStable.assign(this, object); }
12526
12527       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
12528           matches = _.matchesProperty('a', { 'b': 1 });
12529
12530       assert.strictEqual(matches(object), true);
12531     });
12532
12533     QUnit.test('should partial match arrays', function(assert) {
12534       assert.expect(3);
12535
12536       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
12537           actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
12538
12539       assert.deepEqual(actual, [objects[1]]);
12540
12541       actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
12542       assert.deepEqual(actual, []);
12543
12544       actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
12545       assert.deepEqual(actual, []);
12546     });
12547
12548     QUnit.test('should partial match arrays of objects', function(assert) {
12549       assert.expect(1);
12550
12551       var objects = [
12552         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
12553         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
12554       ];
12555
12556       var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
12557       assert.deepEqual(actual, [objects[0]]);
12558     });
12559     QUnit.test('should partial match maps', function(assert) {
12560       assert.expect(3);
12561
12562       if (Map) {
12563         var objects = [{ 'a': new Map }, { 'a': new Map }];
12564         objects[0].a.set('a', 1);
12565         objects[1].a.set('a', 1);
12566         objects[1].a.set('b', 2);
12567
12568         var map = new Map;
12569         map.set('b', 2);
12570         var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
12571
12572         assert.deepEqual(actual, [objects[1]]);
12573
12574         map['delete']('b');
12575         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
12576
12577         assert.deepEqual(actual, objects);
12578
12579         map.set('c', 3);
12580         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
12581
12582         assert.deepEqual(actual, []);
12583       }
12584       else {
12585         skipTest(assert, 3);
12586       }
12587     });
12588
12589     QUnit.test('should partial match sets', function(assert) {
12590       assert.expect(3);
12591
12592       if (Set) {
12593         var objects = [{ 'a': new Set }, { 'a': new Set }];
12594         objects[0].a.add(1);
12595         objects[1].a.add(1);
12596         objects[1].a.add(2);
12597
12598         var set = new Set;
12599         set.add(2);
12600         var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
12601
12602         assert.deepEqual(actual, [objects[1]]);
12603
12604         set['delete'](2);
12605         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
12606
12607         assert.deepEqual(actual, objects);
12608
12609         set.add(3);
12610         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
12611
12612         assert.deepEqual(actual, []);
12613       }
12614       else {
12615         skipTest(assert, 3);
12616       }
12617     });
12618
12619     QUnit.test('should match `undefined` values', function(assert) {
12620       assert.expect(2);
12621
12622       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
12623           actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
12624           expected = [false, false, true];
12625
12626       assert.deepEqual(actual, expected);
12627
12628       objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
12629       actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
12630
12631       assert.deepEqual(actual, expected);
12632     });
12633
12634     QUnit.test('should match `undefined` values on primitives', function(assert) {
12635       assert.expect(2);
12636
12637       numberProto.a = 1;
12638       numberProto.b = undefined;
12639
12640       try {
12641         var matches = _.matchesProperty('b', undefined);
12642         assert.strictEqual(matches(1), true);
12643       } catch (e) {
12644         assert.ok(false, e.message);
12645       }
12646       numberProto.a = { 'b': 1, 'c': undefined };
12647       try {
12648         matches = _.matchesProperty('a', { 'c': undefined });
12649         assert.strictEqual(matches(1), true);
12650       } catch (e) {
12651         assert.ok(false, e.message);
12652       }
12653       delete numberProto.a;
12654       delete numberProto.b;
12655     });
12656
12657     QUnit.test('should return `false` when `object` is nullish', function(assert) {
12658       assert.expect(2);
12659
12660       var values = [, null, undefined],
12661           expected = lodashStable.map(values, alwaysFalse);
12662
12663       lodashStable.each(['constructor', ['constructor']], function(path) {
12664         var matches = _.matchesProperty(path, 1);
12665
12666         var actual = lodashStable.map(values, function(value, index) {
12667           try {
12668             return index ? matches(value) : matches();
12669           } catch (e) {}
12670         });
12671
12672         assert.deepEqual(actual, expected);
12673       });
12674     });
12675
12676     QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
12677       assert.expect(1);
12678
12679       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
12680           matches = _.matchesProperty('a', { 'a': [], 'b': {} });
12681
12682       var actual = lodashStable.filter(objects, function(object) {
12683         return matches({ 'a': object });
12684       });
12685
12686       assert.deepEqual(actual, objects);
12687     });
12688
12689     QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
12690       assert.expect(9);
12691
12692       lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
12693         var object = lodashStable.cloneDeep(source),
12694             matches = _.matchesProperty('a', source);
12695
12696         assert.strictEqual(matches({ 'a': object }), true);
12697
12698         if (index) {
12699           source.a = 2;
12700           source.b = 1;
12701           source.c = 3;
12702         } else {
12703           source.a.b = 1;
12704           source.a.c = 2;
12705           source.a.d = 3;
12706         }
12707         assert.strictEqual(matches({ 'a': object }), true);
12708         assert.strictEqual(matches({ 'a': source }), false);
12709       });
12710     });
12711   }());
12712
12713   /*--------------------------------------------------------------------------*/
12714
12715   QUnit.module('lodash.max');
12716
12717   (function() {
12718     QUnit.test('should return the largest value from a collection', function(assert) {
12719       assert.expect(1);
12720
12721       assert.strictEqual(_.max([1, 2, 3]), 3);
12722     });
12723
12724     QUnit.test('should return `undefined` for empty collections', function(assert) {
12725       assert.expect(1);
12726
12727       var values = falsey.concat([[]]),
12728           expected = lodashStable.map(values, alwaysUndefined);
12729
12730       var actual = lodashStable.map(values, function(value, index) {
12731         try {
12732           return index ? _.max(value) : _.max();
12733         } catch (e) {}
12734       });
12735
12736       assert.deepEqual(actual, expected);
12737     });
12738
12739     QUnit.test('should work with non-numeric collection values', function(assert) {
12740       assert.expect(1);
12741
12742       assert.strictEqual(_.max(['a', 'b']), 'b');
12743     });
12744   }());
12745
12746   /*--------------------------------------------------------------------------*/
12747
12748   QUnit.module('lodash.mean');
12749
12750   (function() {
12751     QUnit.test('should return the mean of an array of numbers', function(assert) {
12752       assert.expect(1);
12753
12754       var array = [4, 2, 8, 6];
12755       assert.strictEqual(_.mean(array), 5);
12756     });
12757   }());
12758
12759   /*--------------------------------------------------------------------------*/
12760
12761   QUnit.module('lodash.memoize');
12762
12763   (function() {
12764     QUnit.test('should memoize results based on the first argument provided', function(assert) {
12765       assert.expect(2);
12766
12767       var memoized = _.memoize(function(a, b, c) {
12768         return a + b + c;
12769       });
12770
12771       assert.strictEqual(memoized(1, 2, 3), 6);
12772       assert.strictEqual(memoized(1, 3, 5), 6);
12773     });
12774
12775     QUnit.test('should support a `resolver` argument', function(assert) {
12776       assert.expect(2);
12777
12778       var fn = function(a, b, c) { return a + b + c; },
12779           memoized = _.memoize(fn, fn);
12780
12781       assert.strictEqual(memoized(1, 2, 3), 6);
12782       assert.strictEqual(memoized(1, 3, 5), 9);
12783     });
12784
12785     QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
12786       assert.expect(2);
12787
12788       var fn = function(a, b, c) { return a + this.b + this.c; },
12789           memoized = _.memoize(fn, fn);
12790
12791       var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
12792       assert.strictEqual(object.memoized(1), 6);
12793
12794       object.b = 3;
12795       object.c = 5;
12796       assert.strictEqual(object.memoized(1), 9);
12797     });
12798
12799     QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
12800       assert.expect(1);
12801
12802       assert.raises(function() { _.memoize(noop, true); }, TypeError);
12803     });
12804
12805     QUnit.test('should not error if `resolver` is falsey', function(assert) {
12806       assert.expect(1);
12807
12808       var expected = lodashStable.map(falsey, alwaysTrue);
12809
12810       var actual = lodashStable.map(falsey, function(resolver, index) {
12811         try {
12812           return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
12813         } catch (e) {}
12814       });
12815
12816       assert.deepEqual(actual, expected);
12817     });
12818
12819     QUnit.test('should check cache for own properties', function(assert) {
12820       assert.expect(1);
12821
12822       var props = [
12823         'constructor',
12824         'hasOwnProperty',
12825         'isPrototypeOf',
12826         'propertyIsEnumerable',
12827         'toLocaleString',
12828         'toString',
12829         'valueOf'
12830       ];
12831
12832       var memoized = _.memoize(identity);
12833
12834       var actual = lodashStable.map(props, function(value) {
12835         return memoized(value);
12836       });
12837
12838       assert.deepEqual(actual, props);
12839     });
12840
12841     QUnit.test('should cache the `__proto__` key', function(assert) {
12842       assert.expect(8);
12843
12844       var array = [],
12845           key = '__proto__';
12846
12847       lodashStable.times(2, function(index) {
12848         var count = 0,
12849             resolver = index && identity;
12850
12851         var memoized = _.memoize(function() {
12852           count++;
12853           return array;
12854         }, resolver);
12855
12856         var cache = memoized.cache;
12857
12858         memoized(key);
12859         memoized(key);
12860
12861         assert.strictEqual(count, 1);
12862         assert.strictEqual(cache.get(key), array);
12863         assert.notOk(cache.__data__ instanceof Array);
12864         assert.strictEqual(cache['delete'](key), true);
12865       });
12866     });
12867
12868     QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
12869       assert.expect(4);
12870
12871       var oldCache = _.memoize.Cache;
12872
12873       function Cache() {
12874         this.__data__ = [];
12875       }
12876
12877       Cache.prototype = {
12878         'get': function(key) {
12879           var entry = _.find(this.__data__, function(entry) {
12880             return key === entry.key;
12881           });
12882           return entry && entry.value;
12883         },
12884         'has': function(key) {
12885           return _.some(this.__data__, function(entry) {
12886             return key === entry.key;
12887           });
12888         },
12889         'set': function(key, value) {
12890           this.__data__.push({ 'key': key, 'value': value });
12891           return this;
12892         }
12893       };
12894
12895       _.memoize.Cache = Cache;
12896
12897       var memoized = _.memoize(function(object) {
12898         return 'value:' + object.id;
12899       });
12900
12901       var cache = memoized.cache,
12902           key1 = { 'id': 'a' },
12903           key2 = { 'id': 'b' };
12904
12905       assert.strictEqual(memoized(key1), 'value:a');
12906       assert.strictEqual(cache.has(key1), true);
12907
12908       assert.strictEqual(memoized(key2), 'value:b');
12909       assert.strictEqual(cache.has(key2), true);
12910
12911       _.memoize.Cache = oldCache;
12912     });
12913
12914     QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
12915       assert.expect(2);
12916
12917       var oldCache = _.memoize.Cache;
12918
12919       function Cache() {
12920         this.__data__ = [];
12921       }
12922
12923       Cache.prototype = {
12924         'get': function(key) {
12925           return _.find(this.__data__, function(entry) {
12926             return key === entry.key;
12927           }).value;
12928         },
12929         'has': function(key) {
12930           return _.some(this.__data__, function(entry) {
12931             return key === entry.key;
12932           });
12933         },
12934         'set': function(key, value) {
12935           var result = new Cache;
12936           result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
12937           return result;
12938         }
12939       };
12940
12941       _.memoize.Cache = Cache;
12942
12943       var memoized = _.memoize(function(object) {
12944         return object.id;
12945       });
12946
12947       var key1 = { 'id': 'a' },
12948           key2 = { 'id': 'b' };
12949
12950       memoized(key1);
12951       memoized(key2);
12952
12953       var cache = memoized.cache;
12954       assert.strictEqual(cache.has(key1), true);
12955       assert.strictEqual(cache.has(key2), true);
12956
12957       _.memoize.Cache = oldCache;
12958     });
12959
12960     QUnit.test('should implement a `Map` interface on the cache object', function(assert) {
12961       assert.expect(164);
12962
12963       var keys = [true, false, 1, -Infinity, NaN, {}, null, 'a', symbol || {} , undefined];
12964
12965       var pairs = lodashStable.map(keys, function(key, index) {
12966         var lastIndex = keys.length - 1;
12967         return [key, keys[lastIndex - index]];
12968       });
12969
12970       lodashStable.times(2, function(index) {
12971         var memoize = (index ? (lodashBizarro || {}) : _).memoize,
12972             Cache = memoize ? memoize.Cache : undefined,
12973             cache = Cache ? new Cache(pairs) : undefined;
12974
12975         lodashStable.each(keys, function(key, index) {
12976           if (cache) {
12977             var value = pairs[index][1];
12978
12979             assert.deepEqual(cache.get(key), value);
12980             assert.strictEqual(cache.has(key), true);
12981             assert.strictEqual(cache['delete'](key), true);
12982             assert.strictEqual(cache.has(key), false);
12983             assert.strictEqual(cache.get(key), undefined);
12984             assert.strictEqual(cache['delete'](key), false);
12985             assert.strictEqual(cache.set(key, value), cache);
12986             assert.strictEqual(cache.has(key), true);
12987           }
12988           else {
12989             skipTest(assert, 8);
12990           }
12991         });
12992
12993         if (cache) {
12994           assert.strictEqual(cache.clear(), undefined);
12995           assert.ok(lodashStable.every(keys, function(key) {
12996             return !cache.has(key);
12997           }));
12998         }
12999         else {
13000           skipTest(assert, 2);
13001         }
13002       });
13003     });
13004   }());
13005
13006   /*--------------------------------------------------------------------------*/
13007
13008   QUnit.module('lodash.merge');
13009
13010   (function() {
13011     var args = arguments;
13012
13013     QUnit.test('should merge `source` into `object`', function(assert) {
13014       assert.expect(1);
13015
13016       var names = {
13017         'characters': [
13018           { 'name': 'barney' },
13019           { 'name': 'fred' }
13020         ]
13021       };
13022
13023       var ages = {
13024         'characters': [
13025           { 'age': 36 },
13026           { 'age': 40 }
13027         ]
13028       };
13029
13030       var heights = {
13031         'characters': [
13032           { 'height': '5\'4"' },
13033           { 'height': '5\'5"' }
13034         ]
13035       };
13036
13037       var expected = {
13038         'characters': [
13039           { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
13040           { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
13041         ]
13042       };
13043
13044       assert.deepEqual(_.merge(names, ages, heights), expected);
13045     });
13046
13047     QUnit.test('should merge sources containing circular references', function(assert) {
13048       assert.expect(1);
13049
13050       var object = {
13051         'foo': { 'a': 1 },
13052         'bar': { 'a': 2 }
13053       };
13054
13055       var source = {
13056         'foo': { 'b': { 'c': { 'd': {} } } },
13057         'bar': {}
13058       };
13059
13060       source.foo.b.c.d = source;
13061       source.bar.b = source.foo.b;
13062
13063       var actual = _.merge(object, source);
13064       assert.ok(actual.bar.b === actual.foo.b && actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
13065     });
13066
13067     QUnit.test('should work with four arguments', function(assert) {
13068       assert.expect(1);
13069
13070       var expected = { 'a': 4 },
13071           actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
13072
13073       assert.deepEqual(actual, expected);
13074     });
13075
13076     QUnit.test('should work with a function for `object`', function(assert) {
13077       assert.expect(2);
13078
13079       function Foo() {}
13080
13081       var source = { 'a': 1 },
13082           actual = _.merge(Foo, source);
13083
13084       assert.strictEqual(actual, Foo);
13085       assert.strictEqual(Foo.a, 1);
13086     });
13087
13088     QUnit.test('should work with a non-plain `object`', function(assert) {
13089       assert.expect(2);
13090
13091       function Foo() {}
13092
13093       var object = new Foo,
13094           source = { 'a': 1 },
13095           actual = _.merge(object, source);
13096
13097       assert.strictEqual(actual, object);
13098       assert.strictEqual(object.a, 1);
13099     });
13100
13101     QUnit.test('should pass thru primitive `object` values', function(assert) {
13102       assert.expect(1);
13103
13104       var values = [true, 1, '1'];
13105
13106       var actual = lodashStable.map(values, function(value) {
13107         return _.merge(value, { 'a': 1 });
13108       });
13109
13110       assert.deepEqual(actual, values);
13111     });
13112
13113     QUnit.test('should treat sparse array sources as dense', function(assert) {
13114       assert.expect(2);
13115
13116       var array = Array(3);
13117       array[0] = 1;
13118       array[2] = 3;
13119
13120       var actual = _.merge([], array),
13121           expected = array.slice();
13122
13123       expected[1] = undefined;
13124
13125       assert.ok('1' in actual);
13126       assert.deepEqual(actual, expected);
13127     });
13128
13129     QUnit.test('should merge `arguments` objects', function(assert) {
13130       assert.expect(7);
13131
13132       var object1 = { 'value': args },
13133           object2 = { 'value': { '3': 4 } },
13134           expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
13135           actual = _.merge(object1, object2);
13136
13137       assert.notOk('3' in args);
13138       assert.notOk(_.isArguments(actual.value));
13139       assert.deepEqual(actual.value, expected);
13140       object1.value = args;
13141
13142       actual = _.merge(object2, object1);
13143       assert.notOk(_.isArguments(actual.value));
13144       assert.deepEqual(actual.value, expected);
13145
13146       expected = { '0': 1, '1': 2, '2': 3 };
13147
13148       actual = _.merge({}, object1);
13149       assert.notOk(_.isArguments(actual.value));
13150       assert.deepEqual(actual.value, expected);
13151     });
13152
13153     QUnit.test('should merge typed arrays', function(assert) {
13154       assert.expect(4);
13155
13156       var array1 = [0],
13157           array2 = [0, 0],
13158           array3 = [0, 0, 0, 0],
13159           array4 = lodashStable.range(0, 8, 0);
13160
13161       var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
13162           buffer = ArrayBuffer && new ArrayBuffer(8);
13163
13164       // juggle for `Float64Array` shim
13165       if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
13166         arrays[1] = array4;
13167       }
13168       var expected = lodashStable.map(typedArrays, function(type, index) {
13169         var array = arrays[index].slice();
13170         array[0] = 1;
13171         return root[type] ? { 'value': array } : false;
13172       });
13173
13174       var actual = lodashStable.map(typedArrays, function(type) {
13175         var Ctor = root[type];
13176         return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
13177       });
13178
13179       assert.ok(lodashStable.isArray(actual));
13180       assert.deepEqual(actual, expected);
13181
13182       expected = lodashStable.map(typedArrays, function(type, index) {
13183         var array = arrays[index].slice();
13184         array.push(1);
13185         return root[type] ? { 'value': array } : false;
13186       });
13187
13188       actual = lodashStable.map(typedArrays, function(type, index) {
13189         var Ctor = root[type],
13190             array = lodashStable.range(arrays[index].length);
13191
13192         array.push(1);
13193         return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
13194       });
13195
13196       assert.ok(lodashStable.isArray(actual));
13197       assert.deepEqual(actual, expected);
13198     });
13199
13200     QUnit.test('should assign `null` values', function(assert) {
13201       assert.expect(1);
13202
13203       var actual = _.merge({ 'a': 1 }, { 'a': null });
13204       assert.strictEqual(actual.a, null);
13205     });
13206
13207     QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
13208       assert.expect(1);
13209
13210       function Foo() {}
13211
13212       var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
13213           expected = lodashStable.map(values, alwaysTrue);
13214
13215       var actual = lodashStable.map(values, function(value) {
13216         var object = _.merge({}, { 'value': value });
13217         return object.value === value;
13218       });
13219
13220       assert.deepEqual(actual, expected);
13221     });
13222
13223     QUnit.test('should shallow clone array/typed-array/plain-object sources', function(assert) {
13224       assert.expect(1);
13225
13226       var values = [[], new (Uint8Array || Object), {}],
13227           expected = lodashStable.map(values, alwaysTrue);
13228
13229       var actual = lodashStable.map(values, function(value) {
13230         var object = _.merge({}, { 'value': value });
13231         return object.value !== value && lodashStable.isEqual(object.value, value);
13232       });
13233
13234       assert.deepEqual(actual, expected);
13235     });
13236
13237     QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
13238       assert.expect(4);
13239
13240       function Foo(object) {
13241         lodashStable.assign(this, object);
13242       }
13243
13244       var object = { 'a': 1 },
13245           actual = _.merge(new Foo, object);
13246
13247       assert.ok(actual instanceof Foo);
13248       assert.deepEqual(actual, new Foo(object));
13249
13250       actual = _.merge([new Foo], [object]);
13251       assert.ok(actual[0] instanceof Foo);
13252       assert.deepEqual(actual, [new Foo(object)]);
13253     });
13254
13255     QUnit.test('should not assign `undefined` values', function(assert) {
13256       assert.expect(1);
13257
13258       var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
13259       assert.deepEqual(actual, { 'a': 1 });
13260     });
13261
13262     QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
13263       assert.expect(2);
13264
13265       var array = Array(3);
13266       array[0] = 1;
13267       array[2] = 3;
13268
13269       var actual = _.merge([4, 5, 6], array),
13270           expected = [1, 5, 3];
13271
13272       assert.deepEqual(actual, expected);
13273
13274       array = [1, , 3];
13275       array[1] = undefined;
13276
13277       actual = _.merge([4, 5, 6], array);
13278       assert.deepEqual(actual, expected);
13279     });
13280
13281     QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
13282       assert.expect(1);
13283
13284       if (defineProperty) {
13285         var object = {},
13286             pass = true;
13287
13288         defineProperty(object, 'a', {
13289           'enumerable': true,
13290           'configurable': true,
13291           'get': function() { pass = false; },
13292           'set': function() { pass = false; }
13293         });
13294
13295         _.merge(object, object);
13296         assert.ok(pass);
13297       }
13298       else {
13299         skipTest(assert);
13300       }
13301     });
13302
13303     QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
13304       assert.expect(2);
13305
13306       var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
13307           actual = _.merge(object, { 'a': ['x'] });
13308
13309       assert.deepEqual(actual, { 'a': ['x', 'y'] });
13310
13311       actual = _.merge({ 'a': {} }, { 'a': [] });
13312       assert.deepEqual(actual, { 'a': [] });
13313     });
13314
13315     QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
13316       assert.expect(1);
13317
13318       var object = { 'a': 'abcdef' },
13319           actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
13320
13321       assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
13322     });
13323
13324     QUnit.test('should not error on DOM elements', function(assert) {
13325       assert.expect(1);
13326
13327       var object1 = { 'el': document && document.createElement('div') },
13328           object2 = { 'el': document && document.createElement('div') },
13329           pairs = [[{}, object1], [object1, object2]],
13330           expected = lodashStable.map(pairs, alwaysTrue);
13331
13332       var actual = lodashStable.map(pairs, function(pair) {
13333         try {
13334           return _.merge(pair[0], pair[1]).el === pair[1].el;
13335         } catch (e) {}
13336       });
13337
13338       assert.deepEqual(actual, expected);
13339     });
13340   }(1, 2, 3));
13341
13342   /*--------------------------------------------------------------------------*/
13343
13344   QUnit.module('lodash.mergeWith');
13345
13346   (function() {
13347     QUnit.test('should handle merging if `customizer` returns `undefined`', function(assert) {
13348       assert.expect(2);
13349
13350       var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
13351       assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
13352
13353       actual = _.mergeWith([], [undefined], identity);
13354       assert.deepEqual(actual, [undefined]);
13355     });
13356
13357     QUnit.test('should defer to `customizer` when it returns a value other than `undefined`', function(assert) {
13358       assert.expect(1);
13359
13360       var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
13361         return lodashStable.isArray(a) ? a.concat(b) : undefined;
13362       });
13363
13364       assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
13365     });
13366   }());
13367
13368   /*--------------------------------------------------------------------------*/
13369
13370   QUnit.module('lodash.method');
13371
13372   (function() {
13373     QUnit.test('should create a function that calls a method of a given object', function(assert) {
13374       assert.expect(4);
13375
13376       var object = { 'a': alwaysOne };
13377
13378       lodashStable.each(['a', ['a']], function(path) {
13379         var method = _.method(path);
13380         assert.strictEqual(method.length, 1);
13381         assert.strictEqual(method(object), 1);
13382       });
13383     });
13384
13385     QUnit.test('should work with deep property values', function(assert) {
13386       assert.expect(2);
13387
13388       var object = { 'a': { 'b': { 'c': alwaysThree } } };
13389
13390       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
13391         var method = _.method(path);
13392         assert.strictEqual(method(object), 3);
13393       });
13394     });
13395
13396     QUnit.test('should work with non-string `path` arguments', function(assert) {
13397       assert.expect(2);
13398
13399       var array = lodashStable.times(3, _.constant);
13400
13401       lodashStable.each([1, [1]], function(path) {
13402         var method = _.method(path);
13403         assert.strictEqual(method(array), 1);
13404       });
13405     });
13406
13407     QUnit.test('should coerce key to a string', function(assert) {
13408       assert.expect(1);
13409
13410       function fn() {}
13411       fn.toString = lodashStable.constant('fn');
13412
13413       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
13414           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
13415           values = [null, undefined, fn, {}];
13416
13417       var actual = lodashStable.transform(objects, function(result, object, index) {
13418         var key = values[index];
13419         lodashStable.each([key, [key]], function(path) {
13420           var method = _.method(key);
13421           result.push(method(object));
13422         });
13423       });
13424
13425       assert.deepEqual(actual, expected);
13426     });
13427
13428     QUnit.test('should work with inherited property values', function(assert) {
13429       assert.expect(2);
13430
13431       function Foo() {}
13432       Foo.prototype.a = alwaysOne;
13433
13434       lodashStable.each(['a', ['a']], function(path) {
13435         var method = _.method(path);
13436         assert.strictEqual(method(new Foo), 1);
13437       });
13438     });
13439
13440     QUnit.test('should use a key over a path', function(assert) {
13441       assert.expect(2);
13442
13443       var object = { 'a.b.c': alwaysThree, 'a': { 'b': { 'c': alwaysFour } } };
13444
13445       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
13446         var method = _.method(path);
13447         assert.strictEqual(method(object), 3);
13448       });
13449     });
13450
13451     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
13452       assert.expect(2);
13453
13454       var values = [, null, undefined],
13455           expected = lodashStable.map(values, alwaysUndefined);
13456
13457       lodashStable.each(['constructor', ['constructor']], function(path) {
13458         var method = _.method(path);
13459
13460         var actual = lodashStable.map(values, function(value, index) {
13461           return index ? method(value) : method();
13462         });
13463
13464         assert.deepEqual(actual, expected);
13465       });
13466     });
13467
13468     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
13469       assert.expect(2);
13470
13471       var values = [, null, undefined],
13472           expected = lodashStable.map(values, alwaysUndefined);
13473
13474       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
13475         var method = _.method(path);
13476
13477         var actual = lodashStable.map(values, function(value, index) {
13478           return index ? method(value) : method();
13479         });
13480
13481         assert.deepEqual(actual, expected);
13482       });
13483     });
13484
13485     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
13486       assert.expect(4);
13487
13488       var object = {};
13489
13490       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
13491         var method = _.method(path);
13492         assert.strictEqual(method(object), undefined);
13493       });
13494     });
13495
13496     QUnit.test('should apply partial arguments to function', function(assert) {
13497       assert.expect(2);
13498
13499       var object = {
13500         'fn': function() {
13501           return slice.call(arguments);
13502         }
13503       };
13504
13505       lodashStable.each(['fn', ['fn']], function(path) {
13506         var method = _.method(path, 1, 2, 3);
13507         assert.deepEqual(method(object), [1, 2, 3]);
13508       });
13509     });
13510
13511     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
13512       assert.expect(2);
13513
13514       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
13515
13516       lodashStable.each(['a.b', ['a', 'b']], function(path) {
13517         var method = _.method(path);
13518         assert.strictEqual(method(object), 1);
13519       });
13520     });
13521   }());
13522
13523   /*--------------------------------------------------------------------------*/
13524
13525   QUnit.module('lodash.methodOf');
13526
13527   (function() {
13528     QUnit.test('should create a function that calls a method of a given key', function(assert) {
13529       assert.expect(4);
13530
13531       var object = { 'a': alwaysOne };
13532
13533       lodashStable.each(['a', ['a']], function(path) {
13534         var methodOf = _.methodOf(object);
13535         assert.strictEqual(methodOf.length, 1);
13536         assert.strictEqual(methodOf(path), 1);
13537       });
13538     });
13539
13540     QUnit.test('should work with deep property values', function(assert) {
13541       assert.expect(2);
13542
13543       var object = { 'a': { 'b': { 'c': alwaysThree } } };
13544
13545       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
13546         var methodOf = _.methodOf(object);
13547         assert.strictEqual(methodOf(path), 3);
13548       });
13549     });
13550
13551     QUnit.test('should work with non-string `path` arguments', function(assert) {
13552       assert.expect(2);
13553
13554       var array = lodashStable.times(3, _.constant);
13555
13556       lodashStable.each([1, [1]], function(path) {
13557         var methodOf = _.methodOf(array);
13558         assert.strictEqual(methodOf(path), 1);
13559       });
13560     });
13561
13562     QUnit.test('should coerce key to a string', function(assert) {
13563       assert.expect(1);
13564
13565       function fn() {}
13566       fn.toString = lodashStable.constant('fn');
13567
13568       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
13569           objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
13570           values = [null, undefined, fn, {}];
13571
13572       var actual = lodashStable.transform(objects, function(result, object, index) {
13573         var key = values[index];
13574         lodashStable.each([key, [key]], function(path) {
13575           var methodOf = _.methodOf(object);
13576           result.push(methodOf(key));
13577         });
13578       });
13579
13580       assert.deepEqual(actual, expected);
13581     });
13582
13583     QUnit.test('should work with inherited property values', function(assert) {
13584       assert.expect(2);
13585
13586       function Foo() {}
13587       Foo.prototype.a = alwaysOne;
13588
13589       lodashStable.each(['a', ['a']], function(path) {
13590         var methodOf = _.methodOf(new Foo);
13591         assert.strictEqual(methodOf(path), 1);
13592       });
13593     });
13594
13595     QUnit.test('should use a key over a path', function(assert) {
13596       assert.expect(2);
13597
13598       var object = { 'a.b.c': alwaysThree, 'a': { 'b': { 'c': alwaysFour } } };
13599
13600       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
13601         var methodOf = _.methodOf(object);
13602         assert.strictEqual(methodOf(path), 3);
13603       });
13604     });
13605
13606     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
13607       assert.expect(2);
13608
13609       var values = [, null, undefined],
13610           expected = lodashStable.map(values, alwaysUndefined);
13611
13612       lodashStable.each(['constructor', ['constructor']], function(path) {
13613         var actual = lodashStable.map(values, function(value, index) {
13614           var methodOf = index ? _.methodOf() : _.methodOf(value);
13615           return methodOf(path);
13616         });
13617
13618         assert.deepEqual(actual, expected);
13619       });
13620     });
13621
13622     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
13623       assert.expect(2);
13624
13625       var values = [, null, undefined],
13626           expected = lodashStable.map(values, alwaysUndefined);
13627
13628       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
13629         var actual = lodashStable.map(values, function(value, index) {
13630           var methodOf = index ? _.methodOf() : _.methodOf(value);
13631           return methodOf(path);
13632         });
13633
13634         assert.deepEqual(actual, expected);
13635       });
13636     });
13637
13638     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
13639       assert.expect(4);
13640
13641       var object = {},
13642           methodOf = _.methodOf(object);
13643
13644       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
13645         assert.strictEqual(methodOf(path), undefined);
13646       });
13647     });
13648
13649     QUnit.test('should apply partial arguments to function', function(assert) {
13650       assert.expect(2);
13651
13652       var object = {
13653         'fn': function() {
13654           return slice.call(arguments);
13655         }
13656       };
13657
13658       var methodOf = _.methodOf(object, 1, 2, 3);
13659
13660       lodashStable.each(['fn', ['fn']], function(path) {
13661         assert.deepEqual(methodOf(path), [1, 2, 3]);
13662       });
13663     });
13664
13665     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
13666       assert.expect(2);
13667
13668       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
13669           methodOf = _.methodOf(object);
13670
13671       lodashStable.each(['a.b', ['a', 'b']], function(path) {
13672         assert.strictEqual(methodOf(path), 1);
13673       });
13674     });
13675   }());
13676
13677   /*--------------------------------------------------------------------------*/
13678
13679   QUnit.module('lodash.min');
13680
13681   (function() {
13682     QUnit.test('should return the smallest value from a collection', function(assert) {
13683       assert.expect(1);
13684
13685       assert.strictEqual(_.min([1, 2, 3]), 1);
13686     });
13687
13688     QUnit.test('should return `undefined` for empty collections', function(assert) {
13689       assert.expect(1);
13690
13691       var values = falsey.concat([[]]),
13692           expected = lodashStable.map(values, alwaysUndefined);
13693
13694       var actual = lodashStable.map(values, function(value, index) {
13695         try {
13696           return index ? _.min(value) : _.min();
13697         } catch (e) {}
13698       });
13699
13700       assert.deepEqual(actual, expected);
13701     });
13702
13703     QUnit.test('should work with non-numeric collection values', function(assert) {
13704       assert.expect(1);
13705
13706       assert.strictEqual(_.min(['a', 'b']), 'a');
13707     });
13708   }());
13709
13710   /*--------------------------------------------------------------------------*/
13711
13712   QUnit.module('extremum methods');
13713
13714   lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
13715     var array = [1, 2, 3],
13716         func = _[methodName],
13717         isMax = /^max/.test(methodName);
13718
13719     QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
13720       assert.expect(1);
13721
13722       var curr = new Date,
13723           past = new Date(0);
13724
13725       assert.strictEqual(func([curr, past]), isMax ? curr : past);
13726     });
13727
13728     QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
13729       assert.expect(1);
13730
13731       var array = lodashStable.range(0, 5e5);
13732       assert.strictEqual(func(array), isMax ? 499999 : 0);
13733     });
13734
13735     QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
13736       assert.expect(1);
13737
13738       if (!isNpm) {
13739         var actual = _([40])[methodName]();
13740         assert.strictEqual(actual, 40);
13741       }
13742       else {
13743         skipTest(assert);
13744       }
13745     });
13746   });
13747
13748   lodashStable.each(['maxBy', 'minBy'], function(methodName) {
13749     var array = [1, 2, 3],
13750         func = _[methodName],
13751         isMax = methodName == 'maxBy';
13752
13753     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
13754       assert.expect(1);
13755
13756       var actual = func(array, function(num) {
13757         return -num;
13758       });
13759
13760       assert.strictEqual(actual, isMax ? 1 : 3);
13761     });
13762
13763     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
13764       assert.expect(2);
13765
13766       var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
13767           actual = func(objects, 'a');
13768
13769       assert.deepEqual(actual, objects[isMax ? 1 : 2]);
13770
13771       var arrays = [[2], [3], [1]];
13772       actual = func(arrays, 0);
13773
13774       assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
13775     });
13776
13777     QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
13778       assert.expect(1);
13779
13780       var value = isMax ? -Infinity : Infinity,
13781           object = { 'a': value };
13782
13783       var actual = func([object, { 'a': value }], function(object) {
13784         return object.a;
13785       });
13786
13787       assert.strictEqual(actual, object);
13788     });
13789   });
13790
13791   /*--------------------------------------------------------------------------*/
13792
13793   QUnit.module('lodash.mixin');
13794
13795   (function() {
13796     function Wrapper(value) {
13797       if (!(this instanceof Wrapper)) {
13798         return new Wrapper(value);
13799       }
13800       if (_.has(value, '__wrapped__')) {
13801         var actions = slice.call(value.__actions__),
13802             chain = value.__chain__;
13803
13804         value = value.__wrapped__;
13805       }
13806       this.__wrapped__ = value;
13807       this.__actions__ = actions || [];
13808       this.__chain__ = chain || false;
13809     }
13810
13811     Wrapper.prototype.value = function() {
13812       return getUnwrappedValue(this);
13813     };
13814
13815     var array = ['a'],
13816         source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
13817
13818     QUnit.test('should mixin `source` methods into lodash', function(assert) {
13819       assert.expect(4);
13820
13821       if (!isNpm) {
13822         _.mixin(source);
13823
13824         assert.strictEqual(_.a(array), 'a');
13825         assert.strictEqual(_(array).a().value(), 'a');
13826
13827         delete _.a;
13828         delete _.prototype.a;
13829
13830         assert.notOk('b' in _);
13831         assert.notOk('b' in _.prototype);
13832
13833         delete _.b;
13834         delete _.prototype.b;
13835       }
13836       else {
13837         skipTest(assert, 4);
13838       }
13839     });
13840
13841     QUnit.test('should mixin chaining methods by reference', function(assert) {
13842       assert.expect(2);
13843
13844       if (!isNpm) {
13845         _.mixin(source);
13846         _.a = alwaysB;
13847
13848         assert.strictEqual(_.a(array), 'b');
13849         assert.strictEqual(_(array).a().value(), 'a');
13850
13851         delete _.a;
13852         delete _.prototype.a;
13853       }
13854       else {
13855         skipTest(assert, 2);
13856       }
13857     });
13858
13859     QUnit.test('should use a default `object` of `this`', function(assert) {
13860       assert.expect(3);
13861
13862       var object = lodashStable.create(_);
13863       object.mixin(source);
13864
13865       assert.strictEqual(object.a(array), 'a');
13866
13867       assert.notOk('a' in _);
13868       assert.notOk('a' in _.prototype);
13869
13870       delete Wrapper.a;
13871       delete Wrapper.prototype.a;
13872       delete Wrapper.b;
13873       delete Wrapper.prototype.b;
13874     });
13875
13876     QUnit.test('should accept an `object` argument', function(assert) {
13877       assert.expect(1);
13878
13879       var object = {};
13880       _.mixin(object, source);
13881       assert.strictEqual(object.a(array), 'a');
13882     });
13883
13884     QUnit.test('should return `object`', function(assert) {
13885       assert.expect(2);
13886
13887       var object = {};
13888       assert.strictEqual(_.mixin(object, source), object);
13889       assert.strictEqual(_.mixin(), _);
13890     });
13891
13892     QUnit.test('should work with a function for `object`', function(assert) {
13893       assert.expect(2);
13894
13895       _.mixin(Wrapper, source);
13896
13897       var wrapped = Wrapper(array),
13898           actual = wrapped.a();
13899
13900       assert.strictEqual(actual.value(), 'a');
13901       assert.ok(actual instanceof Wrapper);
13902
13903       delete Wrapper.a;
13904       delete Wrapper.prototype.a;
13905       delete Wrapper.b;
13906       delete Wrapper.prototype.b;
13907     });
13908
13909     QUnit.test('should not assign inherited `source` methods', function(assert) {
13910       assert.expect(1);
13911
13912       function Foo() {}
13913       Foo.prototype.a = noop;
13914
13915       var object = {};
13916       assert.strictEqual(_.mixin(object, new Foo), object);
13917     });
13918
13919     QUnit.test('should accept an `options` argument', function(assert) {
13920       assert.expect(8);
13921
13922       function message(func, chain) {
13923         return (func === _ ? 'lodash' : 'provided') + ' function should ' + (chain ? '' : 'not ') + 'chain';
13924       }
13925
13926       lodashStable.each([_, Wrapper], function(func) {
13927         lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
13928           if (!isNpm) {
13929             if (func === _) {
13930               _.mixin(source, options);
13931             } else {
13932               _.mixin(func, source, options);
13933             }
13934             var wrapped = func(array),
13935                 actual = wrapped.a();
13936
13937             if (options.chain) {
13938               assert.strictEqual(actual.value(), 'a', message(func, true));
13939               assert.ok(actual instanceof func, message(func, true));
13940             } else {
13941               assert.strictEqual(actual, 'a', message(func, false));
13942               assert.notOk(actual instanceof func, message(func, false));
13943             }
13944             delete func.a;
13945             delete func.prototype.a;
13946             delete func.b;
13947             delete func.prototype.b;
13948           }
13949           else {
13950             skipTest(assert, 2);
13951           }
13952         });
13953       });
13954     });
13955
13956     QUnit.test('should not extend lodash when an `object` is provided with an empty `options` object', function(assert) {
13957       assert.expect(1);
13958
13959       _.mixin({ 'a': noop }, {});
13960       assert.notOk('a' in _);
13961       delete _.a;
13962     });
13963
13964     QUnit.test('should not error for non-object `options` values', function(assert) {
13965       assert.expect(2);
13966
13967       var pass = true;
13968
13969       try {
13970         _.mixin({}, source, 1);
13971       } catch (e) {
13972         pass = false;
13973       }
13974       assert.ok(pass);
13975
13976       pass = true;
13977
13978       try {
13979         _.mixin(source, 1);
13980       } catch (e) {
13981         pass = false;
13982       }
13983       delete _.a;
13984       delete _.prototype.a;
13985       delete _.b;
13986       delete _.prototype.b;
13987
13988       assert.ok(pass);
13989     });
13990
13991     QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
13992       assert.expect(2);
13993
13994       lodashStable.each([_, Wrapper], function(func) {
13995         if (!isNpm) {
13996           if (func === _) {
13997             var wrapped = _(source),
13998                 actual = wrapped.mixin();
13999
14000             assert.strictEqual(actual.value(), _);
14001           }
14002           else {
14003             wrapped = _(func);
14004             actual = wrapped.mixin(source);
14005             assert.notStrictEqual(actual, wrapped);
14006           }
14007           delete func.a;
14008           delete func.prototype.a;
14009           delete func.b;
14010           delete func.prototype.b;
14011         }
14012         else {
14013           skipTest(assert);
14014         }
14015       });
14016     });
14017
14018     QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
14019       assert.expect(1);
14020
14021       if (!isNpm) {
14022         _.mixin({ 'a': _.countBy, 'b': _.filter });
14023
14024         var array = lodashStable.range(LARGE_ARRAY_SIZE),
14025             actual = _(array).a().map(square).b(isEven).take().value();
14026
14027         assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
14028
14029         delete _.a;
14030         delete _.prototype.a;
14031         delete _.b;
14032         delete _.prototype.b;
14033       }
14034       else {
14035         skipTest(assert);
14036       }
14037     });
14038   }());
14039
14040   /*--------------------------------------------------------------------------*/
14041
14042   QUnit.module('lodash.orderBy');
14043
14044   (function() {
14045     var objects = [
14046       { 'a': 'x', 'b': 3 },
14047       { 'a': 'y', 'b': 4 },
14048       { 'a': 'x', 'b': 1 },
14049       { 'a': 'y', 'b': 2 }
14050     ];
14051
14052     QUnit.test('should sort by a single property by a specified order', function(assert) {
14053       assert.expect(1);
14054
14055       var actual = _.orderBy(objects, 'a', 'desc');
14056       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
14057     });
14058
14059     QUnit.test('should sort by multiple properties by specified orders', function(assert) {
14060       assert.expect(1);
14061
14062       var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
14063       assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
14064     });
14065
14066     QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
14067       assert.expect(2);
14068
14069       var expected = [objects[2], objects[0], objects[3], objects[1]],
14070           actual = _.orderBy(objects, ['a', 'b']);
14071
14072       assert.deepEqual(actual, expected);
14073
14074       expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
14075
14076       actual = lodashStable.map(falsey, function(order, index) {
14077         return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
14078       });
14079
14080       assert.deepEqual(actual, expected);
14081     });
14082
14083     QUnit.test('should work with `orders` specified as string objects', function(assert) {
14084       assert.expect(1);
14085
14086       var actual = _.orderBy(objects, ['a'], [Object('desc')]);
14087       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
14088     });
14089   }());
14090
14091   /*--------------------------------------------------------------------------*/
14092
14093   QUnit.module('lodash.overArgs');
14094
14095   (function() {
14096     function fn() {
14097       return slice.call(arguments);
14098     }
14099
14100     QUnit.test('should transform each argument', function(assert) {
14101       assert.expect(1);
14102
14103       var over = _.overArgs(fn, doubled, square);
14104       assert.deepEqual(over(5, 10), [10, 100]);
14105     });
14106
14107     QUnit.test('should flatten `transforms`', function(assert) {
14108       assert.expect(1);
14109
14110       var over = _.overArgs(fn, [doubled, square], String);
14111       assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
14112     });
14113
14114     QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
14115       assert.expect(1);
14116
14117       var over = _.overArgs(fn, doubled, square);
14118       assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
14119     });
14120
14121     QUnit.test('should not transform any arguments if no transforms are provided', function(assert) {
14122       assert.expect(1);
14123
14124       var over = _.overArgs(fn);
14125       assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
14126     });
14127
14128     QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
14129       assert.expect(1);
14130
14131       var over = _.overArgs(fn, doubled, identity);
14132       assert.deepEqual(over(5), [10]);
14133     });
14134
14135     QUnit.test('should provide the correct argument to each transform', function(assert) {
14136       assert.expect(1);
14137
14138       var argsList = [],
14139           transform = function() { argsList.push(slice.call(arguments)); },
14140           over = _.overArgs(noop, transform, transform, transform);
14141
14142       over('a', 'b');
14143       assert.deepEqual(argsList, [['a'], ['b']]);
14144     });
14145
14146     QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
14147       assert.expect(1);
14148
14149       var over = _.overArgs(function(x) {
14150         return this[x];
14151       }, function(x) {
14152         return this === x;
14153       });
14154
14155       var object = { 'over': over, 'true': 1 };
14156       assert.strictEqual(object.over(object), 1);
14157     });
14158   }());
14159
14160   /*--------------------------------------------------------------------------*/
14161
14162   QUnit.module('lodash.negate');
14163
14164   (function() {
14165     QUnit.test('should create a function that negates the result of `func`', function(assert) {
14166       assert.expect(2);
14167
14168       var negate = _.negate(isEven);
14169
14170       assert.strictEqual(negate(1), true);
14171       assert.strictEqual(negate(2), false);
14172     });
14173   }());
14174
14175   /*--------------------------------------------------------------------------*/
14176
14177   QUnit.module('lodash.noop');
14178
14179   (function() {
14180     QUnit.test('should return `undefined`', function(assert) {
14181       assert.expect(1);
14182
14183       var values = empties.concat(true, new Date, _, 1, /x/, 'a'),
14184           expected = lodashStable.map(values, alwaysUndefined);
14185
14186       var actual = lodashStable.map(values, function(value, index) {
14187         return index ? _.noop(value) : _.noop();
14188       });
14189
14190       assert.deepEqual(actual, expected);
14191     });
14192   }());
14193
14194   /*--------------------------------------------------------------------------*/
14195
14196   QUnit.module('lodash.noConflict');
14197
14198   (function() {
14199     QUnit.test('should return the `lodash` function', function(assert) {
14200       assert.expect(2);
14201
14202       if (!isModularize) {
14203         assert.strictEqual(_.noConflict(), oldDash);
14204         assert.notStrictEqual(root._, oldDash);
14205         root._ = oldDash;
14206       }
14207       else {
14208         skipTest(assert, 2);
14209       }
14210     });
14211
14212     QUnit.test('should work with a `root` of `this`', function(assert) {
14213       assert.expect(2);
14214
14215       if (!isModularize && !coverage && (!document && realm.object)) {
14216         var fs = require('fs'),
14217             vm = require('vm'),
14218             expected = {},
14219             context = vm.createContext({ '_': expected, 'console': console }),
14220             source = fs.readFileSync(filePath, 'utf8');
14221
14222         vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
14223
14224         assert.strictEqual(context._, expected);
14225         assert.ok(context.lodash);
14226       }
14227       else {
14228         skipTest(assert, 2);
14229       }
14230     });
14231   }());
14232
14233   /*--------------------------------------------------------------------------*/
14234
14235   QUnit.module('lodash.now');
14236
14237   (function() {
14238     QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
14239       assert.expect(2);
14240
14241       var done = assert.async();
14242
14243       var stamp = +new Date,
14244           actual = _.now();
14245
14246       assert.ok(actual >= stamp);
14247
14248       setTimeout(function() {
14249         assert.ok(_.now() > actual);
14250         done();
14251       }, 32);
14252     });
14253   }());
14254
14255   /*--------------------------------------------------------------------------*/
14256
14257   QUnit.module('lodash.nthArg');
14258
14259   (function() {
14260     QUnit.test('should create a function that returns its nth argument', function(assert) {
14261       assert.expect(1);
14262
14263       var expected = ['a', 'b', 'c'];
14264
14265       var actual = lodashStable.times(expected.length, function(n) {
14266         var func = _.nthArg(n);
14267         return func.apply(undefined, expected);
14268       });
14269
14270       assert.deepEqual(actual, expected);
14271     });
14272
14273     QUnit.test('should coerce `n` to an integer', function(assert) {
14274       assert.expect(2);
14275
14276       var values = falsey,
14277           expected = lodashStable.map(values, alwaysA);
14278
14279       var actual = lodashStable.map(values, function(n) {
14280         var func = n ? _.nthArg(n) : _.nthArg();
14281         return func('a', 'b', 'c');
14282       });
14283
14284       assert.deepEqual(actual, expected);
14285
14286       values = ['1', 1.6];
14287       expected = lodashStable.map(values, alwaysB);
14288
14289       actual = lodashStable.map(values, function(n) {
14290         var func = _.nthArg(n);
14291         return func('a', 'b', 'c');
14292       });
14293
14294       assert.deepEqual(actual, expected);
14295     });
14296   }());
14297
14298   /*--------------------------------------------------------------------------*/
14299
14300   QUnit.module('lodash.omit');
14301
14302   (function() {
14303     var args = arguments,
14304         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
14305
14306     QUnit.test('should flatten `props`', function(assert) {
14307       assert.expect(2);
14308
14309       assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
14310       assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
14311     });
14312
14313     QUnit.test('should work with a primitive `object` argument', function(assert) {
14314       assert.expect(1);
14315
14316       stringProto.a = 1;
14317       stringProto.b = 2;
14318
14319       assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
14320
14321       delete stringProto.a;
14322       delete stringProto.b;
14323     });
14324
14325     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
14326       assert.expect(2);
14327
14328       objectProto.a = 1;
14329       lodashStable.each([null, undefined], function(value) {
14330         assert.deepEqual(_.omit(value, 'valueOf'), {});
14331       });
14332       delete objectProto.a;
14333     });
14334
14335     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
14336       assert.expect(1);
14337
14338       assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
14339     });
14340
14341     QUnit.test('should coerce property names to strings', function(assert) {
14342       assert.expect(1);
14343
14344       assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
14345     });
14346   }('a', 'c'));
14347
14348   /*--------------------------------------------------------------------------*/
14349
14350   QUnit.module('lodash.omitBy');
14351
14352   (function() {
14353     QUnit.test('should work with a predicate argument', function(assert) {
14354       assert.expect(1);
14355
14356       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
14357
14358       var actual = _.omitBy(object, function(num) {
14359         return num != 2 && num != 4;
14360       });
14361
14362       assert.deepEqual(actual, { 'b': 2, 'd': 4 });
14363     });
14364   }());
14365
14366   /*--------------------------------------------------------------------------*/
14367
14368   QUnit.module('omit methods');
14369
14370   lodashStable.each(['omit', 'omitBy'], function(methodName) {
14371     var expected = { 'b': 2, 'd': 4 },
14372         func = _[methodName],
14373         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
14374         prop = function(object, props) { return props; };
14375
14376     if (methodName == 'omitBy') {
14377       prop = function(object, props) {
14378         props = typeof props == 'string' ? [props] : props;
14379         return function(value) {
14380           return _.some(props, function(key) { return object[key] === value; });
14381         };
14382       };
14383     }
14384     QUnit.test('`_.' + methodName + '` should create an object with omitted properties', function(assert) {
14385       assert.expect(2);
14386
14387       assert.deepEqual(func(object, prop(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
14388       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
14389     });
14390
14391     QUnit.test('`_.' + methodName + '` should iterate over inherited properties', function(assert) {
14392       assert.expect(1);
14393
14394       function Foo() {}
14395       Foo.prototype = object;
14396
14397       var foo = new Foo;
14398       assert.deepEqual(func(foo, prop(object, ['a', 'c'])), expected);
14399     });
14400
14401     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
14402       assert.expect(1);
14403
14404       var array = [1, 2, 3];
14405       assert.deepEqual(func(array, prop(array, ['0', '2'])), { '1': 2 });
14406     });
14407   });
14408
14409   /*--------------------------------------------------------------------------*/
14410
14411   QUnit.module('lodash.once');
14412
14413   (function() {
14414     QUnit.test('should invoke `func` once', function(assert) {
14415       assert.expect(2);
14416
14417       var count = 0,
14418           once = _.once(function() { return ++count; });
14419
14420       once();
14421       assert.strictEqual(once(), 1);
14422       assert.strictEqual(count, 1);
14423     });
14424
14425     QUnit.test('should ignore recursive calls', function(assert) {
14426       assert.expect(2);
14427
14428       var count = 0;
14429
14430       var once = _.once(function() {
14431         once();
14432         return ++count;
14433       });
14434
14435       assert.strictEqual(once(), 1);
14436       assert.strictEqual(count, 1);
14437     });
14438
14439     QUnit.test('should not throw more than once', function(assert) {
14440       assert.expect(2);
14441
14442       var pass = true;
14443
14444       var once = _.once(function() {
14445         throw new Error;
14446       });
14447
14448       assert.raises(once);
14449
14450       try {
14451         once();
14452       } catch (e) {
14453         pass = false;
14454       }
14455       assert.ok(pass);
14456     });
14457   }());
14458
14459   /*--------------------------------------------------------------------------*/
14460
14461   QUnit.module('lodash.over');
14462
14463   (function() {
14464     QUnit.test('should create a function that invokes `iteratees`', function(assert) {
14465       assert.expect(1);
14466
14467       var over = _.over(Math.max, Math.min);
14468       assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
14469     });
14470
14471     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
14472       assert.expect(1);
14473
14474       var over = _.over(undefined, null);
14475       assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
14476     });
14477
14478     QUnit.test('should work with a "_.property" style predicate', function(assert) {
14479       assert.expect(1);
14480
14481       var object = { 'a': 1, 'b': 2 },
14482           over = _.over('b', 'a');
14483
14484       assert.deepEqual(over(object), [2, 1]);
14485     });
14486
14487     QUnit.test('should work with a "_.matches" style predicate', function(assert) {
14488       assert.expect(1);
14489
14490       var object = { 'a': 1, 'b': 2 },
14491           over = _.over({ 'c': 3 }, { 'a': 1 });
14492
14493       assert.deepEqual(over(object), [false, true]);
14494     });
14495
14496     QUnit.test('should provide arguments to predicates', function(assert) {
14497       assert.expect(1);
14498
14499       var over = _.over(function() {
14500         return slice.call(arguments);
14501       });
14502
14503       assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
14504     });
14505
14506     QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
14507       assert.expect(1);
14508
14509       var over = _.over(function() { return this.b; }, function() { return this.a; }),
14510           object = { 'over': over, 'a': 1, 'b': 2 };
14511
14512       assert.deepEqual(object.over(), [2, 1]);
14513     });
14514   }());
14515
14516   /*--------------------------------------------------------------------------*/
14517
14518   QUnit.module('lodash.overEvery');
14519
14520   (function() {
14521     QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
14522       assert.expect(1);
14523
14524       var over = _.overEvery(alwaysTrue, alwaysOne, alwaysA);
14525       assert.strictEqual(over(), true);
14526     });
14527
14528     QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
14529       assert.expect(2);
14530
14531       var count = 0,
14532           countFalse = function() { count++; return false; },
14533           countTrue = function() { count++; return true; },
14534           over = _.overEvery(countTrue, countFalse, countTrue);
14535
14536       assert.strictEqual(over(), false);
14537       assert.strictEqual(count, 2);
14538     });
14539
14540     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
14541       assert.expect(2);
14542
14543       var over = _.overEvery(undefined, null);
14544       assert.strictEqual(over(true), true);
14545       assert.strictEqual(over(false), false);
14546     });
14547
14548     QUnit.test('should work with a "_.property" style predicate', function(assert) {
14549       assert.expect(2);
14550
14551       var object = { 'a': 1, 'b': 2 },
14552           over = _.overEvery('a', 'c');
14553
14554       assert.strictEqual(over(object), false);
14555
14556       over = _.overEvery('b', 'a');
14557       assert.strictEqual(over(object), true);
14558     });
14559
14560     QUnit.test('should work with a "_.matches" style predicate', function(assert) {
14561       assert.expect(2);
14562
14563       var object = { 'a': 1, 'b': 2 },
14564           over = _.overEvery({ 'b': 2 }, { 'a': 1 });
14565
14566       assert.strictEqual(over(object), true);
14567
14568       over = _.overEvery({ 'a': 1 }, { 'c': 3 });
14569       assert.strictEqual(over(object), false);
14570     });
14571
14572     QUnit.test('should flatten `predicates`', function(assert) {
14573       assert.expect(1);
14574
14575       var over = _.overEvery(alwaysTrue, [alwaysFalse]);
14576       assert.strictEqual(over(), false);
14577     });
14578
14579     QUnit.test('should provide arguments to predicates', function(assert) {
14580       assert.expect(1);
14581
14582       var args;
14583
14584       var over = _.overEvery(function() {
14585         args = slice.call(arguments);
14586       });
14587
14588       over('a', 'b', 'c');
14589       assert.deepEqual(args, ['a', 'b', 'c']);
14590     });
14591
14592     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
14593       assert.expect(2);
14594
14595       var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
14596           object = { 'over': over, 'a': 1, 'b': 2 };
14597
14598       assert.strictEqual(object.over(), true);
14599
14600       object.a = 0;
14601       assert.strictEqual(object.over(), false);
14602     });
14603   }());
14604
14605   /*--------------------------------------------------------------------------*/
14606
14607   QUnit.module('lodash.overSome');
14608
14609   (function() {
14610     QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
14611       assert.expect(2);
14612
14613       var over = _.overSome(alwaysFalse, alwaysOne, alwaysEmptyString);
14614       assert.strictEqual(over(), true);
14615
14616       over = _.overSome(alwaysNull, alwaysA, alwaysZero);
14617       assert.strictEqual(over(), true);
14618     });
14619
14620     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
14621       assert.expect(2);
14622
14623       var count = 0,
14624           countFalse = function() { count++; return false; },
14625           countTrue = function() { count++; return true; },
14626           over = _.overSome(countFalse, countTrue, countFalse);
14627
14628       assert.strictEqual(over(), true);
14629       assert.strictEqual(count, 2);
14630     });
14631
14632     QUnit.test('should return `false` if all predicates return falsey', function(assert) {
14633       assert.expect(2);
14634
14635       var over = _.overSome(alwaysFalse, alwaysFalse, alwaysFalse);
14636       assert.strictEqual(over(), false);
14637
14638       over = _.overSome(alwaysNull, alwaysZero, alwaysEmptyString);
14639       assert.strictEqual(over(), false);
14640     });
14641
14642     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
14643       assert.expect(2);
14644
14645       var over = _.overSome(undefined, null);
14646       assert.strictEqual(over(true), true);
14647       assert.strictEqual(over(false), false);
14648     });
14649
14650     QUnit.test('should work with a "_.property" style predicate', function(assert) {
14651       assert.expect(2);
14652
14653       var object = { 'a': 1, 'b': 2 },
14654           over = _.overSome('c', 'a');
14655
14656       assert.strictEqual(over(object), true);
14657
14658       over = _.overSome('d', 'c');
14659       assert.strictEqual(over(object), false);
14660     });
14661
14662     QUnit.test('should work with a "_.matches" style predicate', function(assert) {
14663       assert.expect(2);
14664
14665       var object = { 'a': 1, 'b': 2 },
14666           over = _.overSome({ 'c': 3 }, { 'a': 1 });
14667
14668       assert.strictEqual(over(object), true);
14669
14670       over = _.overSome({ 'b': 1 }, { 'a': 2 });
14671       assert.strictEqual(over(object), false);
14672     });
14673
14674     QUnit.test('should flatten `predicates`', function(assert) {
14675       assert.expect(1);
14676
14677       var over = _.overSome(alwaysFalse, [alwaysTrue]);
14678       assert.strictEqual(over(), true);
14679     });
14680
14681     QUnit.test('should provide arguments to predicates', function(assert) {
14682       assert.expect(1);
14683
14684       var args;
14685
14686       var over = _.overSome(function() {
14687         args = slice.call(arguments);
14688       });
14689
14690       over('a', 'b', 'c');
14691       assert.deepEqual(args, ['a', 'b', 'c']);
14692     });
14693
14694     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
14695       assert.expect(2);
14696
14697       var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
14698           object = { 'over': over, 'a': 1, 'b': 2 };
14699
14700       assert.strictEqual(object.over(), true);
14701
14702       object.a = object.b = 0;
14703       assert.strictEqual(object.over(), false);
14704     });
14705   }());
14706
14707   /*--------------------------------------------------------------------------*/
14708
14709   QUnit.module('lodash.pad');
14710
14711   (function() {
14712     QUnit.test('should pad a string to a given length', function(assert) {
14713       assert.expect(1);
14714
14715       assert.strictEqual(_.pad('abc', 9), '   abc   ');
14716     });
14717
14718     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
14719       assert.expect(2);
14720
14721       assert.strictEqual(_.pad('abc', 8), '  abc   ');
14722       assert.strictEqual(_.pad('abc', 8, '_-'), '_-abc_-_');
14723     });
14724
14725     QUnit.test('should coerce `string` to a string', function(assert) {
14726       assert.expect(2);
14727
14728       assert.strictEqual(_.pad(Object('abc'), 4), 'abc ');
14729       assert.strictEqual(_.pad({ 'toString': lodashStable.constant('abc') }, 5), ' abc ');
14730     });
14731   }());
14732
14733   /*--------------------------------------------------------------------------*/
14734
14735   QUnit.module('lodash.padEnd');
14736
14737   (function() {
14738     QUnit.test('should pad a string to a given length', function(assert) {
14739       assert.expect(1);
14740
14741       assert.strictEqual(_.padEnd('abc', 6), 'abc   ');
14742     });
14743
14744     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
14745       assert.expect(1);
14746
14747       assert.strictEqual(_.padEnd('abc', 6, '_-'), 'abc_-_');
14748     });
14749
14750     QUnit.test('should coerce `string` to a string', function(assert) {
14751       assert.expect(2);
14752
14753       assert.strictEqual(_.padEnd(Object('abc'), 4), 'abc ');
14754       assert.strictEqual(_.padEnd({ 'toString': lodashStable.constant('abc') }, 5), 'abc  ');
14755     });
14756   }());
14757
14758   /*--------------------------------------------------------------------------*/
14759
14760   QUnit.module('lodash.padStart');
14761
14762   (function() {
14763     QUnit.test('should pad a string to a given length', function(assert) {
14764       assert.expect(1);
14765
14766       assert.strictEqual(_.padStart('abc', 6), '   abc');
14767     });
14768
14769     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
14770       assert.expect(1);
14771
14772       assert.strictEqual(_.padStart('abc', 6, '_-'), '_-_abc');
14773     });
14774
14775     QUnit.test('should coerce `string` to a string', function(assert) {
14776       assert.expect(2);
14777
14778       assert.strictEqual(_.padStart(Object('abc'), 4), ' abc');
14779       assert.strictEqual(_.padStart({ 'toString': lodashStable.constant('abc') }, 5), '  abc');
14780     });
14781   }());
14782
14783   /*--------------------------------------------------------------------------*/
14784
14785   QUnit.module('pad methods');
14786
14787   lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
14788     var func = _[methodName],
14789         isPad = methodName == 'pad',
14790         isStart = methodName == 'padStart';
14791
14792     QUnit.test('`_.' + methodName + '` should not pad is string is >= `length`', function(assert) {
14793       assert.expect(2);
14794
14795       assert.strictEqual(func('abc', 2), 'abc');
14796       assert.strictEqual(func('abc', 3), 'abc');
14797     });
14798
14799     QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
14800       assert.expect(2);
14801
14802       lodashStable.each([0, -2], function(length) {
14803         assert.strictEqual(func('abc', length), 'abc');
14804       });
14805     });
14806
14807     QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
14808       assert.expect(2);
14809
14810       lodashStable.each(['', '4'], function(length) {
14811         var actual = length ? (isStart ? ' abc' : 'abc ') : 'abc';
14812         assert.strictEqual(func('abc', length), actual);
14813       });
14814     });
14815
14816     QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
14817       assert.expect(6);
14818
14819       lodashStable.each([undefined, '_-'], function(chars) {
14820         var expected = chars ? (isPad ? '__' : chars) : '  ';
14821         assert.strictEqual(func(null, 2, chars), expected);
14822         assert.strictEqual(func(undefined, 2, chars), expected);
14823         assert.strictEqual(func('', 2, chars), expected);
14824       });
14825     });
14826
14827     QUnit.test('`_.' + methodName + '` should work with nullish or empty string values for `chars`', function(assert) {
14828       assert.expect(3);
14829
14830       assert.notStrictEqual(func('abc', 6, null), 'abc');
14831       assert.notStrictEqual(func('abc', 6, undefined), 'abc');
14832       assert.strictEqual(func('abc', 6, ''), 'abc');
14833     });
14834   });
14835
14836   /*--------------------------------------------------------------------------*/
14837
14838   QUnit.module('lodash.parseInt');
14839
14840   (function() {
14841     QUnit.test('should accept a `radix` argument', function(assert) {
14842       assert.expect(1);
14843
14844       var expected = lodashStable.range(2, 37);
14845
14846       var actual = lodashStable.map(expected, function(radix) {
14847         return _.parseInt('10', radix);
14848       });
14849
14850       assert.deepEqual(actual, expected);
14851     });
14852
14853     QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
14854       assert.expect(4);
14855
14856       assert.strictEqual(_.parseInt('10'), 10);
14857       assert.strictEqual(_.parseInt('10', 0), 10);
14858       assert.strictEqual(_.parseInt('10', 10), 10);
14859       assert.strictEqual(_.parseInt('10', undefined), 10);
14860     });
14861
14862     QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
14863       assert.expect(8);
14864
14865       lodashStable.each(['0x20', '0X20'], function(string) {
14866         assert.strictEqual(_.parseInt(string), 32);
14867         assert.strictEqual(_.parseInt(string, 0), 32);
14868         assert.strictEqual(_.parseInt(string, 16), 32);
14869         assert.strictEqual(_.parseInt(string, undefined), 32);
14870       });
14871     });
14872
14873     QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
14874       assert.expect(2);
14875
14876       assert.strictEqual(_.parseInt('08'), 8);
14877       assert.strictEqual(_.parseInt('08', 10), 8);
14878     });
14879
14880     QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
14881       assert.expect(2);
14882
14883       var expected = [8, 8, 10, 10, 32, 32, 32, 32];
14884
14885       lodashStable.times(2, function(index) {
14886         var actual = [],
14887             func = (index ? (lodashBizarro || {}) : _).parseInt;
14888
14889         if (func) {
14890           lodashStable.times(2, function(otherIndex) {
14891             var string = otherIndex ? '10' : '08';
14892             actual.push(
14893               func(whitespace + string, 10),
14894               func(whitespace + string)
14895             );
14896           });
14897
14898           lodashStable.each(['0x20', '0X20'], function(string) {
14899             actual.push(
14900               func(whitespace + string),
14901               func(whitespace + string, 16)
14902             );
14903           });
14904
14905           assert.deepEqual(actual, expected);
14906         }
14907         else {
14908           skipTest(assert);
14909         }
14910       });
14911     });
14912
14913     QUnit.test('should coerce `radix` to a number', function(assert) {
14914       assert.expect(2);
14915
14916       var object = { 'valueOf': alwaysZero };
14917       assert.strictEqual(_.parseInt('08', object), 8);
14918       assert.strictEqual(_.parseInt('0x20', object), 32);
14919     });
14920
14921     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
14922       assert.expect(2);
14923
14924       var strings = lodashStable.map(['6', '08', '10'], Object),
14925           actual = lodashStable.map(strings, _.parseInt);
14926
14927       assert.deepEqual(actual, [6, 8, 10]);
14928
14929       actual = lodashStable.map('123', _.parseInt);
14930       assert.deepEqual(actual, [1, 2, 3]);
14931     });
14932   }());
14933
14934   /*--------------------------------------------------------------------------*/
14935
14936   QUnit.module('partial methods');
14937
14938   lodashStable.each(['partial', 'partialRight'], function(methodName) {
14939     var func = _[methodName],
14940         isPartial = methodName == 'partial',
14941         ph = func.placeholder;
14942
14943     QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
14944       assert.expect(1);
14945
14946       var par = func(identity, 'a');
14947       assert.strictEqual(par(), 'a');
14948     });
14949
14950     QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
14951       assert.expect(1);
14952
14953       var fn = function(a, b) { return [a, b]; },
14954           par = func(fn, 'a'),
14955           expected = ['a', 'b'];
14956
14957       assert.deepEqual(par('b'), isPartial ? expected : expected.reverse());
14958     });
14959
14960     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
14961       assert.expect(1);
14962
14963       var fn = function() { return arguments.length; },
14964           par = func(fn);
14965
14966       assert.strictEqual(par(), 0);
14967     });
14968
14969     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
14970       assert.expect(1);
14971
14972       var par = func(identity);
14973       assert.strictEqual(par('a'), 'a');
14974     });
14975
14976     QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
14977       assert.expect(4);
14978
14979       var fn = function() { return slice.call(arguments); },
14980           par = func(fn, ph, 'b', ph);
14981
14982       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
14983       assert.deepEqual(par('a'), ['a', 'b', undefined]);
14984       assert.deepEqual(par(), [undefined, 'b', undefined]);
14985
14986       if (isPartial) {
14987         assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
14988       } else {
14989         par = func(fn, ph, 'c', ph);
14990         assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
14991       }
14992     });
14993
14994     QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
14995       assert.expect(1);
14996
14997       var fn = function(a, b, c) {},
14998           par = func(fn, 'a');
14999
15000       assert.strictEqual(par.length, 0);
15001     });
15002
15003     QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
15004       assert.expect(2);
15005
15006       function Foo(value) {
15007         return value && object;
15008       }
15009
15010       var object = {},
15011           par = func(Foo);
15012
15013       assert.ok(new par instanceof Foo);
15014       assert.strictEqual(new par(true), object);
15015     });
15016
15017     QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
15018       assert.expect(3);
15019
15020       function greet(greeting, name) {
15021         return greeting + ' ' + name;
15022       }
15023
15024       var par1 = func(greet, 'hi'),
15025           par2 = func(par1, 'barney'),
15026           par3 = func(par1, 'pebbles');
15027
15028       assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
15029       assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
15030       assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
15031     });
15032
15033     QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
15034       assert.expect(2);
15035
15036       var fn = function(a, b, c) { return a + b + c; },
15037           curried = _.curry(func(fn, 1), 2);
15038
15039       assert.strictEqual(curried(2, 3), 6);
15040       assert.strictEqual(curried(2)(3), 6);
15041     });
15042
15043     QUnit.test('should work with placeholders and curried functions', function(assert) {
15044       assert.expect(1);
15045
15046       var fn = function() { return slice.call(arguments); },
15047           curried = _.curry(fn),
15048           par = func(curried, ph, 'b', ph, 'd');
15049
15050       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
15051     });
15052   });
15053
15054   /*--------------------------------------------------------------------------*/
15055
15056   QUnit.module('lodash.partialRight');
15057
15058   (function() {
15059     QUnit.test('should work as a deep `_.defaults`', function(assert) {
15060       assert.expect(1);
15061
15062       var object = { 'a': { 'b': 1 } },
15063           source = { 'a': { 'b': 2, 'c': 3 } },
15064           expected = { 'a': { 'b': 1, 'c': 3 } };
15065
15066       var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
15067         return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
15068       });
15069
15070       assert.deepEqual(defaultsDeep(object, source), expected);
15071     });
15072   }());
15073
15074   /*--------------------------------------------------------------------------*/
15075
15076   QUnit.module('methods using `createWrapper`');
15077
15078   (function() {
15079     function fn() {
15080       return slice.call(arguments);
15081     }
15082
15083     var ph1 = _.bind.placeholder,
15084         ph2 = _.bindKey.placeholder,
15085         ph3 = _.partial.placeholder,
15086         ph4 = _.partialRight.placeholder;
15087
15088     QUnit.test('should work with combinations of partial functions', function(assert) {
15089       assert.expect(1);
15090
15091       var a = _.partial(fn),
15092           b = _.partialRight(a, 3),
15093           c = _.partial(b, 1);
15094
15095       assert.deepEqual(c(2), [1, 2, 3]);
15096     });
15097
15098     QUnit.test('should work with combinations of bound and partial functions', function(assert) {
15099       assert.expect(3);
15100
15101       var fn = function() {
15102         var result = [this.a];
15103         push.apply(result, arguments);
15104         return result;
15105       };
15106
15107       var expected = [1, 2, 3, 4],
15108           object = { 'a': 1, 'fn': fn };
15109
15110       var a = _.bindKey(object, 'fn'),
15111           b = _.partialRight(a, 4),
15112           c = _.partial(b, 2);
15113
15114       assert.deepEqual(c(3), expected);
15115
15116       a = _.bind(fn, object);
15117       b = _.partialRight(a, 4);
15118       c = _.partial(b, 2);
15119
15120       assert.deepEqual(c(3), expected);
15121
15122       a = _.partial(fn, 2);
15123       b = _.bind(a, object);
15124       c = _.partialRight(b, 4);
15125
15126       assert.deepEqual(c(3), expected);
15127     });
15128
15129     QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
15130       assert.expect(2);
15131
15132       function Foo(a, b, c) {
15133         return b === 0 && object;
15134       }
15135
15136       var combo = _.partial(_.partialRight(Foo, 3), 1),
15137           object = {};
15138
15139       assert.ok(new combo(2) instanceof Foo);
15140       assert.strictEqual(new combo(0), object);
15141     });
15142
15143     QUnit.test('should work with combinations of functions with placeholders', function(assert) {
15144       assert.expect(3);
15145
15146       var expected = [1, 2, 3, 4, 5, 6],
15147           object = { 'fn': fn };
15148
15149       var a = _.bindKey(object, 'fn', ph2, 2),
15150           b = _.partialRight(a, ph4, 6),
15151           c = _.partial(b, 1, ph3, 4);
15152
15153       assert.deepEqual(c(3, 5), expected);
15154
15155       a = _.bind(fn, object, ph1, 2);
15156       b = _.partialRight(a, ph4, 6);
15157       c = _.partial(b, 1, ph3, 4);
15158
15159       assert.deepEqual(c(3, 5), expected);
15160
15161       a = _.partial(fn, ph3, 2);
15162       b = _.bind(a, object, 1, ph1, 4);
15163       c = _.partialRight(b, ph4, 6);
15164
15165       assert.deepEqual(c(3, 5), expected);
15166     });
15167
15168     QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
15169       assert.expect(3);
15170
15171       var expected = [1, 2, 3, 4],
15172           object = { 'fn': fn };
15173
15174       var a = _.bindKey(object, 'fn', ph2, 2),
15175           b = _.partialRight(a, ph4, 4),
15176           c = _.partial(b, ph3, 3);
15177
15178       assert.deepEqual(c(1), expected);
15179
15180       a = _.bind(fn, object, ph1, 2);
15181       b = _.partialRight(a, ph4, 4);
15182       c = _.partial(b, ph3, 3);
15183
15184       assert.deepEqual(c(1), expected);
15185
15186       a = _.partial(fn, ph3, 2);
15187       b = _.bind(a, object, ph1, 3);
15188       c = _.partialRight(b, ph4, 4);
15189
15190       assert.deepEqual(c(1), expected);
15191     });
15192
15193     QUnit.test('should work with recursively bound functions', function(assert) {
15194       assert.expect(1);
15195
15196       var fn = function() {
15197         return this.a;
15198       };
15199
15200       var a = _.bind(fn, { 'a': 1 }),
15201           b = _.bind(a,  { 'a': 2 }),
15202           c = _.bind(b,  { 'a': 3 });
15203
15204       assert.strictEqual(c(), 1);
15205     });
15206
15207     QUnit.test('should work when hot', function(assert) {
15208       assert.expect(12);
15209
15210       lodashStable.times(2, function(index) {
15211         var fn = function() {
15212           var result = [this];
15213           push.apply(result, arguments);
15214           return result;
15215         };
15216
15217         var object = {},
15218             bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
15219             expected = [object, 1, 2, 3];
15220
15221         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
15222           var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
15223           return index ? bound2(3) : bound2(1, 2, 3);
15224         }));
15225
15226         assert.deepEqual(actual, expected);
15227
15228         actual = _.last(lodashStable.times(HOT_COUNT, function() {
15229           var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
15230               bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
15231
15232           return index ? bound2(3) : bound2(1, 2, 3);
15233         }));
15234
15235         assert.deepEqual(actual, expected);
15236       });
15237
15238       lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
15239         var fn = function(a, b, c) { return [a, b, c]; },
15240             curried = _[methodName](fn),
15241             expected = index ? [3, 2, 1] :  [1, 2, 3];
15242
15243         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
15244           return curried(1)(2)(3);
15245         }));
15246
15247         assert.deepEqual(actual, expected);
15248
15249         actual = _.last(lodashStable.times(HOT_COUNT, function() {
15250           var curried = _[methodName](fn);
15251           return curried(1)(2)(3);
15252         }));
15253
15254         assert.deepEqual(actual, expected);
15255       });
15256
15257       lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
15258         var func = _[methodName],
15259             fn = function() { return slice.call(arguments); },
15260             par1 = func(fn, 1),
15261             expected = index ? [3, 2, 1] : [1, 2, 3];
15262
15263         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
15264           var par2 = func(par1, 2);
15265           return par2(3);
15266         }));
15267
15268         assert.deepEqual(actual, expected);
15269
15270         actual = _.last(lodashStable.times(HOT_COUNT, function() {
15271           var par1 = func(fn, 1),
15272               par2 = func(par1, 2);
15273
15274           return par2(3);
15275         }));
15276
15277         assert.deepEqual(actual, expected);
15278       });
15279     });
15280   }());
15281
15282   /*--------------------------------------------------------------------------*/
15283
15284   QUnit.module('lodash.partition');
15285
15286   (function() {
15287     var array = [1, 0, 1];
15288
15289     QUnit.test('should return two groups of elements', function(assert) {
15290       assert.expect(3);
15291
15292       assert.deepEqual(_.partition([], identity), [[], []]);
15293       assert.deepEqual(_.partition(array, alwaysTrue), [array, []]);
15294       assert.deepEqual(_.partition(array, alwaysFalse), [[], array]);
15295     });
15296
15297     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
15298       assert.expect(1);
15299
15300       var values = [, null, undefined],
15301           expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
15302
15303       var actual = lodashStable.map(values, function(value, index) {
15304         return index ? _.partition(array, value) : _.partition(array);
15305       });
15306
15307       assert.deepEqual(actual, expected);
15308     });
15309
15310     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
15311       assert.expect(1);
15312
15313       var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
15314           actual = _.partition(objects, 'a');
15315
15316       assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
15317     });
15318
15319     QUnit.test('should work with a number for `predicate`', function(assert) {
15320       assert.expect(2);
15321
15322       var array = [
15323         [1, 0],
15324         [0, 1],
15325         [1, 0]
15326       ];
15327
15328       assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
15329       assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
15330     });
15331
15332     QUnit.test('should work with an object for `collection`', function(assert) {
15333       assert.expect(1);
15334
15335       var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, function(num) {
15336         return Math.floor(num);
15337       });
15338
15339       assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
15340     });
15341   }());
15342
15343   /*--------------------------------------------------------------------------*/
15344
15345   QUnit.module('lodash.pick');
15346
15347   (function() {
15348     var args = arguments,
15349         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
15350
15351     QUnit.test('should flatten `props`', function(assert) {
15352       assert.expect(2);
15353
15354       assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
15355       assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
15356     });
15357
15358     QUnit.test('should work with a primitive `object` argument', function(assert) {
15359       assert.expect(1);
15360
15361       assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
15362     });
15363
15364     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
15365       assert.expect(2);
15366
15367       lodashStable.each([null, undefined], function(value) {
15368         assert.deepEqual(_.pick(value, 'valueOf'), {});
15369       });
15370     });
15371
15372     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
15373       assert.expect(1);
15374
15375       assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
15376     });
15377
15378     QUnit.test('should coerce property names to strings', function(assert) {
15379       assert.expect(1);
15380
15381       assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
15382     });
15383   }('a', 'c'));
15384
15385   /*--------------------------------------------------------------------------*/
15386
15387   QUnit.module('lodash.pickBy');
15388
15389   (function() {
15390     QUnit.test('should work with a predicate argument', function(assert) {
15391       assert.expect(1);
15392
15393       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
15394
15395       var actual = _.pickBy(object, function(num) {
15396         return num == 1 || num == 3;
15397       });
15398
15399       assert.deepEqual(actual, { 'a': 1, 'c': 3 });
15400     });
15401   }());
15402
15403   /*--------------------------------------------------------------------------*/
15404
15405   QUnit.module('pick methods');
15406
15407   lodashStable.each(['pick', 'pickBy'], function(methodName) {
15408     var expected = { 'a': 1, 'c': 3 },
15409         func = _[methodName],
15410         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
15411         prop = function(object, props) { return props; };
15412
15413     if (methodName == 'pickBy') {
15414       prop = function(object, props) {
15415         props = typeof props == 'string' ? [props] : props;
15416         return function(value) {
15417           return _.some(props, function(key) { return object[key] === value; });
15418         };
15419       };
15420     }
15421     QUnit.test('`_.' + methodName + '` should create an object of picked properties', function(assert) {
15422       assert.expect(2);
15423
15424       assert.deepEqual(func(object, prop(object, 'a')), { 'a': 1 });
15425       assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
15426     });
15427
15428     QUnit.test('`_.' + methodName + '` should iterate over inherited properties', function(assert) {
15429       assert.expect(1);
15430
15431       function Foo() {}
15432       Foo.prototype = object;
15433
15434       var foo = new Foo;
15435       assert.deepEqual(func(foo, prop(foo, ['a', 'c'])), expected);
15436     });
15437
15438     QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
15439       assert.expect(1);
15440
15441       var array = [1, 2, 3];
15442       assert.deepEqual(func(array, prop(array, '1')), { '1': 2 });
15443     });
15444   });
15445
15446   /*--------------------------------------------------------------------------*/
15447
15448   QUnit.module('lodash.property');
15449
15450   (function() {
15451     QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
15452       assert.expect(4);
15453
15454       var object = { 'a': 1 };
15455
15456       lodashStable.each(['a', ['a']], function(path) {
15457         var prop = _.property(path);
15458         assert.strictEqual(prop.length, 1);
15459         assert.strictEqual(prop(object), 1);
15460       });
15461     });
15462
15463     QUnit.test('should pluck deep property values', function(assert) {
15464       assert.expect(2);
15465
15466       var object = { 'a': { 'b': { 'c': 3 } } };
15467
15468       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
15469         var prop = _.property(path);
15470         assert.strictEqual(prop(object), 3);
15471       });
15472     });
15473
15474     QUnit.test('should work with non-string `path` arguments', function(assert) {
15475       assert.expect(2);
15476
15477       var array = [1, 2, 3];
15478
15479       lodashStable.each([1, [1]], function(path) {
15480         var prop = _.property(path);
15481         assert.strictEqual(prop(array), 2);
15482       });
15483     });
15484
15485     QUnit.test('should coerce key to a string', function(assert) {
15486       assert.expect(1);
15487
15488       function fn() {}
15489       fn.toString = lodashStable.constant('fn');
15490
15491       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15492           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
15493           values = [null, undefined, fn, {}];
15494
15495       var actual = lodashStable.transform(objects, function(result, object, index) {
15496         var key = values[index];
15497         lodashStable.each([key, [key]], function(path) {
15498           var prop = _.property(key);
15499           result.push(prop(object));
15500         });
15501       });
15502
15503       assert.deepEqual(actual, expected);
15504     });
15505
15506     QUnit.test('should pluck inherited property values', function(assert) {
15507       assert.expect(2);
15508
15509       function Foo() {}
15510       Foo.prototype.a = 1;
15511
15512       lodashStable.each(['a', ['a']], function(path) {
15513         var prop = _.property(path);
15514         assert.strictEqual(prop(new Foo), 1);
15515       });
15516     });
15517
15518     QUnit.test('should pluck a key over a path', function(assert) {
15519       assert.expect(2);
15520
15521       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
15522
15523       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
15524         var prop = _.property(path);
15525         assert.strictEqual(prop(object), 3);
15526       });
15527     });
15528
15529     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15530       assert.expect(2);
15531
15532       var values = [, null, undefined],
15533           expected = lodashStable.map(values, alwaysUndefined);
15534
15535       lodashStable.each(['constructor', ['constructor']], function(path) {
15536         var prop = _.property(path);
15537
15538         var actual = lodashStable.map(values, function(value, index) {
15539           return index ? prop(value) : prop();
15540         });
15541
15542         assert.deepEqual(actual, expected);
15543       });
15544     });
15545
15546     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15547       assert.expect(2);
15548
15549       var values = [, null, undefined],
15550           expected = lodashStable.map(values, alwaysUndefined);
15551
15552       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15553         var prop = _.property(path);
15554
15555         var actual = lodashStable.map(values, function(value, index) {
15556           return index ? prop(value) : prop();
15557         });
15558
15559         assert.deepEqual(actual, expected);
15560       });
15561     });
15562
15563     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15564       assert.expect(4);
15565
15566       var object = {};
15567
15568       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15569         var prop = _.property(path);
15570         assert.strictEqual(prop(object), undefined);
15571       });
15572     });
15573   }());
15574
15575   /*--------------------------------------------------------------------------*/
15576
15577   QUnit.module('lodash.propertyOf');
15578
15579   (function() {
15580     QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
15581       assert.expect(3);
15582
15583       var object = { 'a': 1 },
15584           propOf = _.propertyOf(object);
15585
15586       assert.strictEqual(propOf.length, 1);
15587       lodashStable.each(['a', ['a']], function(path) {
15588         assert.strictEqual(propOf(path), 1);
15589       });
15590     });
15591
15592     QUnit.test('should pluck deep property values', function(assert) {
15593       assert.expect(2);
15594
15595       var object = { 'a': { 'b': { 'c': 3 } } },
15596           propOf = _.propertyOf(object);
15597
15598       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
15599         assert.strictEqual(propOf(path), 3);
15600       });
15601     });
15602
15603     QUnit.test('should work with non-string `path` arguments', function(assert) {
15604       assert.expect(2);
15605
15606       var array = [1, 2, 3],
15607           propOf = _.propertyOf(array);
15608
15609       lodashStable.each([1, [1]], function(path) {
15610         assert.strictEqual(propOf(path), 2);
15611       });
15612     });
15613
15614     QUnit.test('should coerce key to a string', function(assert) {
15615       assert.expect(1);
15616
15617       function fn() {}
15618       fn.toString = lodashStable.constant('fn');
15619
15620       var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15621           objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
15622           values = [null, undefined, fn, {}];
15623
15624       var actual = lodashStable.transform(objects, function(result, object, index) {
15625         var key = values[index];
15626         lodashStable.each([key, [key]], function(path) {
15627           var propOf = _.propertyOf(object);
15628           result.push(propOf(key));
15629         });
15630       });
15631
15632       assert.deepEqual(actual, expected);
15633     });
15634
15635     QUnit.test('should pluck inherited property values', function(assert) {
15636       assert.expect(2);
15637
15638       function Foo() { this.a = 1; }
15639       Foo.prototype.b = 2;
15640
15641       var propOf = _.propertyOf(new Foo);
15642
15643       lodashStable.each(['b', ['b']], function(path) {
15644         assert.strictEqual(propOf(path), 2);
15645       });
15646     });
15647
15648     QUnit.test('should pluck a key over a path', function(assert) {
15649       assert.expect(2);
15650
15651       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } },
15652           propOf = _.propertyOf(object);
15653
15654       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
15655         assert.strictEqual(propOf(path), 3);
15656       });
15657     });
15658
15659     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15660       assert.expect(2);
15661
15662       var values = [, null, undefined],
15663           expected = lodashStable.map(values, alwaysUndefined);
15664
15665       lodashStable.each(['constructor', ['constructor']], function(path) {
15666         var actual = lodashStable.map(values, function(value, index) {
15667           var propOf = index ? _.propertyOf(value) : _.propertyOf();
15668           return propOf(path);
15669         });
15670
15671         assert.deepEqual(actual, expected);
15672       });
15673     });
15674
15675     QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15676       assert.expect(2);
15677
15678       var values = [, null, undefined],
15679           expected = lodashStable.map(values, alwaysUndefined);
15680
15681       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15682         var actual = lodashStable.map(values, function(value, index) {
15683           var propOf = index ? _.propertyOf(value) : _.propertyOf();
15684           return propOf(path);
15685         });
15686
15687         assert.deepEqual(actual, expected);
15688       });
15689     });
15690
15691     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15692       assert.expect(4);
15693
15694       var propOf = _.propertyOf({});
15695
15696       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15697         assert.strictEqual(propOf(path), undefined);
15698       });
15699     });
15700   }());
15701
15702   /*--------------------------------------------------------------------------*/
15703
15704   QUnit.module('pull methods');
15705
15706   lodashStable.each(['pull', 'pullAll'], function(methodName) {
15707     var func = _[methodName],
15708         isPull = methodName == 'pull';
15709
15710     function pull(array, values) {
15711       return isPull
15712         ? func.apply(undefined, [array].concat(values))
15713         : func(array, values);
15714     }
15715
15716     QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
15717       assert.expect(2);
15718
15719       var array = [1, 2, 3],
15720           actual = pull(array, [1, 3]);
15721
15722       assert.deepEqual(array, [2]);
15723       assert.ok(actual === array);
15724     });
15725
15726     QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
15727       assert.expect(2);
15728
15729       var array = [1, 2, 3, 4];
15730       delete array[1];
15731       delete array[3];
15732
15733       pull(array, [1]);
15734       assert.notOk('0' in array);
15735       assert.notOk('2' in array);
15736     });
15737
15738     QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
15739       assert.expect(1);
15740
15741       var array = [1, 2, 3];
15742       delete array[1];
15743
15744       pull(array, [undefined]);
15745       assert.deepEqual(array, [1, 3]);
15746     });
15747
15748     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
15749       assert.expect(1);
15750
15751       var array = [1, NaN, 3, NaN];
15752
15753       pull(array, [NaN]);
15754       assert.deepEqual(array, [1, 3]);
15755     });
15756   });
15757
15758   /*--------------------------------------------------------------------------*/
15759
15760   QUnit.module('lodash.pullAllBy');
15761
15762   (function() {
15763     QUnit.test('should accept an `iteratee` argument', function(assert) {
15764       assert.expect(1);
15765
15766       var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
15767
15768       var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
15769         return object.x;
15770       });
15771
15772       assert.deepEqual(actual, [{ 'x': 2 }]);
15773     });
15774
15775     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
15776       assert.expect(1);
15777
15778       var args,
15779           array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
15780
15781       _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
15782         args || (args = slice.call(arguments));
15783       });
15784
15785       assert.deepEqual(args, [{ 'x': 1 }]);
15786     });
15787   }());
15788
15789   /*--------------------------------------------------------------------------*/
15790
15791   QUnit.module('lodash.pullAt');
15792
15793   (function() {
15794     QUnit.test('should modify the array and return removed elements', function(assert) {
15795       assert.expect(2);
15796
15797       var array = [1, 2, 3],
15798           actual = _.pullAt(array, [0, 1]);
15799
15800       assert.deepEqual(array, [3]);
15801       assert.deepEqual(actual, [1, 2]);
15802     });
15803
15804     QUnit.test('should work with unsorted indexes', function(assert) {
15805       assert.expect(2);
15806
15807       var array = [1, 2, 3, 4],
15808           actual = _.pullAt(array, [1, 3, 0]);
15809
15810       assert.deepEqual(array, [3]);
15811       assert.deepEqual(actual, [2, 4, 1]);
15812     });
15813
15814     QUnit.test('should work with repeated indexes', function(assert) {
15815       assert.expect(2);
15816
15817       var array = [1, 2, 3, 4],
15818           actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
15819
15820       assert.deepEqual(array, [4]);
15821       assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
15822     });
15823
15824     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
15825       assert.expect(2);
15826
15827       var array = ['a', 'b', 'c'],
15828           actual = _.pullAt(array, [2, 4, 0]);
15829
15830       assert.deepEqual(array, ['b']);
15831       assert.deepEqual(actual, ['c', undefined, 'a']);
15832     });
15833
15834     QUnit.test('should flatten `indexes`', function(assert) {
15835       assert.expect(4);
15836
15837       var array = ['a', 'b', 'c'];
15838       assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
15839       assert.deepEqual(array, ['b']);
15840
15841       array = ['a', 'b', 'c', 'd'];
15842       assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
15843       assert.deepEqual(array, ['b']);
15844     });
15845
15846     QUnit.test('should return an empty array when no indexes are provided', function(assert) {
15847       assert.expect(4);
15848
15849       var array = ['a', 'b', 'c'],
15850           actual = _.pullAt(array);
15851
15852       assert.deepEqual(array, ['a', 'b', 'c']);
15853       assert.deepEqual(actual, []);
15854
15855       actual = _.pullAt(array, [], []);
15856
15857       assert.deepEqual(array, ['a', 'b', 'c']);
15858       assert.deepEqual(actual, []);
15859     });
15860
15861     QUnit.test('should work with non-index paths', function(assert) {
15862       assert.expect(2);
15863
15864       var values = lodashStable.reject(empties, function(value) {
15865         return (value === 0) || lodashStable.isArray(value);
15866       }).concat(-1, 1.1);
15867
15868       var array = lodashStable.transform(values, function(result, value) {
15869         result[value] = 1;
15870       }, []);
15871
15872       var expected = lodashStable.map(values, alwaysOne),
15873           actual = _.pullAt(array, values);
15874
15875       assert.deepEqual(actual, expected);
15876
15877       expected = lodashStable.map(values, alwaysUndefined),
15878       actual = _.at(array, values);
15879
15880       assert.deepEqual(actual, expected);
15881     });
15882
15883     QUnit.test('should work with deep paths', function(assert) {
15884       assert.expect(3);
15885
15886       var array = [];
15887       array.a = { 'b': { 'c': 3 } };
15888
15889       var actual = _.pullAt(array, 'a.b.c');
15890
15891       assert.deepEqual(actual, [3]);
15892       assert.deepEqual(array.a, { 'b': {} });
15893
15894       try {
15895         actual = _.pullAt(array, 'a.b.c.d.e');
15896       } catch (e) {}
15897
15898       assert.deepEqual(actual, [undefined]);
15899     });
15900
15901     QUnit.test('should work with a falsey `array` argument when keys are provided', function(assert) {
15902       assert.expect(1);
15903
15904       var values = falsey.slice(),
15905           expected = lodashStable.map(values, lodashStable.constant(Array(4)));
15906
15907       var actual = lodashStable.map(values, function(array) {
15908         try {
15909           return _.pullAt(array, 0, 1, 'pop', 'push');
15910         } catch (e) {}
15911       });
15912
15913       assert.deepEqual(actual, expected);
15914     });
15915   }());
15916
15917   /*--------------------------------------------------------------------------*/
15918
15919   QUnit.module('lodash.random');
15920
15921   (function() {
15922     var array = Array(1000);
15923
15924     QUnit.test('should return `0` or `1` when arguments are not provided', function(assert) {
15925       assert.expect(1);
15926
15927       var actual = lodashStable.map(array, function() {
15928         return _.random();
15929       });
15930
15931       assert.deepEqual(_.uniq(actual).sort(), [0, 1]);
15932     });
15933
15934     QUnit.test('should support a `min` and `max` argument', function(assert) {
15935       assert.expect(1);
15936
15937       var min = 5,
15938           max = 10;
15939
15940       assert.ok(_.some(array, function() {
15941         var result = _.random(min, max);
15942         return result >= min && result <= max;
15943       }));
15944     });
15945
15946     QUnit.test('should support not providing a `max` argument', function(assert) {
15947       assert.expect(1);
15948
15949       var min = 0,
15950           max = 5;
15951
15952       assert.ok(_.some(array, function() {
15953         var result = _.random(max);
15954         return result >= min && result <= max;
15955       }));
15956     });
15957
15958     QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
15959       assert.expect(1);
15960
15961       var min = 4,
15962           max = 2,
15963           expected = [2, 3, 4];
15964
15965       var actual = lodashStable.uniq(lodashStable.map(array, function() {
15966         return _.random(min, max);
15967       })).sort();
15968
15969       assert.deepEqual(actual, expected);
15970     });
15971
15972     QUnit.test('should support large integer values', function(assert) {
15973       assert.expect(2);
15974
15975       var min = Math.pow(2, 31),
15976           max = Math.pow(2, 62);
15977
15978       assert.ok(lodashStable.every(array, function() {
15979         var result = _.random(min, max);
15980         return result >= min && result <= max;
15981       }));
15982
15983       assert.ok(_.some(array, function() {
15984         return _.random(MAX_INTEGER) > 0;
15985       }));
15986     });
15987
15988     QUnit.test('should coerce arguments to finite numbers', function(assert) {
15989       assert.expect(2);
15990
15991       assert.strictEqual(_.random('1', '1'), 1);
15992       assert.strictEqual(_.random(NaN, NaN), 0);
15993     });
15994
15995     QUnit.test('should support floats', function(assert) {
15996       assert.expect(2);
15997
15998       var min = 1.5,
15999           max = 1.6,
16000           actual = _.random(min, max);
16001
16002       assert.ok(actual % 1);
16003       assert.ok(actual >= min && actual <= max);
16004     });
16005
16006     QUnit.test('should support providing a `floating` argument', function(assert) {
16007       assert.expect(3);
16008
16009       var actual = _.random(true);
16010       assert.ok(actual % 1 && actual >= 0 && actual <= 1);
16011
16012       actual = _.random(2, true);
16013       assert.ok(actual % 1 && actual >= 0 && actual <= 2);
16014
16015       actual = _.random(2, 4, true);
16016       assert.ok(actual % 1 && actual >= 2 && actual <= 4);
16017     });
16018
16019     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
16020       assert.expect(1);
16021
16022       var array = [1, 2, 3],
16023           expected = lodashStable.map(array, alwaysTrue),
16024           randoms = lodashStable.map(array, _.random);
16025
16026       var actual = lodashStable.map(randoms, function(result, index) {
16027         return result >= 0 && result <= array[index] && (result % 1) == 0;
16028       });
16029
16030       assert.deepEqual(actual, expected);
16031     });
16032   }());
16033
16034   /*--------------------------------------------------------------------------*/
16035
16036   QUnit.module('range methods');
16037
16038   lodashStable.each(['range', 'rangeRight'], function(methodName) {
16039     var func = _[methodName],
16040         isRange = methodName == 'range';
16041
16042     function resolve(range) {
16043       return isRange ? range : range.reverse();
16044     }
16045
16046     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when provided only an `end` argument', function(assert) {
16047       assert.expect(2);
16048
16049       assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
16050       assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
16051     });
16052
16053     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when provided only a `start` and `end` argument', function(assert) {
16054       assert.expect(2);
16055
16056       assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
16057       assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
16058     });
16059
16060     QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
16061       assert.expect(3);
16062
16063       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
16064       assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
16065       assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
16066     });
16067
16068     QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
16069       assert.expect(1);
16070
16071       assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
16072     });
16073
16074     QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
16075       assert.expect(1);
16076
16077       assert.deepEqual(func(1, 5, 20), [1]);
16078     });
16079
16080     QUnit.test('`_.' + methodName + '` should work with a negative `step` argument', function(assert) {
16081       assert.expect(2);
16082
16083       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
16084       assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
16085     });
16086
16087     QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
16088       assert.expect(1);
16089
16090       var actual = func(-0, 1);
16091       assert.strictEqual(1 / actual[0], -Infinity);
16092     });
16093
16094     QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
16095       assert.expect(13);
16096
16097       lodashStable.each(falsey, function(value, index) {
16098         if (index) {
16099           assert.deepEqual(func(value), []);
16100           assert.deepEqual(func(value, 1), [0]);
16101         } else {
16102           assert.deepEqual(func(), []);
16103         }
16104       });
16105     });
16106
16107     QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
16108       assert.expect(1);
16109
16110       var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
16111       assert.deepEqual(actual, [[0], [0], [0], [], []]);
16112     });
16113
16114     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
16115       assert.expect(2);
16116
16117       var array = [1, 2, 3],
16118           object = { 'a': 1, 'b': 2, 'c': 3 },
16119           expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
16120
16121       lodashStable.each([array, object], function(collection) {
16122         var actual = lodashStable.map(collection, func);
16123         assert.deepEqual(actual, expected);
16124       });
16125     });
16126   });
16127
16128   /*--------------------------------------------------------------------------*/
16129
16130   QUnit.module('lodash.rearg');
16131
16132   (function() {
16133     function fn() {
16134       return slice.call(arguments);
16135     }
16136
16137     QUnit.test('should reorder arguments provided to `func`', function(assert) {
16138       assert.expect(1);
16139
16140       var rearged = _.rearg(fn, [2, 0, 1]);
16141       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
16142     });
16143
16144     QUnit.test('should work with repeated indexes', function(assert) {
16145       assert.expect(1);
16146
16147       var rearged = _.rearg(fn, [1, 1, 1]);
16148       assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
16149     });
16150
16151     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
16152       assert.expect(1);
16153
16154       var rearged = _.rearg(fn, [1, 4]);
16155       assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
16156     });
16157
16158     QUnit.test('should use `undefined` for non-index values', function(assert) {
16159       assert.expect(1);
16160
16161       var values = lodashStable.reject(empties, function(value) {
16162         return (value === 0) || lodashStable.isArray(value);
16163       }).concat(-1, 1.1);
16164
16165       var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
16166
16167       var actual = lodashStable.map(values, function(value) {
16168         var rearged = _.rearg(fn, [value]);
16169         return rearged('a', 'b', 'c');
16170       });
16171
16172       assert.deepEqual(actual, expected);
16173     });
16174
16175     QUnit.test('should not rearrange arguments when no indexes are provided', function(assert) {
16176       assert.expect(2);
16177
16178       var rearged = _.rearg(fn);
16179       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
16180
16181       rearged = _.rearg(fn, [], []);
16182       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
16183     });
16184
16185     QUnit.test('should accept multiple index arguments', function(assert) {
16186       assert.expect(1);
16187
16188       var rearged = _.rearg(fn, 2, 0, 1);
16189       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
16190     });
16191
16192     QUnit.test('should accept multiple arrays of indexes', function(assert) {
16193       assert.expect(1);
16194
16195       var rearged = _.rearg(fn, [2], [0, 1]);
16196       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
16197     });
16198
16199     QUnit.test('should work with fewer indexes than arguments', function(assert) {
16200       assert.expect(1);
16201
16202       var rearged = _.rearg(fn, [1, 0]);
16203       assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
16204     });
16205
16206     QUnit.test('should work on functions that have been rearged', function(assert) {
16207       assert.expect(1);
16208
16209       var rearged1 = _.rearg(fn, 2, 1, 0),
16210           rearged2 = _.rearg(rearged1, 1, 0, 2);
16211
16212       assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
16213     });
16214   }());
16215
16216   /*--------------------------------------------------------------------------*/
16217
16218   QUnit.module('lodash.reduce');
16219
16220   (function() {
16221     var array = [1, 2, 3];
16222
16223     QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
16224       assert.expect(1);
16225
16226       assert.strictEqual(_.reduce(array), 1);
16227     });
16228
16229     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
16230       assert.expect(2);
16231
16232       var args;
16233
16234       _.reduce(array, function() {
16235         args || (args = slice.call(arguments));
16236       }, 0);
16237
16238       assert.deepEqual(args, [0, 1, 0, array]);
16239
16240       args = undefined;
16241       _.reduce(array, function() {
16242         args || (args = slice.call(arguments));
16243       });
16244
16245       assert.deepEqual(args, [1, 2, 1, array]);
16246     });
16247
16248     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
16249       assert.expect(2);
16250
16251       var args,
16252           object = { 'a': 1, 'b': 2 },
16253           firstKey = _.head(_.keys(object));
16254
16255       var expected = firstKey == 'a'
16256         ? [0, 1, 'a', object]
16257         : [0, 2, 'b', object];
16258
16259       _.reduce(object, function() {
16260         args || (args = slice.call(arguments));
16261       }, 0);
16262
16263       assert.deepEqual(args, expected);
16264
16265       args = undefined;
16266       expected = firstKey == 'a'
16267         ? [1, 2, 'b', object]
16268         : [2, 1, 'a', object];
16269
16270       _.reduce(object, function() {
16271         args || (args = slice.call(arguments));
16272       });
16273
16274       assert.deepEqual(args, expected);
16275     });
16276   }());
16277
16278   /*--------------------------------------------------------------------------*/
16279
16280   QUnit.module('lodash.reduceRight');
16281
16282   (function() {
16283     var array = [1, 2, 3];
16284
16285     QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
16286       assert.expect(1);
16287
16288       assert.strictEqual(_.reduceRight(array), 3);
16289     });
16290
16291     QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
16292       assert.expect(2);
16293
16294       var args;
16295
16296       _.reduceRight(array, function() {
16297         args || (args = slice.call(arguments));
16298       }, 0);
16299
16300       assert.deepEqual(args, [0, 3, 2, array]);
16301
16302       args = undefined;
16303       _.reduceRight(array, function() {
16304         args || (args = slice.call(arguments));
16305       });
16306
16307       assert.deepEqual(args, [3, 2, 1, array]);
16308     });
16309
16310     QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
16311       assert.expect(2);
16312
16313       var args,
16314           object = { 'a': 1, 'b': 2 },
16315           isFIFO = lodashStable.keys(object)[0] == 'a';
16316
16317       var expected = isFIFO
16318         ? [0, 2, 'b', object]
16319         : [0, 1, 'a', object];
16320
16321       _.reduceRight(object, function() {
16322         args || (args = slice.call(arguments));
16323       }, 0);
16324
16325       assert.deepEqual(args, expected);
16326
16327       args = undefined;
16328       expected = isFIFO
16329         ? [2, 1, 'a', object]
16330         : [1, 2, 'b', object];
16331
16332       _.reduceRight(object, function() {
16333         args || (args = slice.call(arguments));
16334       });
16335
16336       assert.deepEqual(args, expected);
16337     });
16338   }());
16339
16340   /*--------------------------------------------------------------------------*/
16341
16342   QUnit.module('reduce methods');
16343
16344   lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
16345     var func = _[methodName],
16346         array = [1, 2, 3],
16347         isReduce = methodName == 'reduce';
16348
16349     QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
16350       assert.expect(1);
16351
16352       var actual = func(['a', 'b', 'c'], function(accumulator, value) {
16353         return accumulator + value;
16354       }, '');
16355
16356       assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
16357     });
16358
16359     QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
16360       assert.expect(1);
16361
16362       var actual = [],
16363           expected = lodashStable.map(empties, alwaysUndefined);
16364
16365       lodashStable.each(empties, function(value) {
16366         try {
16367           actual.push(func(value, noop));
16368         } catch (e) {}
16369       });
16370
16371       assert.deepEqual(actual, expected);
16372     });
16373
16374     QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
16375       assert.expect(1);
16376
16377       var expected = lodashStable.map(empties, lodashStable.constant('x'));
16378
16379       var actual = lodashStable.map(empties, function(value) {
16380         try {
16381           return func(value, noop, 'x');
16382         } catch (e) {}
16383       });
16384
16385       assert.deepEqual(actual, expected);
16386     });
16387
16388     QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
16389       assert.expect(1);
16390
16391       var actual = func([], noop, undefined);
16392       assert.strictEqual(actual, undefined);
16393     });
16394
16395     QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is provided (test in IE > 9 and modern browsers)', function(assert) {
16396       assert.expect(2);
16397
16398       var array = [],
16399           object = { '0': 1, 'length': 0 };
16400
16401       if ('__proto__' in array) {
16402         array.__proto__ = object;
16403         assert.strictEqual(func(array, noop), undefined);
16404       }
16405       else {
16406         skipTest(assert);
16407       }
16408       assert.strictEqual(func(object, noop), undefined);
16409     });
16410
16411     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
16412       assert.expect(1);
16413
16414       if (!isNpm) {
16415         assert.strictEqual(_(array)[methodName](add), 6);
16416       }
16417       else {
16418         skipTest(assert);
16419       }
16420     });
16421
16422     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
16423       assert.expect(1);
16424
16425       if (!isNpm) {
16426         assert.ok(_(array).chain()[methodName](add) instanceof _);
16427       }
16428       else {
16429         skipTest(assert);
16430       }
16431     });
16432   });
16433
16434   /*--------------------------------------------------------------------------*/
16435
16436   QUnit.module('lodash.reject');
16437
16438   (function() {
16439     var array = [1, 2, 3];
16440
16441     QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
16442       assert.expect(1);
16443
16444       assert.deepEqual(_.reject(array, isEven), [1, 3]);
16445     });
16446   }());
16447
16448   /*--------------------------------------------------------------------------*/
16449
16450   QUnit.module('filter methods');
16451
16452   lodashStable.each(['filter', 'reject'], function(methodName) {
16453     var array = [1, 2, 3, 4],
16454         func = _[methodName],
16455         isFilter = methodName == 'filter',
16456         objects = [{ 'a': 0 }, { 'a': 1 }];
16457
16458     QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
16459       assert.expect(1);
16460
16461       var actual = func([0], function(num, index, array) {
16462         array[index] = 1;
16463         return isFilter;
16464       });
16465
16466       assert.deepEqual(actual, [0]);
16467     });
16468
16469     QUnit.test('`_.' + methodName + '` should work with a "_.property" style `predicate`', function(assert) {
16470       assert.expect(1);
16471
16472       assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
16473     });
16474
16475     QUnit.test('`_.' + methodName + '` should work with a "_.matches" style `predicate`', function(assert) {
16476       assert.expect(1);
16477
16478       assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
16479     });
16480
16481     QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
16482       assert.expect(2);
16483
16484       if (!isNpm) {
16485         var wrapped = _(array);
16486
16487         var actual = wrapped[methodName](function(num) {
16488           return num < 3;
16489         });
16490
16491         assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
16492
16493         actual = wrapped[methodName](function(num) {
16494           return num > 2;
16495         });
16496
16497         assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
16498       }
16499       else {
16500         skipTest(assert, 2);
16501       }
16502     });
16503
16504     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
16505       assert.expect(2);
16506
16507       if (!isNpm) {
16508         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
16509             predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
16510             actual = _(array).slice(1).map(square)[methodName](predicate).value();
16511
16512         assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
16513
16514         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
16515           return ['key' + index, index];
16516         }));
16517
16518         actual = _(object).mapValues(square)[methodName](predicate).value();
16519         assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
16520       }
16521       else {
16522         skipTest(assert, 2);
16523       }
16524     });
16525
16526     QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
16527       assert.expect(5);
16528
16529       if (!isNpm) {
16530         var args,
16531             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
16532             expected = [1, 0, lodashStable.map(array.slice(1), square)];
16533
16534         _(array).slice(1)[methodName](function(value, index, array) {
16535           args || (args = slice.call(arguments));
16536         }).value();
16537
16538         assert.deepEqual(args, [1, 0, array.slice(1)]);
16539
16540         args = undefined;
16541         _(array).slice(1).map(square)[methodName](function(value, index, array) {
16542           args || (args = slice.call(arguments));
16543         }).value();
16544
16545         assert.deepEqual(args, expected);
16546
16547         args = undefined;
16548         _(array).slice(1).map(square)[methodName](function(value, index) {
16549           args || (args = slice.call(arguments));
16550         }).value();
16551
16552         assert.deepEqual(args, expected);
16553
16554         args = undefined;
16555         _(array).slice(1).map(square)[methodName](function(value) {
16556           args || (args = slice.call(arguments));
16557         }).value();
16558
16559         assert.deepEqual(args, [1]);
16560
16561         args = undefined;
16562         _(array).slice(1).map(square)[methodName](function() {
16563           args || (args = slice.call(arguments));
16564         }).value();
16565
16566         assert.deepEqual(args, expected);
16567       }
16568       else {
16569         skipTest(assert, 5);
16570       }
16571     });
16572   });
16573
16574   /*--------------------------------------------------------------------------*/
16575
16576   QUnit.module('lodash.remove');
16577
16578   (function() {
16579     QUnit.test('should modify the array and return removed elements', function(assert) {
16580       assert.expect(2);
16581
16582       var array = [1, 2, 3];
16583
16584       var actual = _.remove(array, function(num) {
16585         return num < 3;
16586       });
16587
16588       assert.deepEqual(array, [3]);
16589       assert.deepEqual(actual, [1, 2]);
16590     });
16591
16592     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
16593       assert.expect(1);
16594
16595       var argsList = [],
16596           array = [1, 2, 3],
16597           clone = array.slice();
16598
16599       _.remove(array, function(value, index) {
16600         var args = slice.call(arguments);
16601         args[2] = args[2].slice();
16602         argsList.push(args);
16603         return isEven(index);
16604       });
16605
16606       assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
16607     });
16608
16609     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
16610       assert.expect(1);
16611
16612       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
16613       _.remove(objects, { 'a': 1 });
16614       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
16615     });
16616
16617     QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
16618       assert.expect(1);
16619
16620       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
16621       _.remove(objects, ['a', 1]);
16622       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
16623     });
16624
16625     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
16626       assert.expect(1);
16627
16628       var objects = [{ 'a': 0 }, { 'a': 1 }];
16629       _.remove(objects, 'a');
16630       assert.deepEqual(objects, [{ 'a': 0 }]);
16631     });
16632
16633     QUnit.test('should preserve holes in arrays', function(assert) {
16634       assert.expect(2);
16635
16636       var array = [1, 2, 3, 4];
16637       delete array[1];
16638       delete array[3];
16639
16640       _.remove(array, function(num) { return num === 1; });
16641       assert.notOk('0' in array);
16642       assert.notOk('2' in array);
16643     });
16644
16645     QUnit.test('should treat holes as `undefined`', function(assert) {
16646       assert.expect(1);
16647
16648       var array = [1, 2, 3];
16649       delete array[1];
16650
16651       _.remove(array, function(num) { return num == null; });
16652       assert.deepEqual(array, [1, 3]);
16653     });
16654
16655     QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
16656       assert.expect(1);
16657
16658       var array = [1, 2, 3];
16659       _.remove(array, function(num, index) { return isEven(index); });
16660       assert.deepEqual(array, [2]);
16661     });
16662   }());
16663
16664   /*--------------------------------------------------------------------------*/
16665
16666   QUnit.module('lodash.repeat');
16667
16668   (function() {
16669     QUnit.test('should repeat a string `n` times', function(assert) {
16670       assert.expect(2);
16671
16672       assert.strictEqual(_.repeat('*', 3), '***');
16673       assert.strictEqual(_.repeat('abc', 2), 'abcabc');
16674     });
16675
16676     QUnit.test('should return an empty string for negative `n` or `n` of `0`', function(assert) {
16677       assert.expect(2);
16678
16679       assert.strictEqual(_.repeat('abc', 0), '');
16680       assert.strictEqual(_.repeat('abc', -2), '');
16681     });
16682
16683     QUnit.test('should coerce `n` to an integer', function(assert) {
16684       assert.expect(4);
16685
16686       assert.strictEqual(_.repeat('abc'), '');
16687       assert.strictEqual(_.repeat('abc', '2'), 'abcabc');
16688       assert.strictEqual(_.repeat('abc', 2.6), 'abcabc');
16689       assert.strictEqual(_.repeat('*', { 'valueOf': alwaysThree }), '***');
16690     });
16691
16692     QUnit.test('should coerce `string` to a string', function(assert) {
16693       assert.expect(2);
16694
16695       assert.strictEqual(_.repeat(Object('abc'), 2), 'abcabc');
16696       assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
16697     });
16698   }());
16699
16700   /*--------------------------------------------------------------------------*/
16701
16702   QUnit.module('lodash.replace');
16703
16704   (function() {
16705     QUnit.test('should replace the matched pattern', function(assert) {
16706       assert.expect(2);
16707
16708       var string = 'abcdef';
16709       assert.strictEqual(_.replace(string, 'def', '123'), 'abc123');
16710       assert.strictEqual(_.replace(string, /[bdf]/g, '-'), 'a-c-e-');
16711     });
16712   }());
16713
16714   /*--------------------------------------------------------------------------*/
16715
16716   QUnit.module('lodash.result');
16717
16718   (function() {
16719     var object = {
16720       'a': 1,
16721       'b': function() { return this.a; }
16722     };
16723
16724     QUnit.test('should invoke function values', function(assert) {
16725       assert.expect(1);
16726
16727       assert.strictEqual(_.result(object, 'b'), 1);
16728     });
16729
16730     QUnit.test('should invoke default function values', function(assert) {
16731       assert.expect(1);
16732
16733       var actual = _.result(object, 'c', object.b);
16734       assert.strictEqual(actual, 1);
16735     });
16736
16737     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
16738       assert.expect(2);
16739
16740       var value = { 'a': object };
16741
16742       lodashStable.each(['a.b', ['a', 'b']], function(path) {
16743         assert.strictEqual(_.result(value, path), 1);
16744       });
16745     });
16746   }());
16747
16748   /*--------------------------------------------------------------------------*/
16749
16750   QUnit.module('lodash.get and lodash.result');
16751
16752   lodashStable.each(['get', 'result'], function(methodName) {
16753     var func = _[methodName];
16754
16755     QUnit.test('`_.' + methodName + '` should get property values', function(assert) {
16756       assert.expect(2);
16757
16758       var object = { 'a': 1 };
16759
16760       lodashStable.each(['a', ['a']], function(path) {
16761         assert.strictEqual(func(object, path), 1);
16762       });
16763     });
16764
16765     QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
16766       assert.expect(2);
16767
16768       var object = { 'a': { 'b': { 'c': 3 } } };
16769
16770       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
16771         assert.strictEqual(func(object, path), 3);
16772       });
16773     });
16774
16775     QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
16776       assert.expect(2);
16777
16778       var object = { 'a.b.c': 3, 'a': { 'b': { 'c': 4 } } };
16779
16780       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
16781         assert.strictEqual(func(object, path), 3);
16782       });
16783     });
16784
16785     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
16786       assert.expect(1);
16787
16788       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
16789       assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
16790     });
16791
16792     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
16793       assert.expect(1);
16794
16795       var object = { 'a': 1 };
16796       assert.strictEqual(func(object, 'a[]'), 1);
16797     });
16798
16799     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
16800       assert.expect(4);
16801
16802       lodashStable.each([['', ''], [[], ['']]], function(pair) {
16803         assert.strictEqual(func({}, pair[0]), undefined);
16804         assert.strictEqual(func({ '': 3 }, pair[1]), 3);
16805       });
16806     });
16807
16808     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
16809       assert.expect(2);
16810
16811       var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
16812
16813       var paths = [
16814         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
16815         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
16816       ];
16817
16818       lodashStable.each(paths, function(path) {
16819         assert.strictEqual(func(object, path), 8);
16820       });
16821     });
16822
16823     QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
16824       assert.expect(4);
16825
16826       lodashStable.each(['constructor', ['constructor']], function(path) {
16827         assert.strictEqual(func(null, path), undefined);
16828         assert.strictEqual(func(undefined, path), undefined);
16829       });
16830     });
16831
16832     QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
16833       assert.expect(2);
16834
16835       var values = [null, undefined],
16836           expected = lodashStable.map(values, alwaysUndefined),
16837           paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
16838
16839       lodashStable.each(paths, function(path) {
16840         var actual = lodashStable.map(values, function(value) {
16841           return func(value, path);
16842         });
16843
16844         assert.deepEqual(actual, expected);
16845       });
16846     });
16847
16848     QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
16849       assert.expect(2);
16850
16851       var object = { 'a': [, null] };
16852
16853       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
16854         assert.strictEqual(func(object, path), undefined);
16855       });
16856     });
16857
16858     QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
16859       assert.expect(2);
16860
16861       var object = { 'a': { 'b': null } };
16862
16863       lodashStable.each(['a.b', ['a', 'b']], function(path) {
16864         assert.strictEqual(func(object, path), null);
16865       });
16866     });
16867
16868     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
16869       assert.expect(4);
16870
16871       var object = { 'a': '' },
16872           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
16873
16874       lodashStable.each(paths, function(path) {
16875         numberProto.a = 1;
16876
16877         var actual = func(0, path);
16878         assert.strictEqual(actual, 1);
16879
16880         delete numberProto.a;
16881       });
16882
16883       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
16884         stringProto.replace.b = 1;
16885
16886         var actual = func(object, path);
16887         assert.strictEqual(actual, 1);
16888
16889         delete stringProto.replace.b;
16890       });
16891     });
16892
16893     QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
16894       assert.expect(1);
16895
16896       var object = { 'a': {} },
16897           values = empties.concat(true, new Date, 1, /x/, 'a');
16898
16899       var expected = lodashStable.transform(values, function(result, value) {
16900         result.push(value, value, value, value);
16901       });
16902
16903       var actual = lodashStable.transform(values, function(result, value) {
16904         lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
16905           result.push(
16906             func(object, path, value),
16907             func(null, path, value)
16908           );
16909         });
16910       });
16911
16912       assert.deepEqual(actual, expected);
16913     });
16914   });
16915
16916   /*--------------------------------------------------------------------------*/
16917
16918   QUnit.module('lodash.rest');
16919
16920   (function() {
16921     function fn(a, b, c) {
16922       return slice.call(arguments);
16923     }
16924
16925     QUnit.test('should apply a rest parameter to `func`', function(assert) {
16926       assert.expect(1);
16927
16928       var rp = _.rest(fn);
16929       assert.deepEqual(rp(1, 2, 3, 4), [1, 2, [3, 4]]);
16930     });
16931
16932     QUnit.test('should work with `start`', function(assert) {
16933       assert.expect(1);
16934
16935       var rp = _.rest(fn, 1);
16936       assert.deepEqual(rp(1, 2, 3, 4), [1, [2, 3, 4]]);
16937     });
16938
16939     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
16940       assert.expect(1);
16941
16942       var values = [-1, NaN, 'a'],
16943           expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
16944
16945       var actual = lodashStable.map(values, function(value) {
16946         var rp = _.rest(fn, value);
16947         return rp(1, 2, 3, 4);
16948       });
16949
16950       assert.deepEqual(actual, expected);
16951     });
16952
16953     QUnit.test('should coerce `start` to an integer', function(assert) {
16954       assert.expect(1);
16955
16956       var rp = _.rest(fn, 1.6);
16957       assert.deepEqual(rp(1, 2, 3), [1, [2, 3]]);
16958     });
16959
16960     QUnit.test('should use an empty array when `start` is not reached', function(assert) {
16961       assert.expect(1);
16962
16963       var rp = _.rest(fn);
16964       assert.deepEqual(rp(1), [1, undefined, []]);
16965     });
16966
16967     QUnit.test('should work on functions with more than three parameters', function(assert) {
16968       assert.expect(1);
16969
16970       var rp = _.rest(function(a, b, c, d) {
16971         return slice.call(arguments);
16972       });
16973
16974       assert.deepEqual(rp(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
16975     });
16976   }());
16977
16978   /*--------------------------------------------------------------------------*/
16979
16980   QUnit.module('lodash.reverse');
16981
16982   (function() {
16983     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
16984         smallArray = [0, 1, 2, null];
16985
16986     QUnit.test('should reverse `array`', function(assert) {
16987       assert.expect(2);
16988
16989       var array = [1, 2, 3],
16990           actual = _.reverse(array);
16991
16992       assert.deepEqual(array, [3, 2, 1]);
16993       assert.strictEqual(actual, array);
16994     });
16995
16996     QUnit.test('should return the wrapped reversed `array`', function(assert) {
16997       assert.expect(6);
16998
16999       if (!isNpm) {
17000         lodashStable.times(2, function(index) {
17001           var array = (index ? largeArray : smallArray).slice(),
17002               clone = array.slice(),
17003               wrapped = _(array).reverse(),
17004               actual = wrapped.value();
17005
17006           assert.ok(wrapped instanceof _);
17007           assert.strictEqual(actual, array);
17008           assert.deepEqual(actual, clone.slice().reverse());
17009         });
17010       }
17011       else {
17012         skipTest(assert, 6);
17013       }
17014     });
17015
17016     QUnit.test('should work in a lazy sequence', function(assert) {
17017       assert.expect(4);
17018
17019       if (!isNpm) {
17020         lodashStable.times(2, function(index) {
17021           var array = (index ? largeArray : smallArray).slice(),
17022               expected = array.slice(),
17023               actual = _(array).slice(1).reverse().value();
17024
17025           assert.deepEqual(actual, expected.slice(1).reverse());
17026           assert.deepEqual(array, expected);
17027         });
17028       }
17029       else {
17030         skipTest(assert, 4);
17031       }
17032     });
17033
17034     QUnit.test('should be lazy when in a lazy sequence', function(assert) {
17035       assert.expect(3);
17036
17037       if (!isNpm) {
17038         var spy = {
17039           'toString': function() {
17040             throw new Error('spy was revealed');
17041           }
17042         };
17043
17044         var array = largeArray.concat(spy),
17045             expected = array.slice();
17046
17047         try {
17048           var wrapped = _(array).slice(1).map(String).reverse(),
17049               actual = wrapped.last();
17050         } catch (e) {}
17051
17052         assert.ok(wrapped instanceof _);
17053         assert.strictEqual(actual, '1');
17054         assert.deepEqual(array, expected);
17055       }
17056       else {
17057         skipTest(assert, 3);
17058       }
17059     });
17060
17061     QUnit.test('should work in a hybrid sequence', function(assert) {
17062       assert.expect(8);
17063
17064       if (!isNpm) {
17065         lodashStable.times(2, function(index) {
17066           var clone = (index ? largeArray : smallArray).slice();
17067
17068           lodashStable.each(['map', 'filter'], function(methodName) {
17069             var array = clone.slice(),
17070                 expected = clone.slice(1, -1).reverse(),
17071                 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
17072
17073             assert.deepEqual(actual, expected);
17074
17075             array = clone.slice();
17076             actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
17077
17078             assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
17079           });
17080         });
17081       }
17082       else {
17083         skipTest(assert, 8);
17084       }
17085     });
17086
17087     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
17088       assert.expect(6);
17089
17090       if (!isNpm) {
17091         lodashStable.times(2, function(index) {
17092           var array = (index ? largeArray : smallArray).slice(),
17093               expected = array.slice().reverse(),
17094               wrapped = _(array).chain().reverse().head();
17095
17096           assert.ok(wrapped instanceof _);
17097           assert.strictEqual(wrapped.value(), _.head(expected));
17098           assert.deepEqual(array, expected);
17099         });
17100       }
17101       else {
17102         skipTest(assert, 6);
17103       }
17104     });
17105   }());
17106
17107   /*--------------------------------------------------------------------------*/
17108
17109   QUnit.module('round methods');
17110
17111   lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
17112     var func = _[methodName],
17113         isCeil = methodName == 'ceil',
17114         isFloor = methodName == 'floor';
17115
17116     QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
17117       assert.expect(1);
17118
17119       var actual = func(4.006);
17120       assert.strictEqual(actual, isCeil ? 5 : 4);
17121     });
17122
17123     QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
17124       assert.expect(1);
17125
17126       var actual = func(4.006, 0);
17127       assert.strictEqual(actual, isCeil ? 5 : 4);
17128     });
17129
17130     QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
17131       assert.expect(2);
17132
17133       var actual = func(4.016, 2);
17134       assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
17135
17136       actual = func(4.1, 2);
17137       assert.strictEqual(actual, 4.1);
17138     });
17139
17140     QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
17141       assert.expect(1);
17142
17143       var actual = func(4160, -2);
17144       assert.strictEqual(actual, isFloor ? 4100 : 4200);
17145     });
17146
17147     QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
17148       assert.expect(3);
17149
17150       var actual = func(4.006, NaN);
17151       assert.strictEqual(actual, isCeil ? 5 : 4);
17152
17153       var expected = isFloor ? 4.01 : 4.02;
17154
17155       actual = func(4.016, 2.6);
17156       assert.strictEqual(actual, expected);
17157
17158       actual = func(4.016, '+2');
17159       assert.strictEqual(actual, expected);
17160     });
17161
17162     QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
17163       assert.expect(3);
17164
17165       var actual = func(5e1, 2);
17166       assert.deepEqual(actual, 50);
17167
17168       actual = func('5e', 1);
17169       assert.deepEqual(actual, NaN);
17170
17171       actual = func('5e1e1', 1);
17172       assert.deepEqual(actual, NaN);
17173     });
17174
17175     QUnit.test('`_.' + methodName + '` should preserve sign of `0`', function(assert) {
17176       assert.expect(1);
17177
17178       var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
17179           expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
17180
17181       var actual = lodashStable.map(values, function(args) {
17182         return 1 / func.apply(undefined, args);
17183       });
17184
17185       assert.deepEqual(actual, expected);
17186     });
17187   });
17188
17189   /*--------------------------------------------------------------------------*/
17190
17191   QUnit.module('lodash.runInContext');
17192
17193   (function() {
17194     QUnit.test('should not require a fully populated `context` object', function(assert) {
17195       assert.expect(1);
17196
17197       if (!isModularize) {
17198         var lodash = _.runInContext({
17199           'setTimeout': function(callback) {
17200             callback();
17201           }
17202         });
17203
17204         var pass = false;
17205         lodash.delay(function() { pass = true; }, 32);
17206         assert.ok(pass);
17207       }
17208       else {
17209         skipTest(assert);
17210       }
17211     });
17212
17213     QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
17214       assert.expect(3);
17215
17216       if (!isModularize) {
17217         lodashStable.times(2, _.uniqueId);
17218
17219         var oldId = Number(_.uniqueId()),
17220             lodash = _.runInContext();
17221
17222         assert.ok(_.uniqueId() > oldId);
17223
17224         var id = lodash.uniqueId();
17225         assert.strictEqual(id, '1');
17226         assert.ok(id < oldId);
17227       }
17228       else {
17229         skipTest(assert, 3);
17230       }
17231     });
17232   }());
17233
17234   /*--------------------------------------------------------------------------*/
17235
17236   QUnit.module('lodash.sample');
17237
17238   (function() {
17239     var array = [1, 2, 3];
17240
17241     QUnit.test('should return a random element', function(assert) {
17242       assert.expect(1);
17243
17244       var actual = _.sample(array);
17245       assert.ok(lodashStable.includes(array, actual));
17246     });
17247
17248     QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
17249       assert.expect(1);
17250
17251       var expected = lodashStable.map(empties, alwaysUndefined);
17252
17253       var actual = lodashStable.transform(empties, function(result, value) {
17254         try {
17255           result.push(_.sample(value));
17256         } catch (e) {}
17257       });
17258
17259       assert.deepEqual(actual, expected);
17260     });
17261
17262     QUnit.test('should sample an object', function(assert) {
17263       assert.expect(1);
17264
17265       var object = { 'a': 1, 'b': 2, 'c': 3 },
17266           actual = _.sample(object);
17267
17268       assert.ok(lodashStable.includes(array, actual));
17269     });
17270   }());
17271
17272   /*--------------------------------------------------------------------------*/
17273
17274   QUnit.module('lodash.sampleSize');
17275
17276   (function() {
17277     var array = [1, 2, 3];
17278
17279     QUnit.test('should return an array of random elements', function(assert) {
17280       assert.expect(2);
17281
17282       var actual = _.sampleSize(array, 2);
17283       assert.strictEqual(actual.length, 2);
17284       assert.deepEqual(lodashStable.difference(actual, array), []);
17285     });
17286
17287     QUnit.test('should contain elements of the collection', function(assert) {
17288       assert.expect(1);
17289
17290       var actual = _.sampleSize(array, array.length);
17291       assert.deepEqual(actual.sort(), array);
17292     });
17293
17294     QUnit.test('should treat falsey `n` values as `0`', function(assert) {
17295       assert.expect(1);
17296
17297       var expected = lodashStable.map(falsey, alwaysEmptyArray);
17298
17299       var actual = lodashStable.map(falsey, function(n, index) {
17300         return index ? _.sampleSize([1], n) : _.sampleSize([1]);
17301       });
17302
17303       assert.deepEqual(actual, expected);
17304     });
17305
17306     QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
17307       assert.expect(3);
17308
17309       lodashStable.each([0, -1, -Infinity], function(n) {
17310         assert.deepEqual(_.sampleSize(array, n), []);
17311       });
17312     });
17313
17314     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
17315       assert.expect(4);
17316
17317       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
17318         assert.deepEqual(_.sampleSize(array, n).sort(), array);
17319       });
17320     });
17321
17322     QUnit.test('should coerce `n` to an integer', function(assert) {
17323       assert.expect(1);
17324
17325       var actual = _.sampleSize(array, 1.6);
17326       assert.strictEqual(actual.length, 1);
17327     });
17328
17329     QUnit.test('should return an empty array for empty collections', function(assert) {
17330       assert.expect(1);
17331
17332       var expected = lodashStable.map(empties, alwaysEmptyArray);
17333
17334       var actual = lodashStable.transform(empties, function(result, value) {
17335         try {
17336           result.push(_.sampleSize(value, 1));
17337         } catch (e) {}
17338       });
17339
17340       assert.deepEqual(actual, expected);
17341     });
17342
17343     QUnit.test('should sample an object', function(assert) {
17344       assert.expect(2);
17345
17346       var object = { 'a': 1, 'b': 2, 'c': 3 },
17347           actual = _.sampleSize(object, 2);
17348
17349       assert.strictEqual(actual.length, 2);
17350       assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
17351     });
17352   }());
17353
17354   /*--------------------------------------------------------------------------*/
17355
17356   QUnit.module('lodash.setWith');
17357
17358   (function() {
17359     QUnit.test('should work with a `customizer` callback', function(assert) {
17360       assert.expect(1);
17361
17362       var actual = _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, function(value) {
17363         if (!lodashStable.isObject(value)) {
17364           return {};
17365         }
17366       });
17367
17368       assert.deepEqual(actual, { '0': { '1': { '2': 3 }, 'length': 2 } });
17369     });
17370
17371     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
17372       assert.expect(1);
17373
17374       var actual = _.setWith({}, 'a[0].b.c', 4, alwaysUndefined);
17375       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
17376     });
17377   }());
17378
17379   /*--------------------------------------------------------------------------*/
17380
17381   QUnit.module('set methods');
17382
17383   lodashStable.each(['set', 'setWith'], function(methodName) {
17384     var func = _[methodName];
17385
17386     QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
17387       assert.expect(4);
17388
17389       var object = { 'a': 1 };
17390
17391       lodashStable.each(['a', ['a']], function(path) {
17392         var actual = func(object, path, 2);
17393
17394         assert.strictEqual(actual, object);
17395         assert.strictEqual(object.a, 2);
17396
17397         object.a = 1;
17398       });
17399     });
17400
17401     QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
17402       assert.expect(4);
17403
17404       var object = { 'a': { 'b': { 'c': 3 } } };
17405
17406       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
17407         var actual = func(object, path, 4);
17408
17409         assert.strictEqual(actual, object);
17410         assert.strictEqual(object.a.b.c, 4);
17411
17412         object.a.b.c = 3;
17413       });
17414     });
17415
17416     QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
17417       assert.expect(4);
17418
17419       var object = { 'a.b.c': 3 };
17420
17421       lodashStable.each(['a.b.c', ['a.b.c']], function(path) {
17422         var actual = func(object, path, 4);
17423
17424         assert.strictEqual(actual, object);
17425         assert.deepEqual(object, { 'a.b.c': 4 });
17426
17427         object['a.b.c'] = 3;
17428       });
17429     });
17430
17431     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
17432       assert.expect(1);
17433
17434       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 3 } } };
17435       func(object, ['a', 'b', 'c'], 4);
17436       assert.strictEqual(object.a.b.c, 4);
17437     });
17438
17439     QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
17440       assert.expect(1);
17441
17442       var object = {};
17443       func(object, 'a[]', 1);
17444       assert.deepEqual(object, { 'a': 1 });
17445     });
17446
17447     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
17448       assert.expect(4);
17449
17450       lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
17451         var object = {};
17452
17453         func(object, pair[0], 1);
17454         assert.deepEqual(object, index ? {} : { '': 1 });
17455
17456         func(object, pair[1], 2);
17457         assert.deepEqual(object, { '': 2 });
17458       });
17459     });
17460
17461     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
17462       assert.expect(2);
17463
17464       var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
17465
17466       var paths = [
17467         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
17468         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
17469       ];
17470
17471       lodashStable.each(paths, function(path) {
17472         func(object, path, 10);
17473         assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, 10);
17474         object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = 8;
17475       });
17476     });
17477
17478     QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
17479       assert.expect(6);
17480
17481       var object = {};
17482
17483       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
17484         var actual = func(object, path, 4);
17485
17486         assert.strictEqual(actual, object);
17487         assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': 4 } }] });
17488         assert.notOk('0' in object.a);
17489
17490         delete object.a;
17491       });
17492     });
17493
17494     QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
17495       assert.expect(1);
17496
17497       var values = [null, undefined],
17498           expected = [[null, null], [undefined, undefined]];
17499
17500       var actual = lodashStable.map(values, function(value) {
17501         try {
17502           return [func(value, 'a.b', 1), func(value, ['a', 'b'], 1)];
17503         } catch (e) {
17504           return e.message;
17505         }
17506       });
17507
17508       assert.deepEqual(actual, expected);
17509     });
17510
17511     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
17512       assert.expect(4);
17513
17514       var object = { 'a': '' },
17515           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
17516
17517       lodashStable.each(paths, function(path) {
17518         func(0, path, 1);
17519         assert.strictEqual(0..a, 1);
17520         delete numberProto.a;
17521       });
17522
17523       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
17524         func(object, path, 1);
17525         assert.strictEqual(stringProto.replace.b, 1);
17526         delete stringProto.replace.b;
17527       });
17528     });
17529
17530     QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
17531       'use strict';
17532
17533       assert.expect(2);
17534
17535       numberProto.a = 0;
17536
17537       lodashStable.each(['a', 'a.a.a'], function(path) {
17538         try {
17539           func(0, path, 1);
17540           assert.strictEqual(0..a, 0);
17541         } catch (e) {
17542           assert.ok(false, e.message);
17543         }
17544         numberProto.a = 0;
17545       });
17546
17547       delete numberProto.a;
17548     });
17549
17550     QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
17551       assert.expect(1);
17552
17553       var object = {};
17554
17555       func(object, ['1a', '2b', '3c'], 1);
17556       assert.deepEqual(object, { '1a': { '2b': { '3c': 1 } } });
17557     });
17558
17559     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
17560       assert.expect(4);
17561
17562       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
17563         if (defineProperty) {
17564           var object = {},
17565               pass = true;
17566
17567           defineProperty(object, 'a', {
17568             'enumerable': true,
17569             'configurable': true,
17570             'get': lodashStable.constant(value),
17571             'set': function() { pass = false; }
17572           });
17573
17574           func(object, 'a', value);
17575           assert.ok(pass);
17576         }
17577         else {
17578           skipTest(assert);
17579         }
17580       });
17581     });
17582   });
17583
17584   /*--------------------------------------------------------------------------*/
17585
17586   QUnit.module('lodash.shuffle');
17587
17588   (function() {
17589     var array = [1, 2, 3],
17590         object = { 'a': 1, 'b': 2, 'c': 3 };
17591
17592     QUnit.test('should return a new array', function(assert) {
17593       assert.expect(1);
17594
17595       assert.notStrictEqual(_.shuffle(array), array);
17596     });
17597
17598     QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
17599       assert.expect(2);
17600
17601       assert.deepEqual(_.shuffle(array).sort(), array);
17602       assert.deepEqual(_.shuffle(object).sort(), array);
17603     });
17604
17605     QUnit.test('should shuffle small collections', function(assert) {
17606       assert.expect(1);
17607
17608       var uniqBy = lodashStable.uniqBy || lodashStable.uniq;
17609
17610       var actual = lodashStable.times(1000, function(assert) {
17611         return _.shuffle([1, 2]);
17612       });
17613
17614       assert.deepEqual(lodashStable.sortBy(uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
17615     });
17616
17617     QUnit.test('should treat number values for `collection` as empty', function(assert) {
17618       assert.expect(1);
17619
17620       assert.deepEqual(_.shuffle(1), []);
17621     });
17622   }());
17623
17624   /*--------------------------------------------------------------------------*/
17625
17626   QUnit.module('lodash.size');
17627
17628   (function() {
17629     var args = arguments,
17630         array = [1, 2, 3];
17631
17632     QUnit.test('should return the number of own enumerable properties of an object', function(assert) {
17633       assert.expect(1);
17634
17635       assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
17636     });
17637
17638     QUnit.test('should return the length of an array', function(assert) {
17639       assert.expect(1);
17640
17641       assert.strictEqual(_.size(array), 3);
17642     });
17643
17644     QUnit.test('should accept a falsey `object` argument', function(assert) {
17645       assert.expect(1);
17646
17647       var expected = lodashStable.map(falsey, alwaysZero);
17648
17649       var actual = lodashStable.map(falsey, function(object, index) {
17650         try {
17651           return index ? _.size(object) : _.size();
17652         } catch (e) {}
17653       });
17654
17655       assert.deepEqual(actual, expected);
17656     });
17657
17658     QUnit.test('should work with `arguments` objects', function(assert) {
17659       assert.expect(1);
17660
17661       assert.strictEqual(_.size(args), 3);
17662     });
17663
17664     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
17665       assert.expect(1);
17666
17667       function Foo(elements) { push.apply(this, elements); }
17668       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
17669
17670       assert.strictEqual(_.size(new Foo(array)), 3);
17671     });
17672
17673     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
17674       assert.expect(1);
17675
17676       assert.strictEqual(_.size({ 'length': -1 }), 1);
17677     });
17678
17679     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
17680       assert.expect(1);
17681
17682       assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
17683     });
17684
17685     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
17686       assert.expect(1);
17687
17688       assert.strictEqual(_.size({ 'length': '0' }), 1);
17689     });
17690   }(1, 2, 3));
17691
17692   /*--------------------------------------------------------------------------*/
17693
17694   QUnit.module('lodash.slice');
17695
17696   (function() {
17697     var array = [1, 2, 3];
17698
17699     QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
17700       assert.expect(2);
17701
17702       var actual = _.slice(array);
17703       assert.deepEqual(actual, array);
17704       assert.notStrictEqual(actual, array);
17705     });
17706
17707     QUnit.test('should work with a positive `start`', function(assert) {
17708       assert.expect(2);
17709
17710       assert.deepEqual(_.slice(array, 1), [2, 3]);
17711       assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
17712     });
17713
17714     QUnit.test('should work with a `start` >= `array.length`', function(assert) {
17715       assert.expect(4);
17716
17717       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
17718         assert.deepEqual(_.slice(array, start), []);
17719       });
17720     });
17721
17722     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
17723       assert.expect(1);
17724
17725       var expected = lodashStable.map(falsey, lodashStable.constant(array));
17726
17727       var actual = lodashStable.map(falsey, function(start) {
17728         return _.slice(array, start);
17729       });
17730
17731       assert.deepEqual(actual, expected);
17732     });
17733
17734     QUnit.test('should work with a negative `start`', function(assert) {
17735       assert.expect(1);
17736
17737       assert.deepEqual(_.slice(array, -1), [3]);
17738     });
17739
17740     QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
17741       assert.expect(3);
17742
17743       lodashStable.each([-3, -4, -Infinity], function(start) {
17744         assert.deepEqual(_.slice(array, start), array);
17745       });
17746     });
17747
17748     QUnit.test('should work with `start` >= `end`', function(assert) {
17749       assert.expect(2);
17750
17751       lodashStable.each([2, 3], function(start) {
17752         assert.deepEqual(_.slice(array, start, 2), []);
17753       });
17754     });
17755
17756     QUnit.test('should work with a positive `end`', function(assert) {
17757       assert.expect(1);
17758
17759       assert.deepEqual(_.slice(array, 0, 1), [1]);
17760     });
17761
17762     QUnit.test('should work with a `end` >= `array.length`', function(assert) {
17763       assert.expect(4);
17764
17765       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
17766         assert.deepEqual(_.slice(array, 0, end), array);
17767       });
17768     });
17769
17770     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
17771       assert.expect(1);
17772
17773       var expected = lodashStable.map(falsey, function(value) {
17774         return value === undefined ? array : [];
17775       });
17776
17777       var actual = lodashStable.map(falsey, function(end) {
17778         return _.slice(array, 0, end);
17779       });
17780
17781       assert.deepEqual(actual, expected);
17782     });
17783
17784     QUnit.test('should work with a negative `end`', function(assert) {
17785       assert.expect(1);
17786
17787       assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
17788     });
17789
17790     QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
17791       assert.expect(3);
17792
17793       lodashStable.each([-3, -4, -Infinity], function(end) {
17794         assert.deepEqual(_.slice(array, 0, end), []);
17795       });
17796     });
17797
17798     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
17799       assert.expect(1);
17800
17801       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
17802
17803       var actual = lodashStable.map(positions, function(pos) {
17804         return _.slice.apply(_, [array].concat(pos));
17805       });
17806
17807       assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
17808     });
17809
17810     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17811       assert.expect(2);
17812
17813       var array = [[1], [2, 3]],
17814           actual = lodashStable.map(array, _.slice);
17815
17816       assert.deepEqual(actual, array);
17817       assert.notStrictEqual(actual, array);
17818     });
17819
17820     QUnit.test('should work in a lazy sequence', function(assert) {
17821       assert.expect(38);
17822
17823       if (!isNpm) {
17824         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
17825             length = array.length,
17826             wrapped = _(array);
17827
17828         lodashStable.each(['map', 'filter'], function(methodName) {
17829           assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
17830           assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
17831           assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
17832           assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
17833
17834           assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
17835           assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
17836           assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
17837           assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
17838
17839           assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
17840           assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
17841           assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
17842
17843           assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
17844           assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
17845
17846           assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
17847           assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
17848           assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
17849           assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
17850           assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
17851           assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
17852         });
17853       }
17854       else {
17855         skipTest(assert, 38);
17856       }
17857     });
17858   }());
17859
17860   /*--------------------------------------------------------------------------*/
17861
17862   QUnit.module('lodash.some');
17863
17864   (function() {
17865     QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
17866       assert.expect(2);
17867
17868       assert.strictEqual(_.some([false, 1, ''], identity), true);
17869       assert.strictEqual(_.some([null, 'a', 0], identity), true);
17870     });
17871
17872     QUnit.test('should return `false` for empty collections', function(assert) {
17873       assert.expect(1);
17874
17875       var expected = lodashStable.map(empties, alwaysFalse);
17876
17877       var actual = lodashStable.map(empties, function(value) {
17878         try {
17879           return _.some(value, identity);
17880         } catch (e) {}
17881       });
17882
17883       assert.deepEqual(actual, expected);
17884     });
17885
17886     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
17887       assert.expect(2);
17888
17889       var count = 0;
17890
17891       assert.strictEqual(_.some([null, true, null], function(value) {
17892         count++;
17893         return value;
17894       }), true);
17895
17896       assert.strictEqual(count, 2);
17897     });
17898
17899     QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
17900       assert.expect(2);
17901
17902       assert.strictEqual(_.some([false, false, false], identity), false);
17903       assert.strictEqual(_.some([null, 0, ''], identity), false);
17904     });
17905
17906     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17907       assert.expect(2);
17908
17909       var values = [, null, undefined],
17910           expected = lodashStable.map(values, alwaysFalse);
17911
17912       var actual = lodashStable.map(values, function(value, index) {
17913         var array = [0, 0];
17914         return index ? _.some(array, value) : _.some(array);
17915       });
17916
17917       assert.deepEqual(actual, expected);
17918
17919       expected = lodashStable.map(values, alwaysTrue);
17920       actual = lodashStable.map(values, function(value, index) {
17921         var array = [0, 1];
17922         return index ? _.some(array, value) : _.some(array);
17923       });
17924
17925       assert.deepEqual(actual, expected);
17926     });
17927
17928     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
17929       assert.expect(2);
17930
17931       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
17932       assert.strictEqual(_.some(objects, 'a'), false);
17933       assert.strictEqual(_.some(objects, 'b'), true);
17934     });
17935
17936     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
17937       assert.expect(2);
17938
17939       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
17940       assert.strictEqual(_.some(objects, { 'a': 0 }), true);
17941       assert.strictEqual(_.some(objects, { 'b': 2 }), false);
17942     });
17943
17944     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17945       assert.expect(1);
17946
17947       var actual = lodashStable.map([[1]], _.some);
17948       assert.deepEqual(actual, [true]);
17949     });
17950   }());
17951
17952   /*--------------------------------------------------------------------------*/
17953
17954   QUnit.module('lodash.sortBy');
17955
17956   (function() {
17957     var objects = [
17958       { 'a': 'x', 'b': 3 },
17959       { 'a': 'y', 'b': 4 },
17960       { 'a': 'x', 'b': 1 },
17961       { 'a': 'y', 'b': 2 }
17962     ];
17963
17964     QUnit.test('should sort in ascending order', function(assert) {
17965       assert.expect(1);
17966
17967       var actual = lodashStable.map(_.sortBy(objects, function(object) {
17968         return object.b;
17969       }), 'b');
17970
17971       assert.deepEqual(actual, [1, 2, 3, 4]);
17972     });
17973
17974     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
17975       assert.expect(1);
17976
17977       var array = [3, 2, 1],
17978           values = [, null, undefined],
17979           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
17980
17981       var actual = lodashStable.map(values, function(value, index) {
17982         return index ? _.sortBy(array, value) : _.sortBy(array);
17983       });
17984
17985       assert.deepEqual(actual, expected);
17986     });
17987
17988     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
17989       assert.expect(1);
17990
17991       var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
17992       assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
17993     });
17994
17995     QUnit.test('should work with an object for `collection`', function(assert) {
17996       assert.expect(1);
17997
17998       var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, function(num) {
17999         return Math.sin(num);
18000       });
18001
18002       assert.deepEqual(actual, [3, 1, 2]);
18003     });
18004
18005     QUnit.test('should move `null`, `undefined`, and `NaN` values to the end', function(assert) {
18006       assert.expect(2);
18007
18008       var array = [NaN, undefined, null, 4, null, 1, undefined, 3, NaN, 2];
18009       assert.deepEqual(_.sortBy(array), [1, 2, 3, 4, null, null, undefined, undefined, NaN, NaN]);
18010
18011       array = [NaN, undefined, null, 'd', null, 'a', undefined, 'c', NaN, 'b'];
18012       assert.deepEqual(_.sortBy(array), ['a', 'b', 'c', 'd', null, null, undefined, undefined, NaN, NaN]);
18013     });
18014
18015     QUnit.test('should treat number values for `collection` as empty', function(assert) {
18016       assert.expect(1);
18017
18018       assert.deepEqual(_.sortBy(1), []);
18019     });
18020
18021     QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
18022       assert.expect(1);
18023
18024       var actual = _.sortBy(objects, function(object) {
18025         var result = [object.a, object.b];
18026         result.toString = function() { return String(this[0]); };
18027         return result;
18028       });
18029
18030       assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
18031     });
18032
18033     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18034       assert.expect(1);
18035
18036       var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
18037       assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
18038     });
18039   }());
18040
18041   /*--------------------------------------------------------------------------*/
18042
18043   QUnit.module('sortBy methods');
18044
18045   lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
18046     var func = _[methodName];
18047
18048     function Pair(a, b, c) {
18049       this.a = a;
18050       this.b = b;
18051       this.c = c;
18052     }
18053
18054     var objects = [
18055       { 'a': 'x', 'b': 3 },
18056       { 'a': 'y', 'b': 4 },
18057       { 'a': 'x', 'b': 1 },
18058       { 'a': 'y', 'b': 2 }
18059     ];
18060
18061     var stableArray = [
18062       new Pair(1, 1, 1), new Pair(1, 2, 1),
18063       new Pair(1, 1, 1), new Pair(1, 2, 1),
18064       new Pair(1, 3, 1), new Pair(1, 4, 1),
18065       new Pair(1, 5, 1), new Pair(1, 6, 1),
18066       new Pair(2, 1, 2), new Pair(2, 2, 2),
18067       new Pair(2, 3, 2), new Pair(2, 4, 2),
18068       new Pair(2, 5, 2), new Pair(2, 6, 2),
18069       new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
18070       new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
18071       new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
18072     ];
18073
18074     var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
18075
18076     QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
18077       assert.expect(1);
18078
18079       var actual = func(objects, ['a', 'b']);
18080       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
18081     });
18082
18083     QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
18084       assert.expect(1);
18085
18086       var actual = func(objects, ['a', function(object) { return object.b; }]);
18087       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
18088     });
18089
18090     QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
18091       assert.expect(2);
18092
18093       lodashStable.each([stableArray, stableObject], function(value, index) {
18094         var actual = func(value, ['a', 'c']);
18095         assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
18096       });
18097     });
18098
18099     QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
18100       assert.expect(1);
18101
18102       try {
18103         var actual = func(objects.concat(null, undefined), ['a', 'b']);
18104       } catch (e) {}
18105
18106       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
18107     });
18108
18109     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
18110       assert.expect(3);
18111
18112       var objects = [
18113         { 'a': 'x', '0': 3 },
18114         { 'a': 'y', '0': 4 },
18115         { 'a': 'x', '0': 1 },
18116         { 'a': 'y', '0': 2 }
18117       ];
18118
18119       var funcs = [func, lodashStable.partialRight(func, 'bogus')];
18120
18121       lodashStable.each(['a', 0, [0]], function(props, index) {
18122         var expected = lodashStable.map(funcs, lodashStable.constant(
18123           index
18124             ? [objects[2], objects[3], objects[0], objects[1]]
18125             : [objects[0], objects[2], objects[1], objects[3]]
18126         ));
18127
18128         var actual = lodashStable.map(funcs, function(func) {
18129           return lodashStable.reduce([props], func, objects);
18130         });
18131
18132         assert.deepEqual(actual, expected);
18133       });
18134     });
18135   });
18136
18137   /*--------------------------------------------------------------------------*/
18138
18139   QUnit.module('sortedIndex methods');
18140
18141   lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
18142     var func = _[methodName],
18143         isSortedIndex = methodName == 'sortedIndex';
18144
18145     QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
18146       assert.expect(1);
18147
18148       var array = [30, 50],
18149           values = [30, 40, 50],
18150           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
18151
18152       var actual = lodashStable.map(values, function(value) {
18153         return func(array, value);
18154       });
18155
18156       assert.deepEqual(actual, expected);
18157     });
18158
18159     QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
18160       assert.expect(1);
18161
18162       var array = ['a', 'c'],
18163           values = ['a', 'b', 'c'],
18164           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
18165
18166       var actual = lodashStable.map(values, function(value) {
18167         return func(array, value);
18168       });
18169
18170       assert.deepEqual(actual, expected);
18171     });
18172
18173     QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
18174       assert.expect(1);
18175
18176       var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
18177
18178       var actual = lodashStable.map(falsey, function(array) {
18179         return [func(array, 1), func(array, undefined), func(array, NaN)];
18180       });
18181
18182       assert.deepEqual(actual, expected);
18183     });
18184
18185     QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
18186       assert.expect(10);
18187
18188       var expected = [1, '2', {}, null, undefined, NaN, NaN];
18189
18190       lodashStable.each([
18191         [NaN, null, 1, '2', {}, NaN, undefined],
18192         ['2', null, 1, NaN, {}, NaN, undefined]
18193       ], function(array) {
18194         assert.deepEqual(_.sortBy(array), expected);
18195         assert.strictEqual(func(expected, 3), 2);
18196         assert.strictEqual(func(expected, null), isSortedIndex ? 3 : 4);
18197         assert.strictEqual(func(expected, undefined), isSortedIndex ? 4 : 5);
18198         assert.strictEqual(func(expected, NaN), isSortedIndex ? 5 : 7);
18199       });
18200     });
18201   });
18202
18203   /*--------------------------------------------------------------------------*/
18204
18205   QUnit.module('sortedIndexBy methods');
18206
18207   lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
18208     var func = _[methodName],
18209         isSortedIndexBy = methodName == 'sortedIndexBy';
18210
18211     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
18212       assert.expect(1);
18213
18214       var args;
18215
18216       func([30, 50], 40, function(assert) {
18217         args || (args = slice.call(arguments));
18218       });
18219
18220       assert.deepEqual(args, [40]);
18221     });
18222
18223     QUnit.test('`_.' + methodName + '` should work with a "_.property" style `iteratee`', function(assert) {
18224       assert.expect(1);
18225
18226       var objects = [{ 'x': 30 }, { 'x': 50 }],
18227           actual = func(objects, { 'x': 40 }, 'x');
18228
18229       assert.strictEqual(actual, 1);
18230     });
18231
18232     QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
18233       assert.expect(12);
18234
18235       lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
18236         var array = [],
18237             values = [MAX_ARRAY_LENGTH, NaN, undefined];
18238
18239         array.length = length;
18240
18241         lodashStable.each(values, function(value) {
18242           var steps = 0;
18243
18244           var actual = func(array, value, function(value) {
18245             steps++;
18246             return value;
18247           });
18248
18249           var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
18250             ? 0
18251             : Math.min(length, MAX_ARRAY_INDEX);
18252
18253           // Avoid false fails in older Firefox.
18254           if (array.length == length) {
18255             assert.ok(steps == 32 || steps == 33);
18256             assert.strictEqual(actual, expected);
18257           }
18258           else {
18259             skipTest(assert, 2);
18260           }
18261         });
18262       });
18263     });
18264   });
18265
18266   /*--------------------------------------------------------------------------*/
18267
18268   QUnit.module('sortedIndexOf methods');
18269
18270   lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
18271     var func = _[methodName],
18272         isSortedIndexOf = methodName == 'sortedIndexOf';
18273
18274     QUnit.test('should perform a binary search', function(assert) {
18275       assert.expect(1);
18276
18277       var sorted = [4, 4, 5, 5, 6, 6];
18278       assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
18279     });
18280   });
18281
18282   /*--------------------------------------------------------------------------*/
18283
18284   QUnit.module('lodash.sortedUniq');
18285
18286   (function() {
18287     QUnit.test('should return unique values of a sorted array', function(assert) {
18288       assert.expect(3);
18289
18290       var expected = [1, 2, 3];
18291
18292       lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
18293         assert.deepEqual(_.sortedUniq(array), expected);
18294       });
18295     });
18296   }());
18297
18298   /*--------------------------------------------------------------------------*/
18299
18300   QUnit.module('lodash.split');
18301
18302   (function() {
18303     QUnit.test('should support string split', function(assert) {
18304       assert.expect(3);
18305
18306       var string = 'abcde';
18307       assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
18308       assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
18309       assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
18310     });
18311
18312     QUnit.test('should allow mixed string and array prototype methods', function(assert) {
18313       assert.expect(1);
18314
18315       if (!isNpm) {
18316         var wrapped = _('abc');
18317         assert.strictEqual(wrapped.split('b').join(','), 'a,c');
18318       }
18319       else {
18320         skipTest(assert);
18321       }
18322     });
18323   }());
18324
18325   /*--------------------------------------------------------------------------*/
18326
18327   QUnit.module('lodash.spread');
18328
18329   (function() {
18330     QUnit.test('should spread arguments to `func`', function(assert) {
18331       assert.expect(1);
18332
18333       var spread = _.spread(add);
18334       assert.strictEqual(spread([4, 2]), 6);
18335     });
18336
18337     QUnit.test('should accept a falsey `array` argument', function(assert) {
18338       assert.expect(1);
18339
18340       var spread = _.spread(alwaysTrue),
18341           expected = lodashStable.map(falsey, alwaysTrue);
18342
18343       var actual = lodashStable.map(falsey, function(array, index) {
18344         try {
18345           return index ? spread(array) : spread();
18346         } catch (e) {}
18347       });
18348
18349       assert.deepEqual(actual, expected);
18350     });
18351
18352     QUnit.test('should provide the correct `func` arguments', function(assert) {
18353       assert.expect(1);
18354
18355       var args;
18356
18357       var spread = _.spread(function() {
18358         args = slice.call(arguments);
18359       });
18360
18361       spread([4, 2], 'ignored');
18362       assert.deepEqual(args, [4, 2]);
18363     });
18364   }());
18365
18366   /*--------------------------------------------------------------------------*/
18367
18368   QUnit.module('lodash.startsWith');
18369
18370   (function() {
18371     var string = 'abc';
18372
18373     QUnit.test('should return `true` if a string starts with `target`', function(assert) {
18374       assert.expect(1);
18375
18376       assert.strictEqual(_.startsWith(string, 'a'), true);
18377     });
18378
18379     QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
18380       assert.expect(1);
18381
18382       assert.strictEqual(_.startsWith(string, 'b'), false);
18383     });
18384
18385     QUnit.test('should work with a `position` argument', function(assert) {
18386       assert.expect(1);
18387
18388       assert.strictEqual(_.startsWith(string, 'b', 1), true);
18389     });
18390
18391     QUnit.test('should work with `position` >= `string.length`', function(assert) {
18392       assert.expect(4);
18393
18394       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
18395         assert.strictEqual(_.startsWith(string, 'a', position), false);
18396       });
18397     });
18398
18399     QUnit.test('should treat falsey `position` values as `0`', function(assert) {
18400       assert.expect(1);
18401
18402       var expected = lodashStable.map(falsey, alwaysTrue);
18403
18404       var actual = lodashStable.map(falsey, function(position) {
18405         return _.startsWith(string, 'a', position);
18406       });
18407
18408       assert.deepEqual(actual, expected);
18409     });
18410
18411     QUnit.test('should treat a negative `position` as `0`', function(assert) {
18412       assert.expect(6);
18413
18414       lodashStable.each([-1, -3, -Infinity], function(position) {
18415         assert.strictEqual(_.startsWith(string, 'a', position), true);
18416         assert.strictEqual(_.startsWith(string, 'b', position), false);
18417       });
18418     });
18419
18420     QUnit.test('should coerce `position` to an integer', function(assert) {
18421       assert.expect(1);
18422
18423       assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
18424     });
18425
18426     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
18427       assert.expect(1);
18428
18429       assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
18430         return _.startsWith(string, '', position, true);
18431       }));
18432     });
18433   }());
18434
18435   /*--------------------------------------------------------------------------*/
18436
18437   QUnit.module('lodash.startsWith and lodash.endsWith');
18438
18439   lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
18440     var func = _[methodName],
18441         isStartsWith = methodName == 'startsWith';
18442
18443     var string = 'abc',
18444         chr = isStartsWith ? 'a' : 'c';
18445
18446     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
18447       assert.expect(2);
18448
18449       assert.strictEqual(func(Object(string), chr), true);
18450       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
18451     });
18452
18453     QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
18454       assert.expect(2);
18455
18456       assert.strictEqual(func(string, Object(chr)), true);
18457       assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
18458     });
18459
18460     QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
18461       assert.expect(2);
18462
18463       var position = isStartsWith ? 1 : 2;
18464       assert.strictEqual(func(string, 'b', Object(position)), true);
18465       assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
18466     });
18467   });
18468
18469   /*--------------------------------------------------------------------------*/
18470
18471   QUnit.module('lodash.subtract');
18472
18473   (function() {
18474     QUnit.test('should subtract two numbers', function(assert) {
18475       assert.expect(3);
18476
18477       assert.strictEqual(_.subtract(6, 4), 2);
18478       assert.strictEqual(_.subtract(-6, 4), -10);
18479       assert.strictEqual(_.subtract(-6, -4), -2);
18480     });
18481
18482     QUnit.test('should coerce arguments only numbers', function(assert) {
18483       assert.expect(2);
18484
18485       assert.strictEqual(_.subtract('6', '4'), 2);
18486       assert.deepEqual(_.subtract('x', 'y'), NaN);
18487     });
18488
18489     QUnit.test('should work with only a `minuend` or `subtrahend`', function(assert) {
18490       assert.expect(3);
18491
18492       assert.strictEqual(_.subtract(6), 6);
18493       assert.strictEqual(_.subtract(6, undefined), 6);
18494       assert.strictEqual(_.subtract(undefined, 4), 4);
18495     });
18496
18497     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
18498       assert.expect(1);
18499
18500       if (!isNpm) {
18501         assert.strictEqual(_(1).subtract(2), -1);
18502       }
18503       else {
18504         skipTest(assert);
18505       }
18506     });
18507
18508     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
18509       assert.expect(1);
18510
18511       if (!isNpm) {
18512         assert.ok(_(1).chain().subtract(2) instanceof _);
18513       }
18514       else {
18515         skipTest(assert);
18516       }
18517     });
18518   }());
18519
18520   /*--------------------------------------------------------------------------*/
18521
18522   QUnit.module('lodash.sum');
18523
18524   (function() {
18525     var array = [6, 4, 2];
18526
18527     QUnit.test('should return the sum of an array of numbers', function(assert) {
18528       assert.expect(1);
18529
18530       assert.strictEqual(_.sum(array), 12);
18531     });
18532
18533     QUnit.test('should return `undefined` when passing empty `array` values', function(assert) {
18534       assert.expect(1);
18535
18536       var expected = lodashStable.map(empties, alwaysUndefined),
18537           actual = lodashStable.map(empties, _.sum);
18538
18539       assert.deepEqual(actual, expected);
18540     });
18541
18542     QUnit.test('should skip `undefined` values', function(assert) {
18543       assert.expect(1);
18544
18545       assert.strictEqual(_.sum([1, undefined]), 1);
18546     });
18547
18548     QUnit.test('should not skip `NaN` values', function(assert) {
18549       assert.expect(1);
18550
18551       assert.deepEqual(_.sum([1, NaN]), NaN);
18552     });
18553
18554     QUnit.test('should not coerce values to numbers', function(assert) {
18555       assert.expect(1);
18556
18557       assert.strictEqual(_.sum(['1', '2']), '12');
18558     });
18559   }());
18560
18561   /*--------------------------------------------------------------------------*/
18562
18563   QUnit.module('lodash.sumBy');
18564
18565   (function() {
18566     var array = [6, 4, 2],
18567         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
18568
18569     QUnit.test('should work with an `iteratee` argument', function(assert) {
18570       assert.expect(1);
18571
18572       var actual = _.sumBy(objects, function(object) {
18573         return object.a;
18574       });
18575
18576       assert.deepEqual(actual, 6);
18577     });
18578
18579     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
18580       assert.expect(1);
18581
18582       var args;
18583
18584       _.sumBy(array, function() {
18585         args || (args = slice.call(arguments));
18586       });
18587
18588       assert.deepEqual(args, [6]);
18589     });
18590
18591     QUnit.test('should work with a "_.property" style `iteratee`', function(assert) {
18592       assert.expect(2);
18593
18594       var arrays = [[2], [3], [1]];
18595       assert.strictEqual(_.sumBy(arrays, 0), 6);
18596       assert.strictEqual(_.sumBy(objects, 'a'), 6);
18597     });
18598   }());
18599
18600   /*--------------------------------------------------------------------------*/
18601
18602   QUnit.module('lodash.tail');
18603
18604   (function() {
18605     var array = [1, 2, 3];
18606
18607     QUnit.test('should accept a falsey `array` argument', function(assert) {
18608       assert.expect(1);
18609
18610       var expected = lodashStable.map(falsey, alwaysEmptyArray);
18611
18612       var actual = lodashStable.map(falsey, function(array, index) {
18613         try {
18614           return index ? _.tail(array) : _.tail();
18615         } catch (e) {}
18616       });
18617
18618       assert.deepEqual(actual, expected);
18619     });
18620
18621     QUnit.test('should exclude the first element', function(assert) {
18622       assert.expect(1);
18623
18624       assert.deepEqual(_.tail(array), [2, 3]);
18625     });
18626
18627     QUnit.test('should return an empty when querying empty arrays', function(assert) {
18628       assert.expect(1);
18629
18630       assert.deepEqual(_.tail([]), []);
18631     });
18632
18633     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18634       assert.expect(1);
18635
18636       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
18637           actual = lodashStable.map(array, _.tail);
18638
18639       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
18640     });
18641
18642     QUnit.test('should work in a lazy sequence', function(assert) {
18643       assert.expect(4);
18644
18645       if (!isNpm) {
18646         var array = lodashStable.range(LARGE_ARRAY_SIZE),
18647             values = [];
18648
18649         var actual = _(array).tail().filter(function(value) {
18650           values.push(value);
18651           return false;
18652         })
18653         .value();
18654
18655         assert.deepEqual(actual, []);
18656         assert.deepEqual(values, array.slice(1));
18657
18658         values = [];
18659
18660         actual = _(array).filter(function(value) {
18661           values.push(value);
18662           return isEven(value);
18663         })
18664         .tail()
18665         .value();
18666
18667         assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
18668         assert.deepEqual(values, array);
18669       }
18670       else {
18671         skipTest(assert, 4);
18672       }
18673     });
18674
18675     QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
18676       assert.expect(4);
18677
18678       if (!isNpm) {
18679         var array = lodashStable.range(LARGE_ARRAY_SIZE),
18680             iteratee = function() { pass = false; },
18681             pass = true,
18682             actual = _(array).slice(0, 1).tail().map(iteratee).value();
18683
18684         assert.ok(pass);
18685         assert.deepEqual(actual, []);
18686
18687         pass = true;
18688         actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
18689
18690         assert.ok(pass);
18691         assert.deepEqual(actual, []);
18692       }
18693       else {
18694         skipTest(assert, 4);
18695       }
18696     });
18697   }());
18698
18699   /*--------------------------------------------------------------------------*/
18700
18701   QUnit.module('lodash.take');
18702
18703   (function() {
18704     var array = [1, 2, 3];
18705
18706     QUnit.test('should take the first two elements', function(assert) {
18707       assert.expect(1);
18708
18709       assert.deepEqual(_.take(array, 2), [1, 2]);
18710     });
18711
18712     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
18713       assert.expect(1);
18714
18715       var expected = lodashStable.map(falsey, function(value) {
18716         return value === undefined ? [1] : [];
18717       });
18718
18719       var actual = lodashStable.map(falsey, function(n) {
18720         return _.take(array, n);
18721       });
18722
18723       assert.deepEqual(actual, expected);
18724     });
18725
18726     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
18727       assert.expect(3);
18728
18729       lodashStable.each([0, -1, -Infinity], function(n) {
18730         assert.deepEqual(_.take(array, n), []);
18731       });
18732     });
18733
18734     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
18735       assert.expect(4);
18736
18737       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
18738         assert.deepEqual(_.take(array, n), array);
18739       });
18740     });
18741
18742     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18743       assert.expect(1);
18744
18745       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
18746           actual = lodashStable.map(array, _.take);
18747
18748       assert.deepEqual(actual, [[1], [4], [7]]);
18749     });
18750
18751     QUnit.test('should work in a lazy sequence', function(assert) {
18752       assert.expect(6);
18753
18754       if (!isNpm) {
18755         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
18756             predicate = function(value) { values.push(value); return isEven(value); },
18757             values = [],
18758             actual = _(array).take(2).take().value();
18759
18760         assert.deepEqual(actual, _.take(_.take(array, 2)));
18761
18762         actual = _(array).filter(predicate).take(2).take().value();
18763         assert.deepEqual(values, [1, 2]);
18764         assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
18765
18766         actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
18767         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
18768
18769         values = [];
18770
18771         actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
18772         assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
18773         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
18774       }
18775       else {
18776         skipTest(assert, 6);
18777       }
18778     });
18779   }());
18780
18781   /*--------------------------------------------------------------------------*/
18782
18783   QUnit.module('lodash.takeRight');
18784
18785   (function() {
18786     var array = [1, 2, 3];
18787
18788     QUnit.test('should take the last two elements', function(assert) {
18789       assert.expect(1);
18790
18791       assert.deepEqual(_.takeRight(array, 2), [2, 3]);
18792     });
18793
18794     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
18795       assert.expect(1);
18796
18797       var expected = lodashStable.map(falsey, function(value) {
18798         return value === undefined ? [3] : [];
18799       });
18800
18801       var actual = lodashStable.map(falsey, function(n) {
18802         return _.takeRight(array, n);
18803       });
18804
18805       assert.deepEqual(actual, expected);
18806     });
18807
18808     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
18809       assert.expect(3);
18810
18811       lodashStable.each([0, -1, -Infinity], function(n) {
18812         assert.deepEqual(_.takeRight(array, n), []);
18813       });
18814     });
18815
18816     QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
18817       assert.expect(4);
18818
18819       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
18820         assert.deepEqual(_.takeRight(array, n), array);
18821       });
18822     });
18823
18824     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18825       assert.expect(1);
18826
18827       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
18828           actual = lodashStable.map(array, _.takeRight);
18829
18830       assert.deepEqual(actual, [[3], [6], [9]]);
18831     });
18832
18833     QUnit.test('should work in a lazy sequence', function(assert) {
18834       assert.expect(6);
18835
18836       if (!isNpm) {
18837         var array = lodashStable.range(LARGE_ARRAY_SIZE),
18838             predicate = function(value) { values.push(value); return isEven(value); },
18839             values = [],
18840             actual = _(array).takeRight(2).takeRight().value();
18841
18842         assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
18843
18844         actual = _(array).filter(predicate).takeRight(2).takeRight().value();
18845         assert.deepEqual(values, array);
18846         assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
18847
18848         actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
18849         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
18850
18851         values = [];
18852
18853         actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
18854         assert.deepEqual(values, array);
18855         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
18856       }
18857       else {
18858         skipTest(assert, 6);
18859       }
18860     });
18861   }());
18862
18863   /*--------------------------------------------------------------------------*/
18864
18865   QUnit.module('lodash.takeRightWhile');
18866
18867   (function() {
18868     var array = [1, 2, 3, 4];
18869
18870     var objects = [
18871       { 'a': 0, 'b': 0 },
18872       { 'a': 1, 'b': 1 },
18873       { 'a': 2, 'b': 2 }
18874     ];
18875
18876     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
18877       assert.expect(1);
18878
18879       var actual = _.takeRightWhile(array, function(num) {
18880         return num > 2;
18881       });
18882
18883       assert.deepEqual(actual, [3, 4]);
18884     });
18885
18886     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
18887       assert.expect(1);
18888
18889       var args;
18890
18891       _.takeRightWhile(array, function() {
18892         args = slice.call(arguments);
18893       });
18894
18895       assert.deepEqual(args, [4, 3, array]);
18896     });
18897
18898     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
18899       assert.expect(1);
18900
18901       assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
18902     });
18903
18904     QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
18905       assert.expect(1);
18906
18907       assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
18908     });
18909
18910     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
18911       assert.expect(1);
18912
18913       assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
18914     });
18915
18916     QUnit.test('should work in a lazy sequence', function(assert) {
18917       assert.expect(3);
18918
18919       if (!isNpm) {
18920         var array = lodashStable.range(LARGE_ARRAY_SIZE),
18921             predicate = function(num) { return num > 2; },
18922             expected = _.takeRightWhile(array, predicate),
18923             wrapped = _(array).takeRightWhile(predicate);
18924
18925         assert.deepEqual(wrapped.value(), expected);
18926         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
18927         assert.strictEqual(wrapped.last(), _.last(expected));
18928       }
18929       else {
18930         skipTest(assert, 3);
18931       }
18932     });
18933
18934     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
18935       assert.expect(5);
18936
18937       if (!isNpm) {
18938         var args,
18939             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18940             expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
18941
18942         _(array).slice(1).takeRightWhile(function(value, index, array) {
18943           args = slice.call(arguments);
18944         }).value();
18945
18946         assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
18947
18948         _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
18949           args = slice.call(arguments);
18950         }).value();
18951
18952         assert.deepEqual(args, expected);
18953
18954         _(array).slice(1).map(square).takeRightWhile(function(value, index) {
18955           args = slice.call(arguments);
18956         }).value();
18957
18958         assert.deepEqual(args, expected);
18959
18960         _(array).slice(1).map(square).takeRightWhile(function(index) {
18961           args = slice.call(arguments);
18962         }).value();
18963
18964         assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
18965
18966         _(array).slice(1).map(square).takeRightWhile(function() {
18967           args = slice.call(arguments);
18968         }).value();
18969
18970         assert.deepEqual(args, expected);
18971       }
18972       else {
18973         skipTest(assert, 5);
18974       }
18975     });
18976   }());
18977
18978   /*--------------------------------------------------------------------------*/
18979
18980   QUnit.module('lodash.takeWhile');
18981
18982   (function() {
18983     var array = [1, 2, 3, 4];
18984
18985     var objects = [
18986       { 'a': 2, 'b': 2 },
18987       { 'a': 1, 'b': 1 },
18988       { 'a': 0, 'b': 0 }
18989     ];
18990
18991     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
18992       assert.expect(1);
18993
18994       var actual = _.takeWhile(array, function(num) {
18995         return num < 3;
18996       });
18997
18998       assert.deepEqual(actual, [1, 2]);
18999     });
19000
19001     QUnit.test('should provide the correct `predicate` arguments', function(assert) {
19002       assert.expect(1);
19003
19004       var args;
19005
19006       _.takeWhile(array, function() {
19007         args = slice.call(arguments);
19008       });
19009
19010       assert.deepEqual(args, [1, 0, array]);
19011     });
19012
19013     QUnit.test('should work with a "_.matches" style `predicate`', function(assert) {
19014       assert.expect(1);
19015
19016       assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
19017     });
19018
19019     QUnit.test('should work with a "_.matchesProperty" style `predicate`', function(assert) {
19020       assert.expect(1);
19021
19022       assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
19023     });
19024     QUnit.test('should work with a "_.property" style `predicate`', function(assert) {
19025       assert.expect(1);
19026
19027       assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
19028     });
19029
19030     QUnit.test('should work in a lazy sequence', function(assert) {
19031       assert.expect(3);
19032
19033       if (!isNpm) {
19034         var array = lodashStable.range(LARGE_ARRAY_SIZE),
19035             predicate = function(num) { return num < 3; },
19036             expected = _.takeWhile(array, predicate),
19037             wrapped = _(array).takeWhile(predicate);
19038
19039         assert.deepEqual(wrapped.value(), expected);
19040         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
19041         assert.strictEqual(wrapped.last(), _.last(expected));
19042       }
19043       else {
19044         skipTest(assert, 3);
19045       }
19046     });
19047
19048     QUnit.test('should work in a lazy sequence with `take`', function(assert) {
19049       assert.expect(1);
19050
19051       if (!isNpm) {
19052         var array = lodashStable.range(LARGE_ARRAY_SIZE);
19053
19054         var actual = _(array)
19055           .takeWhile(function(num) { return num < 4; })
19056           .take(2)
19057           .takeWhile(function(num) { return num == 0; })
19058           .value();
19059
19060         assert.deepEqual(actual, [0]);
19061       }
19062       else {
19063         skipTest(assert);
19064       }
19065     });
19066
19067     QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
19068       assert.expect(5);
19069
19070       if (!isNpm) {
19071         var args,
19072             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19073             expected = [1, 0, lodashStable.map(array.slice(1), square)];
19074
19075         _(array).slice(1).takeWhile(function(value, index, array) {
19076           args = slice.call(arguments);
19077         }).value();
19078
19079         assert.deepEqual(args, [1, 0, array.slice(1)]);
19080
19081         _(array).slice(1).map(square).takeWhile(function(value, index, array) {
19082           args = slice.call(arguments);
19083         }).value();
19084
19085         assert.deepEqual(args, expected);
19086
19087         _(array).slice(1).map(square).takeWhile(function(value, index) {
19088           args = slice.call(arguments);
19089         }).value();
19090
19091         assert.deepEqual(args, expected);
19092
19093         _(array).slice(1).map(square).takeWhile(function(value) {
19094           args = slice.call(arguments);
19095         }).value();
19096
19097         assert.deepEqual(args, [1]);
19098
19099         _(array).slice(1).map(square).takeWhile(function() {
19100           args = slice.call(arguments);
19101         }).value();
19102
19103         assert.deepEqual(args, expected);
19104       }
19105       else {
19106         skipTest(assert, 5);
19107       }
19108     });
19109   }());
19110
19111   /*--------------------------------------------------------------------------*/
19112
19113   QUnit.module('lodash.tap');
19114
19115   (function() {
19116     QUnit.test('should intercept and return the given value', function(assert) {
19117       assert.expect(2);
19118
19119       if (!isNpm) {
19120         var intercepted,
19121             array = [1, 2, 3];
19122
19123         var actual = _.tap(array, function(value) {
19124           intercepted = value;
19125         });
19126
19127         assert.strictEqual(actual, array);
19128         assert.strictEqual(intercepted, array);
19129       }
19130       else {
19131         skipTest(assert, 2);
19132       }
19133     });
19134
19135     QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
19136       assert.expect(2);
19137
19138       if (!isNpm) {
19139         var intercepted,
19140             array = [1, 2, 3];
19141
19142         var wrapped = _(array).tap(function(value) {
19143           intercepted = value;
19144           value.pop();
19145         });
19146
19147         assert.ok(wrapped instanceof _);
19148
19149         wrapped.value();
19150         assert.strictEqual(intercepted, array);
19151       }
19152       else {
19153         skipTest(assert, 2);
19154       }
19155     });
19156   }());
19157
19158   /*--------------------------------------------------------------------------*/
19159
19160   QUnit.module('lodash.template');
19161
19162   (function() {
19163     QUnit.test('should escape values in "escape" delimiters', function(assert) {
19164       assert.expect(1);
19165
19166       var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
19167           expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
19168           data = { 'value': '&<>"\'`\/' };
19169
19170       var actual = lodashStable.map(strings, function(string) {
19171         return _.template(string)(data);
19172       });
19173
19174       assert.deepEqual(actual, expected);
19175     });
19176
19177     QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
19178       assert.expect(1);
19179
19180       var compiled = _.template('<%= typeof __e %>');
19181       assert.strictEqual(compiled({}), 'undefined');
19182     });
19183
19184     QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
19185       assert.expect(1);
19186
19187       var compiled = _.template(
19188         '<ul><%\
19189         for (var key in collection) {\
19190           %><li><%= collection[key] %></li><%\
19191         } %></ul>'
19192       );
19193
19194       var data = { 'collection': { 'a': 'A', 'b': 'B' } },
19195           actual = compiled(data);
19196
19197       assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
19198     });
19199
19200     QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
19201       assert.expect(1);
19202
19203       var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
19204           data = { 'value': true };
19205
19206       assert.strictEqual(compiled(data), 'yap');
19207     });
19208
19209     QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
19210       assert.expect(1);
19211
19212       var compiled = _.template('<% var b = a; %><%= b.value %>'),
19213           data = { 'a': { 'value': 1 } };
19214
19215       assert.strictEqual(compiled(data), '1');
19216     });
19217
19218     QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
19219       assert.expect(1);
19220
19221       var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
19222           expected = lodashStable.map(strings, lodashStable.constant('ABC')),
19223           data = { 'a': 'A' };
19224
19225       var actual = lodashStable.map(strings, function(string) {
19226         return _.template(string)(data);
19227       });
19228
19229       assert.deepEqual(actual, expected);
19230     });
19231
19232     QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
19233       assert.expect(1);
19234
19235       var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
19236           data = { 'a': true };
19237
19238       assert.strictEqual(compiled(data), 'a="A"');
19239     });
19240
19241     QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
19242       assert.expect(1);
19243
19244       var compiled = _.template('<%= value ? value : "b" %>'),
19245           data = { 'value': 'a' };
19246
19247       assert.strictEqual(compiled(data), 'a');
19248     });
19249
19250     QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
19251       assert.expect(1);
19252
19253       var compiled = _.template('<%= typeof Math.abs %>');
19254
19255       try {
19256         var actual = compiled();
19257       } catch (e) {}
19258
19259       assert.strictEqual(actual, 'function');
19260     });
19261
19262     QUnit.test('should support complex "interpolate" delimiters', function(assert) {
19263       assert.expect(22);
19264
19265       lodashStable.forOwn({
19266         '<%= a + b %>': '3',
19267         '<%= b - a %>': '1',
19268         '<%= a = b %>': '2',
19269         '<%= !a %>': 'false',
19270         '<%= ~a %>': '-2',
19271         '<%= a * b %>': '2',
19272         '<%= a / b %>': '0.5',
19273         '<%= a % b %>': '1',
19274         '<%= a >> b %>': '0',
19275         '<%= a << b %>': '4',
19276         '<%= a & b %>': '0',
19277         '<%= a ^ b %>': '3',
19278         '<%= a | b %>': '3',
19279         '<%= {}.toString.call(0) %>': numberTag,
19280         '<%= a.toFixed(2) %>': '1.00',
19281         '<%= obj["a"] %>': '1',
19282         '<%= delete a %>': 'true',
19283         '<%= "a" in obj %>': 'true',
19284         '<%= obj instanceof Object %>': 'true',
19285         '<%= new Boolean %>': 'false',
19286         '<%= typeof a %>': 'number',
19287         '<%= void a %>': ''
19288       },
19289       function(value, key) {
19290         var compiled = _.template(key),
19291             data = { 'a': 1, 'b': 2 };
19292
19293         assert.strictEqual(compiled(data), value, key);
19294       });
19295     });
19296
19297     QUnit.test('should support ES6 template delimiters', function(assert) {
19298       assert.expect(2);
19299
19300       var data = { 'value': 2 };
19301       assert.strictEqual(_.template('1${value}3')(data), '123');
19302       assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
19303     });
19304
19305     QUnit.test('should support the "imports" option', function(assert) {
19306       assert.expect(1);
19307
19308       var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
19309       assert.strictEqual(compiled({}), '1');
19310     });
19311
19312     QUnit.test('should support the "variable" options', function(assert) {
19313       assert.expect(1);
19314
19315       var compiled = _.template(
19316         '<% _.each( data.a, function( value ) { %>' +
19317             '<%= value.valueOf() %>' +
19318         '<% }) %>', { 'variable': 'data' }
19319       );
19320
19321       var data = { 'a': [1, 2, 3] };
19322
19323       try {
19324         assert.strictEqual(compiled(data), '123');
19325       } catch (e) {
19326         assert.ok(false, e.message);
19327       }
19328     });
19329
19330     QUnit.test('should support custom delimiters', function(assert) {
19331       assert.expect(2);
19332
19333       lodashStable.times(2, function(index) {
19334         var settingsClone = lodashStable.clone(_.templateSettings);
19335
19336         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
19337           'escape': /\{\{-([\s\S]+?)\}\}/g,
19338           'evaluate': /\{\{([\s\S]+?)\}\}/g,
19339           'interpolate': /\{\{=([\s\S]+?)\}\}/g
19340         });
19341
19342         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
19343             compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
19344             data = { 'collection': ['a & A', 'b & B'] };
19345
19346         assert.strictEqual(compiled(data), expected);
19347         lodashStable.assign(_.templateSettings, settingsClone);
19348       });
19349     });
19350
19351     QUnit.test('should support custom delimiters containing special characters', function(assert) {
19352       assert.expect(2);
19353
19354       lodashStable.times(2, function(index) {
19355         var settingsClone = lodashStable.clone(_.templateSettings);
19356
19357         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
19358           'escape': /<\?-([\s\S]+?)\?>/g,
19359           'evaluate': /<\?([\s\S]+?)\?>/g,
19360           'interpolate': /<\?=([\s\S]+?)\?>/g
19361         });
19362
19363         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
19364             compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
19365             data = { 'collection': ['a & A', 'b & B'] };
19366
19367         assert.strictEqual(compiled(data), expected);
19368         lodashStable.assign(_.templateSettings, settingsClone);
19369       });
19370     });
19371
19372     QUnit.test('should use a `with` statement by default', function(assert) {
19373       assert.expect(1);
19374
19375       var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
19376           actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
19377
19378       assert.strictEqual(actual, '1b012');
19379     });
19380
19381     QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
19382       assert.expect(1);
19383
19384       var lodash = _.templateSettings.imports._,
19385           settingsClone = lodashStable.clone(lodash.templateSettings);
19386
19387       lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
19388         'interpolate': /\{\{=([\s\S]+?)\}\}/g
19389       });
19390
19391       var compiled = _.template('{{= a }}');
19392       assert.strictEqual(compiled({ 'a': 1 }), '1');
19393
19394       if (settingsClone) {
19395         lodashStable.assign(lodash.templateSettings, settingsClone);
19396       } else {
19397         delete lodash.templateSettings;
19398       }
19399     });
19400
19401     QUnit.test('should fallback to `_.templateSettings`', function(assert) {
19402       assert.expect(1);
19403
19404       var lodash = _.templateSettings.imports._,
19405           delimiter = _.templateSettings.interpolate;
19406
19407       _.templateSettings.imports._ = { 'escape': lodashStable.escape };
19408       _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
19409
19410       var compiled = _.template('{{= a }}');
19411       assert.strictEqual(compiled({ 'a': 1 }), '1');
19412
19413       _.templateSettings.imports._ = lodash;
19414       _.templateSettings.interpolate = delimiter;
19415     });
19416
19417     QUnit.test('should ignore `null` delimiters', function(assert) {
19418       assert.expect(3);
19419
19420       var delimiter = {
19421         'escape': /\{\{-([\s\S]+?)\}\}/g,
19422         'evaluate': /\{\{([\s\S]+?)\}\}/g,
19423         'interpolate': /\{\{=([\s\S]+?)\}\}/g
19424       };
19425
19426       lodashStable.forOwn({
19427         'escape': '{{- a }}',
19428         'evaluate': '{{ print(a) }}',
19429         'interpolate': '{{= a }}'
19430       },
19431       function(value, key) {
19432         var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
19433         settings[key] = delimiter[key];
19434
19435         var expected = '1 <%- a %> <% print(a) %> <%= a %>',
19436             compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
19437             data = { 'a': 1 };
19438
19439         assert.strictEqual(compiled(data), expected);
19440       });
19441     });
19442
19443     QUnit.test('should work without delimiters', function(assert) {
19444       assert.expect(1);
19445
19446       var expected = 'abc';
19447       assert.strictEqual(_.template(expected)({}), expected);
19448     });
19449
19450     QUnit.test('should work with `this` references', function(assert) {
19451       assert.expect(2);
19452
19453       var compiled = _.template('a<%= this.String("b") %>c');
19454       assert.strictEqual(compiled(), 'abc');
19455
19456       var object = { 'b': 'B' };
19457       object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
19458       assert.strictEqual(object.compiled(), 'ABC');
19459     });
19460
19461     QUnit.test('should work with backslashes', function(assert) {
19462       assert.expect(1);
19463
19464       var compiled = _.template('<%= a %> \\b'),
19465           data = { 'a': 'A' };
19466
19467       assert.strictEqual(compiled(data), 'A \\b');
19468     });
19469
19470     QUnit.test('should work with escaped characters in string literals', function(assert) {
19471       assert.expect(2);
19472
19473       var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
19474       assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
19475
19476       var data = { 'a': 'A' };
19477       compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
19478       assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
19479     });
19480
19481     QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
19482       assert.expect(1);
19483
19484       var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
19485       assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
19486     });
19487
19488     QUnit.test('should work with statements containing quotes', function(assert) {
19489       assert.expect(1);
19490
19491       var compiled = _.template("<%\
19492         if (a == 'A' || a == \"a\") {\
19493           %>'a',\"A\"<%\
19494         } %>"
19495       );
19496
19497       var data = { 'a': 'A' };
19498       assert.strictEqual(compiled(data), "'a',\"A\"");
19499     });
19500
19501     QUnit.test('should work with templates containing newlines and comments', function(assert) {
19502       assert.expect(1);
19503
19504       var compiled = _.template('<%\n\
19505         // A code comment.\n\
19506         if (value) { value += 3; }\n\
19507         %><p><%= value %></p>'
19508       );
19509
19510       assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
19511     });
19512
19513     QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
19514       assert.expect(1);
19515
19516       var compiled = _.template(''),
19517           pass = true;
19518
19519       /*@cc_on @*/
19520       try {
19521         compiled();
19522       } catch (e) {
19523         pass = false;
19524       }
19525       assert.ok(pass);
19526     });
19527
19528     QUnit.test('should tokenize delimiters', function(assert) {
19529       assert.expect(1);
19530
19531       var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
19532           data = { 'type': 1 };
19533
19534       assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
19535     });
19536
19537     QUnit.test('should evaluate delimiters once', function(assert) {
19538       assert.expect(1);
19539
19540       var actual = [],
19541           compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
19542           data = { 'func': function(value) { actual.push(value); } };
19543
19544       compiled(data);
19545       assert.deepEqual(actual, ['a', 'b', 'c']);
19546     });
19547
19548     QUnit.test('should match delimiters before escaping text', function(assert) {
19549       assert.expect(1);
19550
19551       var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
19552       assert.strictEqual(compiled(), '<<\n a \n>>');
19553     });
19554
19555     QUnit.test('should resolve nullish values to an empty string', function(assert) {
19556       assert.expect(3);
19557
19558       var compiled = _.template('<%= a %><%- a %>'),
19559           data = { 'a': null };
19560
19561       assert.strictEqual(compiled(data), '');
19562
19563       data = { 'a': undefined };
19564       assert.strictEqual(compiled(data), '');
19565
19566       data = { 'a': {} };
19567       compiled = _.template('<%= a.b %><%- a.b %>');
19568       assert.strictEqual(compiled(data), '');
19569     });
19570
19571     QUnit.test('should return an empty string for empty values', function(assert) {
19572       assert.expect(1);
19573
19574       var values = [, null, undefined, ''],
19575           expected = lodashStable.map(values, alwaysEmptyString),
19576           data = { 'a': 1 };
19577
19578       var actual = lodashStable.map(values, function(value, index) {
19579         var compiled = index ? _.template(value) : _.template();
19580         return compiled(data);
19581       });
19582
19583       assert.deepEqual(actual, expected);
19584     });
19585
19586     QUnit.test('should parse delimiters without newlines', function(assert) {
19587       assert.expect(1);
19588
19589       var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
19590           compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
19591           data = { 'value': true };
19592
19593       assert.strictEqual(compiled(data), expected);
19594     });
19595
19596     QUnit.test('should support recursive calls', function(assert) {
19597       assert.expect(1);
19598
19599       var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
19600           data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
19601
19602       assert.strictEqual(compiled(data), 'AB');
19603     });
19604
19605     QUnit.test('should coerce `text` argument to a string', function(assert) {
19606       assert.expect(1);
19607
19608       var object = { 'toString': lodashStable.constant('<%= a %>') },
19609           data = { 'a': 1 };
19610
19611       assert.strictEqual(_.template(object)(data), '1');
19612     });
19613
19614     QUnit.test('should not modify the `options` object', function(assert) {
19615       assert.expect(1);
19616
19617       var options = {};
19618       _.template('', options);
19619       assert.deepEqual(options, {});
19620     });
19621
19622     QUnit.test('should not modify `_.templateSettings` when `options` are provided', function(assert) {
19623       assert.expect(2);
19624
19625       var data = { 'a': 1 };
19626
19627       assert.notOk('a' in _.templateSettings);
19628       _.template('', {}, data);
19629       assert.notOk('a' in _.templateSettings);
19630
19631       delete _.templateSettings.a;
19632     });
19633
19634     QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
19635       assert.expect(2);
19636
19637       var pass = true;
19638
19639       try {
19640         _.template('')(1);
19641       } catch (e) {
19642         pass = false;
19643       }
19644       assert.ok(pass, '`data` value');
19645
19646       pass = true;
19647
19648       try {
19649         _.template('', 1)(1);
19650       } catch (e) {
19651         pass = false;
19652       }
19653       assert.ok(pass, '`options` value');
19654     });
19655
19656     QUnit.test('should expose the source on compiled templates', function(assert) {
19657       assert.expect(1);
19658
19659       var compiled = _.template('x'),
19660           values = [String(compiled), compiled.source],
19661           expected = lodashStable.map(values, alwaysTrue);
19662
19663       var actual = lodashStable.map(values, function(value) {
19664         return lodashStable.includes(value, '__p');
19665       });
19666
19667       assert.deepEqual(actual, expected);
19668     });
19669
19670     QUnit.test('should expose the source on SyntaxErrors', function(assert) {
19671       assert.expect(1);
19672
19673       try {
19674         _.template('<% if x %>');
19675       } catch (e) {
19676         var source = e.source;
19677       }
19678       assert.ok(lodashStable.includes(source, '__p'));
19679     });
19680
19681     QUnit.test('should not include sourceURLs in the source', function(assert) {
19682       assert.expect(1);
19683
19684       var options = { 'sourceURL': '/a/b/c' },
19685           compiled = _.template('x', options),
19686           values = [compiled.source, undefined];
19687
19688       try {
19689         _.template('<% if x %>', options);
19690       } catch (e) {
19691         values[1] = e.source;
19692       }
19693       var expected = lodashStable.map(values, alwaysFalse);
19694
19695       var actual = lodashStable.map(values, function(value) {
19696         return lodashStable.includes(value, 'sourceURL');
19697       });
19698
19699       assert.deepEqual(actual, expected);
19700     });
19701
19702     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19703       assert.expect(1);
19704
19705       var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
19706           compiles = lodashStable.map(array, _.template),
19707           data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
19708
19709       var actual = lodashStable.map(compiles, function(compiled) {
19710         return compiled(data);
19711       });
19712
19713       assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
19714     });
19715   }());
19716
19717   /*--------------------------------------------------------------------------*/
19718
19719   QUnit.module('lodash.truncate');
19720
19721   (function() {
19722     var string = 'hi-diddly-ho there, neighborino';
19723
19724     QUnit.test('should use a default `length` of `30`', function(assert) {
19725       assert.expect(1);
19726
19727       assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
19728     });
19729
19730     QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
19731       assert.expect(2);
19732
19733       assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
19734       assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
19735     });
19736
19737     QUnit.test('should truncate string the given length', function(assert) {
19738       assert.expect(1);
19739
19740       assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
19741     });
19742
19743     QUnit.test('should support a `omission` option', function(assert) {
19744       assert.expect(1);
19745
19746       assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
19747     });
19748
19749     QUnit.test('should support a `length` option', function(assert) {
19750       assert.expect(1);
19751
19752       assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
19753     });
19754
19755     QUnit.test('should support a `separator` option', function(assert) {
19756       assert.expect(3);
19757
19758       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
19759       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
19760       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
19761     });
19762
19763     QUnit.test('should treat negative `length` as `0`', function(assert) {
19764       assert.expect(2);
19765
19766       lodashStable.each([0, -2], function(length) {
19767         assert.strictEqual(_.truncate(string, { 'length': length }), '...');
19768       });
19769     });
19770
19771     QUnit.test('should coerce `length` to an integer', function(assert) {
19772       assert.expect(4);
19773
19774       lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
19775         var actual = index > 1 ? 'h...' : '...';
19776         assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
19777       });
19778     });
19779
19780     QUnit.test('should coerce `string` to a string', function(assert) {
19781       assert.expect(2);
19782
19783       assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
19784       assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
19785     });
19786
19787     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19788       assert.expect(1);
19789
19790       var actual = lodashStable.map([string, string, string], _.truncate),
19791           truncated = 'hi-diddly-ho there, neighbo...';
19792
19793       assert.deepEqual(actual, [truncated, truncated, truncated]);
19794     });
19795   }());
19796
19797   /*--------------------------------------------------------------------------*/
19798
19799   QUnit.module('lodash.throttle');
19800
19801   (function() {
19802     QUnit.test('should throttle a function', function(assert) {
19803       assert.expect(2);
19804
19805       var done = assert.async();
19806
19807       var callCount = 0,
19808           throttled = _.throttle(function() { callCount++; }, 32);
19809
19810       throttled();
19811       throttled();
19812       throttled();
19813
19814       var lastCount = callCount;
19815       assert.ok(callCount > 0);
19816
19817       setTimeout(function() {
19818         assert.ok(callCount > lastCount);
19819         done();
19820       }, 64);
19821     });
19822
19823     QUnit.test('subsequent calls should return the result of the first call', function(assert) {
19824       assert.expect(5);
19825
19826       var done = assert.async();
19827
19828       var throttled = _.throttle(identity, 32),
19829           result = [throttled('a'), throttled('b')];
19830
19831       assert.deepEqual(result, ['a', 'a']);
19832
19833       setTimeout(function() {
19834         var result = [throttled('x'), throttled('y')];
19835         assert.notEqual(result[0], 'a');
19836         assert.notStrictEqual(result[0], undefined);
19837
19838         assert.notEqual(result[1], 'y');
19839         assert.notStrictEqual(result[1], undefined);
19840         done();
19841       }, 64);
19842     });
19843
19844     QUnit.test('should clear timeout when `func` is called', function(assert) {
19845       assert.expect(1);
19846
19847       var done = assert.async();
19848
19849       if (!isModularize) {
19850         var callCount = 0,
19851             dateCount = 0;
19852
19853         var getTime = function() {
19854           return ++dateCount == 5 ? Infinity : +new Date;
19855         };
19856
19857         var lodash = _.runInContext(lodashStable.assign({}, root, {
19858           'Date': lodashStable.assign(function() {
19859             return { 'getTime': getTime };
19860           }, {
19861             'now': Date.now
19862           })
19863         }));
19864
19865         var throttled = lodash.throttle(function() {
19866           callCount++;
19867         }, 32);
19868
19869         throttled();
19870         throttled();
19871         throttled();
19872
19873         setTimeout(function() {
19874           assert.strictEqual(callCount, 2);
19875           done();
19876         }, 64);
19877       }
19878       else {
19879         skipTest(assert);
19880         done();
19881       }
19882     });
19883
19884     QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
19885       assert.expect(2);
19886
19887       var done = assert.async();
19888
19889       var callCount = 0,
19890           throttled = _.throttle(function() { callCount++; }, 32);
19891
19892       throttled();
19893       assert.strictEqual(callCount, 1);
19894
19895       setTimeout(function() {
19896         assert.strictEqual(callCount, 1);
19897         done();
19898       }, 64);
19899     });
19900
19901     lodashStable.times(2, function(index) {
19902      QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
19903         assert.expect(1);
19904
19905         var done = assert.async();
19906
19907         var callCount = 0,
19908             limit = (argv || isPhantom) ? 1000 : 320,
19909             options = index ? { 'leading': false } : {};
19910
19911         var throttled = _.throttle(function() {
19912           callCount++;
19913         }, 32, options);
19914
19915         var start = +new Date;
19916         while ((new Date - start) < limit) {
19917           throttled();
19918         }
19919         var actual = callCount > 1;
19920
19921         setTimeout(function() {
19922           assert.ok(actual);
19923           done();
19924         }, 1);
19925       });
19926     });
19927
19928     QUnit.test('should apply default options', function(assert) {
19929       assert.expect(3);
19930
19931       var done = assert.async();
19932
19933       var callCount = 0;
19934
19935       var throttled = _.throttle(function(value) {
19936         callCount++;
19937         return value;
19938       }, 32, {});
19939
19940       assert.strictEqual(throttled('a'), 'a');
19941       assert.strictEqual(throttled('b'), 'a');
19942
19943       setTimeout(function() {
19944         assert.strictEqual(callCount, 2);
19945         done();
19946       }, 128);
19947     });
19948
19949     QUnit.test('should support a `leading` option', function(assert) {
19950       assert.expect(2);
19951
19952       var withLeading = _.throttle(identity, 32, { 'leading': true });
19953       assert.strictEqual(withLeading('a'), 'a');
19954
19955       var withoutLeading = _.throttle(identity, 32, { 'leading': false });
19956       assert.strictEqual(withoutLeading('a'), undefined);
19957     });
19958
19959     QUnit.test('should support a `trailing` option', function(assert) {
19960       assert.expect(6);
19961
19962       var done = assert.async();
19963
19964       var withCount = 0,
19965           withoutCount = 0;
19966
19967       var withTrailing = _.throttle(function(value) {
19968         withCount++;
19969         return value;
19970       }, 64, { 'trailing': true });
19971
19972       var withoutTrailing = _.throttle(function(value) {
19973         withoutCount++;
19974         return value;
19975       }, 64, { 'trailing': false });
19976
19977       assert.strictEqual(withTrailing('a'), 'a');
19978       assert.strictEqual(withTrailing('b'), 'a');
19979
19980       assert.strictEqual(withoutTrailing('a'), 'a');
19981       assert.strictEqual(withoutTrailing('b'), 'a');
19982
19983       setTimeout(function() {
19984         assert.strictEqual(withCount, 2);
19985         assert.strictEqual(withoutCount, 1);
19986         done();
19987       }, 256);
19988     });
19989
19990     QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
19991       assert.expect(1);
19992
19993       var done = assert.async();
19994
19995       var callCount = 0;
19996
19997       var throttled = _.throttle(function() {
19998         callCount++;
19999       }, 64, { 'trailing': false });
20000
20001       throttled();
20002       throttled();
20003
20004       setTimeout(function() {
20005         throttled();
20006         throttled();
20007       }, 96);
20008
20009       setTimeout(function() {
20010         assert.ok(callCount > 1);
20011         done();
20012       }, 192);
20013     });
20014   }());
20015
20016   /*--------------------------------------------------------------------------*/
20017
20018   QUnit.module('lodash.debounce and lodash.throttle');
20019
20020   lodashStable.each(['debounce', 'throttle'], function(methodName) {
20021     var func = _[methodName],
20022         isDebounce = methodName == 'debounce';
20023
20024     QUnit.test('_.' + methodName + ' should not error for non-object `options` values', function(assert) {
20025       assert.expect(1);
20026
20027       var pass = true;
20028
20029       try {
20030         func(noop, 32, 1);
20031       } catch (e) {
20032         pass = false;
20033       }
20034       assert.ok(pass);
20035     });
20036
20037     QUnit.test('_.' + methodName + ' should use a default `wait` of `0`', function(assert) {
20038       assert.expect(1);
20039
20040       var done = assert.async();
20041
20042       var callCount = 0;
20043
20044       var funced = func(function() {
20045         callCount++;
20046       });
20047
20048       funced();
20049
20050       setTimeout(function() {
20051         funced();
20052         assert.strictEqual(callCount, isDebounce ? 1 : 2);
20053         done();
20054       }, 32);
20055     });
20056
20057     QUnit.test('_.' + methodName + ' should invoke `func` with the correct `this` binding', function(assert) {
20058       assert.expect(1);
20059
20060       var done = assert.async();
20061
20062       var object = {
20063         'funced': func(function() { actual.push(this); }, 32)
20064       };
20065
20066       var actual = [],
20067           expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
20068
20069       object.funced();
20070       if (!isDebounce) {
20071         object.funced();
20072       }
20073       setTimeout(function() {
20074         assert.deepEqual(actual, expected);
20075         done();
20076       }, 64);
20077     });
20078
20079     QUnit.test('_.' + methodName + ' supports recursive calls', function(assert) {
20080       assert.expect(2);
20081
20082       var done = assert.async();
20083
20084       var actual = [],
20085           args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
20086           expected = args.slice(),
20087           queue = args.slice();
20088
20089       var funced = func(function() {
20090         var current = [this];
20091         push.apply(current, arguments);
20092         actual.push(current);
20093
20094         var next = queue.shift();
20095         if (next) {
20096           funced.call(next[0], next[1]);
20097         }
20098       }, 32);
20099
20100       var next = queue.shift();
20101       funced.call(next[0], next[1]);
20102       assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
20103
20104       setTimeout(function() {
20105         assert.deepEqual(actual, expected.slice(0, actual.length));
20106         done();
20107       }, 256);
20108     });
20109
20110     QUnit.test('_.' + methodName + ' should work if the system time is set backwards', function(assert) {
20111       assert.expect(1);
20112
20113       var done = assert.async();
20114
20115       if (!isModularize) {
20116         var callCount = 0,
20117             dateCount = 0;
20118
20119         var getTime = function() {
20120           return ++dateCount === 4 ? +new Date(2012, 3, 23, 23, 27, 18) : +new Date;
20121         };
20122
20123         var lodash = _.runInContext(lodashStable.assign({}, root, {
20124           'Date': lodashStable.assign(function() {
20125             return { 'getTime': getTime, 'valueOf': getTime };
20126           }, {
20127             'now': Date.now
20128           })
20129         }));
20130
20131         var funced = lodash[methodName](function() {
20132           callCount++;
20133         }, 32);
20134
20135         funced();
20136
20137         setTimeout(function() {
20138           funced();
20139           assert.strictEqual(callCount, isDebounce ? 1 : 2);
20140           done();
20141         }, 64);
20142       }
20143       else {
20144         skipTest(assert);
20145         done();
20146       }
20147     });
20148
20149     QUnit.test('_.' + methodName + ' should support cancelling delayed calls', function(assert) {
20150       assert.expect(1);
20151
20152       var done = assert.async();
20153
20154       var callCount = 0;
20155
20156       var funced = func(function() {
20157         callCount++;
20158       }, 32, { 'leading': false });
20159
20160       funced();
20161       funced.cancel();
20162
20163       setTimeout(function() {
20164         assert.strictEqual(callCount, 0);
20165         done();
20166       }, 64);
20167     });
20168
20169     QUnit.test('_.' + methodName + ' should reset `lastCalled` after cancelling', function(assert) {
20170       assert.expect(3);
20171
20172       var done = assert.async();
20173
20174       var callCount = 0;
20175
20176       var funced = func(function() {
20177         return ++callCount;
20178       }, 32, { 'leading': true });
20179
20180       assert.strictEqual(funced(), 1);
20181       funced.cancel();
20182       assert.strictEqual(funced(), 2);
20183
20184       setTimeout(function() {
20185         assert.strictEqual(callCount, 2);
20186         done();
20187       }, 64);
20188     });
20189
20190     QUnit.test('_.' + methodName + ' should support flushing delayed calls', function(assert) {
20191       assert.expect(2);
20192
20193       var done = assert.async();
20194
20195       var callCount = 0;
20196
20197       var funced = func(function() {
20198         return ++callCount;
20199       }, 32, { 'leading': false });
20200
20201       funced();
20202       var actual = funced.flush();
20203
20204       setTimeout(function() {
20205         assert.strictEqual(actual, 1);
20206         assert.strictEqual(callCount, 1);
20207         done();
20208       }, 64);
20209     });
20210   });
20211
20212   /*--------------------------------------------------------------------------*/
20213
20214   QUnit.module('lodash.times');
20215
20216   (function() {
20217     QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
20218       assert.expect(3);
20219
20220       lodashStable.each([-Infinity, NaN, Infinity], function(n) {
20221         assert.deepEqual(_.times(n), []);
20222       });
20223     });
20224
20225     QUnit.test('should coerce `n` to an integer', function(assert) {
20226       assert.expect(1);
20227
20228       var actual = _.times(2.6, _.indentify);
20229       assert.deepEqual(actual, [0, 1]);
20230     });
20231
20232     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
20233       assert.expect(1);
20234
20235       var args;
20236
20237       _.times(1, function(assert) {
20238         args || (args = slice.call(arguments));
20239       });
20240
20241       assert.deepEqual(args, [0]);
20242     });
20243
20244     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20245       assert.expect(1);
20246
20247       var values = [, null, undefined],
20248           expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
20249
20250       var actual = lodashStable.map(values, function(value, index) {
20251         return index ? _.times(3, value) : _.times(3);
20252       });
20253
20254       assert.deepEqual(actual, expected);
20255     });
20256
20257     QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
20258       assert.expect(1);
20259
20260       assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
20261     });
20262
20263     QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
20264       assert.expect(1);
20265
20266       var values = falsey.concat(-1, -Infinity),
20267           expected = lodashStable.map(values, alwaysEmptyArray);
20268
20269       var actual = lodashStable.map(values, function(value, index) {
20270         return index ? _.times(value) : _.times();
20271       });
20272
20273       assert.deepEqual(actual, expected);
20274     });
20275
20276     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
20277       assert.expect(1);
20278
20279       if (!isNpm) {
20280         assert.deepEqual(_(3).times(), [0, 1, 2]);
20281       }
20282       else {
20283         skipTest(assert);
20284       }
20285     });
20286
20287     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
20288       assert.expect(1);
20289
20290       if (!isNpm) {
20291         assert.ok(_(3).chain().times() instanceof _);
20292       }
20293       else {
20294         skipTest(assert);
20295       }
20296     });
20297   }());
20298
20299   /*--------------------------------------------------------------------------*/
20300
20301   QUnit.module('lodash.toArray');
20302
20303   (function() {
20304     QUnit.test('should convert objects to arrays', function(assert) {
20305       assert.expect(1);
20306
20307       assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
20308     });
20309
20310     QUnit.test('should convert strings to arrays', function(assert) {
20311       assert.expect(3);
20312
20313       assert.deepEqual(_.toArray(''), []);
20314       assert.deepEqual(_.toArray('ab'), ['a', 'b']);
20315       assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
20316     });
20317
20318     QUnit.test('should convert iterables to arrays', function(assert) {
20319       assert.expect(1);
20320
20321       if (!isNpm && Symbol && Symbol.iterator) {
20322         var object = { '0': 'a', 'length': 1 };
20323         object[Symbol.iterator] = arrayProto[Symbol.iterator];
20324
20325         assert.deepEqual(_.toArray(object), ['a']);
20326       }
20327       else {
20328         skipTest(assert);
20329       }
20330     });
20331
20332     QUnit.test('should work in a lazy sequence', function(assert) {
20333       assert.expect(2);
20334
20335       if (!isNpm) {
20336         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
20337             actual = _(array).slice(1).map(String).toArray().value();
20338
20339         assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
20340
20341         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
20342           return ['key' + index, index];
20343         }));
20344
20345         actual = _(object).toArray().slice(1).map(String).value();
20346         assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
20347       }
20348       else {
20349         skipTest(assert, 2);
20350       }
20351     });
20352   }());
20353
20354   /*--------------------------------------------------------------------------*/
20355
20356   QUnit.module('lodash.toLower');
20357
20358   (function() {
20359     QUnit.test('should convert whole string to lower case', function(assert) {
20360       assert.expect(3);
20361
20362       assert.deepEqual(_.toLower('--Foo-Bar'), '--foo-bar');
20363       assert.deepEqual(_.toLower('fooBar'), 'foobar');
20364       assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
20365     });
20366   }());
20367
20368   /*--------------------------------------------------------------------------*/
20369
20370   QUnit.module('lodash.toUpper');
20371
20372   (function() {
20373     QUnit.test('should convert whole string to upper case', function(assert) {
20374       assert.expect(3);
20375
20376       assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
20377       assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
20378       assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
20379     });
20380   }());
20381
20382   /*--------------------------------------------------------------------------*/
20383
20384   QUnit.module('lodash.slice and lodash.toArray');
20385
20386   lodashStable.each(['slice', 'toArray'], function(methodName) {
20387     var args = (function() { return arguments; }(1, 2, 3)),
20388         array = [1, 2, 3],
20389         func = _[methodName];
20390
20391     QUnit.test('should return a dense array', function(assert) {
20392       assert.expect(3);
20393
20394       var sparse = Array(3);
20395       sparse[1] = 2;
20396
20397       var actual = func(sparse);
20398
20399       assert.ok('0' in actual);
20400       assert.ok('2' in actual);
20401       assert.deepEqual(actual, sparse);
20402     });
20403
20404     QUnit.test('should treat array-like objects like arrays', function(assert) {
20405       assert.expect(2);
20406
20407       var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
20408       assert.deepEqual(func(object), ['a', 'b', 'c']);
20409       assert.deepEqual(func(args), array);
20410     });
20411
20412     QUnit.test('should return a shallow clone of arrays', function(assert) {
20413       assert.expect(2);
20414
20415       var actual = func(array);
20416       assert.deepEqual(actual, array);
20417       assert.notStrictEqual(actual, array);
20418     });
20419
20420     QUnit.test('should work with a node list for `collection`', function(assert) {
20421       assert.expect(1);
20422
20423       if (document) {
20424         try {
20425           var actual = func(document.getElementsByTagName('body'));
20426         } catch (e) {}
20427
20428         assert.deepEqual(actual, [body]);
20429       }
20430       else {
20431         skipTest(assert);
20432       }
20433     });
20434   });
20435
20436   /*--------------------------------------------------------------------------*/
20437
20438   QUnit.module('toInteger methods');
20439
20440   lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
20441     var func = _[methodName],
20442         isSafe = methodName == 'toSafeInteger';
20443
20444     QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
20445       assert.expect(6);
20446
20447       assert.strictEqual(func(-5.6), -5);
20448       assert.strictEqual(func('5.6'), 5);
20449       assert.strictEqual(func(), 0);
20450       assert.strictEqual(func(NaN), 0);
20451
20452       var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
20453       assert.strictEqual(func(Infinity), expected);
20454       assert.strictEqual(func(-Infinity), -expected);
20455     });
20456
20457     QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
20458       assert.expect(1);
20459
20460       assert.strictEqual(1 / func(-0), -Infinity);
20461     });
20462   });
20463
20464   /*--------------------------------------------------------------------------*/
20465
20466   QUnit.module('lodash.toLength');
20467
20468   (function() {
20469     QUnit.test('should return a valid length', function(assert) {
20470       assert.expect(4);
20471
20472       assert.strictEqual(_.toLength(-1), 0);
20473       assert.strictEqual(_.toLength('1'), 1);
20474       assert.strictEqual(_.toLength(1.1), 1);
20475       assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
20476     });
20477
20478     QUnit.test('should return `value` if a valid length', function(assert) {
20479       assert.expect(3);
20480
20481       assert.strictEqual(_.toLength(0), 0);
20482       assert.strictEqual(_.toLength(3), 3);
20483       assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
20484     });
20485
20486     QUnit.test('should convert `-0` to `0`', function(assert) {
20487       assert.expect(1);
20488
20489       assert.strictEqual(1 / _.toLength(-0), Infinity);
20490     });
20491   }());
20492
20493   /*--------------------------------------------------------------------------*/
20494
20495   QUnit.module('lodash.toInteger and lodash.toNumber');
20496
20497   lodashStable.each(['toInteger', 'toNumber'], function(methodName) {
20498     var func = _[methodName],
20499         isInt = methodName == 'toInteger';
20500
20501     function negative(string) {
20502       return '-' + string;
20503     }
20504
20505     function pad(string) {
20506       return whitespace + string + whitespace;
20507     }
20508
20509     function positive(string) {
20510       return '+' + string;
20511     }
20512
20513     QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
20514       assert.expect(1);
20515
20516       var values = falsey.concat(whitespace);
20517
20518       var expected = lodashStable.map(values, function(value) {
20519         return (isInt || (value === whitespace)) ? 0 : Number(value);
20520       });
20521
20522       var actual = lodashStable.map(values, function(value, index) {
20523         return index ? func(value) : func();
20524       });
20525
20526       assert.deepEqual(actual, expected);
20527     });
20528
20529     QUnit.test('`_.' + methodName + '` should preserve sign of `0`', function(assert) {
20530       assert.expect(1);
20531
20532       var values = [0, '0', -0, '-0'],
20533           expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
20534
20535       var actual = lodashStable.map(values, function(value) {
20536         var result = func(value);
20537         return [result, 1 / result];
20538       });
20539
20540       assert.deepEqual(actual, expected);
20541     });
20542
20543     QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
20544       assert.expect(1);
20545
20546       var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
20547
20548       var expected = lodashStable.map(values, function(value) {
20549         if (isInt) {
20550           if (value == 1.2) {
20551             value = 1;
20552           }
20553           else if (value == Infinity) {
20554             value = MAX_INTEGER;
20555           }
20556           else if (value !== value) {
20557             value = 0;
20558           }
20559         }
20560         return [value, value, -value, -value];
20561       });
20562
20563       var actual = lodashStable.map(values, function(value) {
20564         return lodashStable.flattenDeep(
20565           lodashStable.times(2, function(index) {
20566             var other = index ? -value : value;
20567             return [
20568               func(other),
20569               func(Object(other))
20570             ];
20571           })
20572         );
20573       });
20574
20575       assert.deepEqual(actual, expected);
20576     });
20577
20578     QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
20579       assert.expect(1);
20580
20581       var transforms = [identity, pad, positive, negative];
20582
20583       var values = [
20584         '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
20585         '1e+308', '1e308', '1E+308', '1E308',
20586         '5e-324', '5E-324',
20587         'Infinity', 'NaN'
20588       ];
20589
20590       var expected = lodashStable.map(values, function(value) {
20591         var n = +value;
20592         if (isInt) {
20593           if (n == 1.234567890) {
20594             n = 1;
20595           }
20596           else if (n == Infinity) {
20597             n = MAX_INTEGER;
20598           }
20599           else if (n == Number.MIN_VALUE || n !== n) {
20600             n = 0;
20601           }
20602         }
20603         return [n, n, n, n, n, n, -n, -n];
20604       });
20605
20606       var actual = lodashStable.map(values, function(value) {
20607         return lodashStable.flattenDeep(
20608           lodashStable.map(transforms, function(mod) {
20609             return [
20610               func(mod(value)),
20611               func(Object(mod(value)))
20612             ];
20613           })
20614         );
20615       });
20616
20617       assert.deepEqual(actual, expected);
20618     });
20619
20620     QUnit.test('`_.' + methodName + '` should convert binary and octal strings to numbers', function(assert) {
20621       assert.expect(1);
20622
20623       var numbers = [42, 5349, 1715004],
20624           transforms = [identity, pad],
20625           values = ['0b101010', '0o12345', '0x1a2b3c'];
20626
20627       var expected = lodashStable.map(numbers, function(n) {
20628         return lodashStable.times(8, lodashStable.constant(n));
20629       });
20630
20631       var actual = lodashStable.map(values, function(value) {
20632         return lodashStable.flattenDeep(
20633           lodashStable.times(2, function(index) {
20634             var other = index ? value.toUpperCase() : value;
20635             return lodashStable.map(transforms, function(mod) {
20636               return [
20637                 func(mod(other)),
20638                 func(Object(mod(other)))
20639               ];
20640             });
20641           })
20642         );
20643       });
20644
20645       assert.deepEqual(actual, expected);
20646     });
20647
20648     QUnit.test('`_.' + methodName + '` should convert invalid binary and octal strings to `NaN`', function(assert) {
20649       assert.expect(1);
20650
20651       var transforms = [identity, pad, positive, negative],
20652           values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
20653
20654       var expected = lodashStable.map(values, function(n) {
20655         return lodashStable.times(16, lodashStable.constant(isInt ? 0 : NaN));
20656       });
20657
20658       var actual = lodashStable.map(values, function(value) {
20659         return lodashStable.flattenDeep(
20660           lodashStable.times(2, function(index) {
20661             var other = index ? value.toUpperCase() : value;
20662             return lodashStable.map(transforms, function(mod) {
20663               return [
20664                 func(mod(value)),
20665                 func(Object(mod(value)))
20666               ];
20667             });
20668           })
20669         );
20670       });
20671
20672       assert.deepEqual(actual, expected);
20673     });
20674
20675     QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
20676       assert.expect(1);
20677
20678       var values = [
20679         {},
20680         [],
20681         [1],
20682         [1, 2],
20683         { 'valueOf': '1.1' },
20684         { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
20685         { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
20686         { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
20687         { 'valueOf': lodashStable.constant('-0x1a2b3c') },
20688         { 'toString': lodashStable.constant('-0x1a2b3c') },
20689         { 'valueOf': lodashStable.constant('0o12345') },
20690         { 'toString': lodashStable.constant('0o12345') },
20691         { 'valueOf': lodashStable.constant('0b101010') },
20692         { 'toString': lodashStable.constant('0b101010') }
20693       ];
20694
20695       var expected = [
20696         NaN,   0,   1,   NaN,
20697         NaN,  2.2,  1.1, 1.1,
20698         NaN,  NaN,
20699         5349, 5349,
20700         42,   42
20701       ];
20702
20703       if (isInt) {
20704         expected = [
20705           0, 0, 1, 0,
20706           0, 2, 1, 1,
20707           0, 0,
20708           5349, 5349,
20709           42, 42
20710         ];
20711       }
20712       var actual = lodashStable.map(values, func);
20713
20714       assert.deepEqual(actual, expected);
20715     });
20716   });
20717
20718   /*--------------------------------------------------------------------------*/
20719
20720   QUnit.module('lodash.toPairs');
20721
20722   (function() {
20723     QUnit.test('should create a two dimensional array of key-value pairs', function(assert) {
20724       assert.expect(1);
20725
20726       var object = { 'a': 1, 'b': 2 };
20727       assert.deepEqual(_.toPairs(object), [['a', 1], ['b', 2]]);
20728     });
20729
20730     QUnit.test('should work with an object that has a `length` property', function(assert) {
20731       assert.expect(1);
20732
20733       var object = { '0': 'a', '1': 'b', 'length': 2 };
20734       assert.deepEqual(_.toPairs(object), [['0', 'a'], ['1', 'b'], ['length', 2]]);
20735     });
20736
20737     QUnit.test('should work with strings', function(assert) {
20738       assert.expect(2);
20739
20740       lodashStable.each(['xo', Object('xo')], function(string) {
20741         assert.deepEqual(_.toPairs(string), [['0', 'x'], ['1', 'o']]);
20742       });
20743     });
20744   }());
20745
20746   /*--------------------------------------------------------------------------*/
20747
20748   QUnit.module('lodash.toPath');
20749
20750   (function() {
20751     QUnit.test('should convert a string to a path', function(assert) {
20752       assert.expect(2);
20753
20754       assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
20755       assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
20756     });
20757
20758     QUnit.test('should coerce array elements to strings', function(assert) {
20759       assert.expect(4);
20760
20761       var array = ['a', 'b', 'c'];
20762
20763       lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
20764         var actual = _.toPath(value);
20765         assert.deepEqual(actual, array);
20766         assert.notStrictEqual(actual, array);
20767       });
20768     });
20769
20770     QUnit.test('should handle complex paths', function(assert) {
20771       assert.expect(1);
20772
20773       var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
20774       assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
20775     });
20776
20777     QUnit.test('should ignore consecutive brackets and dots', function(assert) {
20778       assert.expect(4);
20779
20780       var expected = ['a'];
20781       assert.deepEqual(_.toPath('a.'), expected);
20782       assert.deepEqual(_.toPath('a[]'), expected);
20783
20784       expected = ['a', 'b'];
20785       assert.deepEqual(_.toPath('a..b'), expected);
20786       assert.deepEqual(_.toPath('a[][]b'), expected);
20787     });
20788   }());
20789
20790   /*--------------------------------------------------------------------------*/
20791
20792   QUnit.module('lodash.toPlainObject');
20793
20794   (function() {
20795     var args = arguments;
20796
20797     QUnit.test('should flatten inherited properties', function(assert) {
20798       assert.expect(1);
20799
20800       function Foo() { this.b = 2; }
20801       Foo.prototype.c = 3;
20802
20803       var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
20804       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
20805     });
20806
20807     QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
20808       assert.expect(1);
20809
20810       var actual = _.toPlainObject(args),
20811           expected = { '0': 1, '1': 2, '2': 3 };
20812
20813       assert.deepEqual(actual, expected);
20814     });
20815
20816     QUnit.test('should convert arrays to plain objects', function(assert) {
20817       assert.expect(1);
20818
20819       var actual = _.toPlainObject(['a', 'b', 'c']),
20820           expected = { '0': 'a', '1': 'b', '2': 'c' };
20821
20822       assert.deepEqual(actual, expected);
20823     });
20824   }(1, 2, 3));
20825
20826   /*--------------------------------------------------------------------------*/
20827
20828   QUnit.module('lodash.toString');
20829
20830   (function() {
20831     QUnit.test('should treat nullish values as empty strings', function(assert) {
20832       assert.expect(1);
20833
20834       var values = [, null, undefined],
20835           expected = lodashStable.map(values, alwaysEmptyString);
20836
20837       var actual = lodashStable.map(values, function(value, index) {
20838         return index ? _.toString(value) : _.toString();
20839       });
20840
20841       assert.deepEqual(actual, expected);
20842     });
20843
20844     QUnit.test('should preserve sign of `0`', function(assert) {
20845       assert.expect(1);
20846
20847       var values = [0, Object(0), -0, Object(-0)],
20848           expected = ['0', '0', '-0', '-0'],
20849           actual = lodashStable.map(values, _.toString);
20850
20851       assert.deepEqual(actual, expected);
20852     });
20853
20854     QUnit.test('should not error on symbols', function(assert) {
20855       assert.expect(1);
20856
20857       if (Symbol) {
20858         try {
20859           assert.strictEqual(_.toString(symbol), 'Symbol(a)');
20860         } catch (e) {
20861           assert.ok(false, e.message);
20862         }
20863       }
20864       else {
20865         skipTest(assert);
20866       }
20867     });
20868
20869     QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
20870       assert.expect(1);
20871
20872       if (!isNpm) {
20873         var wrapped = _([1, 2, 3]);
20874         assert.strictEqual(wrapped.toString(), '1,2,3');
20875       }
20876       else {
20877         skipTest(assert);
20878       }
20879     });
20880   }());
20881
20882   /*--------------------------------------------------------------------------*/
20883
20884   QUnit.module('lodash.transform');
20885
20886   (function() {
20887     function Foo() {
20888       this.a = 1;
20889       this.b = 2;
20890       this.c = 3;
20891     }
20892
20893     QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
20894       assert.expect(4);
20895
20896       var accumulators = [, null, undefined],
20897           expected = lodashStable.map(accumulators, alwaysTrue),
20898           object = new Foo;
20899
20900       var iteratee = function(result, value, key) {
20901         result[key] = square(value);
20902       };
20903
20904       var mapper = function(accumulator, index) {
20905         return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
20906       };
20907
20908       var results = lodashStable.map(accumulators, mapper);
20909
20910       var actual = lodashStable.map(results, function(result) {
20911         return result instanceof Foo;
20912       });
20913
20914       assert.deepEqual(actual, expected);
20915
20916       expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
20917       actual = lodashStable.map(results, lodashStable.toPlainObject);
20918
20919       assert.deepEqual(actual, expected);
20920
20921       object = { 'a': 1, 'b': 2, 'c': 3 };
20922       actual = lodashStable.map(accumulators, mapper);
20923
20924       assert.deepEqual(actual, expected);
20925
20926       object = [1, 2, 3];
20927       expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
20928       actual = lodashStable.map(accumulators, mapper);
20929
20930       assert.deepEqual(actual, expected);
20931     });
20932
20933     QUnit.test('should create regular arrays from typed arrays', function(assert) {
20934       assert.expect(1);
20935
20936       var expected = lodashStable.map(typedArrays, alwaysTrue);
20937
20938       var actual = lodashStable.map(typedArrays, function(type) {
20939         var Ctor = root[type],
20940             array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
20941
20942         return lodashStable.isArray(_.transform(array, noop));
20943       });
20944
20945       assert.deepEqual(actual, expected);
20946     });
20947
20948     QUnit.test('should support an `accumulator` value', function(assert) {
20949       assert.expect(6);
20950
20951       var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
20952           expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
20953
20954       var actual = lodashStable.map(values, function(value) {
20955         return _.transform(value, function(result, value) {
20956           result.push(square(value));
20957         }, []);
20958       });
20959
20960       assert.deepEqual(actual, expected);
20961
20962       var object = { 'a': 1, 'b': 4, 'c': 9 },
20963       expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
20964
20965       actual = lodashStable.map(values, function(value) {
20966         return _.transform(value, function(result, value, key) {
20967           result[key] = square(value);
20968         }, {});
20969       });
20970
20971       assert.deepEqual(actual, expected);
20972
20973       lodashStable.each([[], {}], function(accumulator) {
20974         var actual = lodashStable.map(values, function(value) {
20975           return _.transform(value, noop, accumulator);
20976         });
20977
20978         assert.ok(lodashStable.every(actual, function(result) {
20979           return result === accumulator;
20980         }));
20981
20982         assert.strictEqual(_.transform(null, null, accumulator), accumulator);
20983       });
20984     });
20985
20986     QUnit.test('should treat sparse arrays as dense', function(assert) {
20987       assert.expect(1);
20988
20989       var actual = _.transform(Array(1), function(result, value, index) {
20990         result[index] = String(value);
20991       });
20992
20993       assert.deepEqual(actual, ['undefined']);
20994     });
20995
20996     QUnit.test('should work without an `iteratee` argument', function(assert) {
20997       assert.expect(1);
20998
20999       assert.ok(_.transform(new Foo) instanceof Foo);
21000     });
21001
21002     QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
21003       assert.expect(2);
21004
21005       var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
21006           values = [true, false, 0, 1, NaN, '', 'a'],
21007           expected = lodashStable.map(values, alwaysEmptyObject);
21008
21009       var results = lodashStable.map(values, function(value) {
21010         return _.transform(value);
21011       });
21012
21013       assert.deepEqual(results, expected);
21014
21015       expected = lodashStable.map(values, alwaysFalse);
21016
21017       var actual = lodashStable.map(results, function(value, index) {
21018         return value instanceof Ctors[index];
21019       });
21020
21021       assert.deepEqual(actual, expected);
21022     });
21023
21024     QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
21025       assert.expect(1);
21026
21027       Foo.prototype.constructor = null;
21028       assert.notOk(_.transform(new Foo) instanceof Foo);
21029       Foo.prototype.constructor = Foo;
21030     });
21031
21032     QUnit.test('should create an empty object when provided a falsey `object` argument', function(assert) {
21033       assert.expect(1);
21034
21035       var expected = lodashStable.map(falsey, alwaysEmptyObject);
21036
21037       var actual = lodashStable.map(falsey, function(object, index) {
21038         return index ? _.transform(object) : _.transform();
21039       });
21040
21041       assert.deepEqual(actual, expected);
21042     });
21043
21044     lodashStable.each({
21045       'array': [1, 2, 3],
21046       'object': { 'a': 1, 'b': 2, 'c': 3 }
21047     },
21048     function(object, key) {
21049       QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
21050         assert.expect(2);
21051
21052         var args;
21053
21054         _.transform(object, function() {
21055           args || (args = slice.call(arguments));
21056         });
21057
21058         var first = args[0];
21059         if (key == 'array') {
21060           assert.ok(first !== object && lodashStable.isArray(first));
21061           assert.deepEqual(args, [first, 1, 0, object]);
21062         } else {
21063           assert.ok(first !== object && lodashStable.isPlainObject(first));
21064           assert.deepEqual(args, [first, 1, 'a', object]);
21065         }
21066       });
21067     });
21068
21069     QUnit.test('should create an object from the same realm as `object`', function(assert) {
21070       assert.expect(1);
21071
21072       var objects = lodashStable.filter(realm, function(value) {
21073         return lodashStable.isObject(value) && !lodashStable.isElement(value);
21074       });
21075
21076       var expected = lodashStable.map(objects, alwaysTrue);
21077
21078       var actual = lodashStable.map(objects, function(object) {
21079         var Ctor = object.constructor,
21080             result = _.transform(object);
21081
21082         if (result === object) {
21083           return false;
21084         }
21085         if (lodashStable.isTypedArray(object)) {
21086           return result instanceof Array;
21087         }
21088         return result instanceof Ctor || !(new Ctor instanceof Ctor);
21089       });
21090
21091       assert.deepEqual(actual, expected);
21092     });
21093   }());
21094
21095   /*--------------------------------------------------------------------------*/
21096
21097   QUnit.module('trim methods');
21098
21099   lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
21100     var func = _[methodName];
21101
21102     var parts = [];
21103     if (index != 2) {
21104       parts.push('leading');
21105     }
21106     if (index != 1) {
21107       parts.push('trailing');
21108     }
21109     parts = parts.join(' and ');
21110
21111     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
21112       assert.expect(1);
21113
21114       var string = whitespace + 'a b c' + whitespace,
21115           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
21116
21117       assert.strictEqual(func(string), expected);
21118     });
21119
21120     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
21121       assert.expect(1);
21122
21123       var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
21124           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
21125
21126       assert.strictEqual(func(object), expected);
21127     });
21128
21129     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
21130       assert.expect(1);
21131
21132       var string = '-_-a-b-c-_-',
21133           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
21134
21135       assert.strictEqual(func(string, '_-'), expected);
21136     });
21137
21138     QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
21139       assert.expect(1);
21140
21141       var object = { 'toString': lodashStable.constant('_-') },
21142           string = '-_-a-b-c-_-',
21143           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
21144
21145       assert.strictEqual(func(string, object), expected);
21146     });
21147
21148     QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
21149       assert.expect(6);
21150
21151       lodashStable.each([null, '_-'], function(chars) {
21152         assert.strictEqual(func(null, chars), '');
21153         assert.strictEqual(func(undefined, chars), '');
21154         assert.strictEqual(func('', chars), '');
21155       });
21156     });
21157
21158     QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
21159       assert.expect(2);
21160
21161       var string = whitespace + 'a b c' + whitespace,
21162           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
21163
21164       assert.strictEqual(func(string, undefined), expected);
21165       assert.strictEqual(func(string, ''), string);
21166     });
21167
21168     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
21169       assert.expect(1);
21170
21171       var string = Object(whitespace + 'a b c' + whitespace),
21172           trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
21173           actual = lodashStable.map([string, string, string], func);
21174
21175       assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
21176     });
21177
21178     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
21179       assert.expect(1);
21180
21181       if (!isNpm) {
21182         var string = whitespace + 'a b c' + whitespace,
21183             expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
21184
21185         assert.strictEqual(_(string)[methodName](), expected);
21186       }
21187       else {
21188         skipTest(assert);
21189       }
21190     });
21191
21192     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
21193       assert.expect(1);
21194
21195       if (!isNpm) {
21196         var string = whitespace + 'a b c' + whitespace;
21197         assert.ok(_(string).chain()[methodName]() instanceof _);
21198       }
21199       else {
21200         skipTest(assert);
21201       }
21202     });
21203   });
21204
21205   /*--------------------------------------------------------------------------*/
21206
21207   QUnit.module('uncommon symbols');
21208
21209   (function() {
21210     var flag = '\ud83c\uddfa\ud83c\uddf8',
21211         heart = '\u2764' + emojiVar,
21212         hearts = '\ud83d\udc95',
21213         leafs = '\ud83c\udf42',
21214         raisedHand = '\u270B' + emojiVar,
21215         rocket = '\ud83d\ude80',
21216         thumbsUp = '\ud83d\udc4d',
21217         comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68';
21218
21219     QUnit.test('should account for astral symbols', function(assert) {
21220       assert.expect(25);
21221
21222       var allHearts = _.repeat(hearts, 10),
21223           chars = hearts + comboGlyph,
21224           string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
21225           trimChars = comboGlyph + hearts,
21226           trimString = trimChars + string + trimChars;
21227
21228       assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
21229       assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
21230       assert.strictEqual(_.capitalize(rocket), rocket);
21231
21232       assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
21233       assert.strictEqual(_.padStart(string, 16), '   ' + string);
21234       assert.strictEqual(_.padEnd(string, 16), string + '   ');
21235
21236       assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
21237       assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
21238       assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
21239
21240       assert.strictEqual(_.size(string), 13);
21241       assert.deepEqual(_.toArray(string), ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket]);
21242
21243       assert.strictEqual(_.trim(trimString, chars), string);
21244       assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
21245       assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
21246
21247       assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
21248       assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
21249
21250       assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
21251
21252       lodashStable.times(2, function(index) {
21253         var separator = index ? RegExp(hearts) : hearts,
21254             options = { 'length': 4, 'separator': separator },
21255             actual = _.truncate(string, options);
21256
21257         assert.strictEqual(actual, 'A...');
21258         assert.strictEqual(actual.length, 4);
21259
21260         actual = _.truncate(allHearts, options);
21261         assert.strictEqual(actual, hearts + '...');
21262         assert.strictEqual(actual.length, 5);
21263       });
21264     });
21265
21266     QUnit.test('should match lone surrogates', function(assert) {
21267       assert.expect(3);
21268
21269       var pair = hearts.split(''),
21270           surrogates = pair[0] + ' ' + pair[1];
21271
21272       assert.strictEqual(_.size(surrogates), 3);
21273       assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
21274       assert.deepEqual(_.words(surrogates), []);
21275     });
21276
21277     QUnit.test('should account for regional symbols', function(assert) {
21278       assert.expect(6);
21279
21280       var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
21281           regionals = pair.join(' ');
21282
21283       assert.strictEqual(_.size(flag), 1);
21284       assert.strictEqual(_.size(regionals), 3);
21285
21286       assert.deepEqual(_.toArray(flag), [flag]);
21287       assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
21288
21289       assert.deepEqual(_.words(flag), [flag]);
21290       assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
21291     });
21292
21293     QUnit.test('should account for variation selectors', function(assert) {
21294       assert.expect(3);
21295
21296       assert.strictEqual(_.size(heart), 1);
21297       assert.deepEqual(_.toArray(heart), [heart]);
21298       assert.deepEqual(_.words(heart), [heart]);
21299     });
21300
21301     QUnit.test('should account for modifiers', function(assert) {
21302       assert.expect(1);
21303
21304       var values = lodashStable.map(emojiModifiers, function(modifier) {
21305         return thumbsUp + modifier;
21306       });
21307
21308       var expected = lodashStable.map(values, function(value) {
21309         return [1, [value], [value]];
21310       });
21311
21312       var actual = lodashStable.map(values, function(value) {
21313         return [_.size(value), _.toArray(value), _.words(value)];
21314       });
21315
21316       assert.deepEqual(actual, expected);
21317     });
21318
21319     QUnit.test('should account for variation selectors with modifiers', function(assert) {
21320       assert.expect(1);
21321
21322       var values = lodashStable.map(emojiModifiers, function(modifier) {
21323         return raisedHand + modifier;
21324       });
21325
21326       var expected = lodashStable.map(values, function(value) {
21327         return [1, [value], [value]];
21328       });
21329
21330       var actual = lodashStable.map(values, function(value) {
21331         return [_.size(value), _.toArray(value), _.words(value)];
21332       });
21333
21334       assert.deepEqual(actual, expected);
21335     });
21336
21337     QUnit.test('should account for combining diacritical marks', function(assert) {
21338       assert.expect(1);
21339
21340       var values = lodashStable.map(comboMarks, function(mark) {
21341         return 'o' + mark;
21342       });
21343
21344       var expected = lodashStable.map(values, function(value) {
21345         return [1, [value], [value]];
21346       });
21347
21348       var actual = lodashStable.map(values, function(value) {
21349         return [_.size(value), _.toArray(value), _.words(value)];
21350       });
21351
21352       assert.deepEqual(actual, expected);
21353     });
21354   }());
21355
21356   /*--------------------------------------------------------------------------*/
21357
21358   QUnit.module('lodash.unescape');
21359
21360   (function() {
21361     var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
21362         unescaped = '&<>"\'\/';
21363
21364     escaped += escaped;
21365     unescaped += unescaped;
21366
21367     QUnit.test('should unescape entities in order', function(assert) {
21368       assert.expect(1);
21369
21370       assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
21371     });
21372
21373     QUnit.test('should unescape the proper entities', function(assert) {
21374       assert.expect(1);
21375
21376       assert.strictEqual(_.unescape(escaped), unescaped);
21377     });
21378
21379     QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
21380       assert.expect(1);
21381
21382       assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
21383     });
21384
21385     QUnit.test('should handle strings with nothing to unescape', function(assert) {
21386       assert.expect(1);
21387
21388       assert.strictEqual(_.unescape('abc'), 'abc');
21389     });
21390
21391     QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
21392       assert.expect(1);
21393
21394       assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
21395     });
21396   }());
21397
21398   /*--------------------------------------------------------------------------*/
21399
21400   QUnit.module('lodash.upperCase');
21401
21402   (function() {
21403     QUnit.test('should uppercase as space-separated words', function(assert) {
21404       assert.expect(3);
21405
21406       assert.strictEqual(_.upperCase('--foo-bar'), 'FOO BAR');
21407       assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
21408       assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
21409     });
21410   }());
21411
21412   /*--------------------------------------------------------------------------*/
21413
21414   QUnit.module('lodash.upperFirst');
21415
21416   (function() {
21417     QUnit.test('should uppercase only the first character', function(assert) {
21418       assert.expect(3);
21419
21420       assert.strictEqual(_.upperFirst('fred'), 'Fred');
21421       assert.strictEqual(_.upperFirst('Fred'), 'Fred');
21422       assert.strictEqual(_.upperFirst('FRED'), 'FRED');
21423     });
21424   }());
21425
21426   /*--------------------------------------------------------------------------*/
21427
21428   QUnit.module('lodash.unary');
21429
21430   (function() {
21431     function fn() {
21432       return slice.call(arguments);
21433     }
21434
21435     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
21436       assert.expect(1);
21437
21438       var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
21439       assert.deepEqual(actual, [6, 8, 10]);
21440     });
21441
21442     QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
21443       assert.expect(1);
21444
21445       var capped = _.unary(fn);
21446       assert.deepEqual(capped(), []);
21447     });
21448   }());
21449
21450   /*--------------------------------------------------------------------------*/
21451
21452   QUnit.module('union methods');
21453
21454   lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
21455     var args = (function() { return arguments; }(1, 2, 3)),
21456         func = _[methodName];
21457
21458     QUnit.test('`_.' + methodName + '` should return the union of the given arrays', function(assert) {
21459       assert.expect(1);
21460
21461       var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
21462       assert.deepEqual(actual, [1, 3, 2, 5, 4]);
21463     });
21464
21465     QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
21466       assert.expect(1);
21467
21468       var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
21469       assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
21470     });
21471
21472     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
21473       assert.expect(3);
21474
21475       var array = [0];
21476       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
21477       assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
21478       assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
21479     });
21480   });
21481
21482   /*--------------------------------------------------------------------------*/
21483
21484   QUnit.module('lodash.unionBy');
21485
21486   (function() {
21487     QUnit.test('should accept an `iteratee` argument', function(assert) {
21488       assert.expect(2);
21489
21490       var actual = _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
21491       assert.deepEqual(actual, [2.1, 1.2, 4.3]);
21492
21493       actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
21494       assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
21495     });
21496
21497     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
21498       assert.expect(1);
21499
21500       var args;
21501
21502       _.unionBy([2.1, 1.2], [4.3, 2.4], function() {
21503         args || (args = slice.call(arguments));
21504       });
21505
21506       assert.deepEqual(args, [2.1]);
21507     });
21508   }());
21509
21510   /*--------------------------------------------------------------------------*/
21511
21512   QUnit.module('lodash.unionWith');
21513
21514   (function() {
21515     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
21516
21517     QUnit.test('should work with a `comparator` argument', function(assert) {
21518       assert.expect(1);
21519
21520       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
21521           actual = _.unionWith(objects, others, lodashStable.isEqual);
21522
21523       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]);
21524     });
21525   }());
21526
21527   /*--------------------------------------------------------------------------*/
21528
21529   QUnit.module('lodash.uniq');
21530
21531   (function() {
21532     QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
21533       assert.expect(1);
21534
21535       var array = [[2, 1, 2], [1, 2, 1]],
21536           actual = lodashStable.map(array, lodashStable.uniq);
21537
21538       assert.deepEqual(actual, [[2, 1], [1, 2]]);
21539     });
21540   }());
21541
21542   /*--------------------------------------------------------------------------*/
21543
21544   QUnit.module('uniq methods');
21545
21546   lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
21547     var func = _[methodName],
21548         isSorted = /^sorted/.test(methodName);
21549         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
21550
21551     if (isSorted) {
21552       objects = _.sortBy(objects, 'a');
21553     }
21554     else {
21555       QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
21556         assert.expect(1);
21557
21558         var array = [2, 3, 1, 2, 3, 1];
21559         assert.deepEqual(func(array), [2, 3, 1]);
21560       });
21561     }
21562     QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
21563       assert.expect(1);
21564
21565       var array = [1, 1, 2, 2, 3];
21566       assert.deepEqual(func(array), [1, 2, 3]);
21567     });
21568
21569     QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
21570       assert.expect(1);
21571
21572       assert.deepEqual(func(objects), objects);
21573     });
21574
21575     QUnit.test('`_.' + methodName + '` should not treat `NaN` as unique', function(assert) {
21576       assert.expect(1);
21577
21578       assert.deepEqual(func([1, 3, NaN, NaN]), [1, 3, NaN]);
21579     });
21580
21581     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
21582       assert.expect(1);
21583
21584       var largeArray = [],
21585           expected = [0, {}, 'a'],
21586           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
21587
21588       lodashStable.each(expected, function(value) {
21589         lodashStable.times(count, function() {
21590           largeArray.push(value);
21591         });
21592       });
21593
21594       assert.deepEqual(func(largeArray), expected);
21595     });
21596
21597     QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
21598       assert.expect(1);
21599
21600       var largeArray = [],
21601           expected = [false, true, null, undefined, NaN],
21602           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
21603
21604       lodashStable.each(expected, function(value) {
21605         lodashStable.times(count, function() {
21606           largeArray.push(value);
21607         });
21608       });
21609
21610       assert.deepEqual(func(largeArray), expected);
21611     });
21612
21613     QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
21614       assert.expect(1);
21615
21616       if (Symbol) {
21617         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
21618         assert.deepEqual(func(largeArray), largeArray);
21619       }
21620       else {
21621         skipTest(assert);
21622       }
21623     });
21624
21625     QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
21626       assert.expect(1);
21627
21628       // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
21629       if (Symbol) {
21630         var expected = [
21631           Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
21632           Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
21633           Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
21634         ];
21635
21636         var largeArray = [],
21637             count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
21638
21639         expected = lodashStable.map(expected, function(symbol) {
21640           return symbol || {};
21641         });
21642
21643         lodashStable.each(expected, function(value) {
21644           lodashStable.times(count, function() {
21645             largeArray.push(value);
21646           });
21647         });
21648
21649         assert.deepEqual(func(largeArray), expected);
21650       }
21651       else {
21652         skipTest(assert);
21653       }
21654     });
21655
21656     QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
21657       assert.expect(1);
21658
21659       var largeArray = [],
21660           expected = ['2', 2, Object('2'), Object(2)],
21661           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
21662
21663       lodashStable.each(expected, function(value) {
21664         lodashStable.times(count, function() {
21665           largeArray.push(value);
21666         });
21667       });
21668
21669       assert.deepEqual(func(largeArray), expected);
21670     });
21671   });
21672
21673   /*--------------------------------------------------------------------------*/
21674
21675   QUnit.module('uniqBy methods');
21676
21677   lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
21678     var func = _[methodName],
21679         isSorted = methodName == 'sortedUniqBy',
21680         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
21681
21682     if (isSorted) {
21683       objects = _.sortBy(objects, 'a');
21684     }
21685     QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
21686       assert.expect(1);
21687
21688       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
21689
21690       var actual = func(objects, function(object) {
21691         return object.a;
21692       });
21693
21694       assert.deepEqual(actual, expected);
21695     });
21696
21697     QUnit.test('should work with large arrays', function(assert) {
21698       assert.expect(2);
21699
21700       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
21701         return [1, 2];
21702       });
21703
21704       var actual = func(largeArray, String);
21705
21706       assert.deepEqual(actual, [[1, 2]]);
21707       assert.strictEqual(actual[0], largeArray[0]);
21708     });
21709
21710     QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
21711       assert.expect(1);
21712
21713       var args;
21714
21715       func(objects, function() {
21716         args || (args = slice.call(arguments));
21717       });
21718
21719       assert.deepEqual(args, [objects[0]]);
21720     });
21721
21722     QUnit.test('`_.' + methodName + '` should work with a "_.property" style `iteratee`', function(assert) {
21723       assert.expect(2);
21724
21725       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
21726           actual = func(objects, 'a');
21727
21728       assert.deepEqual(actual, expected);
21729
21730       var arrays = [[2], [3], [1], [2], [3], [1]];
21731       if (isSorted) {
21732         arrays = lodashStable.sortBy(arrays, 0);
21733       }
21734       expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
21735       actual = func(arrays, 0);
21736
21737       assert.deepEqual(actual, expected);
21738     });
21739
21740     lodashStable.each({
21741       'an array': [0, 'a'],
21742       'an object': { '0': 'a' },
21743       'a number': 0,
21744       'a string': '0'
21745     },
21746     function(iteratee, key) {
21747       QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
21748         assert.expect(1);
21749
21750         var actual = func([['a'], ['a'], ['b']], iteratee);
21751         assert.deepEqual(actual, [['a'], ['b']]);
21752       });
21753     });
21754   });
21755
21756   /*--------------------------------------------------------------------------*/
21757
21758   QUnit.module('lodash.uniqWith');
21759
21760   (function() {
21761     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
21762
21763     QUnit.test('should work with a `comparator` argument', function(assert) {
21764       assert.expect(1);
21765
21766       var actual = _.uniqWith(objects, lodashStable.isEqual);
21767       assert.deepEqual(actual, [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]);
21768     });
21769   }());
21770
21771   /*--------------------------------------------------------------------------*/
21772
21773   QUnit.module('lodash.uniqueId');
21774
21775   (function() {
21776     QUnit.test('should generate unique ids', function(assert) {
21777       assert.expect(1);
21778
21779       var actual = lodashStable.times(1000, function(assert) {
21780         return _.uniqueId();
21781       });
21782
21783       assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
21784     });
21785
21786     QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
21787       assert.expect(1);
21788
21789       assert.strictEqual(typeof _.uniqueId(), 'string');
21790     });
21791
21792     QUnit.test('should coerce the prefix argument to a string', function(assert) {
21793       assert.expect(1);
21794
21795       var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
21796       assert.ok(/3\d+,2\d+,1\d+/.test(actual));
21797     });
21798   }());
21799
21800   /*--------------------------------------------------------------------------*/
21801
21802   QUnit.module('lodash.unset');
21803
21804   (function() {
21805     QUnit.test('should unset property values', function(assert) {
21806       assert.expect(4);
21807
21808       lodashStable.each(['a', ['a']], function(path) {
21809         var object = { 'a': 1, 'c': 2 };
21810         assert.strictEqual(_.unset(object, path), true);
21811         assert.deepEqual(object, { 'c': 2 });
21812       });
21813     });
21814
21815     QUnit.test('should unset deep property values', function(assert) {
21816       assert.expect(4);
21817
21818       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
21819         var object = { 'a': { 'b': { 'c': null } } };
21820         assert.strictEqual(_.unset(object, path), true);
21821         assert.deepEqual(object, { 'a': { 'b': {} } });
21822       });
21823     });
21824
21825     QUnit.test('should handle complex paths', function(assert) {
21826       assert.expect(4);
21827
21828       var paths = [
21829         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
21830         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
21831       ];
21832
21833       lodashStable.each(paths, function(path) {
21834         var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
21835         assert.strictEqual(_.unset(object, path), true);
21836         assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
21837       });
21838     });
21839
21840     QUnit.test('should return `true` for nonexistent paths', function(assert) {
21841       assert.expect(5);
21842
21843       var object = { 'a': { 'b': { 'c': null } } };
21844
21845       lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
21846         assert.strictEqual(_.unset(object, path), true);
21847       });
21848
21849       assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
21850     });
21851
21852     QUnit.test('should not error when `object` is nullish', function(assert) {
21853       assert.expect(1);
21854
21855       var values = [null, undefined],
21856           expected = [[true, true], [true, true]];
21857
21858       var actual = lodashStable.map(values, function(value) {
21859         try {
21860           return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
21861         } catch (e) {
21862           return e.message;
21863         }
21864       });
21865
21866       assert.deepEqual(actual, expected);
21867     });
21868
21869     QUnit.test('should follow `path` over non-plain objects', function(assert) {
21870       assert.expect(8);
21871
21872       var object = { 'a': '' },
21873           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
21874
21875       lodashStable.each(paths, function(path) {
21876         numberProto.a = 1;
21877
21878         var actual = _.unset(0, path);
21879         assert.strictEqual(actual, true);
21880         assert.notOk('a' in numberProto);
21881
21882         delete numberProto.a;
21883       });
21884
21885       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
21886         stringProto.replace.b = 1;
21887
21888         var actual = _.unset(object, path);
21889         assert.strictEqual(actual, true);
21890         assert.notOk('a' in stringProto.replace);
21891
21892         delete stringProto.replace.b;
21893       });
21894     });
21895
21896     QUnit.test('should return `false` for non-configurable properties', function(assert) {
21897       assert.expect(1);
21898
21899       var object = {};
21900
21901       if (!isStrict && defineProperty) {
21902         defineProperty(object, 'a', {
21903           'configurable': false,
21904           'enumerable': true,
21905           'writable': true,
21906           'value': 1,
21907         });
21908         assert.strictEqual(_.unset(object, 'a'), false);
21909       }
21910       else {
21911         skipTest(assert);
21912       }
21913     });
21914   }());
21915
21916   /*--------------------------------------------------------------------------*/
21917
21918   QUnit.module('lodash.unzipWith');
21919
21920   (function() {
21921     QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
21922       assert.expect(1);
21923
21924       var array = [[1, 4], [2, 5], [3, 6]];
21925
21926       var actual = _.unzipWith(array, function(a, b, c) {
21927         return a + b + c;
21928       });
21929
21930       assert.deepEqual(actual, [6, 15]);
21931     });
21932
21933     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
21934       assert.expect(1);
21935
21936       var args;
21937
21938       _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
21939         args || (args = slice.call(arguments));
21940       });
21941
21942       assert.deepEqual(args, [1, 2]);
21943     });
21944
21945     QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
21946       assert.expect(1);
21947
21948       var array = [[1, 3], [2, 4]],
21949           values = [, null, undefined],
21950           expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
21951
21952       var actual = lodashStable.map(values, function(value, index) {
21953         return index ? _.unzipWith(array, value) : _.unzipWith(array);
21954       });
21955
21956       assert.deepEqual(actual, expected);
21957     });
21958   }());
21959
21960   /*--------------------------------------------------------------------------*/
21961
21962   QUnit.module('lodash.values');
21963
21964   (function() {
21965     QUnit.test('should get the values of an object', function(assert) {
21966       assert.expect(1);
21967
21968       var object = { 'a': 1, 'b': 2 };
21969       assert.deepEqual(_.values(object), [1, 2]);
21970     });
21971
21972     QUnit.test('should work with an object that has a `length` property', function(assert) {
21973       assert.expect(1);
21974
21975       var object = { '0': 'a', '1': 'b', 'length': 2 };
21976       assert.deepEqual(_.values(object), ['a', 'b', 2]);
21977     });
21978   }());
21979
21980   /*--------------------------------------------------------------------------*/
21981
21982   QUnit.module('lodash.without');
21983
21984   (function() {
21985     QUnit.test('should use strict equality to determine the values to reject', function(assert) {
21986       assert.expect(2);
21987
21988       var object1 = { 'a': 1 },
21989           object2 = { 'b': 2 },
21990           array = [object1, object2];
21991
21992       assert.deepEqual(_.without(array, { 'a': 1 }), array);
21993       assert.deepEqual(_.without(array, object1), [object2]);
21994     });
21995
21996     QUnit.test('should remove all occurrences of each value from an array', function(assert) {
21997       assert.expect(1);
21998
21999       var array = [1, 2, 3, 1, 2, 3];
22000       assert.deepEqual(_.without(array, 1, 2), [3, 3]);
22001     });
22002   }(1, 2, 3));
22003
22004   /*--------------------------------------------------------------------------*/
22005
22006   QUnit.module('lodash.words');
22007
22008   (function() {
22009     QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
22010       assert.expect(1);
22011
22012       var expected = lodashStable.map(burredLetters, function(letter) {
22013         return [letter];
22014       });
22015
22016       var actual = lodashStable.map(burredLetters, function(letter) {
22017         return _.words(letter);
22018       });
22019
22020       assert.deepEqual(actual, expected);
22021     });
22022
22023     QUnit.test('should not treat mathematical operators as words', function(assert) {
22024       assert.expect(1);
22025
22026       var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
22027           expected = lodashStable.map(operators, alwaysEmptyArray),
22028           actual = lodashStable.map(operators, _.words);
22029
22030       assert.deepEqual(actual, expected);
22031     });
22032
22033     QUnit.test('should support a `pattern` argument', function(assert) {
22034       assert.expect(2);
22035
22036       assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
22037       assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
22038     });
22039
22040     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22041       assert.expect(1);
22042
22043       var strings = lodashStable.map(['a', 'b', 'c'], Object),
22044           actual = lodashStable.map(strings, _.words);
22045
22046       assert.deepEqual(actual, [['a'], ['b'], ['c']]);
22047     });
22048
22049     QUnit.test('should work with compound words', function(assert) {
22050       assert.expect(7);
22051
22052       assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
22053       assert.deepEqual(_.words('enable 24h format'), ['enable', '24h', 'format']);
22054       assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
22055       assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
22056       assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
22057       assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
22058       assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
22059     });
22060
22061     QUnit.test('should work with compound words containing diacritical marks', function(assert) {
22062       assert.expect(3);
22063
22064       assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
22065       assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
22066       assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
22067     });
22068   }());
22069
22070   /*--------------------------------------------------------------------------*/
22071
22072   QUnit.module('lodash.wrap');
22073
22074   (function() {
22075     QUnit.test('should create a wrapped function', function(assert) {
22076       assert.expect(1);
22077
22078       var p = _.wrap(_.escape, function(func, text) {
22079         return '<p>' + func(text) + '</p>';
22080       });
22081
22082       assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
22083     });
22084
22085     QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
22086       assert.expect(1);
22087
22088       var args;
22089
22090       var wrapped = _.wrap(noop, function() {
22091         args || (args = slice.call(arguments));
22092       });
22093
22094       wrapped(1, 2, 3);
22095       assert.deepEqual(args, [noop, 1, 2, 3]);
22096     });
22097
22098     QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
22099       assert.expect(1);
22100
22101       var values = [, null, undefined],
22102           expected = lodashStable.map(values, alwaysA);
22103
22104       var actual = lodashStable.map(values, function(value, index) {
22105         var wrapped = index ? _.wrap('a', value) : _.wrap('a');
22106         return wrapped('b', 'c');
22107       });
22108
22109       assert.deepEqual(actual, expected);
22110     });
22111
22112     QUnit.test('should not set a `this` binding', function(assert) {
22113       assert.expect(1);
22114
22115       var p = _.wrap(_.escape, function(func) {
22116         return '<p>' + func(this.text) + '</p>';
22117       });
22118
22119       var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
22120       assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
22121     });
22122   }());
22123
22124   /*--------------------------------------------------------------------------*/
22125
22126   QUnit.module('xor methods');
22127
22128   lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
22129     var args = (function() { return arguments; }(1, 2, 3)),
22130         func = _[methodName];
22131
22132     QUnit.test('`_.' + methodName + '` should return the symmetric difference of the given arrays', function(assert) {
22133       assert.expect(1);
22134
22135       var actual = func([1, 2, 5], [2, 3, 5], [3, 4, 5]);
22136       assert.deepEqual(actual, [1, 4, 5]);
22137     });
22138
22139     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
22140       assert.expect(2);
22141
22142       var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
22143       assert.deepEqual(actual, [1, 4, 5]);
22144
22145       actual = func([1, 1]);
22146       assert.deepEqual(actual, [1]);
22147     });
22148
22149     QUnit.test('`_.' + methodName + '` should return a new array when a single array is provided', function(assert) {
22150       assert.expect(1);
22151
22152       var array = [1];
22153       assert.notStrictEqual(func(array), array);
22154     });
22155
22156     QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
22157       assert.expect(1);
22158
22159       var array = [0];
22160       assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
22161     });
22162
22163     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
22164       assert.expect(3);
22165
22166       var array = [1, 2];
22167       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
22168       assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
22169       assert.deepEqual(func(array, null, args, null), [3]);
22170     });
22171
22172     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
22173       assert.expect(1);
22174
22175       if (!isNpm) {
22176         var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
22177         assert.ok(wrapped instanceof _);
22178       }
22179       else {
22180         skipTest(assert);
22181       }
22182     });
22183
22184     QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
22185       assert.expect(1);
22186
22187       if (!isNpm) {
22188         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
22189             wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
22190
22191         var actual = lodashStable.map(['head', 'last'], function(methodName) {
22192           return wrapped[methodName]();
22193         });
22194
22195         assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
22196       }
22197       else {
22198         skipTest(assert);
22199       }
22200     });
22201   });
22202
22203   /*--------------------------------------------------------------------------*/
22204
22205   QUnit.module('lodash.xorBy');
22206
22207   (function() {
22208     QUnit.test('should accept an `iteratee` argument', function(assert) {
22209       assert.expect(2);
22210
22211       var actual = _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
22212       assert.deepEqual(actual, [1.2, 4.3]);
22213
22214       actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
22215       assert.deepEqual(actual, [{ 'x': 2 }]);
22216     });
22217
22218     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
22219       assert.expect(1);
22220
22221       var args;
22222
22223       _.xorBy([2.1, 1.2], [4.3, 2.4], function() {
22224         args || (args = slice.call(arguments));
22225       });
22226
22227       assert.deepEqual(args, [4.3]);
22228     });
22229   }());
22230
22231   /*--------------------------------------------------------------------------*/
22232
22233   QUnit.module('lodash.xorWith');
22234
22235   (function() {
22236     var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
22237
22238     QUnit.test('should work with a `comparator` argument', function(assert) {
22239       assert.expect(1);
22240
22241       var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
22242           actual = _.xorWith(objects, others, lodashStable.isEqual);
22243
22244       assert.deepEqual(actual, [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]);
22245     });
22246   }());
22247
22248   /*--------------------------------------------------------------------------*/
22249
22250   QUnit.module('lodash.zipObject');
22251
22252   (function() {
22253     var object = { 'barney': 36, 'fred': 40 },
22254         array = [['barney', 36], ['fred', 40]];
22255
22256     QUnit.test('should zip together key/value arrays into an object', function(assert) {
22257       assert.expect(1);
22258
22259       var actual = _.zipObject(['barney', 'fred'], [36, 40]);
22260       assert.deepEqual(actual, object);
22261     });
22262
22263     QUnit.test('should ignore extra `values`', function(assert) {
22264       assert.expect(1);
22265
22266       assert.deepEqual(_.zipObject(['a'], [1, 2]), { 'a': 1 });
22267     });
22268
22269     QUnit.test('should assign `undefined` values for extra `keys`', function(assert) {
22270       assert.expect(1);
22271
22272       assert.deepEqual(_.zipObject(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
22273     });
22274
22275     QUnit.test('should support deep paths', function(assert) {
22276       assert.expect(2);
22277
22278       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path) {
22279         var actual = _.zipObject([path], [1]);
22280         assert.deepEqual(actual, { 'a': { 'b': { 'c': 1 } } });
22281       });
22282     });
22283
22284     QUnit.test('should work in a lazy sequence', function(assert) {
22285       assert.expect(1);
22286
22287       if (!isNpm) {
22288         var values = lodashStable.range(LARGE_ARRAY_SIZE),
22289             props = lodashStable.map(values, function(value) { return 'key' + value; }),
22290             actual = _(props).zipObject(values).map(square).filter(isEven).take().value();
22291
22292         assert.deepEqual(actual, _.take(_.filter(_.map(_.zipObject(props, values), square), isEven)));
22293       }
22294       else {
22295         skipTest(assert);
22296       }
22297     });
22298   }());
22299
22300   /*--------------------------------------------------------------------------*/
22301
22302   QUnit.module('lodash.zipWith');
22303
22304   (function() {
22305     QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
22306       assert.expect(2);
22307
22308       var array1 = [1, 2, 3],
22309           array2 = [4, 5, 6],
22310           array3 = [7, 8, 9];
22311
22312       var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
22313         return a + b + c;
22314       });
22315
22316       assert.deepEqual(actual, [12, 15, 18]);
22317
22318       var actual = _.zipWith(array1, [], function(a, b) {
22319         return a + (b || 0);
22320       });
22321
22322       assert.deepEqual(actual, [1, 2, 3]);
22323     });
22324
22325     QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
22326       assert.expect(1);
22327
22328       var args;
22329
22330       _.zipWith([1, 2], [3, 4], [5, 6], function() {
22331         args || (args = slice.call(arguments));
22332       });
22333
22334       assert.deepEqual(args, [1, 3, 5]);
22335     });
22336
22337     QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
22338       assert.expect(1);
22339
22340       var array1 = [1, 2],
22341           array2 = [3, 4],
22342           values = [, null, undefined],
22343           expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
22344
22345       var actual = lodashStable.map(values, function(value, index) {
22346         return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
22347       });
22348
22349       assert.deepEqual(actual, expected);
22350     });
22351   }());
22352
22353   /*--------------------------------------------------------------------------*/
22354
22355   QUnit.module('lodash.unzip and lodash.zip');
22356
22357   lodashStable.each(['unzip', 'zip'], function(methodName, index) {
22358     var func = _[methodName];
22359     func = _.bind(index ? func.apply : func.call, func, null);
22360
22361     var object = {
22362       'an empty array': [
22363         [],
22364         []
22365       ],
22366       '0-tuples': [
22367         [[], []],
22368         []
22369       ],
22370       '2-tuples': [
22371         [['barney', 'fred'], [36, 40]],
22372         [['barney', 36], ['fred', 40]]
22373       ],
22374       '3-tuples': [
22375         [['barney', 'fred'], [36, 40], [true, false]],
22376         [['barney', 36, true], ['fred', 40, false]]
22377       ]
22378     };
22379
22380     lodashStable.forOwn(object, function(pair, key) {
22381       QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
22382         assert.expect(2);
22383
22384         var actual = func(pair[0]);
22385         assert.deepEqual(actual, pair[1]);
22386         assert.deepEqual(func(actual), actual.length ? pair[0] : []);
22387       });
22388     });
22389
22390     QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
22391       assert.expect(4);
22392
22393       var pair = [
22394         [['barney', 36], ['fred', 40, false]],
22395         [['barney', 'fred'], [36, 40], [undefined, false]]
22396       ];
22397
22398       var actual = func(pair[0]);
22399       assert.ok('0' in actual[2]);
22400       assert.deepEqual(actual, pair[1]);
22401
22402       actual = func(actual);
22403       assert.ok('2' in actual[0]);
22404       assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
22405     });
22406
22407     QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
22408       assert.expect(1);
22409
22410       var expected = lodashStable.map(falsey, alwaysEmptyArray);
22411
22412       var actual = lodashStable.map(falsey, function(value) {
22413         return func([value, value, value]);
22414       });
22415
22416       assert.deepEqual(actual, expected);
22417     });
22418
22419     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
22420       assert.expect(1);
22421
22422       var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
22423       assert.deepEqual(func(array), [[1, 3], [2, 4]]);
22424     });
22425
22426     QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
22427       assert.expect(1);
22428
22429       var expected = [['barney', 'fred'], [36, 40]];
22430       assert.deepEqual(func(func(func(func(expected)))), expected);
22431     });
22432   });
22433
22434   /*--------------------------------------------------------------------------*/
22435
22436   QUnit.module('lodash(...).commit');
22437
22438   (function() {
22439     QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
22440       assert.expect(4);
22441
22442       if (!isNpm) {
22443         var array = [1],
22444             wrapped = _(array).push(2).push(3);
22445
22446         assert.deepEqual(array, [1]);
22447
22448         var otherWrapper = wrapped.commit();
22449         assert.ok(otherWrapper instanceof _);
22450         assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
22451         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
22452       }
22453       else {
22454         skipTest(assert, 4);
22455       }
22456     });
22457
22458     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
22459       assert.expect(2);
22460
22461       if (!isNpm) {
22462         var wrapped = _([1]).chain().commit().head();
22463         assert.ok(wrapped instanceof _);
22464         assert.strictEqual(wrapped.value(), 1);
22465       }
22466       else {
22467         skipTest(assert, 2);
22468       }
22469     });
22470   }());
22471
22472   /*--------------------------------------------------------------------------*/
22473
22474   QUnit.module('lodash(...).next');
22475
22476   lodashStable.each([true, false], function(implict) {
22477     function chain(value) {
22478       return implict ? _(value) : _.chain(value);
22479     }
22480
22481     var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
22482
22483     QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
22484       assert.expect(3);
22485
22486       if (!isNpm) {
22487         var wrapped = chain([1, 2]);
22488
22489         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
22490         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
22491         assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
22492       }
22493       else {
22494         skipTest(assert, 3);
22495       }
22496     });
22497
22498     QUnit.test('should act as an iterable ' + chainType, function(assert) {
22499       assert.expect(2);
22500
22501       if (!isNpm && Symbol && Symbol.iterator) {
22502         var array = [1, 2],
22503             wrapped = chain(array);
22504
22505         assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
22506         assert.deepEqual(_.toArray(wrapped), array);
22507       }
22508       else {
22509         skipTest(assert, 2);
22510       }
22511     });
22512
22513     QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
22514       assert.expect(3);
22515
22516       if (!isNpm && Array.from) {
22517         var hearts = '\ud83d\udc95',
22518             values = [[1], { 'a': 1 }, hearts];
22519
22520         lodashStable.each(values, function(value) {
22521           var wrapped = chain(value);
22522           assert.deepEqual(Array.from(wrapped), _.toArray(value));
22523         });
22524       }
22525       else {
22526         skipTest(assert, 3);
22527       }
22528     });
22529
22530     QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
22531       assert.expect(4);
22532
22533       if (!isNpm && Symbol && Symbol.iterator) {
22534         var array = [1, 2],
22535             wrapped = chain(array);
22536
22537         assert.deepEqual(_.toArray(wrapped), array);
22538         assert.deepEqual(_.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
22539
22540         var other = wrapped.filter();
22541         assert.deepEqual(_.toArray(other), array, 'reset for new chain segments');
22542         assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted');
22543       }
22544       else {
22545         skipTest(assert, 4);
22546       }
22547     });
22548
22549     QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
22550       assert.expect(3);
22551
22552       if (!isNpm && Symbol && Symbol.iterator) {
22553         var array = lodashStable.range(LARGE_ARRAY_SIZE),
22554             predicate = function(value) { values.push(value); return isEven(value); },
22555             values = [],
22556             wrapped = chain(array);
22557
22558         assert.deepEqual(_.toArray(wrapped), array);
22559
22560         wrapped = wrapped.filter(predicate);
22561         assert.deepEqual(_.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
22562         assert.deepEqual(values, array, 'memoizes iterator values');
22563       }
22564       else {
22565         skipTest(assert, 3);
22566       }
22567     });
22568   });
22569
22570   /*--------------------------------------------------------------------------*/
22571
22572   QUnit.module('lodash(...).plant');
22573
22574   (function() {
22575     QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
22576       assert.expect(2);
22577
22578       if (!isNpm) {
22579         var array1 = [5, null, 3, null, 1],
22580             array2 = [10, null, 8, null, 6],
22581             wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
22582             wrapped2 = wrapped1.plant(array2);
22583
22584         assert.deepEqual(wrapped2.value(), [36, 64]);
22585         assert.deepEqual(wrapped1.value(), [1, 9]);
22586       }
22587       else {
22588         skipTest(assert, 2);
22589       }
22590     });
22591
22592     QUnit.test('should clone `chainAll` settings', function(assert) {
22593       assert.expect(1);
22594
22595       if (!isNpm) {
22596         var array1 = [2, 4],
22597             array2 = [6, 8],
22598             wrapped1 = _(array1).chain().map(square),
22599             wrapped2 = wrapped1.plant(array2);
22600
22601         assert.deepEqual(wrapped2.head().value(), 36);
22602       }
22603       else {
22604         skipTest(assert);
22605       }
22606     });
22607
22608     QUnit.test('should reset iterator data on cloned sequences', function(assert) {
22609       assert.expect(3);
22610
22611       if (!isNpm && Symbol && Symbol.iterator) {
22612         var array1 = [2, 4],
22613             array2 = [6, 8],
22614             wrapped1 = _(array1).map(square);
22615
22616         assert.deepEqual(_.toArray(wrapped1), [4, 16]);
22617         assert.deepEqual(_.toArray(wrapped1), []);
22618
22619         var wrapped2 = wrapped1.plant(array2);
22620         assert.deepEqual(_.toArray(wrapped2), [36, 64]);
22621       }
22622       else {
22623         skipTest(assert, 3);
22624       }
22625     });
22626   }());
22627
22628   /*--------------------------------------------------------------------------*/
22629
22630   QUnit.module('lodash(...).pop');
22631
22632   (function() {
22633     QUnit.test('should remove elements from the end of `array`', function(assert) {
22634       assert.expect(5);
22635
22636       if (!isNpm) {
22637         var array = [1, 2],
22638             wrapped = _(array);
22639
22640         assert.strictEqual(wrapped.pop(), 2);
22641         assert.deepEqual(wrapped.value(), [1]);
22642         assert.strictEqual(wrapped.pop(), 1);
22643
22644         var actual = wrapped.value();
22645         assert.deepEqual(actual, []);
22646         assert.strictEqual(actual, array);
22647       }
22648       else {
22649         skipTest(assert, 5);
22650       }
22651     });
22652   }());
22653
22654   /*--------------------------------------------------------------------------*/
22655
22656   QUnit.module('lodash(...).push');
22657
22658   (function() {
22659       QUnit.test('should append elements to `array`', function(assert) {
22660         assert.expect(2);
22661
22662       if (!isNpm) {
22663         var array = [1],
22664             wrapped = _(array).push(2, 3),
22665             actual = wrapped.value();
22666
22667         assert.strictEqual(actual, array);
22668         assert.deepEqual(actual, [1, 2, 3]);
22669       }
22670       else {
22671         skipTest(assert, 2);
22672       }
22673     });
22674   }());
22675
22676   /*--------------------------------------------------------------------------*/
22677
22678   QUnit.module('lodash(...).shift');
22679
22680   (function() {
22681     QUnit.test('should remove elements from the front of `array`', function(assert) {
22682       assert.expect(5);
22683
22684       if (!isNpm) {
22685         var array = [1, 2],
22686             wrapped = _(array);
22687
22688         assert.strictEqual(wrapped.shift(), 1);
22689         assert.deepEqual(wrapped.value(), [2]);
22690         assert.strictEqual(wrapped.shift(), 2);
22691
22692         var actual = wrapped.value();
22693         assert.deepEqual(actual, []);
22694         assert.strictEqual(actual, array);
22695       }
22696       else {
22697         skipTest(assert, 5);
22698       }
22699     });
22700   }());
22701
22702   /*--------------------------------------------------------------------------*/
22703
22704   QUnit.module('lodash(...).sort');
22705
22706   (function() {
22707     QUnit.test('should return the wrapped sorted `array`', function(assert) {
22708       assert.expect(2);
22709
22710       if (!isNpm) {
22711         var array = [3, 1, 2],
22712             wrapped = _(array).sort(),
22713             actual = wrapped.value();
22714
22715         assert.strictEqual(actual, array);
22716         assert.deepEqual(actual, [1, 2, 3]);
22717       }
22718       else {
22719         skipTest(assert, 2);
22720       }
22721     });
22722   }());
22723
22724   /*--------------------------------------------------------------------------*/
22725
22726   QUnit.module('lodash(...).splice');
22727
22728   (function() {
22729     QUnit.test('should support removing and inserting elements', function(assert) {
22730       assert.expect(5);
22731
22732       if (!isNpm) {
22733         var array = [1, 2],
22734             wrapped = _(array);
22735
22736         assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
22737         assert.deepEqual(wrapped.value(), [1, 3]);
22738         assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
22739
22740         var actual = wrapped.value();
22741         assert.deepEqual(actual, []);
22742         assert.strictEqual(actual, array);
22743       }
22744       else {
22745         skipTest(assert, 5);
22746       }
22747     });
22748   }());
22749
22750   /*--------------------------------------------------------------------------*/
22751
22752   QUnit.module('lodash(...).unshift');
22753
22754   (function() {
22755     QUnit.test('should prepend elements to `array`', function(assert) {
22756       assert.expect(2);
22757
22758       if (!isNpm) {
22759         var array = [3],
22760             wrapped = _(array).unshift(1, 2),
22761             actual = wrapped.value();
22762
22763         assert.strictEqual(actual, array);
22764         assert.deepEqual(actual, [1, 2, 3]);
22765       }
22766       else {
22767         skipTest(assert, 2);
22768       }
22769     });
22770   }());
22771
22772   /*--------------------------------------------------------------------------*/
22773
22774   QUnit.module('lodash(...).value');
22775
22776   (function() {
22777     QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
22778       assert.expect(4);
22779
22780       if (!isNpm) {
22781         var array = [1],
22782             wrapped = _(array).push(2).push(3);
22783
22784         assert.deepEqual(array, [1]);
22785         assert.deepEqual(wrapped.value(), [1, 2, 3]);
22786         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
22787         assert.deepEqual(array, [1, 2, 3, 2, 3]);
22788       }
22789       else {
22790         skipTest(assert, 4);
22791       }
22792     });
22793
22794     QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
22795       assert.expect(1);
22796
22797       if (!isNpm) {
22798         var wrapped = _(123);
22799         assert.strictEqual(Number(wrapped), 123);
22800       }
22801       else {
22802         skipTest(assert);
22803       }
22804     });
22805
22806     QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
22807       assert.expect(1);
22808
22809       if (!isNpm && JSON) {
22810         var wrapped = _([1, 2, 3]);
22811         assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
22812       }
22813       else {
22814         skipTest(assert);
22815       }
22816     });
22817
22818     QUnit.test('should be aliased', function(assert) {
22819       assert.expect(2);
22820
22821       if (!isNpm) {
22822         var expected = _.prototype.value;
22823         assert.strictEqual(_.prototype.toJSON, expected);
22824         assert.strictEqual(_.prototype.valueOf, expected);
22825       }
22826       else {
22827         skipTest(assert, 2);
22828       }
22829     });
22830   }());
22831
22832   /*--------------------------------------------------------------------------*/
22833
22834   QUnit.module('lodash(...) methods that return the wrapped modified array');
22835
22836   (function() {
22837     var funcs = [
22838       'push',
22839       'reverse',
22840       'sort',
22841       'unshift'
22842     ];
22843
22844     lodashStable.each(funcs, function(methodName) {
22845       QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
22846         assert.expect(2);
22847
22848         if (!isNpm) {
22849           var array = [1, 2, 3],
22850               wrapped = _(array),
22851               actual = wrapped[methodName]();
22852
22853           assert.ok(actual instanceof _);
22854           assert.notStrictEqual(actual, wrapped);
22855         }
22856         else {
22857           skipTest(assert, 2);
22858         }
22859       });
22860     });
22861   }());
22862
22863   /*--------------------------------------------------------------------------*/
22864
22865   QUnit.module('lodash(...) methods that return new wrapped values');
22866
22867   (function() {
22868     var funcs = [
22869       'concat',
22870       'pull',
22871       'pullAll',
22872       'pullAt',
22873       'sampleSize',
22874       'shuffle',
22875       'slice',
22876       'splice',
22877       'split',
22878       'toArray',
22879       'words'
22880     ];
22881
22882     lodashStable.each(funcs, function(methodName) {
22883       QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
22884         assert.expect(2);
22885
22886         if (!isNpm) {
22887           var value = methodName == 'split' ? 'abc' : [1, 2, 3],
22888               wrapped = _(value),
22889               actual = wrapped[methodName]();
22890
22891           assert.ok(actual instanceof _);
22892           assert.notStrictEqual(actual, wrapped);
22893         }
22894         else {
22895           skipTest(assert, 2);
22896         }
22897       });
22898     });
22899   }());
22900
22901   /*--------------------------------------------------------------------------*/
22902
22903   QUnit.module('lodash(...) methods that return unwrapped values');
22904
22905   (function() {
22906     var funcs = [
22907       'camelCase',
22908       'capitalize',
22909       'ceil',
22910       'clone',
22911       'deburr',
22912       'endsWith',
22913       'escape',
22914       'escapeRegExp',
22915       'every',
22916       'find',
22917       'floor',
22918       'has',
22919       'hasIn',
22920       'head',
22921       'includes',
22922       'isArguments',
22923       'isArray',
22924       'isArrayLike',
22925       'isBoolean',
22926       'isDate',
22927       'isElement',
22928       'isEmpty',
22929       'isEqual',
22930       'isError',
22931       'isFinite',
22932       'isFunction',
22933       'isInteger',
22934       'isNaN',
22935       'isNative',
22936       'isNil',
22937       'isNull',
22938       'isNumber',
22939       'isObject',
22940       'isObjectLike',
22941       'isPlainObject',
22942       'isRegExp',
22943       'isSafeInteger',
22944       'isString',
22945       'isUndefined',
22946       'join',
22947       'kebabCase',
22948       'last',
22949       'lowerCase',
22950       'lowerFirst',
22951       'max',
22952       'maxBy',
22953       'min',
22954       'minBy',
22955       'pad',
22956       'padEnd',
22957       'padStart',
22958       'parseInt',
22959       'pop',
22960       'random',
22961       'reduce',
22962       'reduceRight',
22963       'repeat',
22964       'replace',
22965       'round',
22966       'sample',
22967       'shift',
22968       'size',
22969       'snakeCase',
22970       'some',
22971       'startCase',
22972       'startsWith',
22973       'sum',
22974       'toInteger',
22975       'toLower',
22976       'toNumber',
22977       'toSafeInteger',
22978       'toString',
22979       'toUpper',
22980       'trim',
22981       'trimEnd',
22982       'trimStart',
22983       'truncate',
22984       'unescape',
22985       'upperCase',
22986       'upperFirst'
22987     ];
22988
22989     lodashStable.each(funcs, function(methodName) {
22990       QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
22991         assert.expect(1);
22992
22993         if (!isNpm) {
22994           var array = [1, 2, 3],
22995               actual = _(array)[methodName]();
22996
22997           assert.notOk(actual instanceof _);
22998         }
22999         else {
23000           skipTest(assert);
23001         }
23002       });
23003
23004       QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
23005         assert.expect(1);
23006
23007         if (!isNpm) {
23008           var array = [1, 2, 3],
23009               actual = _(array).chain()[methodName]();
23010
23011           assert.ok(actual instanceof _);
23012         }
23013         else {
23014           skipTest(assert);
23015         }
23016       });
23017     });
23018   }());
23019
23020   /*--------------------------------------------------------------------------*/
23021
23022   QUnit.module('"Arrays" category methods');
23023
23024  (function() {
23025     var args = (function() { return arguments; }(1, null, [3], null, 5)),
23026         sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
23027         array = [1, 2, 3, 4, 5, 6];
23028
23029     QUnit.test('should work with `arguments` objects', function(assert) {
23030       assert.expect(30);
23031
23032       function message(methodName) {
23033         return '`_.' + methodName + '` should work with `arguments` objects';
23034       }
23035
23036       assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
23037       assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
23038
23039       assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
23040       assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
23041
23042       assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
23043       assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
23044       assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
23045       assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
23046       assert.deepEqual(_.dropWhile(args,identity), [ null, [3], null, 5], message('dropWhile'));
23047       assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
23048       assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
23049       assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
23050       assert.deepEqual(_.head(args), 1, message('head'));
23051       assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
23052       assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
23053       assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
23054       assert.deepEqual(_.last(args), 5, message('last'));
23055       assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
23056       assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
23057       assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
23058       assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
23059       assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
23060       assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
23061       assert.deepEqual(_.take(args, 2), [1, null], message('take'));
23062       assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
23063       assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
23064       assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
23065       assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
23066       assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
23067       assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
23068     });
23069
23070     QUnit.test('should accept falsey primary arguments', function(assert) {
23071       assert.expect(4);
23072
23073       function message(methodName) {
23074         return '`_.' + methodName + '` should accept falsey primary arguments';
23075       }
23076
23077       assert.deepEqual(_.difference(null, array), [], message('difference'));
23078       assert.deepEqual(_.intersection(null, array), [], message('intersection'));
23079       assert.deepEqual(_.union(null, array), array, message('union'));
23080       assert.deepEqual(_.xor(null, array), array, message('xor'));
23081     });
23082
23083     QUnit.test('should accept falsey secondary arguments', function(assert) {
23084       assert.expect(3);
23085
23086       function message(methodName) {
23087         return '`_.' + methodName + '` should accept falsey secondary arguments';
23088       }
23089
23090       assert.deepEqual(_.difference(array, null), array, message('difference'));
23091       assert.deepEqual(_.intersection(array, null), [], message('intersection'));
23092       assert.deepEqual(_.union(array, null), array, message('union'));
23093     });
23094   }());
23095
23096   /*--------------------------------------------------------------------------*/
23097
23098   QUnit.module('"Strings" category methods');
23099
23100  (function() {
23101     var stringMethods = [
23102       'camelCase',
23103       'capitalize',
23104       'escape',
23105       'kebabCase',
23106       'lowerCase',
23107       'lowerFirst',
23108       'pad',
23109       'padEnd',
23110       'padStart',
23111       'repeat',
23112       'snakeCase',
23113       'toLower',
23114       'toUpper',
23115       'trim',
23116       'trimEnd',
23117       'trimStart',
23118       'truncate',
23119       'unescape',
23120       'upperCase',
23121       'upperFirst'
23122     ];
23123
23124     lodashStable.each(stringMethods, function(methodName) {
23125       var func = _[methodName];
23126
23127       QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
23128         assert.expect(1);
23129
23130         var values = [, null, undefined, ''],
23131             expected = lodashStable.map(values, alwaysEmptyString);
23132
23133         var actual = lodashStable.map(values, function(value, index) {
23134           return index ? func(value) : func();
23135         });
23136
23137         assert.deepEqual(actual, expected);
23138       });
23139     });
23140   }());
23141
23142   /*--------------------------------------------------------------------------*/
23143
23144   QUnit.module('lodash methods');
23145
23146   (function() {
23147     var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
23148       return lodashStable.startsWith(methodName, '_');
23149     });
23150
23151     var checkFuncs = [
23152       'after',
23153       'ary',
23154       'before',
23155       'bind',
23156       'curry',
23157       'curryRight',
23158       'debounce',
23159       'defer',
23160       'delay',
23161       'flip',
23162       'flow',
23163       'flowRight',
23164       'memoize',
23165       'negate',
23166       'once',
23167       'partial',
23168       'partialRight',
23169       'rearg',
23170       'rest',
23171       'spread',
23172       'throttle',
23173       'unary'
23174     ];
23175
23176     var noBinding = [
23177       'flip',
23178       'memoize',
23179       'negate',
23180       'once',
23181       'overArgs',
23182       'partial',
23183       'partialRight',
23184       'rearg',
23185       'rest',
23186       'spread'
23187     ];
23188
23189     var rejectFalsey = [
23190       'tap',
23191       'thru'
23192     ].concat(checkFuncs);
23193
23194     var returnArrays = [
23195       'at',
23196       'chunk',
23197       'compact',
23198       'difference',
23199       'drop',
23200       'filter',
23201       'flatten',
23202       'functions',
23203       'initial',
23204       'intersection',
23205       'invokeMap',
23206       'keys',
23207       'map',
23208       'orderBy',
23209       'pull',
23210       'pullAll',
23211       'pullAt',
23212       'range',
23213       'rangeRight',
23214       'reject',
23215       'remove',
23216       'sampleSize',
23217       'shuffle',
23218       'sortBy',
23219       'tail',
23220       'take',
23221       'times',
23222       'toArray',
23223       'toPairs',
23224       'union',
23225       'uniq',
23226       'values',
23227       'without',
23228       'xor',
23229       'zip'
23230     ];
23231
23232     var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
23233
23234     QUnit.test('should accept falsey arguments', function(assert) {
23235       assert.expect(287);
23236
23237       var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
23238
23239       lodashStable.each(acceptFalsey, function(methodName) {
23240         var expected = emptyArrays,
23241             func = _[methodName],
23242             pass = true;
23243
23244         var actual = lodashStable.map(falsey, function(value, index) {
23245           try {
23246             return index ? func(value) : func();
23247           } catch (e) {
23248             pass = false;
23249           }
23250         });
23251
23252         if (methodName == 'noConflict') {
23253           root._ = oldDash;
23254         }
23255         else if (methodName == 'pull' || methodName == 'pullAll') {
23256           expected = falsey;
23257         }
23258         if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
23259           assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
23260         }
23261         assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
23262       });
23263
23264       // Skip tests for missing methods of modularized builds.
23265       lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
23266         if (!_[methodName]) {
23267           skipTest(assert);
23268         }
23269       });
23270     });
23271
23272     QUnit.test('should return an array', function(assert) {
23273       assert.expect(70);
23274
23275       var array = [1, 2, 3];
23276
23277       lodashStable.each(returnArrays, function(methodName) {
23278         var actual,
23279             func = _[methodName];
23280
23281         switch (methodName) {
23282           case 'invokeMap':
23283              actual = func(array, 'toFixed');
23284              break;
23285           case 'sample':
23286             actual = func(array, 1);
23287             break;
23288           default:
23289             actual = func(array);
23290         }
23291         assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
23292
23293         var isPull = methodName == 'pull' || methodName == 'pullAll';
23294         assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the provided array');
23295       });
23296     });
23297
23298     QUnit.test('should throw an error for falsey arguments', function(assert) {
23299       assert.expect(24);
23300
23301       lodashStable.each(rejectFalsey, function(methodName) {
23302         var expected = lodashStable.map(falsey, alwaysTrue),
23303             func = _[methodName];
23304
23305         var actual = lodashStable.map(falsey, function(value, index) {
23306           var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
23307
23308           try {
23309             index ? func(value) : func();
23310           } catch (e) {
23311             pass = !pass && (e instanceof TypeError) &&
23312               (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
23313           }
23314           return pass;
23315         });
23316
23317         assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
23318       });
23319     });
23320
23321     QUnit.test('should not set a `this` binding', function(assert) {
23322       assert.expect(30);
23323
23324       lodashStable.each(noBinding, function(methodName) {
23325         var fn = function() { return this.a; },
23326             func = _[methodName],
23327             isNegate = methodName == 'negate',
23328             object = { 'a': 1 },
23329             expected = isNegate ? false : 1;
23330
23331         var wrapper = func(_.bind(fn, object));
23332         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
23333
23334         wrapper = _.bind(func(fn), object);
23335         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
23336
23337         object.wrapper = func(fn);
23338         assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
23339       });
23340     });
23341
23342     QUnit.test('should not contain minified method names (test production builds)', function(assert) {
23343       assert.expect(1);
23344
23345       var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
23346       assert.ok(lodashStable.every(_.functions(_), function(methodName) {
23347         return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
23348       }));
23349     });
23350   }());
23351
23352   /*--------------------------------------------------------------------------*/
23353
23354   QUnit.config.asyncRetries = 10;
23355   QUnit.config.hidepassed = true;
23356
23357   if (!document) {
23358     QUnit.config.noglobals = true;
23359     QUnit.load();
23360   }
23361 }.call(this));