Built motion from commit 76eb00b9e.|1.0.24
[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 the maximum memoize cache size. */
16   var MAX_MEMOIZE_SIZE = 500;
17
18   /** Used as references for various `Number` constants. */
19   var MAX_SAFE_INTEGER = 9007199254740991,
20       MAX_INTEGER = 1.7976931348623157e+308;
21
22   /** Used as references for the maximum length and index of an array. */
23   var MAX_ARRAY_LENGTH = 4294967295,
24       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
25
26   /** `Object#toString` result references. */
27   var funcTag = '[object Function]',
28       numberTag = '[object Number]',
29       objectTag = '[object Object]';
30
31   /** Used as a reference to the global object. */
32   var root = (typeof global == 'object' && global) || this;
33
34   /** Used to store lodash to test for bad extensions/shims. */
35   var lodashBizarro = root.lodashBizarro;
36
37   /** Used for native method references. */
38   var arrayProto = Array.prototype,
39       funcProto = Function.prototype,
40       objectProto = Object.prototype,
41       numberProto = Number.prototype,
42       stringProto = String.prototype;
43
44   /** Method and object shortcuts. */
45   var phantom = root.phantom,
46       process = root.process,
47       amd = root.define ? define.amd : undefined,
48       args = toArgs([1, 2, 3]),
49       argv = process ? process.argv : undefined,
50       defineProperty = Object.defineProperty,
51       document = phantom ? undefined : root.document,
52       body = root.document ? root.document.body : undefined,
53       create = Object.create,
54       fnToString = funcProto.toString,
55       freeze = Object.freeze,
56       getSymbols = Object.getOwnPropertySymbols,
57       identity = function(value) { return value; },
58       noop = function() {},
59       objToString = objectProto.toString,
60       params = argv,
61       push = arrayProto.push,
62       realm = {},
63       slice = arrayProto.slice,
64       strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
65
66   var ArrayBuffer = root.ArrayBuffer,
67       Buffer = root.Buffer,
68       Map = root.Map,
69       Promise = root.Promise,
70       Proxy = root.Proxy,
71       Set = root.Set,
72       Symbol = root.Symbol,
73       Uint8Array = root.Uint8Array,
74       WeakMap = root.WeakMap,
75       WeakSet = root.WeakSet;
76
77   var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
78       map = Map ? new Map : undefined,
79       promise = Promise ? Promise.resolve(1) : undefined,
80       set = Set ? new Set : undefined,
81       symbol = Symbol ? Symbol('a') : undefined,
82       weakMap = WeakMap ? new WeakMap : undefined,
83       weakSet = WeakSet ? new WeakSet : undefined;
84
85   /** Math helpers. */
86   var add = function(x, y) { return x + y; },
87       doubled = function(n) { return n * 2; },
88       isEven = function(n) { return n % 2 == 0; },
89       square = function(n) { return n * n; };
90
91   /** Stub functions. */
92   var stubA = function() { return 'a'; },
93       stubB = function() { return 'b'; },
94       stubC = function() { return 'c'; };
95
96   var stubTrue = function() { return true; },
97       stubFalse = function() { return false; };
98
99   var stubNaN = function() { return NaN; },
100       stubNull = function() { return null; };
101
102   var stubZero = function() { return 0; },
103       stubOne = function() { return 1; },
104       stubTwo = function() { return 2; },
105       stubThree = function() { return 3; },
106       stubFour = function() { return 4; };
107
108   var stubArray = function() { return []; },
109       stubObject = function() { return {}; },
110       stubString = function() { return ''; };
111
112   /** List of Latin Unicode letters. */
113   var burredLetters = [
114     // Latin-1 Supplement letters.
115     '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf',
116     '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6',         '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf',
117     '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
118     '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6',         '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff',
119     // Latin Extended-A letters.
120     '\u0100', '\u0101', '\u0102', '\u0103', '\u0104', '\u0105', '\u0106', '\u0107', '\u0108', '\u0109', '\u010a', '\u010b', '\u010c', '\u010d', '\u010e', '\u010f',
121     '\u0110', '\u0111', '\u0112', '\u0113', '\u0114', '\u0115', '\u0116', '\u0117', '\u0118', '\u0119', '\u011a', '\u011b', '\u011c', '\u011d', '\u011e', '\u011f',
122     '\u0120', '\u0121', '\u0122', '\u0123', '\u0124', '\u0125', '\u0126', '\u0127', '\u0128', '\u0129', '\u012a', '\u012b', '\u012c', '\u012d', '\u012e', '\u012f',
123     '\u0130', '\u0131', '\u0132', '\u0133', '\u0134', '\u0135', '\u0136', '\u0137', '\u0138', '\u0139', '\u013a', '\u013b', '\u013c', '\u013d', '\u013e', '\u013f',
124     '\u0140', '\u0141', '\u0142', '\u0143', '\u0144', '\u0145', '\u0146', '\u0147', '\u0148', '\u0149', '\u014a', '\u014b', '\u014c', '\u014d', '\u014e', '\u014f',
125     '\u0150', '\u0151', '\u0152', '\u0153', '\u0154', '\u0155', '\u0156', '\u0157', '\u0158', '\u0159', '\u015a', '\u015b', '\u015c', '\u015d', '\u015e', '\u015f',
126     '\u0160', '\u0161', '\u0162', '\u0163', '\u0164', '\u0165', '\u0166', '\u0167', '\u0168', '\u0169', '\u016a', '\u016b', '\u016c', '\u016d', '\u016e', '\u016f',
127     '\u0170', '\u0171', '\u0172', '\u0173', '\u0174', '\u0175', '\u0176', '\u0177', '\u0178', '\u0179', '\u017a', '\u017b', '\u017c', '\u017d', '\u017e', '\u017f'
128   ];
129
130   /** List of combining diacritical marks. */
131   var comboMarks = [
132     '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
133     '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
134     '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
135     '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
136     '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
137     '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
138     '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
139     '\ufe20', '\ufe21', '\ufe22', '\ufe23'
140   ];
141
142   /** List of converted Latin Unicode letters. */
143   var deburredLetters = [
144     // Converted Latin-1 Supplement letters.
145     'A',  'A', 'A', 'A', 'A', 'A', 'Ae', 'C',  'E', 'E', 'E', 'E', 'I', 'I', 'I',
146     'I',  'D', 'N', 'O', 'O', 'O', 'O',  'O',  'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
147     'ss', 'a', 'a', 'a', 'a', 'a', 'a',  'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i',  'i',
148     'i',  'd', 'n', 'o', 'o', 'o', 'o',  'o',  'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y',
149     // Converted Latin Extended-A letters.
150     'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c',
151     'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e',
152     'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h',
153     'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j',
154     'K', 'k', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l',
155     'N', 'n', 'N', 'n', 'N', 'n', "'n", 'N', 'n',
156     'O', 'o', 'O', 'o', 'O', 'o', 'Oe', 'oe',
157     'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's',
158     'T', 't', 'T', 't', 'T', 't',
159     'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u',
160     'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's'
161   ];
162
163   /** Used to provide falsey values to methods. */
164   var falsey = [, null, undefined, false, 0, NaN, ''];
165
166   /** Used to specify the emoji style glyph variant of characters. */
167   var emojiVar = '\ufe0f';
168
169   /** Used to provide empty values to methods. */
170   var empties = [[], {}].concat(falsey.slice(1));
171
172   /** Used to test error objects. */
173   var errors = [
174     new Error,
175     new EvalError,
176     new RangeError,
177     new ReferenceError,
178     new SyntaxError,
179     new TypeError,
180     new URIError
181   ];
182
183   /** List of fitzpatrick modifiers. */
184   var fitzModifiers = [
185     '\ud83c\udffb',
186     '\ud83c\udffc',
187     '\ud83c\udffd',
188     '\ud83c\udffe',
189     '\ud83c\udfff'
190   ];
191
192   /** Used to provide primitive values to methods. */
193   var primitives = [null, undefined, false, true, 1, NaN, 'a'];
194
195   /** Used to check whether methods support typed arrays. */
196   var typedArrays = [
197     'Float32Array',
198     'Float64Array',
199     'Int8Array',
200     'Int16Array',
201     'Int32Array',
202     'Uint8Array',
203     'Uint8ClampedArray',
204     'Uint16Array',
205     'Uint32Array'
206   ];
207
208   /** Used to check whether methods support array views. */
209   var arrayViews = typedArrays.concat('DataView');
210
211   /** The file path of the lodash file to test. */
212   var filePath = (function() {
213     var min = 2,
214         result = params || [];
215
216     if (phantom) {
217       min = 0;
218       result = params = phantom.args || require('system').args;
219     }
220     var last = result[result.length - 1];
221     result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
222
223     if (!amd) {
224       try {
225         result = require('fs').realpathSync(result);
226       } catch (e) {}
227
228       try {
229         result = require.resolve(result);
230       } catch (e) {}
231     }
232     return result;
233   }());
234
235   /** The `ui` object. */
236   var ui = root.ui || (root.ui = {
237     'buildPath': filePath,
238     'loaderPath': '',
239     'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath),
240     'isStrict': /\bes\b/.test(filePath) || 'default' in require(filePath),
241     'urlParams': {}
242   });
243
244   /** The basename of the lodash file to test. */
245   var basename = /[\w.-]+$/.exec(filePath)[0];
246
247   /** Used to indicate testing a modularized build. */
248   var isModularize = ui.isModularize;
249
250   /** Detect if testing `npm` modules. */
251   var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
252
253   /** Detect if running in PhantomJS. */
254   var isPhantom = phantom || (typeof callPhantom == 'function');
255
256   /** Detect if lodash is in strict mode. */
257   var isStrict = ui.isStrict;
258
259   /*--------------------------------------------------------------------------*/
260
261   // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
262   root.msWDfn = undefined;
263
264   // Assign `setTimeout` to itself to avoid being flagged as a leak.
265   setProperty(root, 'setTimeout', setTimeout);
266
267   // Exit early if going to run tests in a PhantomJS web page.
268   if (phantom && isModularize) {
269     var page = require('webpage').create();
270
271     page.onCallback = function(details) {
272       var coverage = details.coverage;
273       if (coverage) {
274         var fs = require('fs'),
275             cwd = fs.workingDirectory,
276             sep = fs.separator;
277
278         fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
279       }
280       phantom.exit(details.failed ? 1 : 0);
281     };
282
283     page.onConsoleMessage = function(message) {
284       console.log(message);
285     };
286
287     page.onInitialized = function() {
288       page.evaluate(function() {
289         document.addEventListener('DOMContentLoaded', function() {
290           QUnit.done(function(details) {
291             details.coverage = window.__coverage__;
292             callPhantom(details);
293           });
294         });
295       });
296     };
297
298     page.open(filePath, function(status) {
299       if (status != 'success') {
300         console.log('PhantomJS failed to load page: ' + filePath);
301         phantom.exit(1);
302       }
303     });
304
305     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
306     return;
307   }
308
309   /*--------------------------------------------------------------------------*/
310
311   /** Used to test Web Workers. */
312   var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
313     (document && document.origin != 'null') && root.Worker;
314
315   /** Used to test host objects in IE. */
316   try {
317     var xml = new ActiveXObject('Microsoft.XMLDOM');
318   } catch (e) {}
319
320   /** Poison the free variable `root` in Node.js */
321   try {
322     defineProperty(global.root, 'root', {
323       'configurable': false,
324       'enumerable': false,
325       'get': function() { throw new ReferenceError; }
326     });
327   } catch (e) {}
328
329   /** Load QUnit and extras. */
330   var QUnit = root.QUnit || require('qunit-extras');
331
332   /** Load stable Lodash. */
333   var lodashStable = root.lodashStable;
334   if (!lodashStable) {
335     try {
336       lodashStable = interopRequire('../node_modules/lodash/lodash.js');
337     } catch (e) {
338       console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
339       return;
340     }
341     lodashStable = lodashStable.noConflict();
342   }
343
344   /** The `lodash` function to test. */
345   var _ = root._ || (root._ = interopRequire(filePath));
346
347   /** Used to test pseudo private map caches. */
348   var mapCaches = (function() {
349     var MapCache = _.memoize.Cache;
350     var result = {
351       'Hash': new MapCache().__data__.hash.constructor,
352       'MapCache': MapCache
353     };
354     _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() {
355       var stack = lodashStable.last(arguments);
356       result.ListCache = stack.__data__.constructor;
357       result.Stack = stack.constructor;
358     });
359     return result;
360   }());
361
362   /** Used to detect instrumented istanbul code coverage runs. */
363   var coverage = root.__coverage__ || root[lodashStable.find(lodashStable.keys(root), function(key) {
364     return /^(?:\$\$cov_\d+\$\$)$/.test(key);
365   })];
366
367   /** Used to test async functions. */
368   var asyncFunc = lodashStable.attempt(function() {
369     return Function('return async () => {}');
370   });
371
372   /** Used to test generator functions. */
373   var genFunc = lodashStable.attempt(function() {
374     return Function('return function*(){}');
375   });
376
377   /** Used to restore the `_` reference. */
378   var oldDash = root._;
379
380   /**
381    * Used to check for problems removing whitespace. For a whitespace reference,
382    * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
383    */
384   var whitespace = lodashStable.filter([
385     // Basic whitespace characters.
386     ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
387
388     // Line terminators.
389     '\n', '\r', '\u2028', '\u2029',
390
391     // Unicode category "Zs" space separators.
392     '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
393     '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
394   ],
395   function(chr) { return /\s/.exec(chr); })
396   .join('');
397
398   /**
399    * Creates a custom error object.
400    *
401    * @private
402    * @constructor
403    * @param {string} message The error message.
404    */
405   function CustomError(message) {
406     this.name = 'CustomError';
407     this.message = message;
408   }
409
410   CustomError.prototype = lodashStable.create(Error.prototype, {
411     'constructor': CustomError
412   });
413
414   /**
415    * Removes all own enumerable string keyed properties from a given object.
416    *
417    * @private
418    * @param {Object} object The object to empty.
419    */
420   function emptyObject(object) {
421     lodashStable.forOwn(object, function(value, key, object) {
422       delete object[key];
423     });
424   }
425
426   /**
427    * Extracts the unwrapped value from its wrapper.
428    *
429    * @private
430    * @param {Object} wrapper The wrapper to unwrap.
431    * @returns {*} Returns the unwrapped value.
432    */
433   function getUnwrappedValue(wrapper) {
434     var index = -1,
435         actions = wrapper.__actions__,
436         length = actions.length,
437         result = wrapper.__wrapped__;
438
439     while (++index < length) {
440       var args = [result],
441           action = actions[index];
442
443       push.apply(args, action.args);
444       result = action.func.apply(action.thisArg, args);
445     }
446     return result;
447   }
448
449   /**
450    * Loads the module of `id`. If the module has an `exports.default`, the
451    * exported default value is returned as the resolved module.
452    *
453    * @private
454    * @param {string} id The identifier of the module to resolve.
455    * @returns {*} Returns the resolved module.
456    */
457   function interopRequire(id) {
458     var result = require(id);
459     return 'default' in result ? result['default'] : result;
460   }
461
462   /**
463    * Sets a non-enumerable property value on `object`.
464    *
465    * Note: This function is used to avoid a bug in older versions of V8 where
466    * overwriting non-enumerable built-ins makes them enumerable.
467    * See https://code.google.com/p/v8/issues/detail?id=1623
468    *
469    * @private
470    * @param {Object} object The object modify.
471    * @param {string} key The name of the property to set.
472    * @param {*} value The property value.
473    */
474   function setProperty(object, key, value) {
475     try {
476       defineProperty(object, key, {
477         'configurable': true,
478         'enumerable': false,
479         'writable': true,
480         'value': value
481       });
482     } catch (e) {
483       object[key] = value;
484     }
485     return object;
486   }
487
488   /**
489    * Skips a given number of tests with a passing result.
490    *
491    * @private
492    * @param {Object} assert The QUnit assert object.
493    * @param {number} [count=1] The number of tests to skip.
494    */
495   function skipAssert(assert, count) {
496     count || (count = 1);
497     while (count--) {
498       assert.ok(true, 'test skipped');
499     }
500   }
501
502   /**
503    * Converts `array` to an `arguments` object.
504    *
505    * @private
506    * @param {Array} array The array to convert.
507    * @returns {Object} Returns the converted `arguments` object.
508    */
509   function toArgs(array) {
510     return (function() { return arguments; }.apply(undefined, array));
511   }
512
513   /*--------------------------------------------------------------------------*/
514
515   // Add bizarro values.
516   (function() {
517     if (document || (typeof require != 'function')) {
518       return;
519     }
520     var nativeString = fnToString.call(toString),
521         reToString = /toString/g;
522
523     function createToString(funcName) {
524       return lodashStable.constant(nativeString.replace(reToString, funcName));
525     }
526
527     // Allow bypassing native checks.
528     setProperty(funcProto, 'toString', function wrapper() {
529       setProperty(funcProto, 'toString', fnToString);
530       var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
531       setProperty(funcProto, 'toString', wrapper);
532       return result;
533     });
534
535     // Add prototype extensions.
536     funcProto._method = noop;
537
538     // Set bad shims.
539     setProperty(Object, 'create', undefined);
540     setProperty(Object, 'getOwnPropertySymbols', undefined);
541
542     var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
543     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
544       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
545     });
546
547     if (Buffer) {
548       defineProperty(root, 'Buffer', {
549         'configurable': true,
550         'enumerable': true,
551         'get': function get() {
552           var caller = get.caller,
553               name = caller ? caller.name : '';
554
555           if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
556             return Buffer;
557           }
558         }
559       });
560     }
561     if (Map) {
562       setProperty(root, 'Map', (function() {
563         var count = 0;
564         return function() {
565           if (count++) {
566             return new Map;
567           }
568           setProperty(root, 'Map', Map);
569           return {};
570         };
571       }()));
572
573       setProperty(root.Map, 'toString', createToString('Map'));
574     }
575     setProperty(root, 'Promise', noop);
576     setProperty(root, 'Set', noop);
577     setProperty(root, 'Symbol', undefined);
578     setProperty(root, 'WeakMap', noop);
579
580     // Fake `WinRTError`.
581     setProperty(root, 'WinRTError', Error);
582
583     // Clear cache so lodash can be reloaded.
584     emptyObject(require.cache);
585
586     // Load lodash and expose it to the bad extensions/shims.
587     lodashBizarro = interopRequire(filePath);
588     root._ = oldDash;
589
590     // Restore built-in methods.
591     setProperty(Object, 'create', create);
592     setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
593     setProperty(root, 'Buffer', Buffer);
594
595     if (getSymbols) {
596       Object.getOwnPropertySymbols = getSymbols;
597     } else {
598       delete Object.getOwnPropertySymbols;
599     }
600     if (Map) {
601       setProperty(root, 'Map', Map);
602     } else {
603       delete root.Map;
604     }
605     if (Promise) {
606       setProperty(root, 'Promise', Promise);
607     } else {
608       delete root.Promise;
609     }
610     if (Set) {
611       setProperty(root, 'Set', Set);
612     } else {
613       delete root.Set;
614     }
615     if (Symbol) {
616       setProperty(root, 'Symbol', Symbol);
617     } else {
618       delete root.Symbol;
619     }
620     if (WeakMap) {
621       setProperty(root, 'WeakMap', WeakMap);
622     } else {
623       delete root.WeakMap;
624     }
625     delete root.WinRTError;
626     delete funcProto._method;
627   }());
628
629   // Add other realm values from the `vm` module.
630   lodashStable.attempt(function() {
631     lodashStable.assign(realm, require('vm').runInNewContext([
632       '(function() {',
633       '  var noop = function() {},',
634       '      root = this;',
635       '',
636       '  var object = {',
637       "    'ArrayBuffer': root.ArrayBuffer,",
638       "    'arguments': (function() { return arguments; }(1, 2, 3)),",
639       "    'array': [1],",
640       "    'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
641       "    'boolean': Object(false),",
642       "    'date': new Date,",
643       "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
644       "    'function': noop,",
645       "    'map': root.Map ? new root.Map : undefined,",
646       "    'nan': NaN,",
647       "    'null': null,",
648       "    'number': Object(0),",
649       "    'object': { 'a': 1 },",
650       "    'promise': root.Promise ? Promise.resolve(1) : undefined,",
651       "    'regexp': /x/,",
652       "    'set': root.Set ? new root.Set : undefined,",
653       "    'string': Object('a'),",
654       "    'symbol': root.Symbol ? root.Symbol() : undefined,",
655       "    'undefined': undefined,",
656       "    'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
657       "    'weakSet': root.WeakSet ? new root.WeakSet : undefined",
658       '  };',
659       '',
660       "  ['" + arrayViews.join("', '") + "'].forEach(function(type) {",
661       '    var Ctor = root[type]',
662       '    object[type] = Ctor;',
663       '    object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
664       '  });',
665       '',
666       '  return object;',
667       '}());'
668     ].join('\n')));
669   });
670
671   // Add other realm values from an iframe.
672   lodashStable.attempt(function() {
673     _._realm = realm;
674
675     var iframe = document.createElement('iframe');
676     iframe.frameBorder = iframe.height = iframe.width = 0;
677     body.appendChild(iframe);
678
679     var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
680     idoc.write([
681       '<html>',
682       '<body>',
683       '<script>',
684       'var _ = parent._,',
685       '    noop = function() {},',
686       '    root = this;',
687       '',
688       'var object = {',
689       "  'ArrayBuffer': root.ArrayBuffer,",
690       "  'arguments': (function() { return arguments; }(1, 2, 3)),",
691       "  'array': [1],",
692       "  'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
693       "  'boolean': Object(false),",
694       "  'date': new Date,",
695       "  'element': document.body,",
696       "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
697       "  'function': noop,",
698       "  'map': root.Map ? new root.Map : undefined,",
699       "  'nan': NaN,",
700       "  'null': null,",
701       "  'number': Object(0),",
702       "  'object': { 'a': 1 },",
703       "  'promise': root.Promise ? Promise.resolve(1) : undefined,",
704       "  'regexp': /x/,",
705       "  'set': root.Set ? new root.Set : undefined,",
706       "  'string': Object('a'),",
707       "  'symbol': root.Symbol ? root.Symbol() : undefined,",
708       "  'undefined': undefined,",
709       "  'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
710       "  'weakSet': root.WeakSet ? new root.WeakSet : undefined",
711       '};',
712       '',
713       "_.each(['" + arrayViews.join("', '") + "'], function(type) {",
714       '  var Ctor = root[type];',
715       '  object[type] = Ctor;',
716       '  object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
717       '});',
718       '',
719       '_.assign(_._realm, object);',
720       '</script>',
721       '</body>',
722       '</html>'
723     ].join('\n'));
724
725     idoc.close();
726     delete _._realm;
727   });
728
729   // Add a web worker.
730   lodashStable.attempt(function() {
731     var worker = new Worker('./asset/worker.js?t=' + (+new Date));
732     worker.addEventListener('message', function(e) {
733       _._VERSION = e.data || '';
734     }, false);
735
736     worker.postMessage(ui.buildPath);
737   });
738
739   // Expose internal modules for better code coverage.
740   lodashStable.attempt(function() {
741     var path = require('path'),
742         basePath = path.dirname(filePath);
743
744     if (isModularize && !(amd || isNpm)) {
745       lodashStable.each([
746         'baseEach',
747         'isIndex',
748         'isIterateeCall',
749         'memoizeCapped'
750       ], function(funcName) {
751         _['_' + funcName] = interopRequire(path.join(basePath, '_' + funcName));
752       });
753     }
754   });
755
756   /*--------------------------------------------------------------------------*/
757
758   if (params) {
759     console.log('Running lodash tests.');
760     console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
761   }
762
763   QUnit.module(basename);
764
765   (function() {
766     QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
767       assert.expect(1);
768
769       if (amd) {
770         assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
771       }
772       else {
773         skipAssert(assert);
774       }
775     });
776
777     QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
778       assert.expect(1);
779
780       if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
781         assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
782       } else {
783         skipAssert(assert);
784       }
785     });
786
787     QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
788       assert.expect(1);
789
790       if (amd) {
791         assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
792       }
793       else {
794         skipAssert(assert);
795       }
796     });
797
798     QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
799       assert.expect(1);
800
801       var done = assert.async();
802
803       if (Worker) {
804         var limit = 30000 / QUnit.config.asyncRetries,
805             start = +new Date;
806
807         var attempt = function() {
808           var actual = _._VERSION;
809           if ((new Date - start) < limit && typeof actual != 'string') {
810             setTimeout(attempt, 16);
811             return;
812           }
813           assert.strictEqual(actual, _.VERSION);
814           done();
815         };
816
817         attempt();
818       }
819       else {
820         skipAssert(assert);
821         done();
822       }
823     });
824
825     QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
826       assert.expect(1);
827
828       if (lodashBizarro) {
829         assert.notOk('_method' in lodashBizarro);
830       }
831       else {
832         skipAssert(assert);
833       }
834     });
835
836     QUnit.test('should avoid non-native built-ins', function(assert) {
837       assert.expect(6);
838
839       function message(lodashMethod, nativeMethod) {
840         return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
841       }
842
843       function Foo() {
844         this.a = 1;
845       }
846       Foo.prototype.b = 2;
847
848       var object = { 'a': 1 },
849           otherObject = { 'b': 2 },
850           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
851
852       if (lodashBizarro) {
853         try {
854           var actual = lodashBizarro.create(Foo.prototype);
855         } catch (e) {
856           actual = null;
857         }
858         var label = message('_.create', 'Object.create');
859         assert.ok(actual instanceof Foo, label);
860
861         try {
862           actual = [
863             lodashBizarro.difference([object, otherObject], largeArray),
864             lodashBizarro.intersection(largeArray, [object]),
865             lodashBizarro.uniq(largeArray)
866           ];
867         } catch (e) {
868           actual = null;
869         }
870         label = message('_.difference`, `_.intersection`, and `_.uniq', 'Map');
871         assert.deepEqual(actual, [[otherObject], [object], [object]], label);
872
873         try {
874           if (Symbol) {
875             object[symbol] = {};
876           }
877           actual = [
878             lodashBizarro.clone(object),
879             lodashBizarro.cloneDeep(object)
880           ];
881         } catch (e) {
882           actual = null;
883         }
884         label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
885         assert.deepEqual(actual, [object, object], label);
886
887         try {
888           // Avoid buggy symbol detection in Babel's `_typeof` helper.
889           var symObject = setProperty(Object(symbol), 'constructor', Object);
890           actual = [
891             Symbol ? lodashBizarro.clone(symObject) : {},
892             Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
893             Symbol ? lodashBizarro.toString(symObject) : ''
894           ];
895         } catch (e) {
896           actual = null;
897         }
898         label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
899         assert.deepEqual(actual, [{}, false, ''], label);
900
901         try {
902           var map = new lodashBizarro.memoize.Cache;
903           actual = map.set('a', 1).get('a');
904         } catch (e) {
905           actual = null;
906         }
907         label = message('_.memoize.Cache', 'Map');
908         assert.deepEqual(actual, 1, label);
909
910         try {
911           map = new (Map || Object);
912           if (Symbol && Symbol.iterator) {
913             map[Symbol.iterator] = null;
914           }
915           actual = lodashBizarro.toArray(map);
916         } catch (e) {
917           actual = null;
918         }
919         label = message('_.toArray', 'Map');
920         assert.deepEqual(actual, [], label);
921       }
922       else {
923         skipAssert(assert, 6);
924       }
925     });
926   }());
927
928   /*--------------------------------------------------------------------------*/
929
930   QUnit.module('isIndex');
931
932   (function() {
933     var func = _._isIndex;
934
935     QUnit.test('should return `true` for indexes', function(assert) {
936       assert.expect(1);
937
938       if (func) {
939         var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
940             expected = lodashStable.map(values, stubTrue);
941
942         var actual = lodashStable.map(values, function(args) {
943           return func.apply(undefined, args);
944         });
945
946         assert.deepEqual(actual, expected);
947       }
948       else {
949         skipAssert(assert);
950       }
951     });
952
953     QUnit.test('should return `false` for non-indexes', function(assert) {
954       assert.expect(1);
955
956       if (func) {
957         var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
958             expected = lodashStable.map(values, stubFalse);
959
960         var actual = lodashStable.map(values, function(args) {
961           return func.apply(undefined, args);
962         });
963
964         assert.deepEqual(actual, expected);
965       }
966       else {
967         skipAssert(assert);
968       }
969     });
970   }());
971
972   /*--------------------------------------------------------------------------*/
973
974   QUnit.module('isIterateeCall');
975
976   (function() {
977     var array = [1],
978         func = _._isIterateeCall,
979         object =  { 'a': 1 };
980
981     QUnit.test('should return `true` for iteratee calls', function(assert) {
982       assert.expect(3);
983
984       function Foo() {}
985       Foo.prototype.a = 1;
986
987       if (func) {
988         assert.strictEqual(func(1, 0, array), true);
989         assert.strictEqual(func(1, 'a', object), true);
990         assert.strictEqual(func(1, 'a', new Foo), true);
991       }
992       else {
993         skipAssert(assert, 3);
994       }
995     });
996
997     QUnit.test('should return `false` for non-iteratee calls', function(assert) {
998       assert.expect(4);
999
1000       if (func) {
1001         assert.strictEqual(func(2, 0, array), false);
1002         assert.strictEqual(func(1, 1.1, array), false);
1003         assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
1004         assert.strictEqual(func(1, 'b', object), false);
1005       }
1006       else {
1007         skipAssert(assert, 4);
1008       }
1009     });
1010
1011     QUnit.test('should work with `NaN` values', function(assert) {
1012       assert.expect(2);
1013
1014       if (func) {
1015         assert.strictEqual(func(NaN, 0, [NaN]), true);
1016         assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
1017       }
1018       else {
1019         skipAssert(assert, 2);
1020       }
1021     });
1022
1023     QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
1024       assert.expect(1);
1025
1026       if (func) {
1027         try {
1028           var actual = func(1, { 'toString': null }, [1]);
1029         } catch (e) {
1030           var message = e.message;
1031         }
1032         assert.strictEqual(actual, false, message || '');
1033       }
1034       else {
1035         skipAssert(assert);
1036       }
1037     });
1038   }());
1039
1040   /*--------------------------------------------------------------------------*/
1041
1042   QUnit.module('map caches');
1043
1044   (function() {
1045     var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || noop];
1046
1047     var pairs = lodashStable.map(keys, function(key, index) {
1048       var lastIndex = keys.length - 1;
1049       return [key, keys[lastIndex - index]];
1050     });
1051
1052     function createCaches(pairs) {
1053       var largeStack = new mapCaches.Stack(pairs),
1054           length = pairs ? pairs.length : 0;
1055
1056       lodashStable.times(LARGE_ARRAY_SIZE - length, function() {
1057         largeStack.set({}, {});
1058       });
1059
1060       return {
1061         'hashes': new mapCaches.Hash(pairs),
1062         'list caches': new mapCaches.ListCache(pairs),
1063         'map caches': new mapCaches.MapCache(pairs),
1064         'stack caches': new mapCaches.Stack(pairs),
1065         'large stacks': largeStack
1066       };
1067     }
1068
1069     lodashStable.forOwn(createCaches(pairs), function(cache, kind) {
1070       var isLarge = /^large/.test(kind);
1071
1072       QUnit.test('should implement a `Map` interface for ' + kind, function(assert) {
1073         assert.expect(83);
1074
1075         lodashStable.each(keys, function(key, index) {
1076           var value = pairs[index][1];
1077
1078           assert.deepEqual(cache.get(key), value);
1079           assert.strictEqual(cache.has(key), true);
1080           assert.strictEqual(cache.delete(key), true);
1081           assert.strictEqual(cache.has(key), false);
1082           assert.strictEqual(cache.get(key), undefined);
1083           assert.strictEqual(cache.delete(key), false);
1084           assert.strictEqual(cache.set(key, value), cache);
1085           assert.strictEqual(cache.has(key), true);
1086         });
1087
1088         assert.strictEqual(cache.size, isLarge ? LARGE_ARRAY_SIZE : keys.length);
1089         assert.strictEqual(cache.clear(), undefined);
1090         assert.ok(lodashStable.every(keys, function(key) {
1091           return !cache.has(key);
1092         }));
1093       });
1094     });
1095
1096     lodashStable.forOwn(createCaches(), function(cache, kind) {
1097       QUnit.test('should support changing values of ' + kind, function(assert) {
1098         assert.expect(10);
1099
1100         lodashStable.each(keys, function(key) {
1101           cache.set(key, 1).set(key, 2);
1102           assert.strictEqual(cache.get(key), 2);
1103         });
1104       });
1105     });
1106   }());
1107
1108   /*--------------------------------------------------------------------------*/
1109
1110   QUnit.module('lodash constructor');
1111
1112   (function() {
1113     var values = empties.concat(true, 1, 'a'),
1114         expected = lodashStable.map(values, stubTrue);
1115
1116     QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
1117       assert.expect(1);
1118
1119       if (!isNpm) {
1120         var actual = lodashStable.map(values, function(value) {
1121           return _(value) instanceof _;
1122         });
1123
1124         assert.deepEqual(actual, expected);
1125       }
1126       else {
1127         skipAssert(assert);
1128       }
1129     });
1130
1131     QUnit.test('should return the given `lodash` instances', function(assert) {
1132       assert.expect(1);
1133
1134       if (!isNpm) {
1135         var actual = lodashStable.map(values, function(value) {
1136           var wrapped = _(value);
1137           return _(wrapped) === wrapped;
1138         });
1139
1140         assert.deepEqual(actual, expected);
1141       }
1142       else {
1143         skipAssert(assert);
1144       }
1145     });
1146
1147     QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
1148       assert.expect(1);
1149
1150       if (!isNpm && lodashBizarro) {
1151         var actual = lodashStable.map(values, function(value) {
1152           var wrapped = _(lodashBizarro(value)),
1153               unwrapped = wrapped.value();
1154
1155           return wrapped instanceof _ &&
1156             ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
1157         });
1158
1159         assert.deepEqual(actual, expected);
1160       }
1161       else {
1162         skipAssert(assert);
1163       }
1164     });
1165   }());
1166
1167   /*--------------------------------------------------------------------------*/
1168
1169   QUnit.module('lodash.add');
1170
1171   (function() {
1172     QUnit.test('should add two numbers', function(assert) {
1173       assert.expect(3);
1174
1175       assert.strictEqual(_.add(6, 4), 10);
1176       assert.strictEqual(_.add(-6, 4), -2);
1177       assert.strictEqual(_.add(-6, -4), -10);
1178     });
1179
1180     QUnit.test('should not coerce arguments to numbers', function(assert) {
1181       assert.expect(2);
1182
1183       assert.strictEqual(_.add('6', '4'), '64');
1184       assert.strictEqual(_.add('x', 'y'), 'xy');
1185     });
1186   }());
1187
1188   /*--------------------------------------------------------------------------*/
1189
1190   QUnit.module('lodash.after');
1191
1192   (function() {
1193     function after(n, times) {
1194       var count = 0;
1195       lodashStable.times(times, _.after(n, function() { count++; }));
1196       return count;
1197     }
1198
1199     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1200       assert.expect(4);
1201
1202       assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1203       assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1204       assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1205       assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1206     });
1207
1208     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1209       assert.expect(1);
1210
1211       assert.strictEqual(after(NaN, 1), 1);
1212     });
1213
1214     QUnit.test('should use `this` binding of function', function(assert) {
1215       assert.expect(2);
1216
1217       var after = _.after(1, function(assert) { return ++this.count; }),
1218           object = { 'after': after, 'count': 0 };
1219
1220       object.after();
1221       assert.strictEqual(object.after(), 2);
1222       assert.strictEqual(object.count, 2);
1223     });
1224   }());
1225
1226   /*--------------------------------------------------------------------------*/
1227
1228   QUnit.module('lodash.ary');
1229
1230   (function() {
1231     function fn(a, b, c) {
1232       return slice.call(arguments);
1233     }
1234
1235     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1236       assert.expect(2);
1237
1238       var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1239       assert.deepEqual(actual, [6, 8, 10]);
1240
1241       var capped = _.ary(fn, 2);
1242       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1243     });
1244
1245     QUnit.test('should use `func.length` if `n` is not given', function(assert) {
1246       assert.expect(1);
1247
1248       var capped = _.ary(fn);
1249       assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1250     });
1251
1252     QUnit.test('should treat a negative `n` as `0`', function(assert) {
1253       assert.expect(1);
1254
1255       var capped = _.ary(fn, -1);
1256
1257       try {
1258         var actual = capped('a');
1259       } catch (e) {}
1260
1261       assert.deepEqual(actual, []);
1262     });
1263
1264     QUnit.test('should coerce `n` to an integer', function(assert) {
1265       assert.expect(1);
1266
1267       var values = ['1', 1.6, 'xyz'],
1268           expected = [['a'], ['a'], []];
1269
1270       var actual = lodashStable.map(values, function(n) {
1271         var capped = _.ary(fn, n);
1272         return capped('a', 'b');
1273       });
1274
1275       assert.deepEqual(actual, expected);
1276     });
1277
1278     QUnit.test('should not force a minimum argument count', function(assert) {
1279       assert.expect(1);
1280
1281       var args = ['a', 'b', 'c'],
1282           capped = _.ary(fn, 3);
1283
1284       var expected = lodashStable.map(args, function(arg, index) {
1285         return args.slice(0, index);
1286       });
1287
1288       var actual = lodashStable.map(expected, function(array) {
1289         return capped.apply(undefined, array);
1290       });
1291
1292       assert.deepEqual(actual, expected);
1293     });
1294
1295     QUnit.test('should use `this` binding of function', function(assert) {
1296       assert.expect(1);
1297
1298       var capped = _.ary(function(a, b) { return this; }, 1),
1299           object = { 'capped': capped };
1300
1301       assert.strictEqual(object.capped(), object);
1302     });
1303
1304     QUnit.test('should use the existing `ary` if smaller', function(assert) {
1305       assert.expect(1);
1306
1307       var capped = _.ary(_.ary(fn, 1), 2);
1308       assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1309     });
1310
1311     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1312       assert.expect(1);
1313
1314       var funcs = lodashStable.map([fn], _.ary),
1315           actual = funcs[0]('a', 'b', 'c');
1316
1317       assert.deepEqual(actual, ['a', 'b', 'c']);
1318     });
1319
1320     QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1321       assert.expect(2);
1322
1323       var array = ['a', 'b', 'c'],
1324           includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1325
1326       assert.strictEqual(includes('b')(array, 2), true);
1327
1328       if (!isNpm) {
1329         includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1330         assert.strictEqual(includes('b')(array, 2), true);
1331       }
1332       else {
1333         skipAssert(assert);
1334       }
1335     });
1336   }());
1337
1338   /*--------------------------------------------------------------------------*/
1339
1340   QUnit.module('lodash.assignIn');
1341
1342   (function() {
1343     QUnit.test('should be aliased', function(assert) {
1344       assert.expect(1);
1345
1346       assert.strictEqual(_.extend, _.assignIn);
1347     });
1348   }());
1349
1350   /*--------------------------------------------------------------------------*/
1351
1352   QUnit.module('lodash.assign and lodash.assignIn');
1353
1354   lodashStable.each(['assign', 'assignIn'], function(methodName) {
1355     var func = _[methodName];
1356
1357     QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1358       assert.expect(1);
1359
1360       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1361     });
1362
1363     QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1364       assert.expect(2);
1365
1366       var expected = { 'a': 1, 'b': 2, 'c': 3 };
1367       assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1368       assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1369     });
1370
1371     QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1372       assert.expect(1);
1373
1374       var expected = { 'a': 3, 'b': 2, 'c': 1 };
1375       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1376     });
1377
1378     QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1379       assert.expect(1);
1380
1381       var expected = { 'a': null, 'b': undefined, 'c': null };
1382       assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1383     });
1384
1385     QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1386       assert.expect(1);
1387
1388       var object = {};
1389
1390       var descriptor = {
1391         'configurable': true,
1392         'enumerable': true,
1393         'set': function() { throw new Error; }
1394       };
1395
1396       var source = {
1397         'a': 1,
1398         'b': undefined,
1399         'c': NaN,
1400         'd': undefined,
1401         'constructor': Object,
1402         'toString': lodashStable.constant('source')
1403       };
1404
1405       defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1406         'get': stubOne
1407       }));
1408
1409       defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1410         'get': noop
1411       }));
1412
1413       defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1414         'get': stubNaN
1415       }));
1416
1417       defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1418         'get': lodashStable.constant(Object)
1419       }));
1420
1421       try {
1422         var actual = func(object, source);
1423       } catch (e) {}
1424
1425       assert.deepEqual(actual, source);
1426     });
1427
1428     QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) {
1429       assert.expect(1);
1430
1431       var array = [1];
1432       array[2] = 3;
1433
1434       assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 });
1435     });
1436
1437     QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) {
1438       assert.expect(1);
1439
1440       function Foo() {}
1441       Foo.prototype.a = 1;
1442
1443       assert.deepEqual(func({}, Foo.prototype), { 'a': 1 });
1444     });
1445
1446     QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) {
1447       assert.expect(1);
1448
1449       assert.deepEqual(func({}, 'a'), { '0': 'a' });
1450     });
1451   });
1452
1453   /*--------------------------------------------------------------------------*/
1454
1455   QUnit.module('lodash.assignInWith');
1456
1457   (function() {
1458     QUnit.test('should be aliased', function(assert) {
1459       assert.expect(1);
1460
1461       assert.strictEqual(_.extendWith, _.assignInWith);
1462     });
1463   }());
1464
1465   /*--------------------------------------------------------------------------*/
1466
1467   QUnit.module('lodash.assignWith and lodash.assignInWith');
1468
1469   lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1470     var func = _[methodName];
1471
1472     QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1473       assert.expect(1);
1474
1475       var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1476         return a === undefined ? b : a;
1477       });
1478
1479       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1480     });
1481
1482     QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1483       assert.expect(1);
1484
1485       var expected = { 'a': 1 };
1486       assert.deepEqual(func({}, expected, noop), expected);
1487     });
1488   });
1489
1490   /*--------------------------------------------------------------------------*/
1491
1492   QUnit.module('lodash.at');
1493
1494   (function() {
1495     var array = ['a', 'b', 'c'],
1496         object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1497
1498     QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1499       assert.expect(1);
1500
1501       var actual = _.at(array, [0, 2]);
1502       assert.deepEqual(actual, ['a', 'c']);
1503     });
1504
1505     QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1506       assert.expect(1);
1507
1508       var actual = _.at(array, [2, 4, 0]);
1509       assert.deepEqual(actual, ['c', undefined, 'a']);
1510     });
1511
1512     QUnit.test('should work with non-index keys on array values', function(assert) {
1513       assert.expect(1);
1514
1515       var values = lodashStable.reject(empties, function(value) {
1516         return (value === 0) || lodashStable.isArray(value);
1517       }).concat(-1, 1.1);
1518
1519       var array = lodashStable.transform(values, function(result, value) {
1520         result[value] = 1;
1521       }, []);
1522
1523       var expected = lodashStable.map(values, stubOne),
1524           actual = _.at(array, values);
1525
1526       assert.deepEqual(actual, expected);
1527     });
1528
1529     QUnit.test('should return an empty array when no keys are given', function(assert) {
1530       assert.expect(2);
1531
1532       assert.deepEqual(_.at(array), []);
1533       assert.deepEqual(_.at(array, [], []), []);
1534     });
1535
1536     QUnit.test('should accept multiple key arguments', function(assert) {
1537       assert.expect(1);
1538
1539       var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1540       assert.deepEqual(actual, ['d', 'a', 'c']);
1541     });
1542
1543     QUnit.test('should work with a falsey `object` when keys are given', function(assert) {
1544       assert.expect(1);
1545
1546       var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1547
1548       var actual = lodashStable.map(falsey, function(object) {
1549         try {
1550           return _.at(object, 0, 1, 'pop', 'push');
1551         } catch (e) {}
1552       });
1553
1554       assert.deepEqual(actual, expected);
1555     });
1556
1557     QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1558       assert.expect(1);
1559
1560       var actual = _.at(args, [2, 0]);
1561       assert.deepEqual(actual, [3, 1]);
1562     });
1563
1564     QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1565       assert.expect(1);
1566
1567       var actual = _.at([1, 2, 3, 4, 5], args);
1568       assert.deepEqual(actual, [2, 3, 4]);
1569     });
1570
1571     QUnit.test('should work with an object for `object`', function(assert) {
1572       assert.expect(1);
1573
1574       var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1575       assert.deepEqual(actual, [3, 4]);
1576     });
1577
1578     QUnit.test('should pluck inherited property values', function(assert) {
1579       assert.expect(1);
1580
1581       function Foo() {
1582         this.a = 1;
1583       }
1584       Foo.prototype.b = 2;
1585
1586       var actual = _.at(new Foo, 'b');
1587       assert.deepEqual(actual, [2]);
1588     });
1589
1590     QUnit.test('should work in a lazy sequence', function(assert) {
1591       assert.expect(6);
1592
1593       if (!isNpm) {
1594         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1595             smallArray = array;
1596
1597         lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1598           lodashStable.times(2, function(index) {
1599             var array = index ? largeArray : smallArray,
1600                 wrapped = _(array).map(identity).at(paths);
1601
1602             assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1603           });
1604         });
1605       }
1606       else {
1607         skipAssert(assert, 6);
1608       }
1609     });
1610
1611     QUnit.test('should support shortcut fusion', function(assert) {
1612       assert.expect(8);
1613
1614       if (!isNpm) {
1615         var array = lodashStable.range(LARGE_ARRAY_SIZE),
1616             count = 0,
1617             iteratee = function(value) { count++; return square(value); },
1618             lastIndex = LARGE_ARRAY_SIZE - 1;
1619
1620         lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1621           count = 0;
1622           var actual = _(array).map(iteratee).at(n).value(),
1623               expected = index < 2 ? 1 : 0;
1624
1625           assert.strictEqual(count, expected);
1626
1627           expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1628           assert.deepEqual(actual, expected);
1629         });
1630       }
1631       else {
1632         skipAssert(assert, 8);
1633       }
1634     });
1635
1636     QUnit.test('work with an object for `object` when chaining', function(assert) {
1637       assert.expect(2);
1638
1639       if (!isNpm) {
1640         var paths = ['a[0].b.c', 'a[1]'],
1641             actual = _(object).map(identity).at(paths).value();
1642
1643         assert.deepEqual(actual, _.at(_.map(object, identity), paths));
1644
1645         var indexObject = { '0': 1 };
1646         actual = _(indexObject).at(0).value();
1647         assert.deepEqual(actual, _.at(indexObject, 0));
1648       }
1649       else {
1650         skipAssert(assert, 2);
1651       }
1652     });
1653   }());
1654
1655   /*--------------------------------------------------------------------------*/
1656
1657   QUnit.module('lodash.attempt');
1658
1659   (function() {
1660     QUnit.test('should return the result of `func`', function(assert) {
1661       assert.expect(1);
1662
1663       assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1664     });
1665
1666     QUnit.test('should provide additional arguments to `func`', function(assert) {
1667       assert.expect(1);
1668
1669       var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1670       assert.deepEqual(actual, [1, 2]);
1671     });
1672
1673     QUnit.test('should return the caught error', function(assert) {
1674       assert.expect(1);
1675
1676       var expected = lodashStable.map(errors, stubTrue);
1677
1678       var actual = lodashStable.map(errors, function(error) {
1679         return _.attempt(function() { throw error; }) === error;
1680       });
1681
1682       assert.deepEqual(actual, expected);
1683     });
1684
1685     QUnit.test('should coerce errors to error objects', function(assert) {
1686       assert.expect(1);
1687
1688       var actual = _.attempt(function() { throw 'x'; });
1689       assert.ok(lodashStable.isEqual(actual, Error('x')));
1690     });
1691
1692     QUnit.test('should preserve custom errors', function(assert) {
1693       assert.expect(1);
1694
1695       var actual = _.attempt(function() { throw new CustomError('x'); });
1696       assert.ok(actual instanceof CustomError);
1697     });
1698
1699     QUnit.test('should work with an error object from another realm', function(assert) {
1700       assert.expect(1);
1701
1702       if (realm.errors) {
1703         var expected = lodashStable.map(realm.errors, stubTrue);
1704
1705         var actual = lodashStable.map(realm.errors, function(error) {
1706           return _.attempt(function() { throw error; }) === error;
1707         });
1708
1709         assert.deepEqual(actual, expected);
1710       }
1711       else {
1712         skipAssert(assert);
1713       }
1714     });
1715
1716     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1717       assert.expect(1);
1718
1719       if (!isNpm) {
1720         assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1721       }
1722       else {
1723         skipAssert(assert);
1724       }
1725     });
1726
1727     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1728       assert.expect(1);
1729
1730       if (!isNpm) {
1731         assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1732       }
1733       else {
1734         skipAssert(assert);
1735       }
1736     });
1737   }());
1738
1739   /*--------------------------------------------------------------------------*/
1740
1741   QUnit.module('lodash.before');
1742
1743   (function() {
1744     function before(n, times) {
1745       var count = 0;
1746       lodashStable.times(times, _.before(n, function() { count++; }));
1747       return count;
1748     }
1749
1750     QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1751       assert.expect(4);
1752
1753       assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1754       assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1755       assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1756       assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1757     });
1758
1759     QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1760       assert.expect(1);
1761
1762       assert.strictEqual(before(NaN, 1), 0);
1763     });
1764
1765     QUnit.test('should use `this` binding of function', function(assert) {
1766       assert.expect(2);
1767
1768       var before = _.before(2, function(assert) { return ++this.count; }),
1769           object = { 'before': before, 'count': 0 };
1770
1771       object.before();
1772       assert.strictEqual(object.before(), 1);
1773       assert.strictEqual(object.count, 1);
1774     });
1775   }());
1776
1777   /*--------------------------------------------------------------------------*/
1778
1779   QUnit.module('lodash.bind');
1780
1781   (function() {
1782     function fn() {
1783       var result = [this];
1784       push.apply(result, arguments);
1785       return result;
1786     }
1787
1788     QUnit.test('should bind a function to an object', function(assert) {
1789       assert.expect(1);
1790
1791       var object = {},
1792           bound = _.bind(fn, object);
1793
1794       assert.deepEqual(bound('a'), [object, 'a']);
1795     });
1796
1797     QUnit.test('should accept a falsey `thisArg`', function(assert) {
1798       assert.expect(1);
1799
1800       var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1801           expected = lodashStable.map(values, function(value) { return [value]; });
1802
1803       var actual = lodashStable.map(values, function(value) {
1804         try {
1805           var bound = _.bind(fn, value);
1806           return bound();
1807         } catch (e) {}
1808       });
1809
1810       assert.ok(lodashStable.every(actual, function(value, index) {
1811         return lodashStable.isEqual(value, expected[index]);
1812       }));
1813     });
1814
1815     QUnit.test('should bind a function to nullish values', function(assert) {
1816       assert.expect(6);
1817
1818       var bound = _.bind(fn, null),
1819           actual = bound('a');
1820
1821       assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1822       assert.strictEqual(actual[1], 'a');
1823
1824       lodashStable.times(2, function(index) {
1825         bound = index ? _.bind(fn, undefined) : _.bind(fn);
1826         actual = bound('b');
1827
1828         assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1829         assert.strictEqual(actual[1], 'b');
1830       });
1831     });
1832
1833     QUnit.test('should partially apply arguments ', function(assert) {
1834       assert.expect(4);
1835
1836       var object = {},
1837           bound = _.bind(fn, object, 'a');
1838
1839       assert.deepEqual(bound(), [object, 'a']);
1840
1841       bound = _.bind(fn, object, 'a');
1842       assert.deepEqual(bound('b'), [object, 'a', 'b']);
1843
1844       bound = _.bind(fn, object, 'a', 'b');
1845       assert.deepEqual(bound(), [object, 'a', 'b']);
1846       assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1847     });
1848
1849     QUnit.test('should support placeholders', function(assert) {
1850       assert.expect(4);
1851
1852       var object = {},
1853           ph = _.bind.placeholder,
1854           bound = _.bind(fn, object, ph, 'b', ph);
1855
1856       assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1857       assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1858       assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1859       assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1860     });
1861
1862     QUnit.test('should use `_.placeholder` when set', function(assert) {
1863       assert.expect(1);
1864
1865       if (!isModularize) {
1866         var _ph = _.placeholder = {},
1867             ph = _.bind.placeholder,
1868             object = {},
1869             bound = _.bind(fn, object, _ph, 'b', ph);
1870
1871         assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
1872         delete _.placeholder;
1873       }
1874       else {
1875         skipAssert(assert);
1876       }
1877     });
1878
1879     QUnit.test('should create a function with a `length` of `0`', function(assert) {
1880       assert.expect(2);
1881
1882       var fn = function(a, b, c) {},
1883           bound = _.bind(fn, {});
1884
1885       assert.strictEqual(bound.length, 0);
1886
1887       bound = _.bind(fn, {}, 1);
1888       assert.strictEqual(bound.length, 0);
1889     });
1890
1891     QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1892       assert.expect(3);
1893
1894       function Foo() {
1895         return this;
1896       }
1897
1898       var bound = _.bind(Foo, { 'a': 1 }),
1899           newBound = new bound;
1900
1901       assert.strictEqual(bound().a, 1);
1902       assert.strictEqual(newBound.a, undefined);
1903       assert.ok(newBound instanceof Foo);
1904     });
1905
1906     QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1907       assert.expect(1);
1908
1909       function Foo() {
1910         return this;
1911       }
1912
1913       function Bar() {}
1914
1915       var thisArg = { 'a': 1 },
1916           boundFoo = _.bind(Foo, thisArg),
1917           boundBar = _.bind(Bar, thisArg),
1918           count = 9,
1919           expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1920
1921       var actual = lodashStable.times(count, function(index) {
1922         try {
1923           switch (index) {
1924             case 0: return [new boundFoo().a, new boundBar().a];
1925             case 1: return [new boundFoo(1).a, new boundBar(1).a];
1926             case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1927             case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1928             case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1929             case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1930             case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1931             case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1932             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];
1933           }
1934         } catch (e) {}
1935       });
1936
1937       assert.deepEqual(actual, expected);
1938     });
1939
1940     QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1941       assert.expect(2);
1942
1943       function Foo(value) {
1944         return value && object;
1945       }
1946
1947       var bound = _.bind(Foo),
1948           object = {};
1949
1950       assert.ok(new bound instanceof Foo);
1951       assert.strictEqual(new bound(true), object);
1952     });
1953
1954     QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1955       assert.expect(1);
1956
1957       var object = {},
1958           bound = _.bind(fn, object, 'a');
1959
1960       assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1961     });
1962
1963     QUnit.test('should not rebind functions', function(assert) {
1964       assert.expect(3);
1965
1966       var object1 = {},
1967           object2 = {},
1968           object3 = {};
1969
1970       var bound1 = _.bind(fn, object1),
1971           bound2 = _.bind(bound1, object2, 'a'),
1972           bound3 = _.bind(bound1, object3, 'b');
1973
1974       assert.deepEqual(bound1(), [object1]);
1975       assert.deepEqual(bound2(), [object1, 'a']);
1976       assert.deepEqual(bound3(), [object1, 'b']);
1977     });
1978
1979     QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1980       assert.expect(2);
1981
1982       var Ctor = _.bind(Date, null),
1983           expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1984
1985       try {
1986         var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1987       } catch (e) {}
1988
1989       assert.deepEqual(actual, expected);
1990
1991       Ctor = _.bind(Date, null, 2012, 4, 23);
1992
1993       try {
1994         actual = new Ctor(0, 0, 0, 0);
1995       } catch (e) {}
1996
1997       assert.deepEqual(actual, expected);
1998     });
1999
2000     QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
2001       assert.expect(1);
2002
2003       var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
2004
2005       if (typeof createCtor == 'function') {
2006         var bound = _.bind(createCtor()),
2007             count = 8,
2008             expected = lodashStable.times(count, stubTrue);
2009
2010         var actual = lodashStable.times(count, function(index) {
2011           try {
2012             switch (index) {
2013               case 0: return !!(new bound);
2014               case 1: return !!(new bound(1));
2015               case 2: return !!(new bound(1, 2));
2016               case 3: return !!(new bound(1, 2, 3));
2017               case 4: return !!(new bound(1, 2, 3, 4));
2018               case 5: return !!(new bound(1, 2, 3, 4, 5));
2019               case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
2020               case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
2021             }
2022           } catch (e) {}
2023         });
2024
2025         assert.deepEqual(actual, expected);
2026       }
2027       else {
2028         skipAssert(assert);
2029       }
2030     });
2031
2032     QUnit.test('should return a wrapped value when chaining', function(assert) {
2033       assert.expect(2);
2034
2035       if (!isNpm) {
2036         var object = {},
2037             bound = _(fn).bind({}, 'a', 'b');
2038
2039         assert.ok(bound instanceof _);
2040
2041         var actual = bound.value()('c');
2042         assert.deepEqual(actual, [object, 'a', 'b', 'c']);
2043       }
2044       else {
2045         skipAssert(assert, 2);
2046       }
2047     });
2048   }());
2049
2050   /*--------------------------------------------------------------------------*/
2051
2052   QUnit.module('lodash.bindAll');
2053
2054   (function() {
2055     var args = toArgs(['a']);
2056
2057     var source = {
2058       '_n0': -2,
2059       '_p0': -1,
2060       '_a': 1,
2061       '_b': 2,
2062       '_c': 3,
2063       '_d': 4,
2064       '-0': function() { return this._n0; },
2065       '0': function() { return this._p0; },
2066       'a': function() { return this._a; },
2067       'b': function() { return this._b; },
2068       'c': function() { return this._c; },
2069       'd': function() { return this._d; }
2070     };
2071
2072     QUnit.test('should accept individual method names', function(assert) {
2073       assert.expect(1);
2074
2075       var object = lodashStable.cloneDeep(source);
2076       _.bindAll(object, 'a', 'b');
2077
2078       var actual = lodashStable.map(['a', 'b', 'c'], function(key) {
2079         return object[key].call({});
2080       });
2081
2082       assert.deepEqual(actual, [1, 2, undefined]);
2083     });
2084
2085     QUnit.test('should accept arrays of method names', function(assert) {
2086       assert.expect(1);
2087
2088       var object = lodashStable.cloneDeep(source);
2089       _.bindAll(object, ['a', 'b'], ['c']);
2090
2091       var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) {
2092         return object[key].call({});
2093       });
2094
2095       assert.deepEqual(actual, [1, 2, 3, undefined]);
2096     });
2097
2098     QUnit.test('should preserve the sign of `0`', function(assert) {
2099       assert.expect(1);
2100
2101       var props = [-0, Object(-0), 0, Object(0)];
2102
2103       var actual = lodashStable.map(props, function(key) {
2104         var object = lodashStable.cloneDeep(source);
2105         _.bindAll(object, key);
2106         return object[lodashStable.toString(key)].call({});
2107       });
2108
2109       assert.deepEqual(actual, [-2, -2, -1, -1]);
2110     });
2111
2112     QUnit.test('should work with an array `object`', function(assert) {
2113       assert.expect(1);
2114
2115       var array = ['push', 'pop'];
2116       _.bindAll(array);
2117       assert.strictEqual(array.pop, arrayProto.pop);
2118     });
2119
2120     QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
2121       assert.expect(1);
2122
2123       var object = lodashStable.cloneDeep(source);
2124       _.bindAll(object, args);
2125
2126       var actual = lodashStable.map(args, function(key) {
2127         return object[key].call({});
2128       });
2129
2130       assert.deepEqual(actual, [1]);
2131     });
2132   }());
2133
2134   /*--------------------------------------------------------------------------*/
2135
2136   QUnit.module('lodash.bindKey');
2137
2138   (function() {
2139     QUnit.test('should work when the target function is overwritten', function(assert) {
2140       assert.expect(2);
2141
2142       var object = {
2143         'user': 'fred',
2144         'greet': function(greeting) {
2145           return this.user + ' says: ' + greeting;
2146         }
2147       };
2148
2149       var bound = _.bindKey(object, 'greet', 'hi');
2150       assert.strictEqual(bound(), 'fred says: hi');
2151
2152       object.greet = function(greeting) {
2153         return this.user + ' says: ' + greeting + '!';
2154       };
2155
2156       assert.strictEqual(bound(), 'fred says: hi!');
2157     });
2158
2159     QUnit.test('should support placeholders', function(assert) {
2160       assert.expect(4);
2161
2162       var object = {
2163         'fn': function() {
2164           return slice.call(arguments);
2165         }
2166       };
2167
2168       var ph = _.bindKey.placeholder,
2169           bound = _.bindKey(object, 'fn', ph, 'b', ph);
2170
2171       assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
2172       assert.deepEqual(bound('a'), ['a', 'b', undefined]);
2173       assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
2174       assert.deepEqual(bound(), [undefined, 'b', undefined]);
2175     });
2176
2177     QUnit.test('should use `_.placeholder` when set', function(assert) {
2178       assert.expect(1);
2179
2180       if (!isModularize) {
2181         var object = {
2182           'fn': function() {
2183             return slice.call(arguments);
2184           }
2185         };
2186
2187         var _ph = _.placeholder = {},
2188             ph = _.bindKey.placeholder,
2189             bound = _.bindKey(object, 'fn', _ph, 'b', ph);
2190
2191         assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
2192         delete _.placeholder;
2193       }
2194       else {
2195         skipAssert(assert);
2196       }
2197     });
2198
2199     QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
2200       assert.expect(2);
2201
2202       function Foo(value) {
2203         return value && object;
2204       }
2205
2206       var object = { 'Foo': Foo },
2207           bound = _.bindKey(object, 'Foo');
2208
2209       assert.ok(new bound instanceof Foo);
2210       assert.strictEqual(new bound(true), object);
2211     });
2212   }());
2213
2214   /*--------------------------------------------------------------------------*/
2215
2216   QUnit.module('case methods');
2217
2218   lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
2219     var methodName = caseName + 'Case',
2220         func = _[methodName];
2221
2222     var strings = [
2223       'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
2224       'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'
2225     ];
2226
2227     var converted = (function() {
2228       switch (caseName) {
2229         case 'camel': return 'fooBar';
2230         case 'kebab': return 'foo-bar';
2231         case 'lower': return 'foo bar';
2232         case 'snake': return 'foo_bar';
2233         case 'start': return 'Foo Bar';
2234         case 'upper': return 'FOO BAR';
2235       }
2236     }());
2237
2238     QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
2239       assert.expect(1);
2240
2241       var actual = lodashStable.map(strings, function(string) {
2242         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2243         return func(string) === expected;
2244       });
2245
2246       assert.deepEqual(actual, lodashStable.map(strings, stubTrue));
2247     });
2248
2249     QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
2250       assert.expect(1);
2251
2252       var actual = lodashStable.map(strings, function(string) {
2253         var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2254         return func(func(string)) === expected;
2255       });
2256
2257       assert.deepEqual(actual, lodashStable.map(strings, stubTrue));
2258     });
2259
2260     QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
2261       assert.expect(1);
2262
2263       var actual = lodashStable.map(burredLetters, function(burred, index) {
2264         var letter = deburredLetters[index].replace(/['\u2019]/g, '');
2265         if (caseName == 'start') {
2266           letter = letter == 'IJ' ? letter : lodashStable.capitalize(letter);
2267         } else if (caseName == 'upper') {
2268           letter = letter.toUpperCase();
2269         } else {
2270           letter = letter.toLowerCase();
2271         }
2272         return func(burred) === letter;
2273       });
2274
2275       assert.deepEqual(actual, lodashStable.map(burredLetters, stubTrue));
2276     });
2277
2278     QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) {
2279       assert.expect(2);
2280
2281       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
2282
2283       lodashStable.each(["'", '\u2019'], function(apos) {
2284         var actual = lodashStable.map(postfixes, function(postfix) {
2285           return func('a b' + apos + postfix +  ' c');
2286         });
2287
2288         var expected = lodashStable.map(postfixes, function(postfix) {
2289           switch (caseName) {
2290             case 'camel': return 'aB'  + postfix + 'C';
2291             case 'kebab': return 'a-b' + postfix + '-c';
2292             case 'lower': return 'a b' + postfix + ' c';
2293             case 'snake': return 'a_b' + postfix + '_c';
2294             case 'start': return 'A B' + postfix + ' C';
2295             case 'upper': return 'A B' + postfix.toUpperCase() + ' C';
2296           }
2297         });
2298
2299         assert.deepEqual(actual, expected);
2300       });
2301     });
2302
2303     QUnit.test('`_.' + methodName + '` should remove Latin mathematical operators', function(assert) {
2304       assert.expect(1);
2305
2306       var actual = lodashStable.map(['\xd7', '\xf7'], func);
2307       assert.deepEqual(actual, ['', '']);
2308     });
2309
2310     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2311       assert.expect(2);
2312
2313       var string = 'foo bar';
2314       assert.strictEqual(func(Object(string)), converted);
2315       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2316     });
2317
2318     QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2319       assert.expect(1);
2320
2321       if (!isNpm) {
2322         assert.strictEqual(_('foo bar')[methodName](), converted);
2323       }
2324       else {
2325         skipAssert(assert);
2326       }
2327     });
2328
2329     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2330       assert.expect(1);
2331
2332       if (!isNpm) {
2333         assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2334       }
2335       else {
2336         skipAssert(assert);
2337       }
2338     });
2339   });
2340
2341   (function() {
2342     QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2343       assert.expect(1);
2344
2345       var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase];
2346
2347       var actual = lodashStable.reduce(funcs, function(result, func) {
2348         return func(result);
2349       }, 'enable 6h format');
2350
2351       assert.strictEqual(actual, 'enable6HFormat');
2352     });
2353   }());
2354
2355   /*--------------------------------------------------------------------------*/
2356
2357   QUnit.module('lodash.camelCase');
2358
2359   (function() {
2360     QUnit.test('should work with numbers', function(assert) {
2361       assert.expect(6);
2362
2363       assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2364       assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
2365       assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
2366       assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2367       assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2368       assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2369     });
2370
2371     QUnit.test('should handle acronyms', function(assert) {
2372       assert.expect(6);
2373
2374       lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2375         assert.strictEqual(_.camelCase(string), 'safeHtml');
2376       });
2377
2378       lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2379         assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2380       });
2381
2382       lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2383         assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2384       });
2385     });
2386   }());
2387
2388   /*--------------------------------------------------------------------------*/
2389
2390   QUnit.module('lodash.capitalize');
2391
2392   (function() {
2393     QUnit.test('should capitalize the first character of a string', function(assert) {
2394       assert.expect(3);
2395
2396       assert.strictEqual(_.capitalize('fred'), 'Fred');
2397       assert.strictEqual(_.capitalize('Fred'), 'Fred');
2398       assert.strictEqual(_.capitalize(' fred'), ' fred');
2399     });
2400   }());
2401
2402   /*--------------------------------------------------------------------------*/
2403
2404   QUnit.module('lodash.castArray');
2405
2406   (function() {
2407     QUnit.test('should wrap non-array items in an array', function(assert) {
2408       assert.expect(1);
2409
2410       var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
2411           expected = lodashStable.map(values, function(value) { return [value]; }),
2412           actual = lodashStable.map(values, _.castArray);
2413
2414       assert.deepEqual(actual, expected);
2415     });
2416
2417     QUnit.test('should return array values by reference', function(assert) {
2418       assert.expect(1);
2419
2420       var array = [1];
2421       assert.strictEqual(_.castArray(array), array);
2422     });
2423
2424     QUnit.test('should return an empty array when no arguments are given', function(assert) {
2425       assert.expect(1);
2426
2427       assert.deepEqual(_.castArray(), []);
2428     });
2429   }());
2430
2431   /*--------------------------------------------------------------------------*/
2432
2433   QUnit.module('lodash.chain');
2434
2435   (function() {
2436     QUnit.test('should return a wrapped value', function(assert) {
2437       assert.expect(1);
2438
2439       if (!isNpm) {
2440         var actual = _.chain({ 'a': 0 });
2441         assert.ok(actual instanceof _);
2442       }
2443       else {
2444         skipAssert(assert);
2445       }
2446     });
2447
2448     QUnit.test('should return existing wrapped values', function(assert) {
2449       assert.expect(2);
2450
2451       if (!isNpm) {
2452         var wrapped = _({ 'a': 0 });
2453         assert.strictEqual(_.chain(wrapped), wrapped);
2454         assert.strictEqual(wrapped.chain(), wrapped);
2455       }
2456       else {
2457         skipAssert(assert, 2);
2458       }
2459     });
2460
2461     QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2462       assert.expect(6);
2463
2464       if (!isNpm) {
2465         var array = ['c', 'b', 'a'];
2466
2467         assert.ok(_.chain(array).head() instanceof _);
2468         assert.ok(_(array).chain().head() instanceof _);
2469
2470         assert.ok(_.chain(array).isArray() instanceof _);
2471         assert.ok(_(array).chain().isArray() instanceof _);
2472
2473         assert.ok(_.chain(array).sortBy().head() instanceof _);
2474         assert.ok(_(array).chain().sortBy().head() instanceof _);
2475       }
2476       else {
2477         skipAssert(assert, 6);
2478       }
2479     });
2480
2481     QUnit.test('should chain multiple methods', function(assert) {
2482       assert.expect(6);
2483
2484       if (!isNpm) {
2485         lodashStable.times(2, function(index) {
2486           var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2487               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 },
2488               wrapped = index ? _(array).chain() : _.chain(array);
2489
2490           var actual = wrapped
2491             .chain()
2492             .map(function(value) { return value.split(''); })
2493             .flatten()
2494             .reduce(function(object, chr) {
2495               object[chr] || (object[chr] = 0);
2496               object[chr]++;
2497               return object;
2498             }, {})
2499             .value();
2500
2501           assert.deepEqual(actual, expected);
2502
2503           array = [1, 2, 3, 4, 5, 6];
2504           wrapped = index ? _(array).chain() : _.chain(array);
2505           actual = wrapped
2506             .chain()
2507             .filter(function(n) { return n % 2 != 0; })
2508             .reject(function(n) { return n % 3 == 0; })
2509             .sortBy(function(n) { return -n; })
2510             .value();
2511
2512           assert.deepEqual(actual, [5, 1]);
2513
2514           array = [3, 4];
2515           wrapped = index ? _(array).chain() : _.chain(array);
2516           actual = wrapped
2517             .reverse()
2518             .concat([2, 1])
2519             .unshift(5)
2520             .tap(function(value) { value.pop(); })
2521             .map(square)
2522             .value();
2523
2524           assert.deepEqual(actual, [25, 16, 9, 4]);
2525         });
2526       }
2527       else {
2528         skipAssert(assert, 6);
2529       }
2530     });
2531   }());
2532
2533   /*--------------------------------------------------------------------------*/
2534
2535   QUnit.module('lodash.chunk');
2536
2537   (function() {
2538     var array = [0, 1, 2, 3, 4, 5];
2539
2540     QUnit.test('should return chunked arrays', function(assert) {
2541       assert.expect(1);
2542
2543       var actual = _.chunk(array, 3);
2544       assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2545     });
2546
2547     QUnit.test('should return the last chunk as remaining elements', function(assert) {
2548       assert.expect(1);
2549
2550       var actual = _.chunk(array, 4);
2551       assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2552     });
2553
2554     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
2555       assert.expect(1);
2556
2557       var expected = lodashStable.map(falsey, function(value) {
2558         return value === undefined ? [[0], [1], [2], [3], [4], [5]] : [];
2559       });
2560
2561       var actual = lodashStable.map(falsey, function(size, index) {
2562         return index ? _.chunk(array, size) : _.chunk(array);
2563       });
2564
2565       assert.deepEqual(actual, expected);
2566     });
2567
2568     QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2569       assert.expect(1);
2570
2571       var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity),
2572           expected = lodashStable.map(values, stubArray);
2573
2574       var actual = lodashStable.map(values, function(n) {
2575         return _.chunk(array, n);
2576       });
2577
2578       assert.deepEqual(actual, expected);
2579     });
2580
2581     QUnit.test('should coerce `size` to an integer', function(assert) {
2582       assert.expect(1);
2583
2584       assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2585     });
2586
2587     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
2588       assert.expect(1);
2589
2590       var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk);
2591       assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]);
2592     });
2593   }());
2594
2595   /*--------------------------------------------------------------------------*/
2596
2597   QUnit.module('lodash.clamp');
2598
2599   (function() {
2600     QUnit.test('should work with a `max`', function(assert) {
2601       assert.expect(2);
2602
2603       assert.strictEqual(_.clamp(5, 3), 3);
2604       assert.strictEqual(_.clamp(1, 3), 1);
2605     });
2606
2607     QUnit.test('should clamp negative numbers', function(assert) {
2608       assert.expect(3);
2609
2610       assert.strictEqual(_.clamp(-10, -5, 5), -5);
2611       assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2612       assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2613     });
2614
2615     QUnit.test('should clamp positive numbers', function(assert) {
2616       assert.expect(3);
2617
2618       assert.strictEqual(_.clamp(10, -5, 5), 5);
2619       assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2620       assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2621     });
2622
2623     QUnit.test('should not alter negative numbers in range', function(assert) {
2624       assert.expect(3);
2625
2626       assert.strictEqual(_.clamp(-4, -5, 5), -4);
2627       assert.strictEqual(_.clamp(-5, -5, 5), -5);
2628       assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2629     });
2630
2631     QUnit.test('should not alter positive numbers in range', function(assert) {
2632       assert.expect(3);
2633
2634       assert.strictEqual(_.clamp(4, -5, 5), 4);
2635       assert.strictEqual(_.clamp(5, -5, 5), 5);
2636       assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2637     });
2638
2639     QUnit.test('should not alter `0` in range', function(assert) {
2640       assert.expect(1);
2641
2642       assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2643     });
2644
2645     QUnit.test('should clamp to `0`', function(assert) {
2646       assert.expect(1);
2647
2648       assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2649     });
2650
2651     QUnit.test('should not alter `-0` in range', function(assert) {
2652       assert.expect(1);
2653
2654       assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2655     });
2656
2657     QUnit.test('should clamp to `-0`', function(assert) {
2658       assert.expect(1);
2659
2660       assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2661     });
2662
2663     QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2664       assert.expect(1);
2665
2666       assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2667     });
2668
2669     QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2670       assert.expect(2);
2671
2672       assert.deepEqual(_.clamp(1, -5, NaN), 0);
2673       assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2674     });
2675   }());
2676
2677   /*--------------------------------------------------------------------------*/
2678
2679   QUnit.module('clone methods');
2680
2681   (function() {
2682     function Foo() {
2683       this.a = 1;
2684     }
2685     Foo.prototype.b = 1;
2686     Foo.c = function() {};
2687
2688     if (Map) {
2689       var map = new Map;
2690       map.set('a', 1);
2691       map.set('b', 2);
2692     }
2693     if (Set) {
2694       var set = new Set;
2695       set.add(1);
2696       set.add(2);
2697     }
2698     var objects = {
2699       '`arguments` objects': arguments,
2700       'arrays': ['a', ''],
2701       'array-like objects': { '0': 'a', 'length': 1 },
2702       'booleans': false,
2703       'boolean objects': Object(false),
2704       'date objects': new Date,
2705       'Foo instances': new Foo,
2706       'objects': { 'a': 0, 'b': 1, 'c': 2 },
2707       'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2708       'objects from another document': realm.object || {},
2709       'maps': map,
2710       'null values': null,
2711       'numbers': 0,
2712       'number objects': Object(0),
2713       'regexes': /a/gim,
2714       'sets': set,
2715       'strings': 'a',
2716       'string objects': Object('a'),
2717       'undefined values': undefined
2718     };
2719
2720     objects.arrays.length = 3;
2721
2722     var uncloneable = {
2723       'DOM elements': body,
2724       'functions': Foo,
2725       'async functions': asyncFunc,
2726       'generator functions': genFunc,
2727       'the `Proxy` constructor': Proxy
2728     };
2729
2730     lodashStable.each(errors, function(error) {
2731       uncloneable[error.name + 's'] = error;
2732     });
2733
2734     QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2735       assert.expect(2);
2736
2737       var array = [{ 'a': 0 }, { 'b': 1 }],
2738           actual = _.clone(array);
2739
2740       assert.deepEqual(actual, array);
2741       assert.ok(actual !== array && actual[0] === array[0]);
2742     });
2743
2744     QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2745       assert.expect(1);
2746
2747       var object = {
2748         'foo': { 'b': { 'c': { 'd': {} } } },
2749         'bar': {}
2750       };
2751
2752       object.foo.b.c.d = object;
2753       object.bar.b = object.foo.b;
2754
2755       var actual = _.cloneDeep(object);
2756       assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2757     });
2758
2759     QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2760       assert.expect(2);
2761
2762       var cyclical = {};
2763       lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2764         cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2765       });
2766
2767       var clone = _.cloneDeep(cyclical),
2768           actual = clone['v' + LARGE_ARRAY_SIZE][0];
2769
2770       assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2771       assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2772     });
2773
2774     QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2775       assert.expect(1);
2776
2777       var actual;
2778
2779       _.cloneDeepWith({ 'a': 1 }, function() {
2780         actual = _.last(arguments);
2781       });
2782
2783       assert.ok(isNpm
2784         ? actual.constructor.name == 'Stack'
2785         : actual instanceof mapCaches.Stack
2786       );
2787     });
2788
2789     lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2790       var func = _[methodName],
2791           isDeep = methodName == 'cloneDeep';
2792
2793       lodashStable.forOwn(objects, function(object, kind) {
2794         QUnit.test('`_.' + methodName + '` should clone ' + kind, function(assert) {
2795           assert.expect(2);
2796
2797           var actual = func(object);
2798           assert.ok(lodashStable.isEqual(actual, object));
2799
2800           if (lodashStable.isObject(object)) {
2801             assert.notStrictEqual(actual, object);
2802           } else {
2803             assert.strictEqual(actual, object);
2804           }
2805         });
2806       });
2807
2808       QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2809         assert.expect(2);
2810
2811         if (ArrayBuffer) {
2812           var actual = func(arrayBuffer);
2813           assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
2814           assert.notStrictEqual(actual, arrayBuffer);
2815         }
2816         else {
2817           skipAssert(assert, 2);
2818         }
2819       });
2820
2821       QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
2822         assert.expect(4);
2823
2824         if (Buffer) {
2825           var buffer = new Buffer([1, 2]),
2826               actual = func(buffer);
2827
2828           assert.strictEqual(actual.byteLength, buffer.byteLength);
2829           assert.strictEqual(actual.inspect(), buffer.inspect());
2830           assert.notStrictEqual(actual, buffer);
2831
2832           buffer[0] = 2;
2833           assert.strictEqual(actual[0], isDeep ? 2 : 1);
2834         }
2835         else {
2836           skipAssert(assert, 4);
2837         }
2838       });
2839
2840       QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2841         assert.expect(2);
2842
2843         var array = /c/.exec('abcde'),
2844             actual = func(array);
2845
2846         assert.strictEqual(actual.index, 2);
2847         assert.strictEqual(actual.input, 'abcde');
2848       });
2849
2850       QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2851         assert.expect(1);
2852
2853         var regexp = /c/g;
2854         regexp.exec('abcde');
2855
2856         assert.strictEqual(func(regexp).lastIndex, 3);
2857       });
2858
2859       QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
2860         assert.expect(1);
2861
2862         var values = lodashStable.map([false, true, 1, 'a'], function(value) {
2863           var object = Object(value);
2864           object.a = 1;
2865           return object;
2866         });
2867
2868         var expected = lodashStable.map(values, stubTrue);
2869
2870         var actual = lodashStable.map(values, function(value) {
2871           return func(value).a === 1;
2872         });
2873
2874         assert.deepEqual(actual, expected);
2875       });
2876
2877       QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
2878         assert.expect(2);
2879
2880         var actual = func(Foo.prototype);
2881
2882         assert.notOk(actual instanceof Foo);
2883         assert.deepEqual(actual, { 'b': 1 });
2884       });
2885
2886       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
2887         assert.expect(1);
2888
2889         assert.ok(func(new Foo) instanceof Foo);
2890       });
2891
2892       QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
2893         assert.expect(1);
2894
2895         Foo.prototype.constructor = Object;
2896         assert.ok(func(new Foo) instanceof Foo);
2897         Foo.prototype.constructor = Foo;
2898       });
2899
2900       QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2901         assert.expect(1);
2902
2903         Foo.prototype.constructor = null;
2904         assert.notOk(func(new Foo) instanceof Foo);
2905         Foo.prototype.constructor = Foo;
2906       });
2907
2908       QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2909         assert.expect(2);
2910
2911         var object = {
2912           'constructor': objectProto.constructor,
2913           'hasOwnProperty': objectProto.hasOwnProperty,
2914           'isPrototypeOf': objectProto.isPrototypeOf,
2915           'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2916           'toLocaleString': objectProto.toLocaleString,
2917           'toString': objectProto.toString,
2918           'valueOf': objectProto.valueOf
2919         };
2920
2921         var actual = func(object);
2922
2923         assert.deepEqual(actual, object);
2924         assert.notStrictEqual(actual, object);
2925       });
2926
2927       QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2928         assert.expect(7);
2929
2930         function Foo() {
2931           this[symbol] = { 'c': 1 };
2932         }
2933
2934         if (Symbol) {
2935           var symbol2 = Symbol('b');
2936           Foo.prototype[symbol2] = 2;
2937
2938           var symbol3 = Symbol('c');
2939           defineProperty(Foo.prototype, symbol3, {
2940             'configurable': true,
2941             'enumerable': false,
2942             'writable': true,
2943             'value': 3
2944           });
2945
2946           var object = { 'a': { 'b': new Foo } };
2947           object[symbol] = { 'b': 1 };
2948
2949           var actual = func(object);
2950           if (isDeep) {
2951             assert.notStrictEqual(actual[symbol], object[symbol]);
2952             assert.notStrictEqual(actual.a, object.a);
2953           } else {
2954             assert.strictEqual(actual[symbol], object[symbol]);
2955             assert.strictEqual(actual.a, object.a);
2956           }
2957           assert.deepEqual(actual[symbol], object[symbol]);
2958           assert.deepEqual(getSymbols(actual.a.b), [symbol]);
2959           assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]);
2960           assert.deepEqual(actual.a.b[symbol2], object.a.b[symbol2]);
2961           assert.deepEqual(actual.a.b[symbol3], object.a.b[symbol3])
2962         }
2963         else {
2964           skipAssert(assert, 7);
2965         }
2966       });
2967
2968       QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2969         assert.expect(4);
2970
2971         if (Symbol) {
2972           assert.strictEqual(func(symbol), symbol);
2973
2974           var object = Object(symbol),
2975               actual = func(object);
2976
2977           assert.strictEqual(typeof actual, 'object');
2978           assert.strictEqual(typeof actual.valueOf(), 'symbol');
2979           assert.notStrictEqual(actual, object);
2980         }
2981         else {
2982           skipAssert(assert, 4);
2983         }
2984       });
2985
2986       QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2987         assert.expect(1);
2988
2989         if (Symbol) {
2990           assert.strictEqual(func(symbol), symbol);
2991         }
2992         else {
2993           skipAssert(assert);
2994         }
2995       });
2996
2997       QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2998         assert.expect(1);
2999
3000         if (document) {
3001           var element = document.createElement('div');
3002
3003           try {
3004             assert.deepEqual(func(element), {});
3005           } catch (e) {
3006             assert.ok(false, e.message);
3007           }
3008         }
3009         else {
3010           skipAssert(assert);
3011         }
3012       });
3013
3014       QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
3015         assert.expect(1);
3016
3017         var props = [];
3018
3019         var objects = lodashStable.transform(_, function(result, value, key) {
3020           if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
3021               !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
3022               !lodashStable.isFunction(value)) {
3023             props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
3024             result.push(value);
3025           }
3026         }, []);
3027
3028         var expected = lodashStable.map(objects, stubTrue);
3029
3030         var actual = lodashStable.map(objects, function(object) {
3031           var Ctor = object.constructor,
3032               result = func(object);
3033
3034           return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
3035         });
3036
3037         assert.deepEqual(actual, expected, props.join(', '));
3038       });
3039
3040       QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
3041         assert.expect(2);
3042
3043         var expected = [{ 'a': [0] }, { 'b': [1] }],
3044             actual = lodashStable.map(expected, func);
3045
3046         assert.deepEqual(actual, expected);
3047
3048         if (isDeep) {
3049           assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
3050         } else {
3051           assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
3052         }
3053       });
3054
3055       QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
3056         assert.expect(2);
3057
3058         if (!isNpm) {
3059           var object = objects.objects,
3060               actual = _(object)[methodName]();
3061
3062           assert.deepEqual(actual, object);
3063           assert.notStrictEqual(actual, object);
3064         }
3065         else {
3066           skipAssert(assert, 2);
3067         }
3068       });
3069
3070       lodashStable.each(arrayViews, function(type) {
3071         QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) {
3072           assert.expect(10);
3073
3074           var Ctor = root[type];
3075
3076           lodashStable.times(2, function(index) {
3077             if (Ctor) {
3078               var buffer = new ArrayBuffer(24),
3079                   view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
3080                   actual = func(view);
3081
3082               assert.deepEqual(actual, view);
3083               assert.notStrictEqual(actual, view);
3084               assert.strictEqual(actual.buffer === view.buffer, !isDeep);
3085               assert.strictEqual(actual.byteOffset, view.byteOffset);
3086               assert.strictEqual(actual.length, view.length);
3087             }
3088             else {
3089               skipAssert(assert, 5);
3090             }
3091           });
3092         });
3093       });
3094
3095       lodashStable.forOwn(uncloneable, function(value, key) {
3096         QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
3097           assert.expect(3);
3098
3099           if (value) {
3100             var object = { 'a': value, 'b': { 'c': value } },
3101                 actual = func(object),
3102                 expected = value === Foo ? { 'c': Foo.c } : {};
3103
3104             assert.deepEqual(actual, object);
3105             assert.notStrictEqual(actual, object);
3106             assert.deepEqual(func(value), expected);
3107           }
3108           else {
3109             skipAssert(assert, 3);
3110           }
3111         });
3112       });
3113     });
3114
3115     lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
3116       var func = _[methodName],
3117           isDeep = methodName == 'cloneDeepWith';
3118
3119       QUnit.test('`_.' + methodName + '` should provide correct `customizer` arguments', function(assert) {
3120         assert.expect(1);
3121
3122         var argsList = [],
3123             object = new Foo;
3124
3125         func(object, function() {
3126           var length = arguments.length,
3127               args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
3128
3129           argsList.push(args);
3130         });
3131
3132         assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]);
3133       });
3134
3135       QUnit.test('`_.' + methodName + '` should handle cloning when `customizer` returns `undefined`', function(assert) {
3136         assert.expect(1);
3137
3138         var actual = func({ 'a': { 'b': 'c' } }, noop);
3139         assert.deepEqual(actual, { 'a': { 'b': 'c' } });
3140       });
3141
3142       lodashStable.forOwn(uncloneable, function(value, key) {
3143         QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
3144           assert.expect(3);
3145
3146           var customizer = function(value) {
3147             return lodashStable.isPlainObject(value) ? undefined : value;
3148           };
3149
3150           var actual = func(value, customizer);
3151           assert.strictEqual(actual, value);
3152
3153           var object = { 'a': value, 'b': { 'c': value } };
3154           actual = func(object, customizer);
3155
3156           assert.deepEqual(actual, object);
3157           assert.notStrictEqual(actual, object);
3158         });
3159       });
3160     });
3161   }());
3162
3163   /*--------------------------------------------------------------------------*/
3164
3165   QUnit.module('lodash.compact');
3166
3167   (function() {
3168     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
3169
3170     QUnit.test('should filter falsey values', function(assert) {
3171       assert.expect(1);
3172
3173       var array = ['0', '1', '2'];
3174       assert.deepEqual(_.compact(falsey.concat(array)), array);
3175     });
3176
3177     QUnit.test('should work when in-between lazy operators', function(assert) {
3178       assert.expect(2);
3179
3180       if (!isNpm) {
3181         var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
3182         assert.deepEqual(actual, []);
3183
3184         actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
3185         assert.deepEqual(actual, [true, 1, 'a']);
3186       }
3187       else {
3188         skipAssert(assert, 2);
3189       }
3190     });
3191
3192     QUnit.test('should work in a lazy sequence', function(assert) {
3193       assert.expect(1);
3194
3195       if (!isNpm) {
3196         var actual = _(largeArray).slice(1).compact().reverse().take().value();
3197         assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
3198       }
3199       else {
3200         skipAssert(assert);
3201       }
3202     });
3203
3204     QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
3205       assert.expect(1);
3206
3207       if (!isModularize) {
3208         var iteratee = _.iteratee,
3209             pass = false;
3210
3211         _.iteratee = identity;
3212
3213         try {
3214           var actual = _(largeArray).slice(1).compact().value();
3215           pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
3216         } catch (e) {console.log(e);}
3217
3218         assert.ok(pass);
3219         _.iteratee = iteratee;
3220       }
3221       else {
3222         skipAssert(assert);
3223       }
3224     });
3225   }());
3226
3227   /*--------------------------------------------------------------------------*/
3228
3229   QUnit.module('lodash.concat');
3230
3231   (function() {
3232     QUnit.test('should shallow clone `array`', function(assert) {
3233       assert.expect(2);
3234
3235       var array = [1, 2, 3],
3236           actual = _.concat(array);
3237
3238       assert.deepEqual(actual, array);
3239       assert.notStrictEqual(actual, array);
3240     });
3241
3242     QUnit.test('should concat arrays and values', function(assert) {
3243       assert.expect(2);
3244
3245       var array = [1],
3246           actual = _.concat(array, 2, [3], [[4]]);
3247
3248       assert.deepEqual(actual, [1, 2, 3, [4]]);
3249       assert.deepEqual(array, [1]);
3250     });
3251
3252     QUnit.test('should cast non-array `array` values to arrays', function(assert) {
3253       assert.expect(2);
3254
3255       var values = [, null, undefined, false, true, 1, NaN, 'a'];
3256
3257       var expected = lodashStable.map(values, function(value, index) {
3258         return index ? [value] : [];
3259       });
3260
3261       var actual = lodashStable.map(values, function(value, index) {
3262         return index ? _.concat(value) : _.concat();
3263       });
3264
3265       assert.deepEqual(actual, expected);
3266
3267       expected = lodashStable.map(values, function(value) {
3268         return [value, 2, [3]];
3269       });
3270
3271       actual = lodashStable.map(values, function(value) {
3272         return _.concat(value, [2], [[3]]);
3273       });
3274
3275       assert.deepEqual(actual, expected);
3276     });
3277
3278     QUnit.test('should treat sparse arrays as dense', function(assert) {
3279       assert.expect(3);
3280
3281       var expected = [],
3282           actual = _.concat(Array(1), Array(1));
3283
3284       expected.push(undefined, undefined);
3285
3286       assert.ok('0'in actual);
3287       assert.ok('1' in actual);
3288       assert.deepEqual(actual, expected);
3289     });
3290
3291     QUnit.test('should return a new wrapped array', function(assert) {
3292       assert.expect(2);
3293
3294       if (!isNpm) {
3295         var array = [1],
3296             wrapped = _(array).concat([2, 3]),
3297             actual = wrapped.value();
3298
3299         assert.deepEqual(array, [1]);
3300         assert.deepEqual(actual, [1, 2, 3]);
3301       }
3302       else {
3303         skipAssert(assert, 2);
3304       }
3305     });
3306   }());
3307
3308   /*--------------------------------------------------------------------------*/
3309
3310   QUnit.module('lodash.cond');
3311
3312   (function() {
3313     QUnit.test('should create a conditional function', function(assert) {
3314       assert.expect(3);
3315
3316       var cond = _.cond([
3317         [lodashStable.matches({ 'a': 1 }),     stubA],
3318         [lodashStable.matchesProperty('b', 1), stubB],
3319         [lodashStable.property('c'),           stubC]
3320       ]);
3321
3322       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3323       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3324       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3325     });
3326
3327     QUnit.test('should provide arguments to functions', function(assert) {
3328       assert.expect(2);
3329
3330       var args1,
3331           args2,
3332           expected = ['a', 'b', 'c'];
3333
3334       var cond = _.cond([[
3335         function() { args1 || (args1 = slice.call(arguments)); return true; },
3336         function() { args2 || (args2 = slice.call(arguments)); }
3337       ]]);
3338
3339       cond('a', 'b', 'c');
3340
3341       assert.deepEqual(args1, expected);
3342       assert.deepEqual(args2, expected);
3343     });
3344
3345     QUnit.test('should work with predicate shorthands', function(assert) {
3346       assert.expect(3);
3347
3348       var cond = _.cond([
3349         [{ 'a': 1 }, stubA],
3350         [['b', 1],   stubB],
3351         ['c',        stubC]
3352       ]);
3353
3354       assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
3355       assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
3356       assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3357     });
3358
3359     QUnit.test('should return `undefined` when no condition is met', function(assert) {
3360       assert.expect(1);
3361
3362       var cond = _.cond([[stubFalse, stubA]]);
3363       assert.strictEqual(cond({ 'a': 1 }), undefined);
3364     });
3365
3366     QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
3367       assert.expect(2);
3368
3369       lodashStable.each([false, true], function(value) {
3370         assert.raises(function() { _.cond([[stubTrue, value]])(); }, TypeError);
3371       });
3372     });
3373
3374     QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
3375       assert.expect(1);
3376
3377       var cond = _.cond([
3378         [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
3379       ]);
3380
3381       var object = { 'cond': cond, 'a': 1, 'b': 2 };
3382       assert.strictEqual(object.cond('a', 'b'), 2);
3383     });
3384   }());
3385
3386   /*--------------------------------------------------------------------------*/
3387
3388   QUnit.module('lodash.conforms');
3389
3390   (function() {
3391     QUnit.test('should not change behavior if `source` is modified', function(assert) {
3392       assert.expect(2);
3393
3394       var object = { 'a': 2 },
3395           source = { 'a': function(value) { return value > 1; } },
3396           par = _.conforms(source);
3397
3398       assert.strictEqual(par(object), true);
3399
3400       source.a = function(value) { return value < 2; };
3401       assert.strictEqual(par(object), true);
3402     });
3403   }());
3404
3405   /*--------------------------------------------------------------------------*/
3406
3407   QUnit.module('conforms methods');
3408
3409   lodashStable.each(['conforms', 'conformsTo'], function(methodName) {
3410     var isConforms = methodName == 'conforms';
3411
3412     function conforms(source) {
3413       return isConforms ? _.conforms(source) : function(object) {
3414         return _.conformsTo(object, source);
3415       };
3416     }
3417
3418     QUnit.test('`_.' + methodName + '` should check if `object` conforms to `source`', function(assert) {
3419       assert.expect(2);
3420
3421       var objects = [
3422         { 'a': 1, 'b': 8 },
3423         { 'a': 2, 'b': 4 },
3424         { 'a': 3, 'b': 16 }
3425       ];
3426
3427       var par = conforms({
3428         'b': function(value) { return value > 4; }
3429       });
3430
3431       var actual = lodashStable.filter(objects, par);
3432       assert.deepEqual(actual, [objects[0], objects[2]]);
3433
3434       par = conforms({
3435         'b': function(value) { return value > 8; },
3436         'a': function(value) { return value > 1; }
3437       });
3438
3439       actual = lodashStable.filter(objects, par);
3440       assert.deepEqual(actual, [objects[2]]);
3441     });
3442
3443     QUnit.test('`_.' + methodName + '` should not match by inherited `source` properties', function(assert) {
3444       assert.expect(1);
3445
3446       function Foo() {
3447         this.a = function(value) {
3448           return value > 1;
3449         };
3450       }
3451       Foo.prototype.b = function(value) {
3452         return value > 8;
3453       };
3454
3455       var objects = [
3456         { 'a': 1, 'b': 8 },
3457         { 'a': 2, 'b': 4 },
3458         { 'a': 3, 'b': 16 }
3459       ];
3460
3461       var par = conforms(new Foo),
3462           actual = lodashStable.filter(objects, par);
3463
3464       assert.deepEqual(actual, [objects[1], objects[2]]);
3465     });
3466
3467     QUnit.test('`_.' + methodName + '` should not invoke `source` predicates for missing `object` properties', function(assert) {
3468       assert.expect(2);
3469
3470       var count = 0;
3471
3472       var par = conforms({
3473         'a': function() { count++; return true; }
3474       });
3475
3476       assert.strictEqual(par({}), false);
3477       assert.strictEqual(count, 0);
3478     });
3479
3480     QUnit.test('`_.' + methodName + '` should work with a function for `object`', function(assert) {
3481       assert.expect(2);
3482
3483       function Foo() {}
3484       Foo.a = 1;
3485
3486       function Bar() {}
3487       Bar.a = 2;
3488
3489       var par = conforms({
3490         'a': function(value) { return value > 1; }
3491       });
3492
3493       assert.strictEqual(par(Foo), false);
3494       assert.strictEqual(par(Bar), true);
3495     });
3496
3497     QUnit.test('`_.' + methodName + '` should work with a function for `source`', function(assert) {
3498       assert.expect(1);
3499
3500       function Foo() {}
3501       Foo.a = function(value) { return value > 1; };
3502
3503       var objects = [{ 'a': 1 }, { 'a': 2 }],
3504           actual = lodashStable.filter(objects, conforms(Foo));
3505
3506       assert.deepEqual(actual, [objects[1]]);
3507     });
3508
3509     QUnit.test('`_.' + methodName + '` should work with a non-plain `object`', function(assert) {
3510       assert.expect(1);
3511
3512       function Foo() {
3513         this.a = 1;
3514       }
3515       Foo.prototype.b = 2;
3516
3517       var par = conforms({
3518         'b': function(value) { return value > 1; }
3519       });
3520
3521       assert.strictEqual(par(new Foo), true);
3522     });
3523
3524     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
3525       assert.expect(1);
3526
3527       var values = [, null, undefined],
3528           expected = lodashStable.map(values, stubFalse);
3529
3530       var par = conforms({
3531         'a': function(value) { return value > 1; }
3532       });
3533
3534       var actual = lodashStable.map(values, function(value, index) {
3535         try {
3536           return index ? par(value) : par();
3537         } catch (e) {}
3538       });
3539
3540       assert.deepEqual(actual, expected);
3541     });
3542
3543     QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3544       assert.expect(1);
3545
3546       var values = [, null, undefined],
3547           expected = lodashStable.map(values, stubTrue),
3548           par = conforms({});
3549
3550       var actual = lodashStable.map(values, function(value, index) {
3551         try {
3552           return index ? par(value) : par();
3553         } catch (e) {}
3554       });
3555
3556       assert.deepEqual(actual, expected);
3557     });
3558
3559     QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source`', function(assert) {
3560       assert.expect(1);
3561
3562       var object = { 'a': 1 },
3563           expected = lodashStable.map(empties, stubTrue);
3564
3565       var actual = lodashStable.map(empties, function(value) {
3566         var par = conforms(value);
3567         return par(object);
3568       });
3569
3570       assert.deepEqual(actual, expected);
3571     });
3572   });
3573
3574   /*--------------------------------------------------------------------------*/
3575
3576   QUnit.module('lodash.constant');
3577
3578   (function() {
3579     QUnit.test('should create a function that returns `value`', function(assert) {
3580       assert.expect(1);
3581
3582       var object = { 'a': 1 },
3583           values = Array(2).concat(empties, true, 1, 'a'),
3584           constant = _.constant(object);
3585
3586       var results = lodashStable.map(values, function(value, index) {
3587         if (index < 2) {
3588           return index ? constant.call({}) : constant();
3589         }
3590         return constant(value);
3591       });
3592
3593       assert.ok(lodashStable.every(results, function(result) {
3594         return result === object;
3595       }));
3596     });
3597
3598     QUnit.test('should work with falsey values', function(assert) {
3599       assert.expect(1);
3600
3601       var expected = lodashStable.map(falsey, stubTrue);
3602
3603       var actual = lodashStable.map(falsey, function(value, index) {
3604         var constant = index ? _.constant(value) : _.constant(),
3605             result = constant();
3606
3607         return (result === value) || (result !== result && value !== value);
3608       });
3609
3610       assert.deepEqual(actual, expected);
3611     });
3612
3613     QUnit.test('should return a wrapped value when chaining', function(assert) {
3614       assert.expect(1);
3615
3616       if (!isNpm) {
3617         var wrapped = _(true).constant();
3618         assert.ok(wrapped instanceof _);
3619       }
3620       else {
3621         skipAssert(assert);
3622       }
3623     });
3624   }());
3625
3626   /*--------------------------------------------------------------------------*/
3627
3628   QUnit.module('lodash.countBy');
3629
3630   (function() {
3631     var array = [6.1, 4.2, 6.3];
3632
3633     QUnit.test('should transform keys by `iteratee`', function(assert) {
3634       assert.expect(1);
3635
3636       var actual = _.countBy(array, Math.floor);
3637       assert.deepEqual(actual, { '4': 1, '6': 2 });
3638     });
3639
3640     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3641       assert.expect(1);
3642
3643       var array = [4, 6, 6],
3644           values = [, null, undefined],
3645           expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
3646
3647       var actual = lodashStable.map(values, function(value, index) {
3648         return index ? _.countBy(array, value) : _.countBy(array);
3649       });
3650
3651       assert.deepEqual(actual, expected);
3652     });
3653
3654     QUnit.test('should work with `_.property` shorthands', function(assert) {
3655       assert.expect(1);
3656
3657       var actual = _.countBy(['one', 'two', 'three'], 'length');
3658       assert.deepEqual(actual, { '3': 2, '5': 1 });
3659     });
3660
3661     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3662       assert.expect(2);
3663
3664       var actual = _.countBy(array, function(n) {
3665         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
3666       });
3667
3668       assert.deepEqual(actual.constructor, 1);
3669       assert.deepEqual(actual.hasOwnProperty, 2);
3670     });
3671
3672     QUnit.test('should work with a number for `iteratee`', function(assert) {
3673       assert.expect(2);
3674
3675       var array = [
3676         [1, 'a'],
3677         [2, 'a'],
3678         [2, 'b']
3679       ];
3680
3681       assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3682       assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3683     });
3684
3685     QUnit.test('should work with an object for `collection`', function(assert) {
3686       assert.expect(1);
3687
3688       var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
3689       assert.deepEqual(actual, { '4': 1, '6': 2 });
3690     });
3691
3692     QUnit.test('should work in a lazy sequence', function(assert) {
3693       assert.expect(1);
3694
3695       if (!isNpm) {
3696         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3697           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3698           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3699         );
3700
3701         var actual = _(array).countBy().map(square).filter(isEven).take().value();
3702
3703         assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3704       }
3705       else {
3706         skipAssert(assert);
3707       }
3708     });
3709   }());
3710
3711   /*--------------------------------------------------------------------------*/
3712
3713   QUnit.module('lodash.create');
3714
3715   (function() {
3716     function Shape() {
3717       this.x = 0;
3718       this.y = 0;
3719     }
3720
3721     function Circle() {
3722       Shape.call(this);
3723     }
3724
3725     QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3726       assert.expect(3);
3727
3728       Circle.prototype = _.create(Shape.prototype);
3729       Circle.prototype.constructor = Circle;
3730
3731       var actual = new Circle;
3732
3733       assert.ok(actual instanceof Circle);
3734       assert.ok(actual instanceof Shape);
3735       assert.notStrictEqual(Circle.prototype, Shape.prototype);
3736     });
3737
3738     QUnit.test('should assign `properties` to the created object', function(assert) {
3739       assert.expect(3);
3740
3741       var expected = { 'constructor': Circle, 'radius': 0 };
3742       Circle.prototype = _.create(Shape.prototype, expected);
3743
3744       var actual = new Circle;
3745
3746       assert.ok(actual instanceof Circle);
3747       assert.ok(actual instanceof Shape);
3748       assert.deepEqual(Circle.prototype, expected);
3749     });
3750
3751     QUnit.test('should assign own properties', function(assert) {
3752       assert.expect(1);
3753
3754       function Foo() {
3755         this.a = 1;
3756         this.c = 3;
3757       }
3758       Foo.prototype.b = 2;
3759
3760       assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3761     });
3762
3763     QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
3764       assert.expect(1);
3765
3766       function Foo() {
3767         this.a = 1;
3768       }
3769       var object = _.create(new Foo, { 'a': 1 });
3770       assert.deepEqual(lodashStable.keys(object), ['a']);
3771     });
3772
3773     QUnit.test('should accept a falsey `prototype`', function(assert) {
3774       assert.expect(1);
3775
3776       var expected = lodashStable.map(falsey, stubObject);
3777
3778       var actual = lodashStable.map(falsey, function(prototype, index) {
3779         return index ? _.create(prototype) : _.create();
3780       });
3781
3782       assert.deepEqual(actual, expected);
3783     });
3784
3785     QUnit.test('should ignore a primitive `prototype` and use an empty object instead', function(assert) {
3786       assert.expect(1);
3787
3788       var expected = lodashStable.map(primitives, stubTrue);
3789
3790       var actual = lodashStable.map(primitives, function(value, index) {
3791         return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3792       });
3793
3794       assert.deepEqual(actual, expected);
3795     });
3796
3797     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3798       assert.expect(1);
3799
3800       var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3801           expected = lodashStable.map(array, stubTrue),
3802           objects = lodashStable.map(array, _.create);
3803
3804       var actual = lodashStable.map(objects, function(object) {
3805         return object.a === 1 && !_.keys(object).length;
3806       });
3807
3808       assert.deepEqual(actual, expected);
3809     });
3810   }());
3811
3812   /*--------------------------------------------------------------------------*/
3813
3814   QUnit.module('lodash.curry');
3815
3816   (function() {
3817     function fn(a, b, c, d) {
3818       return slice.call(arguments);
3819     }
3820
3821     QUnit.test('should curry based on the number of arguments given', function(assert) {
3822       assert.expect(3);
3823
3824       var curried = _.curry(fn),
3825           expected = [1, 2, 3, 4];
3826
3827       assert.deepEqual(curried(1)(2)(3)(4), expected);
3828       assert.deepEqual(curried(1, 2)(3, 4), expected);
3829       assert.deepEqual(curried(1, 2, 3, 4), expected);
3830     });
3831
3832     QUnit.test('should allow specifying `arity`', function(assert) {
3833       assert.expect(3);
3834
3835       var curried = _.curry(fn, 3),
3836           expected = [1, 2, 3];
3837
3838       assert.deepEqual(curried(1)(2, 3), expected);
3839       assert.deepEqual(curried(1, 2)(3), expected);
3840       assert.deepEqual(curried(1, 2, 3), expected);
3841     });
3842
3843     QUnit.test('should coerce `arity` to an integer', function(assert) {
3844       assert.expect(2);
3845
3846       var values = ['0', 0.6, 'xyz'],
3847           expected = lodashStable.map(values, stubArray);
3848
3849       var actual = lodashStable.map(values, function(arity) {
3850         return _.curry(fn, arity)();
3851       });
3852
3853       assert.deepEqual(actual, expected);
3854       assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3855     });
3856
3857     QUnit.test('should support placeholders', function(assert) {
3858       assert.expect(4);
3859
3860       var curried = _.curry(fn),
3861           ph = curried.placeholder;
3862
3863       assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3864       assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3865       assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3866       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3867     });
3868
3869     QUnit.test('should persist placeholders', function(assert) {
3870       assert.expect(1);
3871
3872       var curried = _.curry(fn),
3873           ph = curried.placeholder,
3874           actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
3875
3876       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3877     });
3878
3879     QUnit.test('should use `_.placeholder` when set', function(assert) {
3880       assert.expect(1);
3881
3882       if (!isModularize) {
3883         var curried = _.curry(fn),
3884             _ph = _.placeholder = {},
3885             ph = curried.placeholder;
3886
3887         assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
3888         delete _.placeholder;
3889       }
3890       else {
3891         skipAssert(assert);
3892       }
3893     });
3894
3895     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3896       assert.expect(3);
3897
3898       var curried = _.curry(fn, 3);
3899       assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3900       assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3901       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3902     });
3903
3904     QUnit.test('should create a function with a `length` of `0`', function(assert) {
3905       assert.expect(6);
3906
3907       lodashStable.times(2, function(index) {
3908         var curried = index ? _.curry(fn, 4) : _.curry(fn);
3909         assert.strictEqual(curried.length, 0);
3910         assert.strictEqual(curried(1).length, 0);
3911         assert.strictEqual(curried(1, 2).length, 0);
3912       });
3913     });
3914
3915     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3916       assert.expect(2);
3917
3918       function Foo(value) {
3919         return value && object;
3920       }
3921
3922       var curried = _.curry(Foo),
3923           object = {};
3924
3925       assert.ok(new curried(false) instanceof Foo);
3926       assert.strictEqual(new curried(true), object);
3927     });
3928
3929     QUnit.test('should use `this` binding of function', function(assert) {
3930       assert.expect(9);
3931
3932       var fn = function(a, b, c) {
3933         var value = this || {};
3934         return [value[a], value[b], value[c]];
3935       };
3936
3937       var object = { 'a': 1, 'b': 2, 'c': 3 },
3938           expected = [1, 2, 3];
3939
3940       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3941       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3942       assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3943
3944       assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3945       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3946       assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3947
3948       object.curried = _.curry(fn);
3949       assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3950       assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3951       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3952     });
3953
3954     QUnit.test('should work with partialed methods', function(assert) {
3955       assert.expect(2);
3956
3957       var curried = _.curry(fn),
3958           expected = [1, 2, 3, 4];
3959
3960       var a = _.partial(curried, 1),
3961           b = _.bind(a, null, 2),
3962           c = _.partialRight(b, 4),
3963           d = _.partialRight(b(3), 4);
3964
3965       assert.deepEqual(c(3), expected);
3966       assert.deepEqual(d(), expected);
3967     });
3968   }());
3969
3970   /*--------------------------------------------------------------------------*/
3971
3972   QUnit.module('lodash.curryRight');
3973
3974   (function() {
3975     function fn(a, b, c, d) {
3976       return slice.call(arguments);
3977     }
3978
3979     QUnit.test('should curry based on the number of arguments given', function(assert) {
3980       assert.expect(3);
3981
3982       var curried = _.curryRight(fn),
3983           expected = [1, 2, 3, 4];
3984
3985       assert.deepEqual(curried(4)(3)(2)(1), expected);
3986       assert.deepEqual(curried(3, 4)(1, 2), expected);
3987       assert.deepEqual(curried(1, 2, 3, 4), expected);
3988     });
3989
3990     QUnit.test('should allow specifying `arity`', function(assert) {
3991       assert.expect(3);
3992
3993       var curried = _.curryRight(fn, 3),
3994           expected = [1, 2, 3];
3995
3996       assert.deepEqual(curried(3)(1, 2), expected);
3997       assert.deepEqual(curried(2, 3)(1), expected);
3998       assert.deepEqual(curried(1, 2, 3), expected);
3999     });
4000
4001     QUnit.test('should coerce `arity` to an integer', function(assert) {
4002       assert.expect(2);
4003
4004       var values = ['0', 0.6, 'xyz'],
4005           expected = lodashStable.map(values, stubArray);
4006
4007       var actual = lodashStable.map(values, function(arity) {
4008         return _.curryRight(fn, arity)();
4009       });
4010
4011       assert.deepEqual(actual, expected);
4012       assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
4013     });
4014
4015     QUnit.test('should support placeholders', function(assert) {
4016       assert.expect(4);
4017
4018       var curried = _.curryRight(fn),
4019           expected = [1, 2, 3, 4],
4020           ph = curried.placeholder;
4021
4022       assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
4023       assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
4024       assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
4025       assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
4026     });
4027
4028     QUnit.test('should persist placeholders', function(assert) {
4029       assert.expect(1);
4030
4031       var curried = _.curryRight(fn),
4032           ph = curried.placeholder,
4033           actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
4034
4035       assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
4036     });
4037
4038     QUnit.test('should use `_.placeholder` when set', function(assert) {
4039       assert.expect(1);
4040
4041       if (!isModularize) {
4042         var curried = _.curryRight(fn),
4043             _ph = _.placeholder = {},
4044             ph = curried.placeholder;
4045
4046         assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
4047         delete _.placeholder;
4048       }
4049       else {
4050         skipAssert(assert);
4051       }
4052     });
4053
4054     QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
4055       assert.expect(3);
4056
4057       var curried = _.curryRight(fn, 3);
4058       assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
4059       assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
4060       assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
4061     });
4062
4063     QUnit.test('should create a function with a `length` of `0`', function(assert) {
4064       assert.expect(6);
4065
4066       lodashStable.times(2, function(index) {
4067         var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
4068         assert.strictEqual(curried.length, 0);
4069         assert.strictEqual(curried(4).length, 0);
4070         assert.strictEqual(curried(3, 4).length, 0);
4071       });
4072     });
4073
4074     QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
4075       assert.expect(2);
4076
4077       function Foo(value) {
4078         return value && object;
4079       }
4080
4081       var curried = _.curryRight(Foo),
4082           object = {};
4083
4084       assert.ok(new curried(false) instanceof Foo);
4085       assert.strictEqual(new curried(true), object);
4086     });
4087
4088     QUnit.test('should use `this` binding of function', function(assert) {
4089       assert.expect(9);
4090
4091       var fn = function(a, b, c) {
4092         var value = this || {};
4093         return [value[a], value[b], value[c]];
4094       };
4095
4096       var object = { 'a': 1, 'b': 2, 'c': 3 },
4097           expected = [1, 2, 3];
4098
4099       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
4100       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
4101       assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
4102
4103       assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
4104       assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
4105       assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
4106
4107       object.curried = _.curryRight(fn);
4108       assert.deepEqual(object.curried('c')('b')('a'), Array(3));
4109       assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
4110       assert.deepEqual(object.curried('a', 'b', 'c'), expected);
4111     });
4112
4113     QUnit.test('should work with partialed methods', function(assert) {
4114       assert.expect(2);
4115
4116       var curried = _.curryRight(fn),
4117           expected = [1, 2, 3, 4];
4118
4119       var a = _.partialRight(curried, 4),
4120           b = _.partialRight(a, 3),
4121           c = _.bind(b, null, 1),
4122           d = _.partial(b(2), 1);
4123
4124       assert.deepEqual(c(2), expected);
4125       assert.deepEqual(d(), expected);
4126     });
4127   }());
4128
4129   /*--------------------------------------------------------------------------*/
4130
4131   QUnit.module('curry methods');
4132
4133   lodashStable.each(['curry', 'curryRight'], function(methodName) {
4134     var func = _[methodName],
4135         fn = function(a, b) { return slice.call(arguments); },
4136         isCurry = methodName == 'curry';
4137
4138     QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
4139       assert.expect(1);
4140
4141       function run(a, b) {
4142         return a + b;
4143       }
4144
4145       var curried = func(run);
4146
4147       try {
4148         var actual = curried(1)(2);
4149       } catch (e) {}
4150
4151       assert.strictEqual(actual, 3);
4152     });
4153
4154     QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
4155       assert.expect(1);
4156
4157       var curried = _.curry(function hasOwnProperty(a, b, c) {
4158         return [a, b, c];
4159       });
4160
4161       var expected = [1, 2, 3];
4162
4163       assert.deepEqual(curried(1)(2)(3), expected);
4164     });
4165
4166     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
4167       assert.expect(2);
4168
4169       var array = [fn, fn, fn],
4170           object = { 'a': fn, 'b': fn, 'c': fn };
4171
4172       lodashStable.each([array, object], function(collection) {
4173         var curries = lodashStable.map(collection, func),
4174             expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
4175
4176         var actual = lodashStable.map(curries, function(curried) {
4177           return curried('a')('b');
4178         });
4179
4180         assert.deepEqual(actual, expected);
4181       });
4182     });
4183   });
4184
4185   /*--------------------------------------------------------------------------*/
4186
4187   QUnit.module('lodash.debounce');
4188
4189   (function() {
4190     QUnit.test('should debounce a function', function(assert) {
4191       assert.expect(6);
4192
4193       var done = assert.async();
4194
4195       var callCount = 0;
4196
4197       var debounced = _.debounce(function(value) {
4198         ++callCount;
4199         return value;
4200       }, 32);
4201
4202       var results = [debounced('a'), debounced('b'), debounced('c')];
4203       assert.deepEqual(results, [undefined, undefined, undefined]);
4204       assert.strictEqual(callCount, 0);
4205
4206       setTimeout(function() {
4207         assert.strictEqual(callCount, 1);
4208
4209         var results = [debounced('d'), debounced('e'), debounced('f')];
4210         assert.deepEqual(results, ['c', 'c', 'c']);
4211         assert.strictEqual(callCount, 1);
4212       }, 128);
4213
4214       setTimeout(function() {
4215         assert.strictEqual(callCount, 2);
4216         done();
4217       }, 256);
4218     });
4219
4220     QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
4221       assert.expect(2);
4222
4223       var done = assert.async();
4224
4225       var debounced = _.debounce(identity, 32);
4226       debounced('a');
4227
4228       setTimeout(function() {
4229         assert.notEqual(debounced('b'), 'b');
4230       }, 64);
4231
4232       setTimeout(function() {
4233         assert.notEqual(debounced('c'), 'c');
4234         done();
4235       }, 128);
4236     });
4237
4238     QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) {
4239       assert.expect(2);
4240
4241       var done = assert.async();
4242
4243       var callCount = 0,
4244           debounced = _.debounce(function() { ++callCount; }, 0);
4245
4246       debounced();
4247       debounced();
4248       assert.strictEqual(callCount, 0);
4249
4250       setTimeout(function() {
4251         assert.strictEqual(callCount, 1);
4252         done();
4253       }, 5);
4254     });
4255
4256     QUnit.test('should apply default options', function(assert) {
4257       assert.expect(2);
4258
4259       var done = assert.async();
4260
4261       var callCount = 0,
4262           debounced = _.debounce(function() { callCount++; }, 32, {});
4263
4264       debounced();
4265       assert.strictEqual(callCount, 0);
4266
4267       setTimeout(function() {
4268         assert.strictEqual(callCount, 1);
4269         done();
4270       }, 64);
4271     });
4272
4273     QUnit.test('should support a `leading` option', function(assert) {
4274       assert.expect(4);
4275
4276       var done = assert.async();
4277
4278       var callCounts = [0, 0];
4279
4280       var withLeading = _.debounce(function() {
4281         callCounts[0]++;
4282       }, 32, { 'leading': true });
4283
4284       var withLeadingAndTrailing = _.debounce(function() {
4285         callCounts[1]++;
4286       }, 32, { 'leading': true });
4287
4288       withLeading();
4289       assert.strictEqual(callCounts[0], 1);
4290
4291       withLeadingAndTrailing();
4292       withLeadingAndTrailing();
4293       assert.strictEqual(callCounts[1], 1);
4294
4295       setTimeout(function() {
4296         assert.deepEqual(callCounts, [1, 2]);
4297
4298         withLeading();
4299         assert.strictEqual(callCounts[0], 2);
4300
4301         done();
4302       }, 64);
4303     });
4304
4305     QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) {
4306       assert.expect(2);
4307
4308       var done = assert.async();
4309
4310       var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
4311           results = [debounced('a'), debounced('b')];
4312
4313       assert.deepEqual(results, ['a', 'a']);
4314
4315       setTimeout(function() {
4316         var results = [debounced('c'), debounced('d')];
4317         assert.deepEqual(results, ['c', 'c']);
4318         done();
4319       }, 64);
4320     });
4321
4322     QUnit.test('should support a `trailing` option', function(assert) {
4323       assert.expect(4);
4324
4325       var done = assert.async();
4326
4327       var withCount = 0,
4328           withoutCount = 0;
4329
4330       var withTrailing = _.debounce(function() {
4331         withCount++;
4332       }, 32, { 'trailing': true });
4333
4334       var withoutTrailing = _.debounce(function() {
4335         withoutCount++;
4336       }, 32, { 'trailing': false });
4337
4338       withTrailing();
4339       assert.strictEqual(withCount, 0);
4340
4341       withoutTrailing();
4342       assert.strictEqual(withoutCount, 0);
4343
4344       setTimeout(function() {
4345         assert.strictEqual(withCount, 1);
4346         assert.strictEqual(withoutCount, 0);
4347         done();
4348       }, 64);
4349     });
4350
4351     QUnit.test('should support a `maxWait` option', function(assert) {
4352       assert.expect(4);
4353
4354       var done = assert.async();
4355
4356       var callCount = 0;
4357
4358       var debounced = _.debounce(function(value) {
4359         ++callCount;
4360         return value;
4361       }, 32, { 'maxWait': 64 });
4362
4363       debounced();
4364       debounced();
4365       assert.strictEqual(callCount, 0);
4366
4367       setTimeout(function() {
4368         assert.strictEqual(callCount, 1);
4369         debounced();
4370         debounced();
4371         assert.strictEqual(callCount, 1);
4372       }, 128);
4373
4374       setTimeout(function() {
4375         assert.strictEqual(callCount, 2);
4376         done();
4377       }, 256);
4378     });
4379
4380     QUnit.test('should support `maxWait` in a tight loop', function(assert) {
4381       assert.expect(1);
4382
4383       var done = assert.async();
4384
4385       var limit = (argv || isPhantom) ? 1000 : 320,
4386           withCount = 0,
4387           withoutCount = 0;
4388
4389       var withMaxWait = _.debounce(function() {
4390         withCount++;
4391       }, 64, { 'maxWait': 128 });
4392
4393       var withoutMaxWait = _.debounce(function() {
4394         withoutCount++;
4395       }, 96);
4396
4397       var start = +new Date;
4398       while ((new Date - start) < limit) {
4399         withMaxWait();
4400         withoutMaxWait();
4401       }
4402       var actual = [Boolean(withoutCount), Boolean(withCount)];
4403       setTimeout(function() {
4404         assert.deepEqual(actual, [false, true]);
4405         done();
4406       }, 1);
4407     });
4408
4409     QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) {
4410       assert.expect(1);
4411
4412       var done = assert.async();
4413
4414       var callCount = 0;
4415
4416       var debounced = _.debounce(function() {
4417         ++callCount;
4418       }, 200, { 'maxWait': 200 });
4419
4420       debounced();
4421
4422       setTimeout(debounced, 190);
4423       setTimeout(debounced, 200);
4424       setTimeout(debounced, 210);
4425
4426       setTimeout(function() {
4427         assert.strictEqual(callCount, 2);
4428         done();
4429       }, 500);
4430     });
4431
4432     QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
4433       assert.expect(2);
4434
4435       var done = assert.async();
4436
4437       var callCount = 0;
4438
4439       var debounced = _.debounce(function() {
4440         callCount++;
4441       }, 32, { 'maxWait': 64 });
4442
4443       debounced();
4444
4445       setTimeout(function() {
4446         debounced();
4447         assert.strictEqual(callCount, 1);
4448       }, 128);
4449
4450       setTimeout(function() {
4451         assert.strictEqual(callCount, 2);
4452         done();
4453       }, 192);
4454     });
4455
4456     QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) {
4457       assert.expect(2);
4458
4459       var done = assert.async();
4460
4461       var actual,
4462           callCount = 0,
4463           object = {};
4464
4465       var debounced = _.debounce(function(value) {
4466         actual = [this];
4467         push.apply(actual, arguments);
4468         return ++callCount != 2;
4469       }, 32, { 'leading': true, 'maxWait': 64 });
4470
4471       while (true) {
4472         if (!debounced.call(object, 'a')) {
4473           break;
4474         }
4475       }
4476       setTimeout(function() {
4477         assert.strictEqual(callCount, 2);
4478         assert.deepEqual(actual, [object, 'a']);
4479         done();
4480       }, 64);
4481     });
4482   }());
4483
4484   /*--------------------------------------------------------------------------*/
4485
4486   QUnit.module('lodash.deburr');
4487
4488   (function() {
4489     QUnit.test('should convert Latin Unicode letters to basic Latin', function(assert) {
4490       assert.expect(1);
4491
4492       var actual = lodashStable.map(burredLetters, _.deburr);
4493       assert.deepEqual(actual, deburredLetters);
4494     });
4495
4496     QUnit.test('should not deburr Latin mathematical operators', function(assert) {
4497       assert.expect(1);
4498
4499       var operators = ['\xd7', '\xf7'],
4500           actual = lodashStable.map(operators, _.deburr);
4501
4502       assert.deepEqual(actual, operators);
4503     });
4504
4505     QUnit.test('should deburr combining diacritical marks', function(assert) {
4506       assert.expect(1);
4507
4508       var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
4509
4510       var actual = lodashStable.map(comboMarks, function(chr) {
4511         return _.deburr('e' + chr + 'i');
4512       });
4513
4514       assert.deepEqual(actual, expected);
4515     });
4516   }());
4517
4518   /*--------------------------------------------------------------------------*/
4519
4520   QUnit.module('lodash.defaults');
4521
4522   (function() {
4523     QUnit.test('should assign source properties if missing on `object`', function(assert) {
4524       assert.expect(1);
4525
4526       var actual = _.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 });
4527       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
4528     });
4529
4530     QUnit.test('should accept multiple sources', function(assert) {
4531       assert.expect(2);
4532
4533       var expected = { 'a': 1, 'b': 2, 'c': 3 },
4534           actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 });
4535
4536       assert.deepEqual(actual, expected);
4537
4538       actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 });
4539       assert.deepEqual(actual, expected);
4540     });
4541
4542     QUnit.test('should not overwrite `null` values', function(assert) {
4543       assert.expect(1);
4544
4545       var actual = _.defaults({ 'a': null }, { 'a': 1 });
4546       assert.strictEqual(actual.a, null);
4547     });
4548
4549     QUnit.test('should overwrite `undefined` values', function(assert) {
4550       assert.expect(1);
4551
4552       var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
4553       assert.strictEqual(actual.a, 1);
4554     });
4555
4556     QUnit.test('should assign `undefined` values', function(assert) {
4557       assert.expect(1);
4558
4559       var source = { 'a': undefined, 'b': 1 },
4560           actual = _.defaults({}, source);
4561
4562       assert.deepEqual(actual, { 'a': undefined, 'b': 1 });
4563     });
4564
4565     QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
4566       assert.expect(2);
4567
4568       var object = {
4569         'constructor': objectProto.constructor,
4570         'hasOwnProperty': objectProto.hasOwnProperty,
4571         'isPrototypeOf': objectProto.isPrototypeOf,
4572         'propertyIsEnumerable': objectProto.propertyIsEnumerable,
4573         'toLocaleString': objectProto.toLocaleString,
4574         'toString': objectProto.toString,
4575         'valueOf': objectProto.valueOf
4576       };
4577
4578       var source = {
4579         'constructor': 1,
4580         'hasOwnProperty': 2,
4581         'isPrototypeOf': 3,
4582         'propertyIsEnumerable': 4,
4583         'toLocaleString': 5,
4584         'toString': 6,
4585         'valueOf': 7
4586       };
4587
4588       var expected = lodashStable.clone(source);
4589       assert.deepEqual(_.defaults({}, source), expected);
4590
4591       expected = lodashStable.clone(object);
4592       assert.deepEqual(_.defaults({}, object, source), expected);
4593     });
4594   }());
4595
4596   /*--------------------------------------------------------------------------*/
4597
4598   QUnit.module('lodash.defaultsDeep');
4599
4600   (function() {
4601     QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
4602       assert.expect(1);
4603
4604       var object = { 'a': { 'b': 2 }, 'd': 4 },
4605           source = { 'a': { 'b': 3, 'c': 3 }, 'e': 5 },
4606           expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
4607
4608       assert.deepEqual(_.defaultsDeep(object, source), expected);
4609     });
4610
4611     QUnit.test('should accept multiple sources', function(assert) {
4612       assert.expect(2);
4613
4614       var source1 = { 'a': { 'b': 3 } },
4615           source2 = { 'a': { 'c': 3 } },
4616           source3 = { 'a': { 'b': 3, 'c': 3 } },
4617           source4 = { 'a': { 'c': 4 } },
4618           expected = { 'a': { 'b': 2, 'c': 3 } };
4619
4620       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
4621       assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
4622     });
4623
4624     QUnit.test('should not overwrite `null` values', function(assert) {
4625       assert.expect(1);
4626
4627       var object = { 'a': { 'b': null } },
4628           source = { 'a': { 'b': 2 } },
4629           actual = _.defaultsDeep(object, source);
4630
4631       assert.strictEqual(actual.a.b, null);
4632     });
4633
4634     QUnit.test('should not overwrite regexp values', function(assert) {
4635       assert.expect(1);
4636
4637       var object = { 'a': { 'b': /x/ } },
4638           source = { 'a': { 'b': /y/ } },
4639           actual = _.defaultsDeep(object, source);
4640
4641       assert.deepEqual(actual.a.b, /x/);
4642     });
4643
4644     QUnit.test('should not convert function properties to objects', function(assert) {
4645       assert.expect(2);
4646
4647       var actual = _.defaultsDeep({}, { 'a': noop });
4648       assert.strictEqual(actual.a, noop);
4649
4650       actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
4651       assert.strictEqual(actual.a.b, noop);
4652     });
4653
4654     QUnit.test('should overwrite `undefined` values', function(assert) {
4655       assert.expect(1);
4656
4657       var object = { 'a': { 'b': undefined } },
4658           source = { 'a': { 'b': 2 } },
4659           actual = _.defaultsDeep(object, source);
4660
4661       assert.strictEqual(actual.a.b, 2);
4662     });
4663
4664     QUnit.test('should assign `undefined` values', function(assert) {
4665       assert.expect(1);
4666
4667       var source = { 'a': undefined, 'b': { 'c': undefined, 'd': 1 } },
4668           expected = lodashStable.cloneDeep(source),
4669           actual = _.defaultsDeep({}, source);
4670
4671       assert.deepEqual(actual, expected);
4672     });
4673
4674     QUnit.test('should merge sources containing circular references', function(assert) {
4675       assert.expect(2);
4676
4677       var object = {
4678         'foo': { 'b': { 'c': { 'd': {} } } },
4679         'bar': { 'a': 2 }
4680       };
4681
4682       var source = {
4683         'foo': { 'b': { 'c': { 'd': {} } } },
4684         'bar': {}
4685       };
4686
4687       object.foo.b.c.d = object;
4688       source.foo.b.c.d = source;
4689       source.bar.b = source.foo.b;
4690
4691       var actual = _.defaultsDeep(object, source);
4692
4693       assert.strictEqual(actual.bar.b, actual.foo.b);
4694       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
4695     });
4696
4697     QUnit.test('should not modify sources', function(assert) {
4698       assert.expect(3);
4699
4700       var source1 = { 'a': 1, 'b': { 'c': 2 } },
4701           source2 = { 'b': { 'c': 3, 'd': 3 } },
4702           actual = _.defaultsDeep({}, source1, source2);
4703
4704       assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4705       assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4706       assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4707     });
4708
4709     QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4710       assert.expect(1);
4711
4712       var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4713       assert.deepEqual(actual.a, ['abc']);
4714     });
4715   }());
4716
4717   /*--------------------------------------------------------------------------*/
4718
4719   QUnit.module('lodash.defaultTo');
4720
4721   (function() {
4722     QUnit.test('should return a default value if `value` is `NaN` or nullish', function(assert) {
4723       assert.expect(1);
4724
4725       var expected = lodashStable.map(falsey, function(value) {
4726         return (value == null || value !== value) ? 1 : value;
4727       });
4728
4729       var actual = lodashStable.map(falsey, function(value) {
4730         return _.defaultTo(value, 1);
4731       });
4732
4733       assert.deepEqual(actual, expected);
4734     });
4735   }());
4736
4737   /*--------------------------------------------------------------------------*/
4738
4739   QUnit.module('lodash.defer');
4740
4741   (function() {
4742     QUnit.test('should defer `func` execution', function(assert) {
4743       assert.expect(1);
4744
4745       var done = assert.async();
4746
4747       var pass = false;
4748       _.defer(function() { pass = true; });
4749
4750       setTimeout(function() {
4751         assert.ok(pass);
4752         done();
4753       }, 32);
4754     });
4755
4756     QUnit.test('should provide additional arguments to `func`', function(assert) {
4757       assert.expect(1);
4758
4759       var done = assert.async();
4760
4761       var args;
4762
4763       _.defer(function() {
4764         args = slice.call(arguments);
4765       }, 1, 2);
4766
4767       setTimeout(function() {
4768         assert.deepEqual(args, [1, 2]);
4769         done();
4770       }, 32);
4771     });
4772
4773     QUnit.test('should be cancelable', function(assert) {
4774       assert.expect(1);
4775
4776       var done = assert.async();
4777
4778       var pass = true,
4779           timerId = _.defer(function() { pass = false; });
4780
4781       clearTimeout(timerId);
4782
4783       setTimeout(function() {
4784         assert.ok(pass);
4785         done();
4786       }, 32);
4787     });
4788   }());
4789
4790   /*--------------------------------------------------------------------------*/
4791
4792   QUnit.module('lodash.delay');
4793
4794   (function() {
4795     QUnit.test('should delay `func` execution', function(assert) {
4796       assert.expect(2);
4797
4798       var done = assert.async();
4799
4800       var pass = false;
4801       _.delay(function() { pass = true; }, 32);
4802
4803       setTimeout(function() {
4804         assert.notOk(pass);
4805       }, 1);
4806
4807       setTimeout(function() {
4808         assert.ok(pass);
4809         done();
4810       }, 64);
4811     });
4812
4813     QUnit.test('should provide additional arguments to `func`', function(assert) {
4814       assert.expect(1);
4815
4816       var done = assert.async();
4817
4818       var args;
4819
4820       _.delay(function() {
4821         args = slice.call(arguments);
4822       }, 32, 1, 2);
4823
4824       setTimeout(function() {
4825         assert.deepEqual(args, [1, 2]);
4826         done();
4827       }, 64);
4828     });
4829
4830     QUnit.test('should use a default `wait` of `0`', function(assert) {
4831       assert.expect(2);
4832
4833       var done = assert.async();
4834
4835       var pass = false;
4836       _.delay(function() { pass = true; });
4837
4838       assert.notOk(pass);
4839
4840       setTimeout(function() {
4841         assert.ok(pass);
4842         done();
4843       }, 0);
4844     });
4845
4846     QUnit.test('should be cancelable', function(assert) {
4847       assert.expect(1);
4848
4849       var done = assert.async();
4850
4851       var pass = true,
4852           timerId = _.delay(function() { pass = false; }, 32);
4853
4854       clearTimeout(timerId);
4855
4856       setTimeout(function() {
4857         assert.ok(pass);
4858         done();
4859       }, 64);
4860     });
4861
4862     QUnit.test('should work with mocked `setTimeout`', function(assert) {
4863       assert.expect(1);
4864
4865       if (!isPhantom) {
4866         var pass = false,
4867             setTimeout = root.setTimeout;
4868
4869         setProperty(root, 'setTimeout', function(func) { func(); });
4870         _.delay(function() { pass = true; }, 32);
4871         setProperty(root, 'setTimeout', setTimeout);
4872
4873         assert.ok(pass);
4874       }
4875       else {
4876         skipAssert(assert);
4877       }
4878     });
4879   }());
4880
4881   /*--------------------------------------------------------------------------*/
4882
4883   QUnit.module('difference methods');
4884
4885   lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4886     var func = _[methodName];
4887
4888     QUnit.test('`_.' + methodName + '` should return the difference of two arrays', function(assert) {
4889       assert.expect(1);
4890
4891       var actual = func([2, 1], [2, 3]);
4892       assert.deepEqual(actual, [1]);
4893     });
4894
4895     QUnit.test('`_.' + methodName + '` should return the difference of multiple arrays', function(assert) {
4896       assert.expect(1);
4897
4898       var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
4899       assert.deepEqual(actual, [1]);
4900     });
4901
4902     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
4903       assert.expect(2);
4904
4905       var array = [-0, 0];
4906
4907       var actual = lodashStable.map(array, function(value) {
4908         return func(array, [value]);
4909       });
4910
4911       assert.deepEqual(actual, [[], []]);
4912
4913       actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
4914       assert.deepEqual(actual, ['0']);
4915     });
4916
4917     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4918       assert.expect(1);
4919
4920       assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4921     });
4922
4923     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4924       assert.expect(1);
4925
4926       var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4927           array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4928           a = {},
4929           b = {},
4930           c = {};
4931
4932       array1.push(a, b, c);
4933       array2.push(b, c, a);
4934
4935       assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4936     });
4937
4938     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
4939       assert.expect(2);
4940
4941       var array = [-0, 0];
4942
4943       var actual = lodashStable.map(array, function(value) {
4944         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
4945         return func(array, largeArray);
4946       });
4947
4948       assert.deepEqual(actual, [[], []]);
4949
4950       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne);
4951       actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
4952       assert.deepEqual(actual, ['0']);
4953     });
4954
4955     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4956       assert.expect(1);
4957
4958       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
4959       assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4960     });
4961
4962     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4963       assert.expect(1);
4964
4965       var object1 = {},
4966           object2 = {},
4967           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4968
4969       assert.deepEqual(func([object1, object2], largeArray), [object2]);
4970     });
4971
4972     QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4973       assert.expect(3);
4974
4975       var array = [1, null, 3];
4976
4977       assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4978       assert.deepEqual(func(null, array, 1), []);
4979       assert.deepEqual(func(array, args, null), [null]);
4980     });
4981   });
4982
4983   /*--------------------------------------------------------------------------*/
4984
4985   QUnit.module('lodash.differenceBy');
4986
4987   (function() {
4988     QUnit.test('should accept an `iteratee`', function(assert) {
4989       assert.expect(2);
4990
4991       var actual = _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
4992       assert.deepEqual(actual, [1.2]);
4993
4994       actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4995       assert.deepEqual(actual, [{ 'x': 2 }]);
4996     });
4997
4998     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
4999       assert.expect(1);
5000
5001       var args;
5002
5003       _.differenceBy([2.1, 1.2], [2.3, 3.4], function() {
5004         args || (args = slice.call(arguments));
5005       });
5006
5007       assert.deepEqual(args, [2.3]);
5008     });
5009   }());
5010
5011   /*--------------------------------------------------------------------------*/
5012
5013   QUnit.module('lodash.differenceWith');
5014
5015   (function() {
5016     QUnit.test('should work with a `comparator`', function(assert) {
5017       assert.expect(1);
5018
5019       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
5020           actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
5021
5022       assert.deepEqual(actual, [objects[1]]);
5023     });
5024
5025     QUnit.test('should preserve the sign of `0`', function(assert) {
5026       assert.expect(1);
5027
5028       var array = [-0, 1],
5029           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne),
5030           others = [[1], largeArray],
5031           expected = lodashStable.map(others, lodashStable.constant(['-0']));
5032
5033       var actual = lodashStable.map(others, function(other) {
5034         return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
5035       });
5036
5037       assert.deepEqual(actual, expected);
5038     });
5039   }());
5040
5041   /*--------------------------------------------------------------------------*/
5042
5043   QUnit.module('lodash.divide');
5044
5045   (function() {
5046     QUnit.test('should divide two numbers', function(assert) {
5047       assert.expect(3);
5048
5049       assert.strictEqual(_.divide(6, 4), 1.5);
5050       assert.strictEqual(_.divide(-6, 4), -1.5);
5051       assert.strictEqual(_.divide(-6, -4), 1.5);
5052     });
5053
5054     QUnit.test('should coerce arguments to numbers', function(assert) {
5055       assert.expect(2);
5056
5057       assert.strictEqual(_.divide('6', '4'), 1.5);
5058       assert.deepEqual(_.divide('x', 'y'), NaN);
5059     });
5060   }());
5061
5062   /*--------------------------------------------------------------------------*/
5063
5064   QUnit.module('lodash.drop');
5065
5066   (function() {
5067     var array = [1, 2, 3];
5068
5069     QUnit.test('should drop the first two elements', function(assert) {
5070       assert.expect(1);
5071
5072       assert.deepEqual(_.drop(array, 2), [3]);
5073     });
5074
5075     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
5076       assert.expect(1);
5077
5078       var expected = lodashStable.map(falsey, function(value) {
5079         return value === undefined ? [2, 3] : array;
5080       });
5081
5082       var actual = lodashStable.map(falsey, function(n) {
5083         return _.drop(array, n);
5084       });
5085
5086       assert.deepEqual(actual, expected);
5087     });
5088
5089     QUnit.test('should return all elements when `n` < `1`', function(assert) {
5090       assert.expect(3);
5091
5092       lodashStable.each([0, -1, -Infinity], function(n) {
5093         assert.deepEqual(_.drop(array, n), array);
5094       });
5095     });
5096
5097     QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
5098       assert.expect(4);
5099
5100       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5101         assert.deepEqual(_.drop(array, n), []);
5102       });
5103     });
5104
5105     QUnit.test('should coerce `n` to an integer', function(assert) {
5106       assert.expect(1);
5107
5108       assert.deepEqual(_.drop(array, 1.6), [2, 3]);
5109     });
5110
5111     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5112       assert.expect(1);
5113
5114       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5115           actual = lodashStable.map(array, _.drop);
5116
5117       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
5118     });
5119
5120     QUnit.test('should work in a lazy sequence', function(assert) {
5121       assert.expect(6);
5122
5123       if (!isNpm) {
5124         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5125             predicate = function(value) { values.push(value); return isEven(value); },
5126             values = [],
5127             actual = _(array).drop(2).drop().value();
5128
5129         assert.deepEqual(actual, array.slice(3));
5130
5131         actual = _(array).filter(predicate).drop(2).drop().value();
5132         assert.deepEqual(values, array);
5133         assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
5134
5135         actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
5136         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
5137
5138         values = [];
5139
5140         actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
5141         assert.deepEqual(values, array.slice(1));
5142         assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
5143       }
5144       else {
5145         skipAssert(assert, 6);
5146       }
5147     });
5148   }());
5149
5150   /*--------------------------------------------------------------------------*/
5151
5152   QUnit.module('lodash.dropRight');
5153
5154   (function() {
5155     var array = [1, 2, 3];
5156
5157     QUnit.test('should drop the last two elements', function(assert) {
5158       assert.expect(1);
5159
5160       assert.deepEqual(_.dropRight(array, 2), [1]);
5161     });
5162
5163     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
5164       assert.expect(1);
5165
5166       var expected = lodashStable.map(falsey, function(value) {
5167         return value === undefined ? [1, 2] : array;
5168       });
5169
5170       var actual = lodashStable.map(falsey, function(n) {
5171         return _.dropRight(array, n);
5172       });
5173
5174       assert.deepEqual(actual, expected);
5175     });
5176
5177     QUnit.test('should return all elements when `n` < `1`', function(assert) {
5178       assert.expect(3);
5179
5180       lodashStable.each([0, -1, -Infinity], function(n) {
5181         assert.deepEqual(_.dropRight(array, n), array);
5182       });
5183     });
5184
5185     QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
5186       assert.expect(4);
5187
5188       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5189         assert.deepEqual(_.dropRight(array, n), []);
5190       });
5191     });
5192
5193     QUnit.test('should coerce `n` to an integer', function(assert) {
5194       assert.expect(1);
5195
5196       assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
5197     });
5198
5199     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5200       assert.expect(1);
5201
5202       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5203           actual = lodashStable.map(array, _.dropRight);
5204
5205       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
5206     });
5207
5208     QUnit.test('should work in a lazy sequence', function(assert) {
5209       assert.expect(6);
5210
5211       if (!isNpm) {
5212         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5213             predicate = function(value) { values.push(value); return isEven(value); },
5214             values = [],
5215             actual = _(array).dropRight(2).dropRight().value();
5216
5217         assert.deepEqual(actual, array.slice(0, -3));
5218
5219         actual = _(array).filter(predicate).dropRight(2).dropRight().value();
5220         assert.deepEqual(values, array);
5221         assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
5222
5223         actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
5224         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
5225
5226         values = [];
5227
5228         actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
5229         assert.deepEqual(values, array.slice(0, -1));
5230         assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
5231       }
5232       else {
5233         skipAssert(assert, 6);
5234       }
5235     });
5236   }());
5237
5238   /*--------------------------------------------------------------------------*/
5239
5240   QUnit.module('lodash.dropRightWhile');
5241
5242   (function() {
5243     var array = [1, 2, 3, 4];
5244
5245     var objects = [
5246       { 'a': 0, 'b': 0 },
5247       { 'a': 1, 'b': 1 },
5248       { 'a': 2, 'b': 2 }
5249     ];
5250
5251     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5252       assert.expect(1);
5253
5254       var actual = _.dropRightWhile(array, function(n) {
5255         return n > 2;
5256       });
5257
5258       assert.deepEqual(actual, [1, 2]);
5259     });
5260
5261     QUnit.test('should provide correct `predicate` arguments', function(assert) {
5262       assert.expect(1);
5263
5264       var args;
5265
5266       _.dropRightWhile(array, function() {
5267         args = slice.call(arguments);
5268       });
5269
5270       assert.deepEqual(args, [4, 3, array]);
5271     });
5272
5273     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5274       assert.expect(1);
5275
5276       assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
5277     });
5278
5279     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5280       assert.expect(1);
5281
5282       assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
5283     });
5284
5285     QUnit.test('should work with `_.property` shorthands', function(assert) {
5286       assert.expect(1);
5287
5288       assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
5289     });
5290
5291     QUnit.test('should return a wrapped value when chaining', function(assert) {
5292       assert.expect(2);
5293
5294       if (!isNpm) {
5295         var wrapped = _(array).dropRightWhile(function(n) {
5296           return n > 2;
5297         });
5298
5299         assert.ok(wrapped instanceof _);
5300         assert.deepEqual(wrapped.value(), [1, 2]);
5301       }
5302       else {
5303         skipAssert(assert, 2);
5304       }
5305     });
5306   }());
5307
5308   /*--------------------------------------------------------------------------*/
5309
5310   QUnit.module('lodash.dropWhile');
5311
5312   (function() {
5313     var array = [1, 2, 3, 4];
5314
5315     var objects = [
5316       { 'a': 2, 'b': 2 },
5317       { 'a': 1, 'b': 1 },
5318       { 'a': 0, 'b': 0 }
5319     ];
5320
5321     QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5322       assert.expect(1);
5323
5324       var actual = _.dropWhile(array, function(n) {
5325         return n < 3;
5326       });
5327
5328       assert.deepEqual(actual, [3, 4]);
5329     });
5330
5331     QUnit.test('should provide correct `predicate` arguments', function(assert) {
5332       assert.expect(1);
5333
5334       var args;
5335
5336       _.dropWhile(array, function() {
5337         args = slice.call(arguments);
5338       });
5339
5340       assert.deepEqual(args, [1, 0, array]);
5341     });
5342
5343     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5344       assert.expect(1);
5345
5346       assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
5347     });
5348
5349     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5350       assert.expect(1);
5351
5352       assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
5353     });
5354
5355     QUnit.test('should work with `_.property` shorthands', function(assert) {
5356       assert.expect(1);
5357
5358       assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
5359     });
5360
5361     QUnit.test('should work in a lazy sequence', function(assert) {
5362       assert.expect(3);
5363
5364       if (!isNpm) {
5365         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
5366             predicate = function(n) { return n < 3; },
5367             expected = _.dropWhile(array, predicate),
5368             wrapped = _(array).dropWhile(predicate);
5369
5370         assert.deepEqual(wrapped.value(), expected);
5371         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
5372         assert.strictEqual(wrapped.last(), _.last(expected));
5373       }
5374       else {
5375         skipAssert(assert, 3);
5376       }
5377     });
5378
5379     QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
5380       assert.expect(1);
5381
5382       if (!isNpm) {
5383         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
5384
5385         var actual = _(array)
5386           .dropWhile(function(n) { return n == 1; })
5387           .drop()
5388           .dropWhile(function(n) { return n == 3; })
5389           .value();
5390
5391         assert.deepEqual(actual, array.slice(3));
5392       }
5393       else {
5394         skipAssert(assert);
5395       }
5396     });
5397   }());
5398
5399   /*--------------------------------------------------------------------------*/
5400
5401   QUnit.module('lodash.endsWith');
5402
5403   (function() {
5404     var string = 'abc';
5405
5406     QUnit.test('should return `true` if a string ends with `target`', function(assert) {
5407       assert.expect(1);
5408
5409       assert.strictEqual(_.endsWith(string, 'c'), true);
5410     });
5411
5412     QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
5413       assert.expect(1);
5414
5415       assert.strictEqual(_.endsWith(string, 'b'), false);
5416     });
5417
5418     QUnit.test('should work with a `position`', function(assert) {
5419       assert.expect(1);
5420
5421       assert.strictEqual(_.endsWith(string, 'b', 2), true);
5422     });
5423
5424     QUnit.test('should work with `position` >= `length`', function(assert) {
5425       assert.expect(4);
5426
5427       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5428         assert.strictEqual(_.endsWith(string, 'c', position), true);
5429       });
5430     });
5431
5432     QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5433       assert.expect(1);
5434
5435       var expected = lodashStable.map(falsey, stubTrue);
5436
5437       var actual = lodashStable.map(falsey, function(position) {
5438         return _.endsWith(string, position === undefined ? 'c' : '', position);
5439       });
5440
5441       assert.deepEqual(actual, expected);
5442     });
5443
5444     QUnit.test('should treat a negative `position` as `0`', function(assert) {
5445       assert.expect(6);
5446
5447       lodashStable.each([-1, -3, -Infinity], function(position) {
5448         assert.ok(lodashStable.every(string, function(chr) {
5449           return !_.endsWith(string, chr, position);
5450         }));
5451         assert.strictEqual(_.endsWith(string, '', position), true);
5452       });
5453     });
5454
5455     QUnit.test('should coerce `position` to an integer', function(assert) {
5456       assert.expect(1);
5457
5458       assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5459     });
5460   }());
5461
5462   /*--------------------------------------------------------------------------*/
5463
5464   QUnit.module('lodash.eq');
5465
5466   (function() {
5467     QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5468       assert.expect(11);
5469
5470       assert.strictEqual(_.eq(), true);
5471       assert.strictEqual(_.eq(undefined), true);
5472       assert.strictEqual(_.eq(0, -0), true);
5473       assert.strictEqual(_.eq(NaN, NaN), true);
5474       assert.strictEqual(_.eq(1, 1), true);
5475
5476       assert.strictEqual(_.eq(null, undefined), false);
5477       assert.strictEqual(_.eq(1, Object(1)), false);
5478       assert.strictEqual(_.eq(1, '1'), false);
5479       assert.strictEqual(_.eq(1, '1'), false);
5480
5481       var object = { 'a': 1 };
5482       assert.strictEqual(_.eq(object, object), true);
5483       assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5484     });
5485   }());
5486
5487   /*--------------------------------------------------------------------------*/
5488
5489   QUnit.module('lodash.escape');
5490
5491   (function() {
5492     var escaped = '&amp;&lt;&gt;&quot;&#39;/',
5493         unescaped = '&<>"\'/';
5494
5495     escaped += escaped;
5496     unescaped += unescaped;
5497
5498     QUnit.test('should escape values', function(assert) {
5499       assert.expect(1);
5500
5501       assert.strictEqual(_.escape(unescaped), escaped);
5502     });
5503
5504     QUnit.test('should handle strings with nothing to escape', function(assert) {
5505       assert.expect(1);
5506
5507       assert.strictEqual(_.escape('abc'), 'abc');
5508     });
5509
5510     QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5511       assert.expect(1);
5512
5513       assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5514     });
5515
5516     lodashStable.each(['`', '/'], function(chr) {
5517       QUnit.test('should not escape the "' + chr + '" character', function(assert) {
5518         assert.expect(1);
5519
5520         assert.strictEqual(_.escape(chr), chr);
5521       });
5522     });
5523   }());
5524
5525   /*--------------------------------------------------------------------------*/
5526
5527   QUnit.module('lodash.escapeRegExp');
5528
5529   (function() {
5530     var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5531         unescaped = '^$.*+?()[]{}|\\';
5532
5533     QUnit.test('should escape values', function(assert) {
5534       assert.expect(1);
5535
5536       assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5537     });
5538
5539     QUnit.test('should handle strings with nothing to escape', function(assert) {
5540       assert.expect(1);
5541
5542       assert.strictEqual(_.escapeRegExp('abc'), 'abc');
5543     });
5544
5545     QUnit.test('should return an empty string for empty values', function(assert) {
5546       assert.expect(1);
5547
5548       var values = [, null, undefined, ''],
5549           expected = lodashStable.map(values, stubString);
5550
5551       var actual = lodashStable.map(values, function(value, index) {
5552         return index ? _.escapeRegExp(value) : _.escapeRegExp();
5553       });
5554
5555       assert.deepEqual(actual, expected);
5556     });
5557   }());
5558
5559   /*--------------------------------------------------------------------------*/
5560
5561   QUnit.module('lodash.every');
5562
5563   (function() {
5564     QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5565       assert.expect(1);
5566
5567       assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5568     });
5569
5570     QUnit.test('should return `true` for empty collections', function(assert) {
5571       assert.expect(1);
5572
5573       var expected = lodashStable.map(empties, stubTrue);
5574
5575       var actual = lodashStable.map(empties, function(value) {
5576         try {
5577           return _.every(value, identity);
5578         } catch (e) {}
5579       });
5580
5581       assert.deepEqual(actual, expected);
5582     });
5583
5584     QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5585       assert.expect(2);
5586
5587       var count = 0;
5588
5589       assert.strictEqual(_.every([true, null, true], function(value) {
5590         count++;
5591         return value;
5592       }), false);
5593
5594       assert.strictEqual(count, 2);
5595     });
5596
5597     QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5598       assert.expect(1);
5599
5600       assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5601     });
5602
5603     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5604       assert.expect(2);
5605
5606       var values = [, null, undefined],
5607           expected = lodashStable.map(values, stubFalse);
5608
5609       var actual = lodashStable.map(values, function(value, index) {
5610         var array = [0];
5611         return index ? _.every(array, value) : _.every(array);
5612       });
5613
5614       assert.deepEqual(actual, expected);
5615
5616       expected = lodashStable.map(values, stubTrue);
5617       actual = lodashStable.map(values, function(value, index) {
5618         var array = [1];
5619         return index ? _.every(array, value) : _.every(array);
5620       });
5621
5622       assert.deepEqual(actual, expected);
5623     });
5624
5625     QUnit.test('should work with `_.property` shorthands', function(assert) {
5626       assert.expect(2);
5627
5628       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5629       assert.strictEqual(_.every(objects, 'a'), false);
5630       assert.strictEqual(_.every(objects, 'b'), true);
5631     });
5632
5633     QUnit.test('should work with `_.matches` shorthands', function(assert) {
5634       assert.expect(2);
5635
5636       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5637       assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5638       assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5639     });
5640
5641     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5642       assert.expect(1);
5643
5644       var actual = lodashStable.map([[1]], _.every);
5645       assert.deepEqual(actual, [true]);
5646     });
5647   }());
5648
5649   /*--------------------------------------------------------------------------*/
5650
5651   QUnit.module('strict mode checks');
5652
5653   lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults', 'defaultsDeep', 'merge'], function(methodName) {
5654     var func = _[methodName],
5655         isBindAll = methodName == 'bindAll';
5656
5657     QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5658       assert.expect(1);
5659
5660       var object = freeze({ 'a': undefined, 'b': function() {} }),
5661           pass = !isStrict;
5662
5663       try {
5664         func(object, isBindAll ? 'b' : { 'a': 1 });
5665       } catch (e) {
5666         pass = !pass;
5667       }
5668       assert.ok(pass);
5669     });
5670   });
5671
5672   /*--------------------------------------------------------------------------*/
5673
5674   QUnit.module('lodash.fill');
5675
5676   (function() {
5677     QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
5678       assert.expect(1);
5679
5680       var array = [1, 2, 3];
5681       assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5682     });
5683
5684     QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5685       assert.expect(2);
5686
5687       var array = [1, 2, 3],
5688           actual = _.fill(array);
5689
5690       assert.deepEqual(actual, Array(3));
5691       assert.ok(lodashStable.every(actual, function(value, index) {
5692         return index in actual;
5693       }));
5694     });
5695
5696     QUnit.test('should work with a positive `start`', function(assert) {
5697       assert.expect(1);
5698
5699       var array = [1, 2, 3];
5700       assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5701     });
5702
5703     QUnit.test('should work with a `start` >= `length`', function(assert) {
5704       assert.expect(4);
5705
5706       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5707         var array = [1, 2, 3];
5708         assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5709       });
5710     });
5711
5712     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5713       assert.expect(1);
5714
5715       var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5716
5717       var actual = lodashStable.map(falsey, function(start) {
5718         var array = [1, 2, 3];
5719         return _.fill(array, 'a', start);
5720       });
5721
5722       assert.deepEqual(actual, expected);
5723     });
5724
5725     QUnit.test('should work with a negative `start`', function(assert) {
5726       assert.expect(1);
5727
5728       var array = [1, 2, 3];
5729       assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5730     });
5731
5732     QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
5733       assert.expect(3);
5734
5735       lodashStable.each([-3, -4, -Infinity], function(start) {
5736         var array = [1, 2, 3];
5737         assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5738       });
5739     });
5740
5741     QUnit.test('should work with `start` >= `end`', function(assert) {
5742       assert.expect(2);
5743
5744       lodashStable.each([2, 3], function(start) {
5745         var array = [1, 2, 3];
5746         assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5747       });
5748     });
5749
5750     QUnit.test('should work with a positive `end`', function(assert) {
5751       assert.expect(1);
5752
5753       var array = [1, 2, 3];
5754       assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5755     });
5756
5757     QUnit.test('should work with a `end` >= `length`', function(assert) {
5758       assert.expect(4);
5759
5760       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5761         var array = [1, 2, 3];
5762         assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5763       });
5764     });
5765
5766     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5767       assert.expect(1);
5768
5769       var expected = lodashStable.map(falsey, function(value) {
5770         return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5771       });
5772
5773       var actual = lodashStable.map(falsey, function(end) {
5774         var array = [1, 2, 3];
5775         return _.fill(array, 'a', 0, end);
5776       });
5777
5778       assert.deepEqual(actual, expected);
5779     });
5780
5781     QUnit.test('should work with a negative `end`', function(assert) {
5782       assert.expect(1);
5783
5784       var array = [1, 2, 3];
5785       assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5786     });
5787
5788     QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
5789       assert.expect(3);
5790
5791       lodashStable.each([-3, -4, -Infinity], function(end) {
5792         var array = [1, 2, 3];
5793         assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5794       });
5795     });
5796
5797     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5798       assert.expect(1);
5799
5800       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5801
5802       var actual = lodashStable.map(positions, function(pos) {
5803         var array = [1, 2, 3];
5804         return _.fill.apply(_, [array, 'a'].concat(pos));
5805       });
5806
5807       assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5808     });
5809
5810     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5811       assert.expect(1);
5812
5813       var array = [[1, 2], [3, 4]],
5814           actual = lodashStable.map(array, _.fill);
5815
5816       assert.deepEqual(actual, [[0, 0], [1, 1]]);
5817     });
5818
5819     QUnit.test('should return a wrapped value when chaining', function(assert) {
5820       assert.expect(3);
5821
5822       if (!isNpm) {
5823         var array = [1, 2, 3],
5824             wrapped = _(array).fill('a'),
5825             actual = wrapped.value();
5826
5827         assert.ok(wrapped instanceof _);
5828         assert.strictEqual(actual, array);
5829         assert.deepEqual(actual, ['a', 'a', 'a']);
5830       }
5831       else {
5832         skipAssert(assert, 3);
5833       }
5834     });
5835   }());
5836
5837   /*--------------------------------------------------------------------------*/
5838
5839   QUnit.module('lodash.filter');
5840
5841   (function() {
5842     var array = [1, 2, 3];
5843
5844     QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5845       assert.expect(1);
5846
5847       assert.deepEqual(_.filter(array, isEven), [2]);
5848     });
5849   }());
5850
5851   /*--------------------------------------------------------------------------*/
5852
5853   lodashStable.each(['find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', 'findLastKey'], function(methodName) {
5854     QUnit.module('lodash.' + methodName);
5855
5856     var array = [1, 2, 3, 4],
5857         func = _[methodName];
5858
5859     var objects = [
5860       { 'a': 0, 'b': 0 },
5861       { 'a': 1, 'b': 1 },
5862       { 'a': 2, 'b': 2 }
5863     ];
5864
5865     var expected = ({
5866       'find': [objects[1], undefined, objects[2]],
5867       'findIndex': [1, -1, 2],
5868       'findKey': ['1', undefined, '2'],
5869       'findLast': [objects[2], undefined, objects[2]],
5870       'findLastIndex': [2, -1, 2],
5871       'findLastKey': ['2', undefined, '2']
5872     })[methodName];
5873
5874     QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
5875       assert.expect(1);
5876
5877       assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5878     });
5879
5880     QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
5881       assert.expect(1);
5882
5883       assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5884     });
5885
5886     QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
5887       assert.expect(1);
5888
5889       assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5890     });
5891
5892     QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
5893       assert.expect(1);
5894
5895       assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5896     });
5897
5898     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5899       assert.expect(1);
5900
5901       assert.strictEqual(func(objects, 'b'), expected[0]);
5902     });
5903
5904     QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
5905       assert.expect(1);
5906
5907       var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5908           expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5909
5910       var actual = lodashStable.map(emptyValues, function(value) {
5911         try {
5912           return func(value, { 'a': 3 });
5913         } catch (e) {}
5914       });
5915
5916       assert.deepEqual(actual, expecting);
5917     });
5918
5919     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5920       assert.expect(1);
5921
5922       var expected = ({
5923         'find': 1,
5924         'findIndex': 0,
5925         'findKey': '0',
5926         'findLast': 4,
5927         'findLastIndex': 3,
5928         'findLastKey': '3'
5929       })[methodName];
5930
5931       if (!isNpm) {
5932         assert.strictEqual(_(array)[methodName](), expected);
5933       }
5934       else {
5935         skipAssert(assert);
5936       }
5937     });
5938
5939     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5940       assert.expect(1);
5941
5942       if (!isNpm) {
5943         assert.ok(_(array).chain()[methodName]() instanceof _);
5944       }
5945       else {
5946         skipAssert(assert);
5947       }
5948     });
5949
5950     QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
5951       assert.expect(1);
5952
5953       if (!isNpm) {
5954         var wrapped = _(array).chain()[methodName]();
5955         assert.strictEqual(wrapped.__wrapped__, array);
5956       }
5957       else {
5958         skipAssert(assert);
5959       }
5960     });
5961
5962     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
5963       assert.expect(2);
5964
5965       if (!isNpm) {
5966         var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5967             smallArray = array;
5968
5969         lodashStable.times(2, function(index) {
5970           var array = index ? largeArray : smallArray,
5971               wrapped = _(array).filter(isEven);
5972
5973           assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5974         });
5975       }
5976       else {
5977         skipAssert(assert, 2);
5978       }
5979     });
5980   });
5981
5982   _.each(['find', 'findIndex', 'findLast', 'findLastIndex'], function(methodName) {
5983     var func = _[methodName];
5984
5985     QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for arrays', function(assert) {
5986       assert.expect(1);
5987
5988       var args,
5989           array = ['a'];
5990
5991       func(array, function() {
5992         args || (args = slice.call(arguments));
5993       });
5994
5995       assert.deepEqual(args, ['a', 0, array]);
5996     });
5997   });
5998
5999   _.each(['find', 'findKey', 'findLast', 'findLastKey'], function(methodName) {
6000     var func = _[methodName];
6001
6002     QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
6003       assert.expect(1);
6004
6005       var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
6006         return n < 3;
6007       });
6008
6009       var expected = ({
6010         'find': 1,
6011         'findKey': 'a',
6012         'findLast': 2,
6013         'findLastKey': 'b'
6014       })[methodName];
6015
6016       assert.strictEqual(actual, expected);
6017     });
6018
6019     QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for objects', function(assert) {
6020       assert.expect(1);
6021
6022       var args,
6023           object = { 'a': 1 };
6024
6025       func(object, function() {
6026         args || (args = slice.call(arguments));
6027       });
6028
6029       assert.deepEqual(args, [1, 'a', object]);
6030     });
6031   });
6032
6033   /*--------------------------------------------------------------------------*/
6034
6035   QUnit.module('lodash.find and lodash.findLast');
6036
6037   lodashStable.each(['find', 'findLast'], function(methodName) {
6038     var isFind = methodName == 'find';
6039
6040     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6041       assert.expect(3);
6042
6043       if (!isNpm) {
6044         var findCount = 0,
6045             mapCount = 0,
6046             array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
6047             iteratee = function(value) { mapCount++; return square(value); },
6048             predicate = function(value) { findCount++; return isEven(value); },
6049             actual = _(array).map(iteratee)[methodName](predicate);
6050
6051         assert.strictEqual(findCount, isFind ? 2 : 1);
6052         assert.strictEqual(mapCount, isFind ? 2 : 1);
6053         assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
6054       }
6055       else {
6056         skipAssert(assert, 3);
6057       }
6058     });
6059   });
6060
6061   /*--------------------------------------------------------------------------*/
6062
6063   QUnit.module('lodash.find and lodash.includes');
6064
6065   lodashStable.each(['includes', 'find'], function(methodName) {
6066     var func = _[methodName],
6067         isIncludes = methodName == 'includes',
6068         resolve = methodName == 'find' ? lodashStable.curry(lodashStable.eq) : identity;
6069
6070     lodashStable.each({
6071       'an `arguments` object': args,
6072       'an array': [1, 2, 3]
6073     },
6074     function(collection, key) {
6075       var values = lodashStable.toArray(collection);
6076
6077       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6078         assert.expect(1);
6079
6080         var expected = [
6081           isIncludes || values[2],
6082           isIncludes ? false : undefined
6083         ];
6084
6085         var actual = [
6086           func(collection, resolve(values[2]), 2),
6087           func(collection, resolve(values[1]), 2)
6088         ];
6089
6090         assert.deepEqual(actual, expected);
6091       });
6092
6093       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6094         assert.expect(1);
6095
6096         var indexes = [4, 6, Math.pow(2, 32), Infinity];
6097
6098         var expected = lodashStable.map(indexes, function() {
6099           var result = isIncludes ? false : undefined;
6100           return [result, result, result];
6101         });
6102
6103         var actual = lodashStable.map(indexes, function(fromIndex) {
6104           return [
6105             func(collection, resolve(1), fromIndex),
6106             func(collection, resolve(undefined), fromIndex),
6107             func(collection, resolve(''), fromIndex)
6108           ];
6109         });
6110
6111         assert.deepEqual(actual, expected);
6112       });
6113
6114       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
6115         assert.expect(1);
6116
6117         var expected = lodashStable.map(falsey, lodashStable.constant(isIncludes || values[0]));
6118
6119         var actual = lodashStable.map(falsey, function(fromIndex) {
6120           return func(collection, resolve(values[0]), fromIndex);
6121         });
6122
6123         assert.deepEqual(actual, expected);
6124       });
6125
6126       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6127         assert.expect(1);
6128
6129         var expected = [
6130           isIncludes || values[0],
6131           isIncludes || values[0],
6132           isIncludes ? false : undefined
6133         ];
6134
6135         var actual = [
6136           func(collection, resolve(values[0]), 0.1),
6137           func(collection, resolve(values[0]), NaN),
6138           func(collection, resolve(values[0]), '1')
6139         ];
6140
6141         assert.deepEqual(actual, expected);
6142       });
6143
6144       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6145         assert.expect(1);
6146
6147         var expected = [
6148           isIncludes || values[2],
6149           isIncludes ? false : undefined
6150         ];
6151
6152         var actual = [
6153           func(collection, resolve(values[2]), -1),
6154           func(collection, resolve(values[1]), -1)
6155         ];
6156
6157         assert.deepEqual(actual, expected);
6158       });
6159
6160       QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6161         assert.expect(1);
6162
6163         var indexes = [-4, -6, -Infinity],
6164             expected = lodashStable.map(indexes, lodashStable.constant(isIncludes || values[0]));
6165
6166         var actual = lodashStable.map(indexes, function(fromIndex) {
6167           return func(collection, resolve(values[0]), fromIndex);
6168         });
6169
6170         assert.deepEqual(actual, expected);
6171       });
6172     });
6173   });
6174
6175   /*--------------------------------------------------------------------------*/
6176
6177   QUnit.module('lodash.findIndex and lodash.indexOf');
6178
6179   lodashStable.each(['findIndex', 'indexOf'], function(methodName) {
6180     var array = [1, 2, 3, 1, 2, 3],
6181         func = _[methodName],
6182         resolve = methodName == 'findIndex' ? lodashStable.curry(lodashStable.eq) : identity;
6183
6184     QUnit.test('`_.' + methodName + '` should return the index of the first matched value', function(assert) {
6185       assert.expect(1);
6186
6187       assert.strictEqual(func(array, resolve(3)), 2);
6188     });
6189
6190     QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
6191       assert.expect(1);
6192
6193       assert.strictEqual(func(array, resolve(1), 2), 3);
6194     });
6195
6196     QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
6197       assert.expect(1);
6198
6199       var values = [6, 8, Math.pow(2, 32), Infinity],
6200           expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
6201
6202       var actual = lodashStable.map(values, function(fromIndex) {
6203         return [
6204           func(array, resolve(undefined), fromIndex),
6205           func(array, resolve(1), fromIndex),
6206           func(array, resolve(''), fromIndex)
6207         ];
6208       });
6209
6210       assert.deepEqual(actual, expected);
6211     });
6212
6213     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
6214       assert.expect(1);
6215
6216       assert.strictEqual(func(array, resolve(2), -3), 4);
6217     });
6218
6219     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
6220       assert.expect(1);
6221
6222       var values = [-6, -8, -Infinity],
6223           expected = lodashStable.map(values, stubZero);
6224
6225       var actual = lodashStable.map(values, function(fromIndex) {
6226         return func(array, resolve(1), fromIndex);
6227       });
6228
6229       assert.deepEqual(actual, expected);
6230     });
6231
6232     QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values as `0`', function(assert) {
6233       assert.expect(1);
6234
6235       var expected = lodashStable.map(falsey, stubZero);
6236
6237       var actual = lodashStable.map(falsey, function(fromIndex) {
6238         return func(array, resolve(1), fromIndex);
6239       });
6240
6241       assert.deepEqual(actual, expected);
6242     });
6243
6244     QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
6245       assert.expect(1);
6246
6247       assert.strictEqual(func(array, resolve(2), 1.2), 1);
6248     });
6249   });
6250
6251   /*--------------------------------------------------------------------------*/
6252
6253   QUnit.module('lodash.findLast');
6254
6255   (function() {
6256     var resolve = lodashStable.curry(lodashStable.eq);
6257
6258     lodashStable.each({
6259       'an `arguments` object': args,
6260       'an array': [1, 2, 3]
6261     },
6262     function(collection, key) {
6263       var values = lodashStable.toArray(collection);
6264
6265       QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6266         assert.expect(1);
6267
6268         var expected = [
6269           values[1],
6270           undefined
6271         ];
6272
6273         var actual = [
6274           _.findLast(collection, resolve(values[1]), 1),
6275           _.findLast(collection, resolve(values[2]), 1)
6276         ];
6277
6278         assert.deepEqual(actual, expected);
6279       });
6280
6281       QUnit.test('should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6282         assert.expect(1);
6283
6284         var indexes = [4, 6, Math.pow(2, 32), Infinity];
6285
6286         var expected = lodashStable.map(indexes, lodashStable.constant([values[0], undefined, undefined]));
6287
6288         var actual = lodashStable.map(indexes, function(fromIndex) {
6289           return [
6290             _.findLast(collection, resolve(1), fromIndex),
6291             _.findLast(collection, resolve(undefined), fromIndex),
6292             _.findLast(collection, resolve(''), fromIndex)
6293           ];
6294         });
6295
6296         assert.deepEqual(actual, expected);
6297       });
6298
6299       QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values correctly', function(assert) {
6300         assert.expect(1);
6301
6302         var expected = lodashStable.map(falsey, function(value) {
6303           return value === undefined ? values[3] : undefined;
6304         });
6305
6306         var actual = lodashStable.map(falsey, function(fromIndex) {
6307           return _.findLast(collection, resolve(values[3]), fromIndex);
6308         });
6309
6310         assert.deepEqual(actual, expected);
6311       });
6312
6313       QUnit.test('should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6314         assert.expect(1);
6315
6316         var expected = [
6317           values[0],
6318           values[0],
6319           undefined
6320         ];
6321
6322         var actual = [
6323           _.findLast(collection, resolve(values[0]), 0.1),
6324           _.findLast(collection, resolve(values[0]), NaN),
6325           _.findLast(collection, resolve(values[2]), '1')
6326         ];
6327
6328         assert.deepEqual(actual, expected);
6329       });
6330
6331       QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6332         assert.expect(1);
6333
6334         var expected = [
6335           values[1],
6336           undefined
6337         ];
6338
6339         var actual = [
6340           _.findLast(collection, resolve(values[1]), -2),
6341           _.findLast(collection, resolve(values[2]), -2)
6342         ];
6343
6344         assert.deepEqual(actual, expected);
6345       });
6346
6347       QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6348         assert.expect(1);
6349
6350         var indexes = [-4, -6, -Infinity],
6351             expected = lodashStable.map(indexes, lodashStable.constant(values[0]));
6352
6353         var actual = lodashStable.map(indexes, function(fromIndex) {
6354           return _.findLast(collection, resolve(values[0]), fromIndex);
6355         });
6356
6357         assert.deepEqual(actual, expected);
6358       });
6359     });
6360   }());
6361
6362   /*--------------------------------------------------------------------------*/
6363
6364   QUnit.module('lodash.flip');
6365
6366   (function() {
6367     function fn() {
6368       return slice.call(arguments);
6369     }
6370
6371     QUnit.test('should flip arguments provided to `func`', function(assert) {
6372       assert.expect(1);
6373
6374       var flipped = _.flip(fn);
6375       assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
6376     });
6377   }());
6378
6379   /*--------------------------------------------------------------------------*/
6380
6381   QUnit.module('lodash.flatMapDepth');
6382
6383   (function() {
6384     var array = [1, [2, [3, [4]], 5]];
6385
6386     QUnit.test('should use a default `depth` of `1`', function(assert) {
6387       assert.expect(1);
6388
6389       assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
6390     });
6391
6392     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
6393       assert.expect(1);
6394
6395       var values = [, null, undefined],
6396           expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
6397
6398       var actual = lodashStable.map(values, function(value, index) {
6399         return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
6400       });
6401
6402       assert.deepEqual(actual, expected);
6403     });
6404
6405     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6406       assert.expect(2);
6407
6408       lodashStable.each([-1, 0], function(depth) {
6409         assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
6410       });
6411     });
6412
6413     QUnit.test('should coerce `depth` to an integer', function(assert) {
6414       assert.expect(1);
6415
6416       assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
6417     });
6418   }());
6419
6420   /*--------------------------------------------------------------------------*/
6421
6422   QUnit.module('flatMap methods');
6423
6424   lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
6425     var func = _[methodName],
6426         array = [1, 2, 3, 4];
6427
6428     function duplicate(n) {
6429       return [n, n];
6430     }
6431
6432     QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
6433       assert.expect(1);
6434
6435       var actual = func(array, duplicate),
6436           expected = lodashStable.flatten(lodashStable.map(array, duplicate));
6437
6438       assert.deepEqual(actual, expected);
6439     });
6440
6441     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
6442       assert.expect(1);
6443
6444       var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
6445       assert.deepEqual(func(objects, 'a'), array);
6446     });
6447
6448     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
6449       assert.expect(1);
6450
6451       function Foo() {
6452         this.a = [1, 2];
6453       }
6454       Foo.prototype.b = [3, 4];
6455
6456       var actual = func(new Foo, identity);
6457       assert.deepEqual(actual, [1, 2]);
6458     });
6459
6460     QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
6461       assert.expect(2);
6462
6463       var array = [[1, 2], [3, 4]],
6464           object = { 'a': [1, 2], 'b': [3, 4] },
6465           values = [, null, undefined],
6466           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
6467
6468       lodashStable.each([array, object], function(collection) {
6469         var actual = lodashStable.map(values, function(value, index) {
6470           return index ? func(collection, value) : func(collection);
6471         });
6472
6473         assert.deepEqual(actual, expected);
6474       });
6475     });
6476
6477     QUnit.test('`_.' + methodName + '` should accept a falsey `collection`', function(assert) {
6478       assert.expect(1);
6479
6480       var expected = lodashStable.map(falsey, stubArray);
6481
6482       var actual = lodashStable.map(falsey, function(collection, index) {
6483         try {
6484           return index ? func(collection) : func();
6485         } catch (e) {}
6486       });
6487
6488       assert.deepEqual(actual, expected);
6489     });
6490
6491     QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
6492       assert.expect(1);
6493
6494       assert.deepEqual(func(1), []);
6495     });
6496
6497     QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
6498       assert.expect(1);
6499
6500       var object = { 'length': [1, 2] };
6501       assert.deepEqual(func(object, identity), [1, 2]);
6502     });
6503   });
6504
6505   /*--------------------------------------------------------------------------*/
6506
6507   QUnit.module('lodash.flattenDepth');
6508
6509   (function() {
6510     var array = [1, [2, [3, [4]], 5]];
6511
6512     QUnit.test('should use a default `depth` of `1`', function(assert) {
6513       assert.expect(1);
6514
6515       assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
6516     });
6517
6518     QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6519       assert.expect(2);
6520
6521       lodashStable.each([-1, 0], function(depth) {
6522         assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
6523       });
6524     });
6525
6526     QUnit.test('should coerce `depth` to an integer', function(assert) {
6527       assert.expect(1);
6528
6529       assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
6530     });
6531   }());
6532
6533   /*--------------------------------------------------------------------------*/
6534
6535   QUnit.module('flatten methods');
6536
6537   (function() {
6538     var array = [1, [2, [3, [4]], 5]],
6539         methodNames = ['flatten', 'flattenDeep', 'flattenDepth'];
6540
6541     QUnit.test('should flatten `arguments` objects', function(assert) {
6542       assert.expect(3);
6543
6544       var array = [args, [args]];
6545
6546       assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
6547       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
6548       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
6549     });
6550
6551     QUnit.test('should treat sparse arrays as dense', function(assert) {
6552       assert.expect(6);
6553
6554       var array = [[1, 2, 3], Array(3)],
6555           expected = [1, 2, 3];
6556
6557       expected.push(undefined, undefined, undefined);
6558
6559       lodashStable.each(methodNames, function(methodName) {
6560         var actual = _[methodName](array);
6561         assert.deepEqual(actual, expected);
6562         assert.ok('4' in actual);
6563       });
6564     });
6565
6566     QUnit.test('should flatten objects with a truthy `Symbol.isConcatSpreadable` value', function(assert) {
6567       assert.expect(1);
6568
6569       if (Symbol && Symbol.isConcatSpreadable) {
6570         var object = { '0': 'a', 'length': 1 },
6571             array = [object],
6572             expected = lodashStable.map(methodNames, lodashStable.constant(['a']));
6573
6574         object[Symbol.isConcatSpreadable] = true;
6575
6576         var actual = lodashStable.map(methodNames, function(methodName) {
6577           return _[methodName](array);
6578         });
6579
6580         assert.deepEqual(actual, expected);
6581       }
6582       else {
6583         skipAssert(assert);
6584       }
6585     });
6586
6587     QUnit.test('should work with extremely large arrays', function(assert) {
6588       assert.expect(3);
6589
6590       lodashStable.times(3, function(index) {
6591         var expected = Array(5e5);
6592         try {
6593           var func = _.flatten;
6594           if (index == 1) {
6595             func = _.flattenDeep;
6596           } else if (index == 2) {
6597             func = _.flattenDepth;
6598           }
6599           assert.deepEqual(func([expected]), expected);
6600         } catch (e) {
6601           assert.ok(false, e.message);
6602         }
6603       });
6604     });
6605
6606     QUnit.test('should work with empty arrays', function(assert) {
6607       assert.expect(3);
6608
6609       var array = [[], [[]], [[], [[[]]]]];
6610
6611       assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
6612       assert.deepEqual(_.flattenDeep(array), []);
6613       assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
6614     });
6615
6616     QUnit.test('should support flattening of nested arrays', function(assert) {
6617       assert.expect(3);
6618
6619       assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
6620       assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
6621       assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
6622     });
6623
6624     QUnit.test('should return an empty array for non array-like objects', function(assert) {
6625       assert.expect(3);
6626
6627       var expected = [],
6628           nonArray = { '0': 'a' };
6629
6630       assert.deepEqual(_.flatten(nonArray), expected);
6631       assert.deepEqual(_.flattenDeep(nonArray), expected);
6632       assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
6633     });
6634
6635     QUnit.test('should return a wrapped value when chaining', function(assert) {
6636       assert.expect(6);
6637
6638       if (!isNpm) {
6639         var wrapped = _(array),
6640             actual = wrapped.flatten();
6641
6642         assert.ok(actual instanceof _);
6643         assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
6644
6645         actual = wrapped.flattenDeep();
6646
6647         assert.ok(actual instanceof _);
6648         assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
6649
6650         actual = wrapped.flattenDepth(2);
6651
6652         assert.ok(actual instanceof _);
6653         assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
6654       }
6655       else {
6656         skipAssert(assert, 6);
6657       }
6658     });
6659   }());
6660
6661   /*--------------------------------------------------------------------------*/
6662
6663   QUnit.module('flow methods');
6664
6665   lodashStable.each(['flow', 'flowRight'], function(methodName) {
6666     var func = _[methodName],
6667         isFlow = methodName == 'flow';
6668
6669     QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
6670       assert.expect(1);
6671
6672       var fixed = function(n) { return n.toFixed(1); },
6673           combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
6674
6675       assert.strictEqual(combined(1, 2), '9.0');
6676     });
6677
6678     QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
6679       assert.expect(1);
6680
6681       assert.notStrictEqual(func(noop), noop);
6682     });
6683
6684     QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
6685       assert.expect(6);
6686
6687       _.times(2, function(index) {
6688         try {
6689           var combined = index ? func([]) : func();
6690           assert.strictEqual(combined('a'), 'a');
6691         } catch (e) {
6692           assert.ok(false, e.message);
6693         }
6694         assert.strictEqual(combined.length, 0);
6695         assert.notStrictEqual(combined, identity);
6696       });
6697     });
6698
6699     QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
6700       assert.expect(1);
6701
6702       var curried = _.curry(identity);
6703
6704       var combined = isFlow
6705         ? func(_.head, curried)
6706         : func(curried, _.head);
6707
6708       assert.strictEqual(combined([1]), 1);
6709     });
6710
6711     QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6712       assert.expect(6);
6713
6714       var filterCount,
6715           mapCount,
6716           array = lodashStable.range(LARGE_ARRAY_SIZE),
6717           iteratee = function(value) { mapCount++; return square(value); },
6718           predicate = function(value) { filterCount++; return isEven(value); };
6719
6720       lodashStable.times(2, function(index) {
6721         var filter1 = _.filter,
6722             filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
6723             filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
6724
6725         var map1 = _.map,
6726             map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
6727             map3 = (_.map = index ? map2 : map1, map2(iteratee));
6728
6729         var take1 = _.take,
6730             take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
6731             take3 = (_.take = index ? take2 : take1, take2(2));
6732
6733         var combined = isFlow
6734           ? func(map3, filter3, _.compact, take3)
6735           : func(take3, _.compact, filter3, map3);
6736
6737         filterCount = mapCount = 0;
6738         assert.deepEqual(combined(array), [4, 16]);
6739
6740         if (!isNpm && WeakMap && WeakMap.name) {
6741           assert.strictEqual(filterCount, 5, 'filterCount');
6742           assert.strictEqual(mapCount, 5, 'mapCount');
6743         }
6744         else {
6745           skipAssert(assert, 2);
6746         }
6747         _.filter = filter1;
6748         _.map = map1;
6749         _.take = take1;
6750       });
6751     });
6752
6753     QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
6754       assert.expect(1);
6755
6756       var curried = _.curry(_.ary(_.map, 2), 2),
6757           getProp = curried(curried.placeholder, 'a'),
6758           objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
6759
6760       var combined = isFlow
6761         ? func(getProp, _.uniq)
6762         : func(_.uniq, getProp);
6763
6764       assert.deepEqual(combined(objects), [1, 2]);
6765     });
6766
6767     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6768       assert.expect(1);
6769
6770       if (!isNpm) {
6771         var wrapped = _(noop)[methodName]();
6772         assert.ok(wrapped instanceof _);
6773       }
6774       else {
6775         skipAssert(assert);
6776       }
6777     });
6778   });
6779
6780   /*--------------------------------------------------------------------------*/
6781
6782   QUnit.module('lodash.forEach');
6783
6784   (function() {
6785     QUnit.test('should be aliased', function(assert) {
6786       assert.expect(1);
6787
6788       assert.strictEqual(_.each, _.forEach);
6789     });
6790   }());
6791
6792   /*--------------------------------------------------------------------------*/
6793
6794   QUnit.module('lodash.forEachRight');
6795
6796   (function() {
6797     QUnit.test('should be aliased', function(assert) {
6798       assert.expect(1);
6799
6800       assert.strictEqual(_.eachRight, _.forEachRight);
6801     });
6802   }());
6803
6804   /*--------------------------------------------------------------------------*/
6805
6806   QUnit.module('forIn methods');
6807
6808   lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6809     var func = _[methodName];
6810
6811     QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
6812       assert.expect(1);
6813
6814       function Foo() {
6815         this.a = 1;
6816       }
6817       Foo.prototype.b = 2;
6818
6819       var keys = [];
6820       func(new Foo, function(value, key) { keys.push(key); });
6821       assert.deepEqual(keys.sort(), ['a', 'b']);
6822     });
6823   });
6824
6825   /*--------------------------------------------------------------------------*/
6826
6827   QUnit.module('forOwn methods');
6828
6829   lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6830     var func = _[methodName];
6831
6832     QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
6833       assert.expect(1);
6834
6835       var object = { '0': 'zero', '1': 'one', 'length': 2 },
6836           props = [];
6837
6838       func(object, function(value, prop) { props.push(prop); });
6839       assert.deepEqual(props.sort(), ['0', '1', 'length']);
6840     });
6841   });
6842
6843   /*--------------------------------------------------------------------------*/
6844
6845   QUnit.module('iteration methods');
6846
6847   (function() {
6848     var methods = [
6849       '_baseEach',
6850       'countBy',
6851       'every',
6852       'filter',
6853       'find',
6854       'findIndex',
6855       'findKey',
6856       'findLast',
6857       'findLastIndex',
6858       'findLastKey',
6859       'forEach',
6860       'forEachRight',
6861       'forIn',
6862       'forInRight',
6863       'forOwn',
6864       'forOwnRight',
6865       'groupBy',
6866       'keyBy',
6867       'map',
6868       'mapKeys',
6869       'mapValues',
6870       'maxBy',
6871       'minBy',
6872       'omitBy',
6873       'partition',
6874       'pickBy',
6875       'reject',
6876       'some'
6877     ];
6878
6879     var arrayMethods = [
6880       'findIndex',
6881       'findLastIndex',
6882       'maxBy',
6883       'minBy'
6884     ];
6885
6886     var collectionMethods = [
6887       '_baseEach',
6888       'countBy',
6889       'every',
6890       'filter',
6891       'find',
6892       'findLast',
6893       'forEach',
6894       'forEachRight',
6895       'groupBy',
6896       'keyBy',
6897       'map',
6898       'partition',
6899       'reduce',
6900       'reduceRight',
6901       'reject',
6902       'some'
6903     ];
6904
6905     var forInMethods = [
6906       'forIn',
6907       'forInRight',
6908       'omitBy',
6909       'pickBy'
6910     ];
6911
6912     var iterationMethods = [
6913       '_baseEach',
6914       'forEach',
6915       'forEachRight',
6916       'forIn',
6917       'forInRight',
6918       'forOwn',
6919       'forOwnRight'
6920     ];
6921
6922     var objectMethods = [
6923       'findKey',
6924       'findLastKey',
6925       'forIn',
6926       'forInRight',
6927       'forOwn',
6928       'forOwnRight',
6929       'mapKeys',
6930       'mapValues',
6931       'omitBy',
6932       'pickBy'
6933     ];
6934
6935     var rightMethods = [
6936       'findLast',
6937       'findLastIndex',
6938       'findLastKey',
6939       'forEachRight',
6940       'forInRight',
6941       'forOwnRight'
6942     ];
6943
6944     var unwrappedMethods = [
6945       'each',
6946       'eachRight',
6947       'every',
6948       'find',
6949       'findIndex',
6950       'findKey',
6951       'findLast',
6952       'findLastIndex',
6953       'findLastKey',
6954       'forEach',
6955       'forEachRight',
6956       'forIn',
6957       'forInRight',
6958       'forOwn',
6959       'forOwnRight',
6960       'max',
6961       'maxBy',
6962       'min',
6963       'minBy',
6964       'some'
6965     ];
6966
6967     lodashStable.each(methods, function(methodName) {
6968       var array = [1, 2, 3],
6969           func = _[methodName],
6970           isBy = /(^partition|By)$/.test(methodName),
6971           isFind = /^find/.test(methodName),
6972           isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6973           isSome = methodName == 'some';
6974
6975       QUnit.test('`_.' + methodName + '` should provide correct iteratee arguments', function(assert) {
6976         assert.expect(1);
6977
6978         if (func) {
6979           var args,
6980               expected = [1, 0, array];
6981
6982           func(array, function() {
6983             args || (args = slice.call(arguments));
6984           });
6985
6986           if (lodashStable.includes(rightMethods, methodName)) {
6987             expected[0] = 3;
6988             expected[1] = 2;
6989           }
6990           if (lodashStable.includes(objectMethods, methodName)) {
6991             expected[1] += '';
6992           }
6993           if (isBy) {
6994             expected.length = isOmitPick ? 2 : 1;
6995           }
6996           assert.deepEqual(args, expected);
6997         }
6998         else {
6999           skipAssert(assert);
7000         }
7001       });
7002
7003       QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
7004         assert.expect(1);
7005
7006         if (func) {
7007           var array = [1];
7008           array[2] = 3;
7009
7010           var expected = lodashStable.includes(objectMethods, methodName)
7011             ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
7012             : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
7013
7014           if (isBy) {
7015             expected = lodashStable.map(expected, function(args) {
7016               return args.slice(0, isOmitPick ? 2 : 1);
7017             });
7018           }
7019           else if (lodashStable.includes(objectMethods, methodName)) {
7020             expected = lodashStable.map(expected, function(args) {
7021               args[1] += '';
7022               return args;
7023             });
7024           }
7025           if (lodashStable.includes(rightMethods, methodName)) {
7026             expected.reverse();
7027           }
7028           var argsList = [];
7029           func(array, function() {
7030             argsList.push(slice.call(arguments));
7031             return !(isFind || isSome);
7032           });
7033
7034           assert.deepEqual(argsList, expected);
7035         }
7036         else {
7037           skipAssert(assert);
7038         }
7039       });
7040     });
7041
7042     lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
7043       var array = [1, 2, 3],
7044           func = _[methodName],
7045           isEvery = methodName == 'every';
7046
7047       array.a = 1;
7048
7049       QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
7050         assert.expect(1);
7051
7052         if (func) {
7053           var keys = [];
7054           func(array, function(value, key) {
7055             keys.push(key);
7056             return isEvery;
7057           });
7058
7059           assert.notOk(lodashStable.includes(keys, 'a'));
7060         }
7061         else {
7062           skipAssert(assert);
7063         }
7064       });
7065     });
7066
7067     lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
7068       var array = [1, 2, 3],
7069           isBaseEach = methodName == '_baseEach';
7070
7071       QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
7072         assert.expect(1);
7073
7074         if (!(isBaseEach || isNpm)) {
7075           var wrapped = _(array)[methodName](noop);
7076           assert.ok(wrapped instanceof _);
7077         }
7078         else {
7079           skipAssert(assert);
7080         }
7081       });
7082     });
7083
7084     lodashStable.each(unwrappedMethods, function(methodName) {
7085       var array = [1, 2, 3];
7086
7087       QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
7088         assert.expect(1);
7089
7090         if (!isNpm) {
7091           var actual = _(array)[methodName](noop);
7092           assert.notOk(actual instanceof _);
7093         }
7094         else {
7095           skipAssert(assert);
7096         }
7097       });
7098
7099       QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
7100         assert.expect(2);
7101
7102         if (!isNpm) {
7103           var wrapped = _(array).chain(),
7104               actual = wrapped[methodName](noop);
7105
7106           assert.ok(actual instanceof _);
7107           assert.notStrictEqual(actual, wrapped);
7108         }
7109         else {
7110           skipAssert(assert, 2);
7111         }
7112       });
7113     });
7114
7115     lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
7116       var func = _[methodName];
7117
7118       QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
7119         assert.expect(1);
7120
7121         function Foo() {
7122           this.a = 1;
7123         }
7124         Foo.prototype.b = 2;
7125
7126         if (func) {
7127           var values = [];
7128           func(new Foo, function(value) { values.push(value); });
7129           assert.deepEqual(values, [1]);
7130         }
7131         else {
7132           skipAssert(assert);
7133         }
7134       });
7135     });
7136
7137     lodashStable.each(iterationMethods, function(methodName) {
7138       var array = [1, 2, 3],
7139           func = _[methodName];
7140
7141       QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
7142         assert.expect(1);
7143
7144         if (func) {
7145           assert.strictEqual(func(array, Boolean), array);
7146         }
7147         else {
7148           skipAssert(assert);
7149         }
7150       });
7151     });
7152
7153     lodashStable.each(collectionMethods, function(methodName) {
7154       var func = _[methodName];
7155
7156       QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
7157         assert.expect(3);
7158
7159         if (func) {
7160           var isIteratedAsObject = function(object) {
7161             var result = false;
7162             func(object, function() { result = true; }, 0);
7163             return result;
7164           };
7165
7166           var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
7167               expected = lodashStable.map(values, stubTrue);
7168
7169           var actual = lodashStable.map(values, function(length) {
7170             return isIteratedAsObject({ 'length': length });
7171           });
7172
7173           var Foo = function(a) {};
7174           Foo.a = 1;
7175
7176           assert.deepEqual(actual, expected);
7177           assert.ok(isIteratedAsObject(Foo));
7178           assert.notOk(isIteratedAsObject({ 'length': 0 }));
7179         }
7180         else {
7181           skipAssert(assert, 3);
7182         }
7183       });
7184     });
7185
7186     lodashStable.each(methods, function(methodName) {
7187       var func = _[methodName],
7188           isFind = /^find/.test(methodName),
7189           isSome = methodName == 'some',
7190           isReduce = /^reduce/.test(methodName);
7191
7192       QUnit.test('`_.' + methodName + '` should ignore changes to `length`', function(assert) {
7193         assert.expect(1);
7194
7195         if (func) {
7196           var count = 0,
7197               array = [1];
7198
7199           func(array, function() {
7200             if (++count == 1) {
7201               array.push(2);
7202             }
7203             return !(isFind || isSome);
7204           }, isReduce ? array : null);
7205
7206           assert.strictEqual(count, 1);
7207         }
7208         else {
7209           skipAssert(assert);
7210         }
7211       });
7212     });
7213
7214     lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
7215       var func = _[methodName],
7216           isFind = /^find/.test(methodName),
7217           isSome = methodName == 'some',
7218           isReduce = /^reduce/.test(methodName);
7219
7220       QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
7221         assert.expect(1);
7222
7223         if (func) {
7224           var count = 0,
7225               object = { 'a': 1 };
7226
7227           func(object, function() {
7228             if (++count == 1) {
7229               object.b = 2;
7230             }
7231             return !(isFind || isSome);
7232           }, isReduce ? object : null);
7233
7234           assert.strictEqual(count, 1);
7235         }
7236         else {
7237           skipAssert(assert);
7238         }
7239       });
7240     });
7241   }());
7242
7243   /*--------------------------------------------------------------------------*/
7244
7245   QUnit.module('object assignments');
7246
7247   lodashStable.each(['assign', 'assignIn', 'defaults', 'defaultsDeep', 'merge'], function(methodName) {
7248     var func = _[methodName],
7249         isAssign = methodName == 'assign',
7250         isDefaults = /^defaults/.test(methodName);
7251
7252     QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
7253       assert.expect(1);
7254
7255       var expected = lodashStable.map(primitives, function(value) {
7256         var object = Object(value);
7257         object.a = 1;
7258         return object;
7259       });
7260
7261       var actual = lodashStable.map(primitives, function(value) {
7262         return func(value, { 'a': 1 });
7263       });
7264
7265       assert.deepEqual(actual, expected);
7266     });
7267
7268     QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
7269       assert.expect(1);
7270
7271       function Foo() {
7272         this.a = 1;
7273       }
7274       Foo.prototype.b = 2;
7275
7276       var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
7277       assert.deepEqual(func({}, new Foo), expected);
7278     });
7279
7280     QUnit.test('`_.' + methodName + '` should not skip a trailing function source', function(assert) {
7281       assert.expect(1);
7282
7283       function fn() {}
7284       fn.b = 2;
7285
7286       assert.deepEqual(func({}, { 'a': 1 }, fn), { 'a': 1, 'b': 2 });
7287     });
7288
7289     QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
7290       assert.expect(1);
7291
7292       try {
7293         assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
7294       } catch (e) {
7295         assert.ok(false, e.message);
7296       }
7297     });
7298
7299     QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
7300       assert.expect(2);
7301
7302       var source = { 'a': 1 },
7303           values = [null, undefined],
7304           expected = lodashStable.map(values, stubTrue);
7305
7306       var actual = lodashStable.map(values, function(value) {
7307         var object = func(value, source);
7308         return object !== source && lodashStable.isEqual(object, source);
7309       });
7310
7311       assert.deepEqual(actual, expected);
7312
7313       actual = lodashStable.map(values, function(value) {
7314         return lodashStable.isEqual(func(value), {});
7315       });
7316
7317       assert.deepEqual(actual, expected);
7318     });
7319
7320     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
7321       assert.expect(2);
7322
7323       var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
7324           expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
7325
7326       function fn() {};
7327       fn.a = array[0];
7328       fn.b = array[1];
7329       fn.c = array[2];
7330
7331       assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
7332       assert.deepEqual(lodashStable.reduce(fn, func, { 'a': 0 }), expected);
7333     });
7334
7335     QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
7336       assert.expect(1);
7337
7338       if (!isNpm) {
7339         var wrapped = _({ 'a': 1 }),
7340             actual = wrapped[methodName]({ 'b': 2 });
7341
7342         assert.notStrictEqual(actual, wrapped);
7343       }
7344       else {
7345         skipAssert(assert);
7346       }
7347     });
7348   });
7349
7350   lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
7351     var func = _[methodName];
7352
7353     QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
7354       assert.expect(1);
7355
7356       function Foo() {}
7357       Foo.prototype.a = 1;
7358
7359       var actual = func(new Foo, { 'b': 2 });
7360       assert.notOk(_.has(actual, 'a'));
7361     });
7362   });
7363
7364   lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'defaultsDeep', 'merge', 'mergeWith'], function(methodName) {
7365     var func = _[methodName];
7366
7367     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
7368       assert.expect(4);
7369
7370       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
7371         var object = {},
7372             pass = true;
7373
7374         defineProperty(object, 'a', {
7375           'configurable': true,
7376           'enumerable': true,
7377           'get': lodashStable.constant(value),
7378           'set': function() { pass = false; }
7379         });
7380
7381         func(object, { 'a': value });
7382         assert.ok(pass);
7383       });
7384     });
7385   });
7386
7387   lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
7388     var func = _[methodName],
7389         isMergeWith = methodName == 'mergeWith';
7390
7391     QUnit.test('`_.' + methodName + '` should provide correct `customizer` arguments', function(assert) {
7392       assert.expect(3);
7393
7394       var args,
7395           object = { 'a': 1 },
7396           source = { 'a': 2 },
7397           expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
7398
7399       func(object, source, function() {
7400         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7401       });
7402
7403       assert.deepEqual(args, expected, 'primitive values');
7404
7405       var argsList = [],
7406           objectValue = [1, 2],
7407           sourceValue = { 'b': 2 };
7408
7409       object = { 'a': objectValue };
7410       source = { 'a': sourceValue };
7411       expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
7412
7413       if (isMergeWith) {
7414         expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
7415       }
7416       func(object, source, function() {
7417         argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7418       });
7419
7420       assert.deepEqual(argsList, expected, 'object values');
7421
7422       args = undefined;
7423       object = { 'a': 1 };
7424       source = { 'b': 2 };
7425       expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
7426
7427       func(object, source, function() {
7428         args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7429       });
7430
7431       assert.deepEqual(args, expected, 'undefined properties');
7432     });
7433
7434     QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
7435       assert.expect(2);
7436
7437       function callback() {}
7438       callback.b = 2;
7439
7440       var actual = func({ 'a': 1 }, callback);
7441       assert.deepEqual(actual, { 'a': 1, 'b': 2 });
7442
7443       actual = func({ 'a': 1 }, callback, { 'c': 3 });
7444       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
7445     });
7446   });
7447
7448   /*--------------------------------------------------------------------------*/
7449
7450   QUnit.module('exit early');
7451
7452   lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
7453     var func = _[methodName];
7454
7455     QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
7456       assert.expect(1);
7457
7458       if (func) {
7459         var array = [1, 2, 3],
7460             values = [];
7461
7462         func(array, function(value, other) {
7463           values.push(lodashStable.isArray(value) ? other : value);
7464           return false;
7465         });
7466
7467         assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
7468       }
7469       else {
7470         skipAssert(assert);
7471       }
7472     });
7473
7474     QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
7475       assert.expect(1);
7476
7477       if (func) {
7478         var object = { 'a': 1, 'b': 2, 'c': 3 },
7479             values = [];
7480
7481         func(object, function(value, other) {
7482           values.push(lodashStable.isArray(value) ? other : value);
7483           return false;
7484         });
7485
7486         assert.strictEqual(values.length, 1);
7487       }
7488       else {
7489         skipAssert(assert);
7490       }
7491     });
7492   });
7493
7494   /*--------------------------------------------------------------------------*/
7495
7496   QUnit.module('`__proto__` property bugs');
7497
7498   (function() {
7499     QUnit.test('should work with the "__proto__" key in internal data objects', function(assert) {
7500       assert.expect(4);
7501
7502       var stringLiteral = '__proto__',
7503           stringObject = Object(stringLiteral),
7504           expected = [stringLiteral, stringObject];
7505
7506       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
7507         return isEven(count) ? stringLiteral : stringObject;
7508       });
7509
7510       assert.deepEqual(_.difference(largeArray, largeArray), []);
7511       assert.deepEqual(_.intersection(largeArray, largeArray), expected);
7512       assert.deepEqual(_.uniq(largeArray), expected);
7513       assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
7514     });
7515
7516     QUnit.test('should treat "__proto__" as a regular key in assignments', function(assert) {
7517       assert.expect(2);
7518
7519       var methods = [
7520         'assign',
7521         'assignIn',
7522         'defaults',
7523         'defaultsDeep',
7524         'merge'
7525       ];
7526
7527       var source = create(null);
7528       source.__proto__ = [];
7529
7530       var expected = lodashStable.map(methods, stubFalse);
7531
7532       var actual = lodashStable.map(methods, function(methodName) {
7533         var result = _[methodName]({}, source);
7534         return result instanceof Array;
7535       });
7536
7537       assert.deepEqual(actual, expected);
7538
7539       actual = _.groupBy([{ 'a': '__proto__' }], 'a');
7540       assert.notOk(actual instanceof Array);
7541     });
7542   }());
7543
7544   /*--------------------------------------------------------------------------*/
7545
7546   QUnit.module('lodash.fromPairs');
7547
7548   (function() {
7549     QUnit.test('should accept a two dimensional array', function(assert) {
7550       assert.expect(1);
7551
7552       var array = [['a', 1], ['b', 2]],
7553           object = { 'a': 1, 'b': 2 },
7554           actual = _.fromPairs(array);
7555
7556       assert.deepEqual(actual, object);
7557     });
7558
7559     QUnit.test('should accept a falsey `array`', function(assert) {
7560       assert.expect(1);
7561
7562       var expected = lodashStable.map(falsey, stubObject);
7563
7564       var actual = lodashStable.map(falsey, function(array, index) {
7565         try {
7566           return index ? _.fromPairs(array) : _.fromPairs();
7567         } catch (e) {}
7568       });
7569
7570       assert.deepEqual(actual, expected);
7571     });
7572
7573     QUnit.test('should not support deep paths', function(assert) {
7574       assert.expect(1);
7575
7576       var actual = _.fromPairs([['a.b', 1]]);
7577       assert.deepEqual(actual, { 'a.b': 1 });
7578     });
7579
7580     QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
7581       assert.expect(1);
7582
7583       var object = { 'a.b': 1 };
7584       assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
7585     });
7586
7587     QUnit.test('should work in a lazy sequence', function(assert) {
7588       assert.expect(1);
7589
7590       if (!isNpm) {
7591         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7592           return ['key' + index, index];
7593         });
7594
7595         var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
7596
7597         assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
7598       }
7599       else {
7600         skipAssert(assert);
7601       }
7602     });
7603   }());
7604
7605   /*--------------------------------------------------------------------------*/
7606
7607   QUnit.module('lodash.functions');
7608
7609   (function() {
7610     QUnit.test('should return the function names of an object', function(assert) {
7611       assert.expect(1);
7612
7613       var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
7614           actual = _.functions(object).sort();
7615
7616       assert.deepEqual(actual, ['b', 'd']);
7617     });
7618
7619     QUnit.test('should not include inherited functions', function(assert) {
7620       assert.expect(1);
7621
7622       function Foo() {
7623         this.a = identity;
7624         this.b = 'b';
7625       }
7626       Foo.prototype.c = noop;
7627
7628       assert.deepEqual(_.functions(new Foo), ['a']);
7629     });
7630   }());
7631
7632   /*--------------------------------------------------------------------------*/
7633
7634   QUnit.module('lodash.groupBy');
7635
7636   (function() {
7637     var array = [6.1, 4.2, 6.3];
7638
7639     QUnit.test('should transform keys by `iteratee`', function(assert) {
7640       assert.expect(1);
7641
7642       var actual = _.groupBy(array, Math.floor);
7643       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7644     });
7645
7646     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7647       assert.expect(1);
7648
7649       var array = [6, 4, 6],
7650           values = [, null, undefined],
7651           expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
7652
7653       var actual = lodashStable.map(values, function(value, index) {
7654         return index ? _.groupBy(array, value) : _.groupBy(array);
7655       });
7656
7657       assert.deepEqual(actual, expected);
7658     });
7659
7660     QUnit.test('should work with `_.property` shorthands', function(assert) {
7661       assert.expect(1);
7662
7663       var actual = _.groupBy(['one', 'two', 'three'], 'length');
7664       assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
7665     });
7666
7667     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
7668       assert.expect(2);
7669
7670       var actual = _.groupBy(array, function(n) {
7671         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
7672       });
7673
7674       assert.deepEqual(actual.constructor, [4.2]);
7675       assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
7676     });
7677
7678     QUnit.test('should work with a number for `iteratee`', function(assert) {
7679       assert.expect(2);
7680
7681       var array = [
7682         [1, 'a'],
7683         [2, 'a'],
7684         [2, 'b']
7685       ];
7686
7687       assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
7688       assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
7689     });
7690
7691     QUnit.test('should work with an object for `collection`', function(assert) {
7692       assert.expect(1);
7693
7694       var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
7695       assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7696     });
7697
7698     QUnit.test('should work in a lazy sequence', function(assert) {
7699       assert.expect(1);
7700
7701       if (!isNpm) {
7702         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
7703           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
7704           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
7705         );
7706
7707         var iteratee = function(value) { value.push(value[0]); return value; },
7708             predicate = function(value) { return isEven(value[0]); },
7709             actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
7710
7711         assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
7712       }
7713       else {
7714         skipAssert(assert);
7715       }
7716     });
7717   }());
7718
7719   /*--------------------------------------------------------------------------*/
7720
7721   QUnit.module('lodash.gt');
7722
7723   (function() {
7724     QUnit.test('should return `true` if `value` > `other`', function(assert) {
7725       assert.expect(2);
7726
7727       assert.strictEqual(_.gt(3, 1), true);
7728       assert.strictEqual(_.gt('def', 'abc'), true);
7729     });
7730
7731     QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
7732       assert.expect(4);
7733
7734       assert.strictEqual(_.gt(1, 3), false);
7735       assert.strictEqual(_.gt(3, 3), false);
7736       assert.strictEqual(_.gt('abc', 'def'), false);
7737       assert.strictEqual(_.gt('def', 'def'), false);
7738     });
7739   }());
7740
7741   /*--------------------------------------------------------------------------*/
7742
7743   QUnit.module('lodash.gte');
7744
7745   (function() {
7746     QUnit.test('should return `true` if `value` >= `other`', function(assert) {
7747       assert.expect(4);
7748
7749       assert.strictEqual(_.gte(3, 1), true);
7750       assert.strictEqual(_.gte(3, 3), true);
7751       assert.strictEqual(_.gte('def', 'abc'), true);
7752       assert.strictEqual(_.gte('def', 'def'), true);
7753     });
7754
7755     QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
7756       assert.expect(2);
7757
7758       assert.strictEqual(_.gte(1, 3), false);
7759       assert.strictEqual(_.gte('abc', 'def'), false);
7760     });
7761   }());
7762
7763   /*--------------------------------------------------------------------------*/
7764
7765   QUnit.module('has methods');
7766
7767   lodashStable.each(['has', 'hasIn'], function(methodName) {
7768     var func = _[methodName],
7769         isHas = methodName == 'has',
7770         sparseArgs = toArgs([1]),
7771         sparseArray = Array(1),
7772         sparseString = Object('a');
7773
7774     delete sparseArgs[0];
7775     delete sparseString[0];
7776
7777     QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
7778       assert.expect(2);
7779
7780       var object = { 'a': 1 };
7781
7782       lodashStable.each(['a', ['a']], function(path) {
7783         assert.strictEqual(func(object, path), true);
7784       });
7785     });
7786
7787     QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of `object`', function(assert) {
7788       assert.expect(1);
7789
7790       var object = { 'hasOwnProperty': null, 'a': 1 };
7791       assert.strictEqual(func(object, 'a'), true);
7792     });
7793
7794     QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
7795       assert.expect(4);
7796
7797       var object = { 'a': { 'b': 2 } };
7798
7799       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7800         assert.strictEqual(func(object, path), true);
7801       });
7802
7803       lodashStable.each(['a.a', ['a', 'a']], function(path) {
7804         assert.strictEqual(func(object, path), false);
7805       });
7806     });
7807
7808     QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
7809       assert.expect(2);
7810
7811       function fn() {}
7812       fn.toString = lodashStable.constant('fn');
7813
7814       var object = { 'null': 1 , 'undefined': 2, 'fn': 3, '[object Object]': 4 },
7815           paths = [null, undefined, fn, {}],
7816           expected = lodashStable.map(paths, stubTrue);
7817
7818       lodashStable.times(2, function(index) {
7819         var actual = lodashStable.map(paths, function(path) {
7820           return func(object, index ? [path] : path);
7821         });
7822
7823         assert.deepEqual(actual, expected);
7824       });
7825     });
7826
7827     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7828       assert.expect(1);
7829
7830       assert.strictEqual(func(args, 1), true);
7831     });
7832
7833     QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
7834       assert.expect(2);
7835
7836       var array = [1, 2, 3];
7837
7838       lodashStable.each([1, [1]], function(path) {
7839         assert.strictEqual(func(array, path), true);
7840       });
7841     });
7842
7843     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
7844       assert.expect(1);
7845
7846       var object = { '-0': 'a', '0': 'b' },
7847           props = [-0, Object(-0), 0, Object(0)],
7848           expected = lodashStable.map(props, stubTrue);
7849
7850       var actual = lodashStable.map(props, function(key) {
7851         return func(object, key);
7852       });
7853
7854       assert.deepEqual(actual, expected);
7855     });
7856
7857     QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
7858       assert.expect(2);
7859
7860       function Foo() {}
7861
7862       if (Symbol) {
7863         Foo.prototype[symbol] = 1;
7864
7865         var symbol2 = Symbol('b');
7866         defineProperty(Foo.prototype, symbol2, {
7867           'configurable': true,
7868           'enumerable': false,
7869           'writable': true,
7870           'value': 2
7871         });
7872
7873         var object = isHas ? Foo.prototype : new Foo;
7874         assert.strictEqual(func(object, symbol), true);
7875         assert.strictEqual(func(object, symbol2), true);
7876       }
7877       else {
7878         skipAssert(assert, 2);
7879       }
7880     });
7881
7882     QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7883       assert.expect(2);
7884
7885       var object = { 'a.b': 1 };
7886
7887       lodashStable.each(['a.b', ['a.b']], function(path) {
7888         assert.strictEqual(func(object, path), true);
7889       });
7890     });
7891
7892     QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values', function(assert) {
7893       assert.expect(1);
7894
7895       var values = [sparseArgs, sparseArray, sparseString],
7896           expected = lodashStable.map(values, stubTrue);
7897
7898       var actual = lodashStable.map(values, function(value) {
7899         return func(value, 0);
7900       });
7901
7902       assert.deepEqual(actual, expected);
7903     });
7904
7905     QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values with deep paths', function(assert) {
7906       assert.expect(1);
7907
7908       var values = [sparseArgs, sparseArray, sparseString],
7909           expected = lodashStable.map(values, lodashStable.constant([true, true]));
7910
7911       var actual = lodashStable.map(values, function(value) {
7912         return lodashStable.map(['a[0]', ['a', '0']], function(path) {
7913           return func({ 'a': value }, path);
7914         });
7915       });
7916
7917       assert.deepEqual(actual, expected);
7918     });
7919
7920     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7921       assert.expect(2);
7922
7923       function Foo() {}
7924       Foo.prototype.a = 1;
7925
7926       lodashStable.each(['a', ['a']], function(path) {
7927         assert.strictEqual(func(new Foo, path), !isHas);
7928       });
7929     });
7930
7931     QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
7932       assert.expect(2);
7933
7934       function Foo() {}
7935       Foo.prototype.a = { 'b': 1 };
7936
7937       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7938         assert.strictEqual(func(new Foo, path), !isHas);
7939       });
7940     });
7941
7942     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7943       assert.expect(2);
7944
7945       var values = [null, undefined],
7946           expected = lodashStable.map(values, stubFalse);
7947
7948       lodashStable.each(['constructor', ['constructor']], function(path) {
7949         var actual = lodashStable.map(values, function(value) {
7950           return func(value, path);
7951         });
7952
7953         assert.deepEqual(actual, expected);
7954       });
7955     });
7956
7957     QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
7958       assert.expect(2);
7959
7960       var values = [null, undefined],
7961           expected = lodashStable.map(values, stubFalse);
7962
7963       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
7964         var actual = lodashStable.map(values, function(value) {
7965           return func(value, path);
7966         });
7967
7968         assert.deepEqual(actual, expected);
7969       });
7970     });
7971
7972     QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
7973       assert.expect(2);
7974
7975       var values = [, null, undefined],
7976           expected = lodashStable.map(values, stubFalse);
7977
7978       lodashStable.each(['a.b', ['a', 'b']], function(path) {
7979         var actual = lodashStable.map(values, function(value, index) {
7980           var object = index ? { 'a': value } : {};
7981           return func(object, path);
7982         });
7983
7984         assert.deepEqual(actual, expected);
7985       });
7986     });
7987
7988     QUnit.test('`_.' + methodName + '` should return `false` over sparse values of deep paths', function(assert) {
7989       assert.expect(1);
7990
7991       var values = [sparseArgs, sparseArray, sparseString],
7992           expected = lodashStable.map(values, lodashStable.constant([false, false]));
7993
7994       var actual = lodashStable.map(values, function(value) {
7995         return lodashStable.map(['a[0].b', ['a', '0', 'b']], function(path) {
7996           return func({ 'a': value }, path);
7997         });
7998       });
7999
8000       assert.deepEqual(actual, expected);
8001     });
8002   });
8003
8004   /*--------------------------------------------------------------------------*/
8005
8006   QUnit.module('lodash.head');
8007
8008   (function() {
8009     var array = [1, 2, 3, 4];
8010
8011     QUnit.test('should return the first element', function(assert) {
8012       assert.expect(1);
8013
8014       assert.strictEqual(_.head(array), 1);
8015     });
8016
8017     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
8018       assert.expect(1);
8019
8020       arrayProto[0] = 1;
8021       assert.strictEqual(_.head([]), undefined);
8022       arrayProto.length = 0;
8023     });
8024
8025     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
8026       assert.expect(1);
8027
8028       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
8029           actual = lodashStable.map(array, _.head);
8030
8031       assert.deepEqual(actual, [1, 4, 7]);
8032     });
8033
8034     QUnit.test('should be aliased', function(assert) {
8035       assert.expect(1);
8036
8037       assert.strictEqual(_.first, _.head);
8038     });
8039
8040     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8041       assert.expect(2);
8042
8043       if (!isNpm) {
8044         var wrapped = _(array);
8045         assert.strictEqual(wrapped.head(), 1);
8046         assert.strictEqual(wrapped.first(), 1);
8047       }
8048       else {
8049         skipAssert(assert, 2);
8050       }
8051     });
8052
8053     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8054       assert.expect(2);
8055
8056       if (!isNpm) {
8057         var wrapped = _(array).chain();
8058         assert.ok(wrapped.head() instanceof _);
8059         assert.ok(wrapped.first() instanceof _);
8060       }
8061       else {
8062         skipAssert(assert, 2);
8063       }
8064     });
8065
8066     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
8067       assert.expect(2);
8068
8069       if (!isNpm) {
8070         var wrapped = _(array).chain();
8071         assert.strictEqual(wrapped.head().__wrapped__, array);
8072         assert.strictEqual(wrapped.first().__wrapped__, array);
8073       }
8074       else {
8075         skipAssert(assert, 2);
8076       }
8077     });
8078
8079     QUnit.test('should work in a lazy sequence', function(assert) {
8080       assert.expect(4);
8081
8082       if (!isNpm) {
8083         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
8084             smallArray = array;
8085
8086         lodashStable.each(['head', 'first'], function(methodName) {
8087           lodashStable.times(2, function(index) {
8088             var array = index ? largeArray : smallArray,
8089                 actual = _(array).filter(isEven)[methodName]();
8090
8091             assert.strictEqual(actual, _[methodName](_.filter(array, isEven)));
8092           });
8093         });
8094       }
8095       else {
8096         skipAssert(assert, 4);
8097       }
8098     });
8099   }());
8100
8101   /*--------------------------------------------------------------------------*/
8102
8103   QUnit.module('lodash.identity');
8104
8105   (function() {
8106     QUnit.test('should return the first argument given', function(assert) {
8107       assert.expect(1);
8108
8109       var object = { 'name': 'fred' };
8110       assert.strictEqual(_.identity(object), object);
8111     });
8112   }());
8113
8114   /*--------------------------------------------------------------------------*/
8115
8116   QUnit.module('lodash.includes');
8117
8118   (function() {
8119     lodashStable.each({
8120       'an `arguments` object': arguments,
8121       'an array': [1, 2, 3, 4],
8122       'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
8123       'a string': '1234'
8124     },
8125     function(collection, key) {
8126       QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
8127         assert.expect(1);
8128
8129         assert.strictEqual(_.includes(collection, 3), true);
8130       });
8131
8132       QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
8133         assert.expect(1);
8134
8135         assert.strictEqual(_.includes(collection, 5), false);
8136       });
8137
8138       QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
8139         assert.expect(1);
8140
8141         assert.strictEqual(_.includes(collection, 2, 1.2), true);
8142       });
8143
8144       QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
8145         assert.expect(1);
8146
8147         if (!isNpm) {
8148           assert.strictEqual(_(collection).includes(3), true);
8149         }
8150         else {
8151           skipAssert(assert);
8152         }
8153       });
8154
8155       QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
8156         assert.expect(1);
8157
8158         if (!isNpm) {
8159           assert.ok(_(collection).chain().includes(3) instanceof _);
8160         }
8161         else {
8162           skipAssert(assert);
8163         }
8164       });
8165     });
8166
8167     lodashStable.each({
8168       'literal': 'abc',
8169       'object': Object('abc')
8170     },
8171     function(collection, key) {
8172       QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
8173         assert.expect(2);
8174
8175         assert.strictEqual(_.includes(collection, 'bc'), true);
8176         assert.strictEqual(_.includes(collection, 'd'), false);
8177       });
8178     });
8179
8180     QUnit.test('should return `false` for empty collections', function(assert) {
8181       assert.expect(1);
8182
8183       var expected = lodashStable.map(empties, stubFalse);
8184
8185       var actual = lodashStable.map(empties, function(value) {
8186         try {
8187           return _.includes(value);
8188         } catch (e) {}
8189       });
8190
8191       assert.deepEqual(actual, expected);
8192     });
8193
8194     QUnit.test('should work with a string and a `fromIndex` >= `length`', function(assert) {
8195       assert.expect(1);
8196
8197       var string = '1234',
8198           length = string.length,
8199           indexes = [4, 6, Math.pow(2, 32), Infinity];
8200
8201       var expected = lodashStable.map(indexes, function(index) {
8202         return [false, false, index == length];
8203       });
8204
8205       var actual = lodashStable.map(indexes, function(fromIndex) {
8206         return [
8207           _.includes(string, 1, fromIndex),
8208           _.includes(string, undefined, fromIndex),
8209           _.includes(string, '', fromIndex)
8210         ];
8211       });
8212
8213       assert.deepEqual(actual, expected);
8214     });
8215
8216     QUnit.test('should match `NaN`', function(assert) {
8217       assert.expect(1);
8218
8219       assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
8220     });
8221
8222     QUnit.test('should match `-0` as `0`', function(assert) {
8223       assert.expect(2);
8224
8225       assert.strictEqual(_.includes([-0], 0), true);
8226       assert.strictEqual(_.includes([0], -0), true);
8227     });
8228
8229     QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
8230       assert.expect(1);
8231
8232       var array = [2, 3, 1],
8233           values = [1, 2, 3];
8234
8235       assert.ok(lodashStable.every(values, lodashStable.partial(_.includes, array)));
8236     });
8237   }(1, 2, 3, 4));
8238
8239   /*--------------------------------------------------------------------------*/
8240
8241   QUnit.module('lodash.initial');
8242
8243   (function() {
8244     var array = [1, 2, 3];
8245
8246     QUnit.test('should accept a falsey `array`', function(assert) {
8247       assert.expect(1);
8248
8249       var expected = lodashStable.map(falsey, stubArray);
8250
8251       var actual = lodashStable.map(falsey, function(array, index) {
8252         try {
8253           return index ? _.initial(array) : _.initial();
8254         } catch (e) {}
8255       });
8256
8257       assert.deepEqual(actual, expected);
8258     });
8259
8260     QUnit.test('should exclude last element', function(assert) {
8261       assert.expect(1);
8262
8263       assert.deepEqual(_.initial(array), [1, 2]);
8264     });
8265
8266     QUnit.test('should return an empty when querying empty arrays', function(assert) {
8267       assert.expect(1);
8268
8269       assert.deepEqual(_.initial([]), []);
8270     });
8271
8272     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
8273       assert.expect(1);
8274
8275       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
8276           actual = lodashStable.map(array, _.initial);
8277
8278       assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
8279     });
8280
8281     QUnit.test('should work in a lazy sequence', function(assert) {
8282       assert.expect(4);
8283
8284       if (!isNpm) {
8285         var array = lodashStable.range(LARGE_ARRAY_SIZE),
8286             values = [];
8287
8288         var actual = _(array).initial().filter(function(value) {
8289           values.push(value);
8290           return false;
8291         })
8292         .value();
8293
8294         assert.deepEqual(actual, []);
8295         assert.deepEqual(values, _.initial(array));
8296
8297         values = [];
8298
8299         actual = _(array).filter(function(value) {
8300           values.push(value);
8301           return isEven(value);
8302         })
8303         .initial()
8304         .value();
8305
8306         assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
8307         assert.deepEqual(values, array);
8308       }
8309       else {
8310         skipAssert(assert, 4);
8311       }
8312     });
8313   }());
8314
8315   /*--------------------------------------------------------------------------*/
8316
8317   QUnit.module('lodash.inRange');
8318
8319   (function() {
8320     QUnit.test('should work with an `end`', function(assert) {
8321       assert.expect(3);
8322
8323       assert.strictEqual(_.inRange(3, 5), true);
8324       assert.strictEqual(_.inRange(5, 5), false);
8325       assert.strictEqual(_.inRange(6, 5), false);
8326     });
8327
8328     QUnit.test('should work with a `start` and `end`', function(assert) {
8329       assert.expect(4);
8330
8331       assert.strictEqual(_.inRange(1, 1, 5), true);
8332       assert.strictEqual(_.inRange(3, 1, 5), true);
8333       assert.strictEqual(_.inRange(0, 1, 5), false);
8334       assert.strictEqual(_.inRange(5, 1, 5), false);
8335     });
8336
8337     QUnit.test('should treat falsey `start` as `0`', function(assert) {
8338       assert.expect(13);
8339
8340       lodashStable.each(falsey, function(value, index) {
8341         if (index) {
8342           assert.strictEqual(_.inRange(0, value), false);
8343           assert.strictEqual(_.inRange(0, value, 1), true);
8344         } else {
8345           assert.strictEqual(_.inRange(0), false);
8346         }
8347       });
8348     });
8349
8350     QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
8351       assert.expect(2);
8352
8353       assert.strictEqual(_.inRange(2, 5, 1), true);
8354       assert.strictEqual(_.inRange(-3, -2, -6), true);
8355     });
8356
8357     QUnit.test('should work with a floating point `n` value', function(assert) {
8358       assert.expect(4);
8359
8360       assert.strictEqual(_.inRange(0.5, 5), true);
8361       assert.strictEqual(_.inRange(1.2, 1, 5), true);
8362       assert.strictEqual(_.inRange(5.2, 5), false);
8363       assert.strictEqual(_.inRange(0.5, 1, 5), false);
8364     });
8365
8366     QUnit.test('should coerce arguments to finite numbers', function(assert) {
8367       assert.expect(1);
8368
8369       var actual = [
8370         _.inRange(0, '1'),
8371         _.inRange(0, '0', 1),
8372         _.inRange(0, 0, '1'),
8373         _.inRange(0, NaN, 1),
8374         _.inRange(-1, -1, NaN)
8375       ];
8376
8377       assert.deepEqual(actual, lodashStable.map(actual, stubTrue));
8378     });
8379   }());
8380
8381   /*--------------------------------------------------------------------------*/
8382
8383   QUnit.module('intersection methods');
8384
8385   lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
8386     var func = _[methodName];
8387
8388     QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
8389       assert.expect(1);
8390
8391       var actual = func([2, 1], [2, 3]);
8392       assert.deepEqual(actual, [2]);
8393     });
8394
8395     QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
8396       assert.expect(1);
8397
8398       var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
8399       assert.deepEqual(actual, [3]);
8400     });
8401
8402     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
8403       assert.expect(1);
8404
8405       var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
8406       assert.deepEqual(actual, [1, 2]);
8407     });
8408
8409     QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
8410       assert.expect(1);
8411
8412       var actual = func([1, 1, 3, 2, 2]);
8413       assert.deepEqual(actual, [1, 3, 2]);
8414     });
8415
8416     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
8417       assert.expect(2);
8418
8419       var array = [0, 1, null, 3],
8420           expected = [1, 3];
8421
8422       assert.deepEqual(func(array, args), expected);
8423       assert.deepEqual(func(args, array), expected);
8424     });
8425
8426     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
8427       assert.expect(1);
8428
8429       var values = [-0, 0],
8430           expected = lodashStable.map(values, lodashStable.constant(['0']));
8431
8432       var actual = lodashStable.map(values, function(value) {
8433         return lodashStable.map(func(values, [value]), lodashStable.toString);
8434       });
8435
8436       assert.deepEqual(actual, expected);
8437     });
8438
8439     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
8440       assert.expect(1);
8441
8442       var actual = func([1, NaN, 3], [NaN, 5, NaN]);
8443       assert.deepEqual(actual, [NaN]);
8444     });
8445
8446     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
8447       assert.expect(1);
8448
8449       var values = [-0, 0],
8450           expected = lodashStable.map(values, lodashStable.constant(['0']));
8451
8452       var actual = lodashStable.map(values, function(value) {
8453         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
8454         return lodashStable.map(func(values, largeArray), lodashStable.toString);
8455       });
8456
8457       assert.deepEqual(actual, expected);
8458     });
8459
8460     QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
8461       assert.expect(1);
8462
8463       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
8464       assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
8465     });
8466
8467     QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
8468       assert.expect(2);
8469
8470       var object = {},
8471           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
8472
8473       assert.deepEqual(func([object], largeArray), [object]);
8474       assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
8475     });
8476
8477     QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
8478       assert.expect(3);
8479
8480       var array = [0, 1, null, 3];
8481       assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
8482       assert.deepEqual(func(null, array, null, [2, 3]), []);
8483       assert.deepEqual(func(array, null, args, null), []);
8484     });
8485
8486     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
8487       assert.expect(2);
8488
8489       if (!isNpm) {
8490         var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
8491         assert.ok(wrapped instanceof _);
8492         assert.deepEqual(wrapped.value(), [1, 2]);
8493       }
8494       else {
8495         skipAssert(assert, 2);
8496       }
8497     });
8498   });
8499
8500   /*--------------------------------------------------------------------------*/
8501
8502   QUnit.module('lodash.intersectionBy');
8503
8504   (function() {
8505     QUnit.test('should accept an `iteratee`', function(assert) {
8506       assert.expect(2);
8507
8508       var actual = _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8509       assert.deepEqual(actual, [2.1]);
8510
8511       actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8512       assert.deepEqual(actual, [{ 'x': 1 }]);
8513     });
8514
8515     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
8516       assert.expect(1);
8517
8518       var args;
8519
8520       _.intersectionBy([2.1, 1.2], [2.3, 3.4], function() {
8521         args || (args = slice.call(arguments));
8522       });
8523
8524       assert.deepEqual(args, [2.3]);
8525     });
8526   }());
8527
8528   /*--------------------------------------------------------------------------*/
8529
8530   QUnit.module('lodash.intersectionWith');
8531
8532   (function() {
8533     QUnit.test('should work with a `comparator`', function(assert) {
8534       assert.expect(1);
8535
8536       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
8537           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
8538           actual = _.intersectionWith(objects, others, lodashStable.isEqual);
8539
8540       assert.deepEqual(actual, [objects[0]]);
8541     });
8542
8543     QUnit.test('should preserve the sign of `0`', function(assert) {
8544       assert.expect(1);
8545
8546       var array = [-0],
8547           largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubZero),
8548           others = [[0], largeArray],
8549           expected = lodashStable.map(others, lodashStable.constant(['-0']));
8550
8551       var actual = lodashStable.map(others, function(other) {
8552         return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
8553       });
8554
8555       assert.deepEqual(actual, expected);
8556     });
8557   }());
8558
8559   /*--------------------------------------------------------------------------*/
8560
8561   QUnit.module('lodash.invert');
8562
8563   (function() {
8564     QUnit.test('should invert an object', function(assert) {
8565       assert.expect(2);
8566
8567       var object = { 'a': 1, 'b': 2 },
8568           actual = _.invert(object);
8569
8570       assert.deepEqual(actual, { '1': 'a', '2': 'b' });
8571       assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
8572     });
8573
8574     QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
8575       assert.expect(1);
8576
8577       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
8578       assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
8579     });
8580
8581     QUnit.test('should work with an object that has a `length` property', function(assert) {
8582       assert.expect(1);
8583
8584       var object = { '0': 'a', '1': 'b', 'length': 2 };
8585       assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
8586     });
8587
8588     QUnit.test('should return a wrapped value when chaining', function(assert) {
8589       assert.expect(2);
8590
8591       if (!isNpm) {
8592         var object = { 'a': 1, 'b': 2 },
8593             wrapped = _(object).invert();
8594
8595         assert.ok(wrapped instanceof _);
8596         assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
8597       }
8598       else {
8599         skipAssert(assert, 2);
8600       }
8601     });
8602   }());
8603
8604   /*--------------------------------------------------------------------------*/
8605
8606   QUnit.module('lodash.invertBy');
8607
8608   (function() {
8609     var object = { 'a': 1, 'b': 2, 'c': 1 };
8610
8611     QUnit.test('should transform keys by `iteratee`', function(assert) {
8612       assert.expect(1);
8613
8614       var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
8615
8616       var actual = _.invertBy(object, function(value) {
8617         return 'group' + value;
8618       });
8619
8620       assert.deepEqual(actual, expected);
8621     });
8622
8623     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
8624       assert.expect(1);
8625
8626       var values = [, null, undefined],
8627           expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
8628
8629       var actual = lodashStable.map(values, function(value, index) {
8630         return index ? _.invertBy(object, value) : _.invertBy(object);
8631       });
8632
8633       assert.deepEqual(actual, expected);
8634     });
8635
8636     QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
8637       assert.expect(1);
8638
8639       var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
8640           expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
8641
8642       assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
8643     });
8644
8645     QUnit.test('should return a wrapped value when chaining', function(assert) {
8646       assert.expect(2);
8647
8648       if (!isNpm) {
8649         var wrapped = _(object).invertBy();
8650
8651         assert.ok(wrapped instanceof _);
8652         assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
8653       }
8654       else {
8655         skipAssert(assert, 2);
8656       }
8657     });
8658   }());
8659
8660   /*--------------------------------------------------------------------------*/
8661
8662   QUnit.module('lodash.invoke');
8663
8664   (function() {
8665     QUnit.test('should invoke a method on `object`', function(assert) {
8666       assert.expect(1);
8667
8668       var object = { 'a': lodashStable.constant('A') },
8669           actual = _.invoke(object, 'a');
8670
8671       assert.strictEqual(actual, 'A');
8672     });
8673
8674     QUnit.test('should support invoking with arguments', function(assert) {
8675       assert.expect(1);
8676
8677       var object = { 'a': function(a, b) { return [a, b]; } },
8678           actual = _.invoke(object, 'a', 1, 2);
8679
8680       assert.deepEqual(actual, [1, 2]);
8681     });
8682
8683     QUnit.test('should not error on nullish elements', function(assert) {
8684       assert.expect(1);
8685
8686       var values = [null, undefined],
8687           expected = lodashStable.map(values, noop);
8688
8689       var actual = lodashStable.map(values, function(value) {
8690         try {
8691           return _.invoke(value, 'a.b', 1, 2);
8692         } catch (e) {}
8693       });
8694
8695       assert.deepEqual(actual, expected);
8696     });
8697
8698     QUnit.test('should preserve the sign of `0`', function(assert) {
8699       assert.expect(1);
8700
8701       var object = { '-0': stubA, '0': stubB },
8702           props = [-0, Object(-0), 0, Object(0)];
8703
8704       var actual = lodashStable.map(props, function(key) {
8705         return _.invoke(object, key);
8706       });
8707
8708       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
8709     });
8710
8711     QUnit.test('should support deep paths', function(assert) {
8712       assert.expect(2);
8713
8714       var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
8715
8716       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8717         var actual = _.invoke(object, path, 1, 2);
8718         assert.deepEqual(actual, [1, 2]);
8719       });
8720     });
8721
8722     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8723       assert.expect(2);
8724
8725       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8726
8727       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8728         assert.deepEqual(_.invoke(object, path), 1);
8729       });
8730     });
8731
8732     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8733       assert.expect(1);
8734
8735       if (!isNpm) {
8736         var object = { 'a': stubOne };
8737         assert.strictEqual(_(object).invoke('a'), 1);
8738       }
8739       else {
8740         skipAssert(assert);
8741       }
8742     });
8743
8744     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8745       assert.expect(1);
8746
8747       if (!isNpm) {
8748         var object = { 'a': stubOne };
8749         assert.ok(_(object).chain().invoke('a') instanceof _);
8750       }
8751       else {
8752         skipAssert(assert);
8753       }
8754     });
8755   }());
8756
8757   /*--------------------------------------------------------------------------*/
8758
8759   QUnit.module('lodash.invokeMap');
8760
8761   (function() {
8762     QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
8763       assert.expect(1);
8764
8765       var array = ['a', 'b', 'c'],
8766           actual = _.invokeMap(array, 'toUpperCase');
8767
8768       assert.deepEqual(actual, ['A', 'B', 'C']);
8769     });
8770
8771     QUnit.test('should support invoking with arguments', function(assert) {
8772       assert.expect(1);
8773
8774       var array = [function() { return slice.call(arguments); }],
8775           actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
8776
8777       assert.deepEqual(actual, [['a', 'b', 'c']]);
8778     });
8779
8780     QUnit.test('should work with a function for `methodName`', function(assert) {
8781       assert.expect(1);
8782
8783       var array = ['a', 'b', 'c'];
8784
8785       var actual = _.invokeMap(array, function(left, right) {
8786         return left + this.toUpperCase() + right;
8787       }, '(', ')');
8788
8789       assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
8790     });
8791
8792     QUnit.test('should work with an object for `collection`', function(assert) {
8793       assert.expect(1);
8794
8795       var object = { 'a': 1, 'b': 2, 'c': 3 },
8796           actual = _.invokeMap(object, 'toFixed', 1);
8797
8798       assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
8799     });
8800
8801     QUnit.test('should treat number values for `collection` as empty', function(assert) {
8802       assert.expect(1);
8803
8804       assert.deepEqual(_.invokeMap(1), []);
8805     });
8806
8807     QUnit.test('should not error on nullish elements', function(assert) {
8808       assert.expect(1);
8809
8810       var array = ['a', null, undefined, 'd'];
8811
8812       try {
8813         var actual = _.invokeMap(array, 'toUpperCase');
8814       } catch (e) {}
8815
8816       assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
8817     });
8818
8819     QUnit.test('should not error on elements with missing properties', function(assert) {
8820       assert.expect(1);
8821
8822       var objects = lodashStable.map([null, undefined, stubOne], function(value) {
8823         return { 'a': value };
8824       });
8825
8826       var expected = lodashStable.map(objects, function(object) {
8827         return object.a ? object.a() : undefined;
8828       });
8829
8830       try {
8831         var actual = _.invokeMap(objects, 'a');
8832       } catch (e) {}
8833
8834       assert.deepEqual(actual, expected);
8835     });
8836
8837     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8838       assert.expect(2);
8839
8840       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8841
8842       lodashStable.each(['a.b', ['a', 'b']], function(path) {
8843         assert.deepEqual(_.invokeMap([object], path), [1]);
8844       });
8845     });
8846
8847     QUnit.test('should return a wrapped value when chaining', function(assert) {
8848       assert.expect(4);
8849
8850       if (!isNpm) {
8851         var array = ['a', 'b', 'c'],
8852             wrapped = _(array),
8853             actual = wrapped.invokeMap('toUpperCase');
8854
8855         assert.ok(actual instanceof _);
8856         assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8857
8858         actual = wrapped.invokeMap(function(left, right) {
8859           return left + this.toUpperCase() + right;
8860         }, '(', ')');
8861
8862         assert.ok(actual instanceof _);
8863         assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8864       }
8865       else {
8866         skipAssert(assert, 4);
8867       }
8868     });
8869
8870     QUnit.test('should support shortcut fusion', function(assert) {
8871       assert.expect(2);
8872
8873       if (!isNpm) {
8874         var count = 0,
8875             method = function() { count++; return this.index; };
8876
8877         var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8878           return { 'index': index, 'method': method };
8879         });
8880
8881         var actual = _(array).invokeMap('method').take(1).value();
8882
8883         assert.strictEqual(count, 1);
8884         assert.deepEqual(actual, [0]);
8885       }
8886       else {
8887         skipAssert(assert, 2);
8888       }
8889     });
8890   }());
8891
8892   /*--------------------------------------------------------------------------*/
8893
8894   QUnit.module('lodash.isArguments');
8895
8896   (function() {
8897     QUnit.test('should return `true` for `arguments` objects', function(assert) {
8898       assert.expect(2);
8899
8900       assert.strictEqual(_.isArguments(args), true);
8901       assert.strictEqual(_.isArguments(strictArgs), true);
8902     });
8903
8904     QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8905       assert.expect(12);
8906
8907       var expected = lodashStable.map(falsey, stubFalse);
8908
8909       var actual = lodashStable.map(falsey, function(value, index) {
8910         return index ? _.isArguments(value) : _.isArguments();
8911       });
8912
8913       assert.deepEqual(actual, expected);
8914
8915       assert.strictEqual(_.isArguments([1, 2, 3]), false);
8916       assert.strictEqual(_.isArguments(true), false);
8917       assert.strictEqual(_.isArguments(new Date), false);
8918       assert.strictEqual(_.isArguments(new Error), false);
8919       assert.strictEqual(_.isArguments(_), false);
8920       assert.strictEqual(_.isArguments(slice), false);
8921       assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8922       assert.strictEqual(_.isArguments(1), false);
8923       assert.strictEqual(_.isArguments(/x/), false);
8924       assert.strictEqual(_.isArguments('a'), false);
8925       assert.strictEqual(_.isArguments(symbol), false);
8926     });
8927
8928     QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8929       assert.expect(1);
8930
8931       if (realm.arguments) {
8932         assert.strictEqual(_.isArguments(realm.arguments), true);
8933       }
8934       else {
8935         skipAssert(assert);
8936       }
8937     });
8938   }());
8939
8940   /*--------------------------------------------------------------------------*/
8941
8942   QUnit.module('lodash.isArray');
8943
8944   (function() {
8945     QUnit.test('should return `true` for arrays', function(assert) {
8946       assert.expect(1);
8947
8948       assert.strictEqual(_.isArray([1, 2, 3]), true);
8949     });
8950
8951     QUnit.test('should return `false` for non-arrays', function(assert) {
8952       assert.expect(12);
8953
8954       var expected = lodashStable.map(falsey, stubFalse);
8955
8956       var actual = lodashStable.map(falsey, function(value, index) {
8957         return index ? _.isArray(value) : _.isArray();
8958       });
8959
8960       assert.deepEqual(actual, expected);
8961
8962       assert.strictEqual(_.isArray(args), false);
8963       assert.strictEqual(_.isArray(true), false);
8964       assert.strictEqual(_.isArray(new Date), false);
8965       assert.strictEqual(_.isArray(new Error), false);
8966       assert.strictEqual(_.isArray(_), false);
8967       assert.strictEqual(_.isArray(slice), false);
8968       assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
8969       assert.strictEqual(_.isArray(1), false);
8970       assert.strictEqual(_.isArray(/x/), false);
8971       assert.strictEqual(_.isArray('a'), false);
8972       assert.strictEqual(_.isArray(symbol), false);
8973     });
8974
8975     QUnit.test('should work with an array from another realm', function(assert) {
8976       assert.expect(1);
8977
8978       if (realm.array) {
8979         assert.strictEqual(_.isArray(realm.array), true);
8980       }
8981       else {
8982         skipAssert(assert);
8983       }
8984     });
8985   }());
8986
8987   /*--------------------------------------------------------------------------*/
8988
8989   QUnit.module('lodash.isArrayBuffer');
8990
8991   (function() {
8992     QUnit.test('should return `true` for array buffers', function(assert) {
8993       assert.expect(1);
8994
8995       if (ArrayBuffer) {
8996         assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
8997       }
8998       else {
8999         skipAssert(assert);
9000       }
9001     });
9002
9003     QUnit.test('should return `false` for non array buffers', function(assert) {
9004       assert.expect(13);
9005
9006       var expected = lodashStable.map(falsey, stubFalse);
9007
9008       var actual = lodashStable.map(falsey, function(value, index) {
9009         return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
9010       });
9011
9012       assert.deepEqual(actual, expected);
9013
9014       assert.strictEqual(_.isArrayBuffer(args), false);
9015       assert.strictEqual(_.isArrayBuffer([1]), false);
9016       assert.strictEqual(_.isArrayBuffer(true), false);
9017       assert.strictEqual(_.isArrayBuffer(new Date), false);
9018       assert.strictEqual(_.isArrayBuffer(new Error), false);
9019       assert.strictEqual(_.isArrayBuffer(_), false);
9020       assert.strictEqual(_.isArrayBuffer(slice), false);
9021       assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
9022       assert.strictEqual(_.isArrayBuffer(1), false);
9023       assert.strictEqual(_.isArrayBuffer(/x/), false);
9024       assert.strictEqual(_.isArrayBuffer('a'), false);
9025       assert.strictEqual(_.isArrayBuffer(symbol), false);
9026     });
9027
9028     QUnit.test('should work with array buffers from another realm', function(assert) {
9029       assert.expect(1);
9030
9031       if (realm.arrayBuffer) {
9032         assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
9033       }
9034       else {
9035         skipAssert(assert);
9036       }
9037     });
9038   }());
9039
9040   /*--------------------------------------------------------------------------*/
9041
9042   QUnit.module('lodash.isArrayLike');
9043
9044   (function() {
9045     QUnit.test('should return `true` for array-like values', function(assert) {
9046       assert.expect(1);
9047
9048       var values = [args, [1, 2, 3], { '0': 'a', 'length': 1 }, 'a'],
9049           expected = lodashStable.map(values, stubTrue),
9050           actual = lodashStable.map(values, _.isArrayLike);
9051
9052       assert.deepEqual(actual, expected);
9053     });
9054
9055     QUnit.test('should return `false` for non-arrays', function(assert) {
9056       assert.expect(12);
9057
9058       var expected = lodashStable.map(falsey, function(value) {
9059         return value === '';
9060       });
9061
9062       var actual = lodashStable.map(falsey, function(value, index) {
9063         return index ? _.isArrayLike(value) : _.isArrayLike();
9064       });
9065
9066       assert.deepEqual(actual, expected);
9067
9068       assert.strictEqual(_.isArrayLike(true), false);
9069       assert.strictEqual(_.isArrayLike(new Date), false);
9070       assert.strictEqual(_.isArrayLike(new Error), false);
9071       assert.strictEqual(_.isArrayLike(_), false);
9072       assert.strictEqual(_.isArrayLike(asyncFunc), false);
9073       assert.strictEqual(_.isArrayLike(genFunc), false);
9074       assert.strictEqual(_.isArrayLike(slice), false);
9075       assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
9076       assert.strictEqual(_.isArrayLike(1), false);
9077       assert.strictEqual(_.isArrayLike(/x/), false);
9078       assert.strictEqual(_.isArrayLike(symbol), false);
9079     });
9080
9081     QUnit.test('should work with an array from another realm', function(assert) {
9082       assert.expect(1);
9083
9084       if (realm.object) {
9085         var values = [realm.arguments, realm.array, realm.string],
9086             expected = lodashStable.map(values, stubTrue),
9087             actual = lodashStable.map(values, _.isArrayLike);
9088
9089         assert.deepEqual(actual, expected);
9090       }
9091       else {
9092         skipAssert(assert);
9093       }
9094     });
9095   }());
9096
9097   /*--------------------------------------------------------------------------*/
9098
9099   QUnit.module('lodash.isBoolean');
9100
9101   (function() {
9102     QUnit.test('should return `true` for booleans', function(assert) {
9103       assert.expect(4);
9104
9105       assert.strictEqual(_.isBoolean(true), true);
9106       assert.strictEqual(_.isBoolean(false), true);
9107       assert.strictEqual(_.isBoolean(Object(true)), true);
9108       assert.strictEqual(_.isBoolean(Object(false)), true);
9109     });
9110
9111     QUnit.test('should return `false` for non-booleans', function(assert) {
9112       assert.expect(12);
9113
9114       var expected = lodashStable.map(falsey, function(value) {
9115         return value === false;
9116       });
9117
9118       var actual = lodashStable.map(falsey, function(value, index) {
9119         return index ? _.isBoolean(value) : _.isBoolean();
9120       });
9121
9122       assert.deepEqual(actual, expected);
9123
9124       assert.strictEqual(_.isBoolean(args), false);
9125       assert.strictEqual(_.isBoolean([1, 2, 3]), false);
9126       assert.strictEqual(_.isBoolean(new Date), false);
9127       assert.strictEqual(_.isBoolean(new Error), false);
9128       assert.strictEqual(_.isBoolean(_), false);
9129       assert.strictEqual(_.isBoolean(slice), false);
9130       assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
9131       assert.strictEqual(_.isBoolean(1), false);
9132       assert.strictEqual(_.isBoolean(/x/), false);
9133       assert.strictEqual(_.isBoolean('a'), false);
9134       assert.strictEqual(_.isBoolean(symbol), false);
9135     });
9136
9137     QUnit.test('should work with a boolean from another realm', function(assert) {
9138       assert.expect(1);
9139
9140       if (realm.boolean) {
9141         assert.strictEqual(_.isBoolean(realm.boolean), true);
9142       }
9143       else {
9144         skipAssert(assert);
9145       }
9146     });
9147   }());
9148
9149   /*--------------------------------------------------------------------------*/
9150
9151   QUnit.module('lodash.isBuffer');
9152
9153   (function() {
9154     QUnit.test('should return `true` for buffers', function(assert) {
9155       assert.expect(1);
9156
9157       if (Buffer) {
9158         assert.strictEqual(_.isBuffer(new Buffer(2)), true);
9159       }
9160       else {
9161         skipAssert(assert);
9162       }
9163     });
9164
9165     QUnit.test('should return `false` for non-buffers', function(assert) {
9166       assert.expect(13);
9167
9168       var expected = lodashStable.map(falsey, stubFalse);
9169
9170       var actual = lodashStable.map(falsey, function(value, index) {
9171         return index ? _.isBuffer(value) : _.isBuffer();
9172       });
9173
9174       assert.deepEqual(actual, expected);
9175
9176       assert.strictEqual(_.isBuffer(args), false);
9177       assert.strictEqual(_.isBuffer([1]), false);
9178       assert.strictEqual(_.isBuffer(true), false);
9179       assert.strictEqual(_.isBuffer(new Date), false);
9180       assert.strictEqual(_.isBuffer(new Error), false);
9181       assert.strictEqual(_.isBuffer(_), false);
9182       assert.strictEqual(_.isBuffer(slice), false);
9183       assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
9184       assert.strictEqual(_.isBuffer(1), false);
9185       assert.strictEqual(_.isBuffer(/x/), false);
9186       assert.strictEqual(_.isBuffer('a'), false);
9187       assert.strictEqual(_.isBuffer(symbol), false);
9188     });
9189
9190     QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
9191       assert.expect(1);
9192
9193       if (!isStrict && Buffer && lodashBizarro) {
9194         assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
9195       }
9196       else {
9197         skipAssert(assert);
9198       }
9199     });
9200   }());
9201
9202   /*--------------------------------------------------------------------------*/
9203
9204   QUnit.module('lodash.isDate');
9205
9206   (function() {
9207     QUnit.test('should return `true` for dates', function(assert) {
9208       assert.expect(1);
9209
9210       assert.strictEqual(_.isDate(new Date), true);
9211     });
9212
9213     QUnit.test('should return `false` for non-dates', function(assert) {
9214       assert.expect(12);
9215
9216       var expected = lodashStable.map(falsey, stubFalse);
9217
9218       var actual = lodashStable.map(falsey, function(value, index) {
9219         return index ? _.isDate(value) : _.isDate();
9220       });
9221
9222       assert.deepEqual(actual, expected);
9223
9224       assert.strictEqual(_.isDate(args), false);
9225       assert.strictEqual(_.isDate([1, 2, 3]), false);
9226       assert.strictEqual(_.isDate(true), false);
9227       assert.strictEqual(_.isDate(new Error), false);
9228       assert.strictEqual(_.isDate(_), false);
9229       assert.strictEqual(_.isDate(slice), false);
9230       assert.strictEqual(_.isDate({ 'a': 1 }), false);
9231       assert.strictEqual(_.isDate(1), false);
9232       assert.strictEqual(_.isDate(/x/), false);
9233       assert.strictEqual(_.isDate('a'), false);
9234       assert.strictEqual(_.isDate(symbol), false);
9235     });
9236
9237     QUnit.test('should work with a date object from another realm', function(assert) {
9238       assert.expect(1);
9239
9240       if (realm.date) {
9241         assert.strictEqual(_.isDate(realm.date), true);
9242       }
9243       else {
9244         skipAssert(assert);
9245       }
9246     });
9247   }());
9248
9249   /*--------------------------------------------------------------------------*/
9250
9251   QUnit.module('lodash.isElement');
9252
9253   (function() {
9254     QUnit.test('should return `true` for elements', function(assert) {
9255       assert.expect(1);
9256
9257       if (document) {
9258         assert.strictEqual(_.isElement(body), true);
9259       }
9260       else {
9261         skipAssert(assert);
9262       }
9263     });
9264
9265     QUnit.test('should return `true` for non-plain objects', function(assert) {
9266       assert.expect(1);
9267
9268       function Foo() {
9269         this.nodeType = 1;
9270       }
9271
9272       assert.strictEqual(_.isElement(new Foo), true);
9273     });
9274
9275     QUnit.test('should return `false` for non DOM elements', function(assert) {
9276       assert.expect(13);
9277
9278       var expected = lodashStable.map(falsey, stubFalse);
9279
9280       var actual = lodashStable.map(falsey, function(value, index) {
9281         return index ? _.isElement(value) : _.isElement();
9282       });
9283
9284       assert.deepEqual(actual, expected);
9285
9286       assert.strictEqual(_.isElement(args), false);
9287       assert.strictEqual(_.isElement([1, 2, 3]), false);
9288       assert.strictEqual(_.isElement(true), false);
9289       assert.strictEqual(_.isElement(new Date), false);
9290       assert.strictEqual(_.isElement(new Error), false);
9291       assert.strictEqual(_.isElement(_), false);
9292       assert.strictEqual(_.isElement(slice), false);
9293       assert.strictEqual(_.isElement({ 'a': 1 }), false);
9294       assert.strictEqual(_.isElement(1), false);
9295       assert.strictEqual(_.isElement(/x/), false);
9296       assert.strictEqual(_.isElement('a'), false);
9297       assert.strictEqual(_.isElement(symbol), false);
9298     });
9299
9300     QUnit.test('should return `false` for plain objects', function(assert) {
9301       assert.expect(6);
9302
9303       assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
9304       assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
9305       assert.strictEqual(_.isElement({ 'nodeType': true }), false);
9306       assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
9307       assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
9308       assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
9309     });
9310
9311     QUnit.test('should work with a DOM element from another realm', function(assert) {
9312       assert.expect(1);
9313
9314       if (realm.element) {
9315         assert.strictEqual(_.isElement(realm.element), true);
9316       }
9317       else {
9318         skipAssert(assert);
9319       }
9320     });
9321   }());
9322
9323   /*--------------------------------------------------------------------------*/
9324
9325   QUnit.module('lodash.isEmpty');
9326
9327   (function() {
9328     QUnit.test('should return `true` for empty values', function(assert) {
9329       assert.expect(10);
9330
9331       var expected = lodashStable.map(empties, stubTrue),
9332           actual = lodashStable.map(empties, _.isEmpty);
9333
9334       assert.deepEqual(actual, expected);
9335
9336       assert.strictEqual(_.isEmpty(true), true);
9337       assert.strictEqual(_.isEmpty(slice), true);
9338       assert.strictEqual(_.isEmpty(1), true);
9339       assert.strictEqual(_.isEmpty(NaN), true);
9340       assert.strictEqual(_.isEmpty(/x/), true);
9341       assert.strictEqual(_.isEmpty(symbol), true);
9342       assert.strictEqual(_.isEmpty(), true);
9343
9344       if (Buffer) {
9345         assert.strictEqual(_.isEmpty(new Buffer(0)), true);
9346         assert.strictEqual(_.isEmpty(new Buffer(1)), false);
9347       }
9348       else {
9349         skipAssert(assert, 2);
9350       }
9351     });
9352
9353     QUnit.test('should return `false` for non-empty values', function(assert) {
9354       assert.expect(3);
9355
9356       assert.strictEqual(_.isEmpty([0]), false);
9357       assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
9358       assert.strictEqual(_.isEmpty('a'), false);
9359     });
9360
9361     QUnit.test('should work with an object that has a `length` property', function(assert) {
9362       assert.expect(1);
9363
9364       assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
9365     });
9366
9367     QUnit.test('should work with `arguments` objects', function(assert) {
9368       assert.expect(1);
9369
9370       assert.strictEqual(_.isEmpty(args), false);
9371     });
9372
9373     QUnit.test('should work with prototytpe objects', function(assert) {
9374       assert.expect(2);
9375
9376       function Foo() {}
9377       Foo.prototype = { 'constructor': Foo };
9378
9379       assert.strictEqual(_.isEmpty(Foo.prototype), true);
9380
9381       Foo.prototype.a = 1;
9382       assert.strictEqual(_.isEmpty(Foo.prototype), false);
9383     });
9384
9385     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
9386       assert.expect(1);
9387
9388       function Foo(elements) {
9389         push.apply(this, elements);
9390       }
9391       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
9392
9393       assert.strictEqual(_.isEmpty(new Foo([])), true);
9394     });
9395
9396     QUnit.test('should work with maps', function(assert) {
9397       assert.expect(4);
9398
9399       if (Map) {
9400         lodashStable.each([new Map, realm.map], function(map) {
9401           assert.strictEqual(_.isEmpty(map), true);
9402           map.set('a', 1);
9403           assert.strictEqual(_.isEmpty(map), false);
9404           map.clear();
9405         });
9406       }
9407       else {
9408         skipAssert(assert, 4);
9409       }
9410     });
9411
9412     QUnit.test('should work with sets', function(assert) {
9413       assert.expect(4);
9414
9415       if (Set) {
9416         lodashStable.each([new Set, realm.set], function(set) {
9417           assert.strictEqual(_.isEmpty(set), true);
9418           set.add(1);
9419           assert.strictEqual(_.isEmpty(set), false);
9420           set.clear();
9421         });
9422       }
9423       else {
9424         skipAssert(assert, 4);
9425       }
9426     });
9427
9428     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
9429       assert.expect(1);
9430
9431       function Foo() {}
9432       Foo.prototype.length = -1;
9433
9434       assert.strictEqual(_.isEmpty(new Foo), true);
9435     });
9436
9437     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
9438       assert.expect(1);
9439
9440       function Foo() {}
9441       Foo.prototype.length = MAX_SAFE_INTEGER + 1;
9442
9443       assert.strictEqual(_.isEmpty(new Foo), true);
9444     });
9445
9446     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
9447       assert.expect(1);
9448
9449       assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
9450     });
9451
9452     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9453       assert.expect(1);
9454
9455       if (!isNpm) {
9456         assert.strictEqual(_({}).isEmpty(), true);
9457       }
9458       else {
9459         skipAssert(assert);
9460       }
9461     });
9462
9463     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9464       assert.expect(1);
9465
9466       if (!isNpm) {
9467         assert.ok(_({}).chain().isEmpty() instanceof _);
9468       }
9469       else {
9470         skipAssert(assert);
9471       }
9472     });
9473   }());
9474
9475   /*--------------------------------------------------------------------------*/
9476
9477   QUnit.module('lodash.isEqual');
9478
9479   (function() {
9480     var symbol1 = Symbol ? Symbol('a') : true,
9481         symbol2 = Symbol ? Symbol('b') : false;
9482
9483     QUnit.test('should compare primitives', function(assert) {
9484       assert.expect(1);
9485
9486       var pairs = [
9487         [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
9488         [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
9489         [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
9490         ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
9491         [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
9492         [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
9493         [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
9494         [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
9495         [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
9496       ];
9497
9498       var expected = lodashStable.map(pairs, function(pair) {
9499         return pair[2];
9500       });
9501
9502       var actual = lodashStable.map(pairs, function(pair) {
9503         return _.isEqual(pair[0], pair[1]);
9504       });
9505
9506       assert.deepEqual(actual, expected);
9507     });
9508
9509     QUnit.test('should compare arrays', function(assert) {
9510       assert.expect(6);
9511
9512       var array1 = [true, null, 1, 'a', undefined],
9513           array2 = [true, null, 1, 'a', undefined];
9514
9515       assert.strictEqual(_.isEqual(array1, array2), true);
9516
9517       array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9518       array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9519
9520       assert.strictEqual(_.isEqual(array1, array2), true);
9521
9522       array1 = [1];
9523       array1[2] = 3;
9524
9525       array2 = [1];
9526       array2[1] = undefined;
9527       array2[2] = 3;
9528
9529       assert.strictEqual(_.isEqual(array1, array2), true);
9530
9531       array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
9532       array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
9533
9534       assert.strictEqual(_.isEqual(array1, array2), true);
9535
9536       array1 = [1, 2, 3];
9537       array2 = [3, 2, 1];
9538
9539       assert.strictEqual(_.isEqual(array1, array2), false);
9540
9541       array1 = [1, 2];
9542       array2 = [1, 2, 3];
9543
9544       assert.strictEqual(_.isEqual(array1, array2), false);
9545     });
9546
9547     QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
9548       assert.expect(3);
9549
9550       var array1 = [1, 2, 3],
9551           array2 = [1, 2, 3];
9552
9553       array1.every = array1.filter = array1.forEach =
9554       array1.indexOf = array1.lastIndexOf = array1.map =
9555       array1.some = array1.reduce = array1.reduceRight = null;
9556
9557       array2.concat = array2.join = array2.pop =
9558       array2.reverse = array2.shift = array2.slice =
9559       array2.sort = array2.splice = array2.unshift = null;
9560
9561       assert.strictEqual(_.isEqual(array1, array2), true);
9562
9563       array1 = [1, 2, 3];
9564       array1.a = 1;
9565
9566       array2 = [1, 2, 3];
9567       array2.b = 1;
9568
9569       assert.strictEqual(_.isEqual(array1, array2), true);
9570
9571       array1 = /c/.exec('abcde');
9572       array2 = ['c'];
9573
9574       assert.strictEqual(_.isEqual(array1, array2), true);
9575     });
9576
9577     QUnit.test('should compare sparse arrays', function(assert) {
9578       assert.expect(3);
9579
9580       var array = Array(1);
9581
9582       assert.strictEqual(_.isEqual(array, Array(1)), true);
9583       assert.strictEqual(_.isEqual(array, [undefined]), true);
9584       assert.strictEqual(_.isEqual(array, Array(2)), false);
9585     });
9586
9587     QUnit.test('should compare plain objects', function(assert) {
9588       assert.expect(5);
9589
9590       var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
9591           object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
9592
9593       assert.strictEqual(_.isEqual(object1, object2), true);
9594
9595       object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9596       object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9597
9598       assert.strictEqual(_.isEqual(object1, object2), true);
9599
9600       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9601       object2 = { 'a': 3, 'b': 2, 'c': 1 };
9602
9603       assert.strictEqual(_.isEqual(object1, object2), false);
9604
9605       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9606       object2 = { 'd': 1, 'e': 2, 'f': 3 };
9607
9608       assert.strictEqual(_.isEqual(object1, object2), false);
9609
9610       object1 = { 'a': 1, 'b': 2 };
9611       object2 = { 'a': 1, 'b': 2, 'c': 3 };
9612
9613       assert.strictEqual(_.isEqual(object1, object2), false);
9614     });
9615
9616     QUnit.test('should compare objects regardless of key order', function(assert) {
9617       assert.expect(1);
9618
9619       var object1 = { 'a': 1, 'b': 2, 'c': 3 },
9620           object2 = { 'c': 3, 'a': 1, 'b': 2 };
9621
9622       assert.strictEqual(_.isEqual(object1, object2), true);
9623     });
9624
9625     QUnit.test('should compare nested objects', function(assert) {
9626       assert.expect(1);
9627
9628       var object1 = {
9629         'a': [1, 2, 3],
9630         'b': true,
9631         'c': Object(1),
9632         'd': 'a',
9633         'e': {
9634           'f': ['a', Object('b'), 'c'],
9635           'g': Object(false),
9636           'h': new Date(2012, 4, 23),
9637           'i': noop,
9638           'j': 'a'
9639         }
9640       };
9641
9642       var object2 = {
9643         'a': [1, Object(2), 3],
9644         'b': Object(true),
9645         'c': 1,
9646         'd': Object('a'),
9647         'e': {
9648           'f': ['a', 'b', 'c'],
9649           'g': false,
9650           'h': new Date(2012, 4, 23),
9651           'i': noop,
9652           'j': 'a'
9653         }
9654       };
9655
9656       assert.strictEqual(_.isEqual(object1, object2), true);
9657     });
9658
9659     QUnit.test('should compare object instances', function(assert) {
9660       assert.expect(4);
9661
9662       function Foo() {
9663         this.a = 1;
9664       }
9665       Foo.prototype.a = 1;
9666
9667       function Bar() {
9668         this.a = 1;
9669       }
9670       Bar.prototype.a = 2;
9671
9672       assert.strictEqual(_.isEqual(new Foo, new Foo), true);
9673       assert.strictEqual(_.isEqual(new Foo, new Bar), false);
9674       assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
9675       assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
9676     });
9677
9678     QUnit.test('should compare objects with constructor properties', function(assert) {
9679       assert.expect(5);
9680
9681       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
9682       assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
9683       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
9684       assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
9685       assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
9686     });
9687
9688     QUnit.test('should compare arrays with circular references', function(assert) {
9689       assert.expect(4);
9690
9691       var array1 = [],
9692           array2 = [];
9693
9694       array1.push(array1);
9695       array2.push(array2);
9696
9697       assert.strictEqual(_.isEqual(array1, array2), true);
9698
9699       array1.push('b');
9700       array2.push('b');
9701
9702       assert.strictEqual(_.isEqual(array1, array2), true);
9703
9704       array1.push('c');
9705       array2.push('d');
9706
9707       assert.strictEqual(_.isEqual(array1, array2), false);
9708
9709       array1 = ['a', 'b', 'c'];
9710       array1[1] = array1;
9711       array2 = ['a', ['a', 'b', 'c'], 'c'];
9712
9713       assert.strictEqual(_.isEqual(array1, array2), false);
9714     });
9715
9716     QUnit.test('should have transitive equivalence for circular references of arrays', function(assert) {
9717       assert.expect(3);
9718
9719       var array1 = [],
9720           array2 = [array1],
9721           array3 = [array2];
9722
9723       array1[0] = array1;
9724
9725       assert.strictEqual(_.isEqual(array1, array2), true);
9726       assert.strictEqual(_.isEqual(array2, array3), true);
9727       assert.strictEqual(_.isEqual(array1, array3), true);
9728     });
9729
9730     QUnit.test('should compare objects with circular references', function(assert) {
9731       assert.expect(4);
9732
9733       var object1 = {},
9734           object2 = {};
9735
9736       object1.a = object1;
9737       object2.a = object2;
9738
9739       assert.strictEqual(_.isEqual(object1, object2), true);
9740
9741       object1.b = 0;
9742       object2.b = Object(0);
9743
9744       assert.strictEqual(_.isEqual(object1, object2), true);
9745
9746       object1.c = Object(1);
9747       object2.c = Object(2);
9748
9749       assert.strictEqual(_.isEqual(object1, object2), false);
9750
9751       object1 = { 'a': 1, 'b': 2, 'c': 3 };
9752       object1.b = object1;
9753       object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
9754
9755       assert.strictEqual(_.isEqual(object1, object2), false);
9756     });
9757
9758     QUnit.test('should have transitive equivalence for circular references of objects', function(assert) {
9759       assert.expect(3);
9760
9761       var object1 = {},
9762           object2 = { 'a': object1 },
9763           object3 = { 'a': object2 };
9764
9765       object1.a = object1;
9766
9767       assert.strictEqual(_.isEqual(object1, object2), true);
9768       assert.strictEqual(_.isEqual(object2, object3), true);
9769       assert.strictEqual(_.isEqual(object1, object3), true);
9770     });
9771
9772     QUnit.test('should compare objects with multiple circular references', function(assert) {
9773       assert.expect(3);
9774
9775       var array1 = [{}],
9776           array2 = [{}];
9777
9778       (array1[0].a = array1).push(array1);
9779       (array2[0].a = array2).push(array2);
9780
9781       assert.strictEqual(_.isEqual(array1, array2), true);
9782
9783       array1[0].b = 0;
9784       array2[0].b = Object(0);
9785
9786       assert.strictEqual(_.isEqual(array1, array2), true);
9787
9788       array1[0].c = Object(1);
9789       array2[0].c = Object(2);
9790
9791       assert.strictEqual(_.isEqual(array1, array2), false);
9792     });
9793
9794     QUnit.test('should compare objects with complex circular references', function(assert) {
9795       assert.expect(1);
9796
9797       var object1 = {
9798         'foo': { 'b': { 'c': { 'd': {} } } },
9799         'bar': { 'a': 2 }
9800       };
9801
9802       var object2 = {
9803         'foo': { 'b': { 'c': { 'd': {} } } },
9804         'bar': { 'a': 2 }
9805       };
9806
9807       object1.foo.b.c.d = object1;
9808       object1.bar.b = object1.foo.b;
9809
9810       object2.foo.b.c.d = object2;
9811       object2.bar.b = object2.foo.b;
9812
9813       assert.strictEqual(_.isEqual(object1, object2), true);
9814     });
9815
9816     QUnit.test('should compare objects with shared property values', function(assert) {
9817       assert.expect(1);
9818
9819       var object1 = {
9820         'a': [1, 2]
9821       };
9822
9823       var object2 = {
9824         'a': [1, 2],
9825         'b': [1, 2]
9826       };
9827
9828       object1.b = object1.a;
9829
9830       assert.strictEqual(_.isEqual(object1, object2), true);
9831     });
9832
9833     QUnit.test('should treat objects created by `Object.create(null)` like plain objects', function(assert) {
9834       assert.expect(2);
9835
9836       function Foo() {
9837         this.a = 1;
9838       }
9839       Foo.prototype.constructor = null;
9840
9841       var object1 = create(null);
9842       object1.a = 1;
9843
9844       var object2 = { 'a': 1 };
9845
9846       assert.strictEqual(_.isEqual(object1, object2), true);
9847       assert.strictEqual(_.isEqual(new Foo, object2), false);
9848     });
9849
9850     QUnit.test('should avoid common type coercions', function(assert) {
9851       assert.expect(9);
9852
9853       assert.strictEqual(_.isEqual(true, Object(false)), false);
9854       assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
9855       assert.strictEqual(_.isEqual(false, Object('')), false);
9856       assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
9857       assert.strictEqual(_.isEqual(0, ''), false);
9858       assert.strictEqual(_.isEqual(1, true), false);
9859       assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
9860       assert.strictEqual(_.isEqual('36', 36), false);
9861       assert.strictEqual(_.isEqual(36, '36'), false);
9862     });
9863
9864     QUnit.test('should compare `arguments` objects', function(assert) {
9865       assert.expect(2);
9866
9867       var args1 = (function() { return arguments; }()),
9868           args2 = (function() { return arguments; }()),
9869           args3 = (function() { return arguments; }(1, 2));
9870
9871       assert.strictEqual(_.isEqual(args1, args2), true);
9872       assert.strictEqual(_.isEqual(args1, args3), false);
9873     });
9874
9875     QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
9876       assert.expect(4);
9877
9878       var object = { '0': 1, '1': 2, '2': 3 };
9879
9880       function Foo() {}
9881       Foo.prototype = object;
9882
9883       assert.strictEqual(_.isEqual(args, object), true);
9884       assert.strictEqual(_.isEqual(object, args), true);
9885       assert.strictEqual(_.isEqual(args, new Foo), false);
9886       assert.strictEqual(_.isEqual(new Foo, args), false);
9887     });
9888
9889     QUnit.test('should compare array buffers', function(assert) {
9890       assert.expect(2);
9891
9892       if (ArrayBuffer) {
9893         var buffer = new Int8Array([-1]).buffer;
9894
9895         assert.strictEqual(_.isEqual(buffer, new Uint8Array([255]).buffer), true);
9896         assert.strictEqual(_.isEqual(buffer, new ArrayBuffer(1)), false);
9897       }
9898       else {
9899         skipAssert(assert, 2);
9900       }
9901     });
9902
9903     QUnit.test('should compare array views', function(assert) {
9904       assert.expect(2);
9905
9906       lodashStable.times(2, function(index) {
9907         var ns = index ? realm : root;
9908
9909         var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
9910           var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
9911               CtorA = ns[type] || function(n) { this.n = n; },
9912               CtorB = ns[otherType] || function(n) { this.n = n; },
9913               bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
9914               bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
9915               bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
9916
9917           return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
9918         });
9919
9920         var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9921
9922         var actual = lodashStable.map(pairs, function(pair) {
9923           return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9924         });
9925
9926         assert.deepEqual(actual, expected);
9927       });
9928     });
9929
9930     QUnit.test('should compare buffers', function(assert) {
9931       assert.expect(3);
9932
9933       if (Buffer) {
9934         var buffer = new Buffer([1]);
9935
9936         assert.strictEqual(_.isEqual(buffer, new Buffer([1])), true);
9937         assert.strictEqual(_.isEqual(buffer, new Buffer([2])), false);
9938         assert.strictEqual(_.isEqual(buffer, new Uint8Array([1])), false);
9939       }
9940       else {
9941         skipAssert(assert, 3);
9942       }
9943     });
9944
9945     QUnit.test('should compare date objects', function(assert) {
9946       assert.expect(4);
9947
9948       var date = new Date(2012, 4, 23);
9949
9950       assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
9951       assert.strictEqual(_.isEqual(new Date('a'), new Date('b')), true);
9952       assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
9953       assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
9954     });
9955
9956     QUnit.test('should compare error objects', function(assert) {
9957       assert.expect(1);
9958
9959       var pairs = lodashStable.map([
9960         'Error',
9961         'EvalError',
9962         'RangeError',
9963         'ReferenceError',
9964         'SyntaxError',
9965         'TypeError',
9966         'URIError'
9967       ], function(type, index, errorTypes) {
9968         var otherType = errorTypes[++index % errorTypes.length],
9969             CtorA = root[type],
9970             CtorB = root[otherType];
9971
9972         return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
9973       });
9974
9975       var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9976
9977       var actual = lodashStable.map(pairs, function(pair) {
9978         return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9979       });
9980
9981       assert.deepEqual(actual, expected);
9982     });
9983
9984     QUnit.test('should compare functions', function(assert) {
9985       assert.expect(2);
9986
9987       function a() { return 1 + 2; }
9988       function b() { return 1 + 2; }
9989
9990       assert.strictEqual(_.isEqual(a, a), true);
9991       assert.strictEqual(_.isEqual(a, b), false);
9992     });
9993
9994     QUnit.test('should compare maps', function(assert) {
9995       assert.expect(8);
9996
9997       if (Map) {
9998         lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
9999           var map1 = maps[0],
10000               map2 = maps[1];
10001
10002           map1.set('a', 1);
10003           map2.set('b', 2);
10004           assert.strictEqual(_.isEqual(map1, map2), false);
10005
10006           map1.set('b', 2);
10007           map2.set('a', 1);
10008           assert.strictEqual(_.isEqual(map1, map2), true);
10009
10010           map1.delete('a');
10011           map1.set('a', 1);
10012           assert.strictEqual(_.isEqual(map1, map2), true);
10013
10014           map2.delete('a');
10015           assert.strictEqual(_.isEqual(map1, map2), false);
10016
10017           map1.clear();
10018           map2.clear();
10019         });
10020       }
10021       else {
10022         skipAssert(assert, 8);
10023       }
10024     });
10025
10026     QUnit.test('should compare maps with circular references', function(assert) {
10027       assert.expect(2);
10028
10029       if (Map) {
10030         var map1 = new Map,
10031             map2 = new Map;
10032
10033         map1.set('a', map1);
10034         map2.set('a', map2);
10035         assert.strictEqual(_.isEqual(map1, map2), true);
10036
10037         map1.set('b', 1);
10038         map2.set('b', 2);
10039         assert.strictEqual(_.isEqual(map1, map2), false);
10040       }
10041       else {
10042         skipAssert(assert, 2);
10043       }
10044     });
10045
10046     QUnit.test('should compare promises by reference', function(assert) {
10047       assert.expect(4);
10048
10049       if (promise) {
10050         lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
10051           var promise1 = promises[0],
10052               promise2 = promises[1];
10053
10054           assert.strictEqual(_.isEqual(promise1, promise2), false);
10055           assert.strictEqual(_.isEqual(promise1, promise1), true);
10056         });
10057       }
10058       else {
10059         skipAssert(assert, 4);
10060       }
10061     });
10062
10063     QUnit.test('should compare regexes', function(assert) {
10064       assert.expect(5);
10065
10066       assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
10067       assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
10068       assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
10069       assert.strictEqual(_.isEqual(/x/, /y/), false);
10070       assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
10071     });
10072
10073     QUnit.test('should compare sets', function(assert) {
10074       assert.expect(8);
10075
10076       if (Set) {
10077         lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
10078           var set1 = sets[0],
10079               set2 = sets[1];
10080
10081           set1.add(1);
10082           set2.add(2);
10083           assert.strictEqual(_.isEqual(set1, set2), false);
10084
10085           set1.add(2);
10086           set2.add(1);
10087           assert.strictEqual(_.isEqual(set1, set2), true);
10088
10089           set1.delete(1);
10090           set1.add(1);
10091           assert.strictEqual(_.isEqual(set1, set2), true);
10092
10093           set2.delete(1);
10094           assert.strictEqual(_.isEqual(set1, set2), false);
10095
10096           set1.clear();
10097           set2.clear();
10098         });
10099       }
10100       else {
10101         skipAssert(assert, 8);
10102       }
10103     });
10104
10105     QUnit.test('should compare sets with circular references', function(assert) {
10106       assert.expect(2);
10107
10108       if (Set) {
10109         var set1 = new Set,
10110             set2 = new Set;
10111
10112         set1.add(set1);
10113         set2.add(set2);
10114         assert.strictEqual(_.isEqual(set1, set2), true);
10115
10116         set1.add(1);
10117         set2.add(2);
10118         assert.strictEqual(_.isEqual(set1, set2), false);
10119       }
10120       else {
10121         skipAssert(assert, 2);
10122       }
10123     });
10124
10125     QUnit.test('should compare symbol properties', function(assert) {
10126       assert.expect(3);
10127
10128       if (Symbol) {
10129         var object1 = { 'a': 1 },
10130             object2 = { 'a': 1 };
10131
10132         object1[symbol1] = { 'a': { 'b': 2 } };
10133         object2[symbol1] = { 'a': { 'b': 2 } };
10134
10135         defineProperty(object2, symbol2, {
10136           'configurable': true,
10137           'enumerable': false,
10138           'writable': true,
10139           'value': 2
10140         });
10141
10142         assert.strictEqual(_.isEqual(object1, object2), true);
10143
10144         object2[symbol1] = { 'a': 1 };
10145         assert.strictEqual(_.isEqual(object1, object2), false);
10146
10147         delete object2[symbol1];
10148         object2[Symbol('a')] = { 'a': { 'b': 2 } };
10149         assert.strictEqual(_.isEqual(object1, object2), false);
10150       }
10151       else {
10152         skipAssert(assert, 3);
10153       }
10154     });
10155
10156     QUnit.test('should compare wrapped values', function(assert) {
10157       assert.expect(32);
10158
10159       var stamp = +new Date;
10160
10161       var values = [
10162         [[1, 2], [1, 2], [1, 2, 3]],
10163         [true, true, false],
10164         [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
10165         [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
10166         [1, 1, 2],
10167         [NaN, NaN, Infinity],
10168         [/x/, /x/, /x/i],
10169         ['a', 'a', 'A']
10170       ];
10171
10172       lodashStable.each(values, function(vals) {
10173         if (!isNpm) {
10174           var wrapped1 = _(vals[0]),
10175               wrapped2 = _(vals[1]),
10176               actual = wrapped1.isEqual(wrapped2);
10177
10178           assert.strictEqual(actual, true);
10179           assert.strictEqual(_.isEqual(_(actual), _(true)), true);
10180
10181           wrapped1 = _(vals[0]);
10182           wrapped2 = _(vals[2]);
10183
10184           actual = wrapped1.isEqual(wrapped2);
10185           assert.strictEqual(actual, false);
10186           assert.strictEqual(_.isEqual(_(actual), _(false)), true);
10187         }
10188         else {
10189           skipAssert(assert, 4);
10190         }
10191       });
10192     });
10193
10194     QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
10195       assert.expect(4);
10196
10197       if (!isNpm) {
10198         var object1 = _({ 'a': 1, 'b': 2 }),
10199             object2 = { 'a': 1, 'b': 2 };
10200
10201         assert.strictEqual(object1.isEqual(object2), true);
10202         assert.strictEqual(_.isEqual(object1, object2), true);
10203
10204         object1 = _({ 'a': 1, 'b': 2 });
10205         object2 = { 'a': 1, 'b': 1 };
10206
10207         assert.strictEqual(object1.isEqual(object2), false);
10208         assert.strictEqual(_.isEqual(object1, object2), false);
10209       }
10210       else {
10211         skipAssert(assert, 4);
10212       }
10213     });
10214
10215     QUnit.test('should work as an iteratee for `_.every`', function(assert) {
10216       assert.expect(1);
10217
10218       var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
10219       assert.ok(actual);
10220     });
10221
10222     QUnit.test('should not error on DOM elements', function(assert) {
10223       assert.expect(1);
10224
10225       if (document) {
10226         var element1 = document.createElement('div'),
10227             element2 = element1.cloneNode(true);
10228
10229         try {
10230           assert.strictEqual(_.isEqual(element1, element2), false);
10231         } catch (e) {
10232           assert.ok(false, e.message);
10233         }
10234       }
10235       else {
10236         skipAssert(assert);
10237       }
10238     });
10239
10240     QUnit.test('should return `true` for like-objects from different documents', function(assert) {
10241       assert.expect(4);
10242
10243       if (realm.object) {
10244         assert.strictEqual(_.isEqual([1], realm.array), true);
10245         assert.strictEqual(_.isEqual([2], realm.array), false);
10246         assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
10247         assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
10248       }
10249       else {
10250         skipAssert(assert, 4);
10251       }
10252     });
10253
10254     QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
10255       assert.expect(1);
10256
10257       var primitive,
10258           object = { 'toString': function() { return primitive; } },
10259           values = [true, null, 1, 'a', undefined],
10260           expected = lodashStable.map(values, stubFalse);
10261
10262       var actual = lodashStable.map(values, function(value) {
10263         primitive = value;
10264         return _.isEqual(object, value);
10265       });
10266
10267       assert.deepEqual(actual, expected);
10268     });
10269
10270     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
10271       assert.expect(1);
10272
10273       if (!isNpm) {
10274         assert.strictEqual(_('a').isEqual('a'), true);
10275       }
10276       else {
10277         skipAssert(assert);
10278       }
10279     });
10280
10281     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
10282       assert.expect(1);
10283
10284       if (!isNpm) {
10285         assert.ok(_('a').chain().isEqual('a') instanceof _);
10286       }
10287       else {
10288         skipAssert(assert);
10289       }
10290     });
10291   }());
10292
10293   /*--------------------------------------------------------------------------*/
10294
10295   QUnit.module('lodash.isEqualWith');
10296
10297   (function() {
10298     QUnit.test('should provide correct `customizer` arguments', function(assert) {
10299       assert.expect(1);
10300
10301       var argsList = [],
10302           object1 = { 'a': [1, 2], 'b': null },
10303           object2 = { 'a': [1, 2], 'b': null };
10304
10305       object1.b = object2;
10306       object2.b = object1;
10307
10308       var expected = [
10309         [object1, object2],
10310         [object1.a, object2.a, 'a', object1, object2],
10311         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10312         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10313         [object1.b, object2.b, 'b', object1.b, object2.b]
10314       ];
10315
10316       _.isEqualWith(object1, object2, function(assert) {
10317         var length = arguments.length,
10318             args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10319
10320         argsList.push(args);
10321       });
10322
10323       assert.deepEqual(argsList, expected);
10324     });
10325
10326     QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10327       assert.expect(3);
10328
10329       assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
10330       assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
10331       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
10332     });
10333
10334     QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10335       assert.expect(3);
10336
10337       var customizer = function(value) {
10338         return _.isString(value) || undefined;
10339       };
10340
10341       assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
10342       assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
10343       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10344     });
10345
10346     QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10347       assert.expect(3);
10348
10349       var customizer = function(value) {
10350         return _.isString(value) ? false : undefined;
10351       };
10352
10353       assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
10354       assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
10355       assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10356     });
10357
10358     QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10359       assert.expect(2);
10360
10361       var actual = _.isEqualWith('a', 'b', stubC);
10362       assert.strictEqual(actual, true);
10363
10364       var values = _.without(falsey, undefined),
10365           expected = lodashStable.map(values, stubFalse);
10366
10367       actual = [];
10368       lodashStable.each(values, function(value) {
10369         actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
10370       });
10371
10372       assert.deepEqual(actual, expected);
10373     });
10374
10375     QUnit.test('should ensure `customizer` is a function', function(assert) {
10376       assert.expect(1);
10377
10378       var array = [1, 2, 3],
10379           eq = _.partial(_.isEqualWith, array),
10380           actual = lodashStable.map([array, [1, 0, 3]], eq);
10381
10382       assert.deepEqual(actual, [true, false]);
10383     });
10384
10385     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10386       assert.expect(2);
10387
10388       var value = { 'a': { 'b': 2 } };
10389
10390       if (Map) {
10391         var map1 = new Map;
10392         map1.set('a', value);
10393
10394         var map2 = new Map;
10395         map2.set('a', value);
10396       }
10397       if (Set) {
10398         var set1 = new Set;
10399         set1.add(value);
10400
10401         var set2 = new Set;
10402         set2.add(value);
10403       }
10404       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10405         if (pair[0]) {
10406           var argsList = [],
10407               array = lodashStable.toArray(pair[0]);
10408
10409           var expected = [
10410             [pair[0], pair[1]],
10411             [array[0], array[0], 0, array, array],
10412             [array[0][0], array[0][0], 0, array[0], array[0]],
10413             [array[0][1], array[0][1], 1, array[0], array[0]]
10414           ];
10415
10416           if (index) {
10417             expected.length = 2;
10418           }
10419           _.isEqualWith(pair[0], pair[1], function() {
10420             var length = arguments.length,
10421                 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10422
10423             argsList.push(args);
10424           });
10425
10426           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10427         }
10428         else {
10429           skipAssert(assert);
10430         }
10431       });
10432     });
10433   }());
10434
10435   /*--------------------------------------------------------------------------*/
10436
10437   QUnit.module('lodash.isError');
10438
10439   (function() {
10440     QUnit.test('should return `true` for error objects', function(assert) {
10441       assert.expect(1);
10442
10443       var expected = lodashStable.map(errors, stubTrue);
10444
10445       var actual = lodashStable.map(errors, function(error) {
10446         return _.isError(error) === true;
10447       });
10448
10449       assert.deepEqual(actual, expected);
10450     });
10451
10452     QUnit.test('should return `true` for subclassed values', function(assert) {
10453       assert.expect(1);
10454
10455       assert.strictEqual(_.isError(new CustomError('x')), true);
10456     });
10457
10458     QUnit.test('should return `false` for non error objects', function(assert) {
10459       assert.expect(12);
10460
10461       var expected = lodashStable.map(falsey, stubFalse);
10462
10463       var actual = lodashStable.map(falsey, function(value, index) {
10464         return index ? _.isError(value) : _.isError();
10465       });
10466
10467       assert.deepEqual(actual, expected);
10468
10469       assert.strictEqual(_.isError(args), false);
10470       assert.strictEqual(_.isError([1, 2, 3]), false);
10471       assert.strictEqual(_.isError(true), false);
10472       assert.strictEqual(_.isError(new Date), false);
10473       assert.strictEqual(_.isError(_), false);
10474       assert.strictEqual(_.isError(slice), false);
10475       assert.strictEqual(_.isError({ 'a': 1 }), false);
10476       assert.strictEqual(_.isError(1), false);
10477       assert.strictEqual(_.isError(/x/), false);
10478       assert.strictEqual(_.isError('a'), false);
10479       assert.strictEqual(_.isError(symbol), false);
10480     });
10481
10482     QUnit.test('should return `false` for plain objects', function(assert) {
10483       assert.expect(1);
10484
10485       assert.strictEqual(_.isError({ 'name': 'Error', 'message': '' }), false);
10486     });
10487
10488     QUnit.test('should work with an error object from another realm', function(assert) {
10489       assert.expect(1);
10490
10491       if (realm.errors) {
10492         var expected = lodashStable.map(realm.errors, stubTrue);
10493
10494         var actual = lodashStable.map(realm.errors, function(error) {
10495           return _.isError(error) === true;
10496         });
10497
10498         assert.deepEqual(actual, expected);
10499       }
10500       else {
10501         skipAssert(assert);
10502       }
10503     });
10504   }());
10505
10506   /*--------------------------------------------------------------------------*/
10507
10508   QUnit.module('lodash.isFinite');
10509
10510   (function() {
10511     QUnit.test('should return `true` for finite values', function(assert) {
10512       assert.expect(1);
10513
10514       var values = [0, 1, 3.14, -1],
10515           expected = lodashStable.map(values, stubTrue),
10516           actual = lodashStable.map(values, _.isFinite);
10517
10518       assert.deepEqual(actual, expected);
10519     });
10520
10521     QUnit.test('should return `false` for non-finite values', function(assert) {
10522       assert.expect(1);
10523
10524       var values = [NaN, Infinity, -Infinity, Object(1)],
10525           expected = lodashStable.map(values, stubFalse),
10526           actual = lodashStable.map(values, _.isFinite);
10527
10528       assert.deepEqual(actual, expected);
10529     });
10530
10531     QUnit.test('should return `false` for non-numeric values', function(assert) {
10532       assert.expect(10);
10533
10534       var values = [undefined, [], true, '', ' ', '2px'],
10535           expected = lodashStable.map(values, stubFalse),
10536           actual = lodashStable.map(values, _.isFinite);
10537
10538       assert.deepEqual(actual, expected);
10539
10540       assert.strictEqual(_.isFinite(args), false);
10541       assert.strictEqual(_.isFinite([1, 2, 3]), false);
10542       assert.strictEqual(_.isFinite(true), false);
10543       assert.strictEqual(_.isFinite(new Date), false);
10544       assert.strictEqual(_.isFinite(new Error), false);
10545       assert.strictEqual(_.isFinite({ 'a': 1 }), false);
10546       assert.strictEqual(_.isFinite(/x/), false);
10547       assert.strictEqual(_.isFinite('a'), false);
10548       assert.strictEqual(_.isFinite(symbol), false);
10549     });
10550
10551     QUnit.test('should return `false` for numeric string values', function(assert) {
10552       assert.expect(1);
10553
10554       var values = ['2', '0', '08'],
10555           expected = lodashStable.map(values, stubFalse),
10556           actual = lodashStable.map(values, _.isFinite);
10557
10558       assert.deepEqual(actual, expected);
10559     });
10560   }());
10561
10562   /*--------------------------------------------------------------------------*/
10563
10564   QUnit.module('lodash.isFunction');
10565
10566   (function() {
10567     QUnit.test('should return `true` for functions', function(assert) {
10568       assert.expect(2);
10569
10570       assert.strictEqual(_.isFunction(_), true);
10571       assert.strictEqual(_.isFunction(slice), true);
10572     });
10573
10574     QUnit.test('should return `true` for async functions', function(assert) {
10575       assert.expect(1);
10576
10577       assert.strictEqual(_.isFunction(asyncFunc), typeof asyncFunc == 'function');
10578     });
10579
10580     QUnit.test('should return `true` for generator functions', function(assert) {
10581       assert.expect(1);
10582
10583       assert.strictEqual(_.isFunction(genFunc), typeof genFunc == 'function');
10584     });
10585
10586     QUnit.test('should return `true` for the `Proxy` constructor', function(assert) {
10587       assert.expect(1);
10588
10589       if (Proxy) {
10590         assert.strictEqual(_.isFunction(Proxy), true);
10591       }
10592       else {
10593         skipAssert(assert);
10594       }
10595     });
10596
10597     QUnit.test('should return `true` for array view constructors', function(assert) {
10598       assert.expect(1);
10599
10600       var expected = lodashStable.map(arrayViews, function(type) {
10601         return objToString.call(root[type]) == funcTag;
10602       });
10603
10604       var actual = lodashStable.map(arrayViews, function(type) {
10605         return _.isFunction(root[type]);
10606       });
10607
10608       assert.deepEqual(actual, expected);
10609     });
10610
10611     QUnit.test('should return `false` for non-functions', function(assert) {
10612       assert.expect(12);
10613
10614       var expected = lodashStable.map(falsey, stubFalse);
10615
10616       var actual = lodashStable.map(falsey, function(value, index) {
10617         return index ? _.isFunction(value) : _.isFunction();
10618       });
10619
10620       assert.deepEqual(actual, expected);
10621
10622       assert.strictEqual(_.isFunction(args), false);
10623       assert.strictEqual(_.isFunction([1, 2, 3]), false);
10624       assert.strictEqual(_.isFunction(true), false);
10625       assert.strictEqual(_.isFunction(new Date), false);
10626       assert.strictEqual(_.isFunction(new Error), false);
10627       assert.strictEqual(_.isFunction({ 'a': 1 }), false);
10628       assert.strictEqual(_.isFunction(1), false);
10629       assert.strictEqual(_.isFunction(/x/), false);
10630       assert.strictEqual(_.isFunction('a'), false);
10631       assert.strictEqual(_.isFunction(symbol), false);
10632
10633       if (document) {
10634         assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
10635       }
10636       else {
10637         skipAssert(assert);
10638       }
10639     });
10640
10641     QUnit.test('should work with a function from another realm', function(assert) {
10642       assert.expect(1);
10643
10644       if (realm.function) {
10645         assert.strictEqual(_.isFunction(realm.function), true);
10646       }
10647       else {
10648         skipAssert(assert);
10649       }
10650     });
10651   }());
10652
10653   /*--------------------------------------------------------------------------*/
10654
10655   QUnit.module('isInteger methods');
10656
10657   lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
10658     var func = _[methodName],
10659         isSafe = methodName == 'isSafeInteger';
10660
10661     QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
10662       assert.expect(2);
10663
10664       var values = [-1, 0, 1],
10665           expected = lodashStable.map(values, stubTrue);
10666
10667       var actual = lodashStable.map(values, function(value) {
10668         return func(value);
10669       });
10670
10671       assert.deepEqual(actual, expected);
10672       assert.strictEqual(func(MAX_INTEGER), !isSafe);
10673     });
10674
10675     QUnit.test('should return `false` for non-integer number values', function(assert) {
10676       assert.expect(1);
10677
10678       var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
10679           expected = lodashStable.map(values, stubFalse);
10680
10681       var actual = lodashStable.map(values, function(value) {
10682         return func(value);
10683       });
10684
10685       assert.deepEqual(actual, expected);
10686     });
10687
10688     QUnit.test('should return `false` for non-numeric values', function(assert) {
10689       assert.expect(10);
10690
10691       var expected = lodashStable.map(falsey, function(value) {
10692         return value === 0;
10693       });
10694
10695       var actual = lodashStable.map(falsey, function(value, index) {
10696         return index ? func(value) : func();
10697       });
10698
10699       assert.deepEqual(actual, expected);
10700
10701       assert.strictEqual(func(args), false);
10702       assert.strictEqual(func([1, 2, 3]), false);
10703       assert.strictEqual(func(true), false);
10704       assert.strictEqual(func(new Date), false);
10705       assert.strictEqual(func(new Error), false);
10706       assert.strictEqual(func({ 'a': 1 }), false);
10707       assert.strictEqual(func(/x/), false);
10708       assert.strictEqual(func('a'), false);
10709       assert.strictEqual(func(symbol), false);
10710     });
10711   });
10712
10713   /*--------------------------------------------------------------------------*/
10714
10715   QUnit.module('lodash.isLength');
10716
10717   (function() {
10718     QUnit.test('should return `true` for lengths', function(assert) {
10719       assert.expect(1);
10720
10721       var values = [0, 3, MAX_SAFE_INTEGER],
10722           expected = lodashStable.map(values, stubTrue),
10723           actual = lodashStable.map(values, _.isLength);
10724
10725       assert.deepEqual(actual, expected);
10726     });
10727
10728     QUnit.test('should return `false` for non-lengths', function(assert) {
10729       assert.expect(1);
10730
10731       var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
10732           expected = lodashStable.map(values, stubFalse),
10733           actual = lodashStable.map(values, _.isLength);
10734
10735       assert.deepEqual(actual, expected);
10736     });
10737   }());
10738
10739   /*--------------------------------------------------------------------------*/
10740
10741   QUnit.module('lodash.isMap');
10742
10743   (function() {
10744     QUnit.test('should return `true` for maps', function(assert) {
10745       assert.expect(1);
10746
10747       if (Map) {
10748         assert.strictEqual(_.isMap(map), true);
10749       }
10750       else {
10751         skipAssert(assert);
10752       }
10753     });
10754
10755     QUnit.test('should return `false` for non-maps', function(assert) {
10756       assert.expect(14);
10757
10758       var expected = lodashStable.map(falsey, stubFalse);
10759
10760       var actual = lodashStable.map(falsey, function(value, index) {
10761         return index ? _.isMap(value) : _.isMap();
10762       });
10763
10764       assert.deepEqual(actual, expected);
10765
10766       assert.strictEqual(_.isMap(args), false);
10767       assert.strictEqual(_.isMap([1, 2, 3]), false);
10768       assert.strictEqual(_.isMap(true), false);
10769       assert.strictEqual(_.isMap(new Date), false);
10770       assert.strictEqual(_.isMap(new Error), false);
10771       assert.strictEqual(_.isMap(_), false);
10772       assert.strictEqual(_.isMap(slice), false);
10773       assert.strictEqual(_.isMap({ 'a': 1 }), false);
10774       assert.strictEqual(_.isMap(1), false);
10775       assert.strictEqual(_.isMap(/x/), false);
10776       assert.strictEqual(_.isMap('a'), false);
10777       assert.strictEqual(_.isMap(symbol), false);
10778       assert.strictEqual(_.isMap(weakMap), false);
10779     });
10780
10781     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
10782       assert.expect(1);
10783
10784       var values = [false, true],
10785           expected = lodashStable.map(values, stubFalse);
10786
10787       var actual = lodashStable.map(values, function(value) {
10788         return _.isMap({ 'constructor': value });
10789       });
10790
10791       assert.deepEqual(actual, expected);
10792     });
10793
10794     QUnit.test('should work with maps from another realm', function(assert) {
10795       assert.expect(1);
10796
10797       if (realm.map) {
10798         assert.strictEqual(_.isMap(realm.map), true);
10799       }
10800       else {
10801         skipAssert(assert);
10802       }
10803     });
10804   }());
10805
10806   /*--------------------------------------------------------------------------*/
10807
10808   QUnit.module('lodash.isMatchWith');
10809
10810   (function() {
10811     QUnit.test('should provide correct `customizer` arguments', function(assert) {
10812       assert.expect(1);
10813
10814       var argsList = [],
10815           object1 = { 'a': [1, 2], 'b': null },
10816           object2 = { 'a': [1, 2], 'b': null };
10817
10818       object1.b = object2;
10819       object2.b = object1;
10820
10821       var expected = [
10822         [object1.a, object2.a, 'a', object1, object2],
10823         [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10824         [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10825         [object1.b, object2.b, 'b', object1, object2],
10826         [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10827         [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10828         [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10829         [object1.b.b, object2.b.b, 'b', object1.b, object2.b]
10830       ];
10831
10832       _.isMatchWith(object1, object2, function(assert) {
10833         argsList.push(slice.call(arguments, 0, -1));
10834       });
10835
10836       assert.deepEqual(argsList, expected);
10837     });
10838
10839     QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10840       assert.expect(1);
10841
10842       assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10843     });
10844
10845     QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10846       assert.expect(2);
10847
10848       var customizer = function(value) {
10849         return _.isString(value) || undefined;
10850       };
10851
10852       assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10853       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10854     });
10855
10856     QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10857       assert.expect(2);
10858
10859       var customizer = function(value) {
10860         return _.isString(value) ? false : undefined;
10861       };
10862
10863       assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10864       assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10865     });
10866
10867     QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10868       assert.expect(2);
10869
10870       var object = { 'a': 1 },
10871           actual = _.isMatchWith(object, { 'a': 1 }, stubA);
10872
10873       assert.strictEqual(actual, true);
10874
10875       var expected = lodashStable.map(falsey, stubFalse);
10876
10877       actual = [];
10878       lodashStable.each(falsey, function(value) {
10879         actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
10880       });
10881
10882       assert.deepEqual(actual, expected);
10883     });
10884
10885     QUnit.test('should provide `stack` to `customizer`', function(assert) {
10886       assert.expect(1);
10887
10888       var actual;
10889
10890       _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() {
10891         actual = _.last(arguments);
10892       });
10893
10894       assert.ok(isNpm
10895         ? actual.constructor.name == 'Stack'
10896         : actual instanceof mapCaches.Stack
10897       );
10898     });
10899
10900     QUnit.test('should ensure `customizer` is a function', function(assert) {
10901       assert.expect(1);
10902
10903       var object = { 'a': 1 },
10904           matches = _.partial(_.isMatchWith, object),
10905           actual = lodashStable.map([object, { 'a': 2 }], matches);
10906
10907       assert.deepEqual(actual, [true, false]);
10908     });
10909
10910     QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10911       assert.expect(2);
10912
10913       var value = { 'a': { 'b': 2 } };
10914
10915       if (Map) {
10916         var map1 = new Map;
10917         map1.set('a', value);
10918
10919         var map2 = new Map;
10920         map2.set('a', value);
10921       }
10922       if (Set) {
10923         var set1 = new Set;
10924         set1.add(value);
10925
10926         var set2 = new Set;
10927         set2.add(value);
10928       }
10929       lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10930         if (pair[0]) {
10931           var argsList = [],
10932               array = lodashStable.toArray(pair[0]),
10933               object1 = { 'a': pair[0] },
10934               object2 = { 'a': pair[1] };
10935
10936           var expected = [
10937             [pair[0], pair[1], 'a', object1, object2],
10938             [array[0], array[0], 0, array, array],
10939             [array[0][0], array[0][0], 0, array[0], array[0]],
10940             [array[0][1], array[0][1], 1, array[0], array[0]]
10941           ];
10942
10943           if (index) {
10944             expected.length = 2;
10945           }
10946           _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
10947             argsList.push(slice.call(arguments, 0, -1));
10948           });
10949
10950           assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10951         }
10952         else {
10953           skipAssert(assert);
10954         }
10955       });
10956     });
10957   }());
10958
10959   /*--------------------------------------------------------------------------*/
10960
10961   QUnit.module('lodash.isNaN');
10962
10963   (function() {
10964     QUnit.test('should return `true` for NaNs', function(assert) {
10965       assert.expect(2);
10966
10967       assert.strictEqual(_.isNaN(NaN), true);
10968       assert.strictEqual(_.isNaN(Object(NaN)), true);
10969     });
10970
10971     QUnit.test('should return `false` for non-NaNs', function(assert) {
10972       assert.expect(14);
10973
10974       var expected = lodashStable.map(falsey, function(value) {
10975         return value !== value;
10976       });
10977
10978       var actual = lodashStable.map(falsey, function(value, index) {
10979         return index ? _.isNaN(value) : _.isNaN();
10980       });
10981
10982       assert.deepEqual(actual, expected);
10983
10984       assert.strictEqual(_.isNaN(args), false);
10985       assert.strictEqual(_.isNaN([1, 2, 3]), false);
10986       assert.strictEqual(_.isNaN(true), false);
10987       assert.strictEqual(_.isNaN(new Date), false);
10988       assert.strictEqual(_.isNaN(new Error), false);
10989       assert.strictEqual(_.isNaN(_), false);
10990       assert.strictEqual(_.isNaN(slice), false);
10991       assert.strictEqual(_.isNaN({ 'a': 1 }), false);
10992       assert.strictEqual(_.isNaN(1), false);
10993       assert.strictEqual(_.isNaN(Object(1)), false);
10994       assert.strictEqual(_.isNaN(/x/), false);
10995       assert.strictEqual(_.isNaN('a'), false);
10996       assert.strictEqual(_.isNaN(symbol), false);
10997     });
10998
10999     QUnit.test('should work with `NaN` from another realm', function(assert) {
11000       assert.expect(1);
11001
11002       if (realm.object) {
11003         assert.strictEqual(_.isNaN(realm.nan), true);
11004       }
11005       else {
11006         skipAssert(assert);
11007       }
11008     });
11009   }());
11010
11011   /*--------------------------------------------------------------------------*/
11012
11013   QUnit.module('lodash.isNative');
11014
11015   (function() {
11016     QUnit.test('should return `true` for native methods', function(assert) {
11017       assert.expect(1);
11018
11019       var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
11020           expected = lodashStable.map(values, Boolean),
11021           actual = lodashStable.map(values, _.isNative);
11022
11023       assert.deepEqual(actual, expected);
11024     });
11025
11026     QUnit.test('should return `false` for non-native methods', function(assert) {
11027       assert.expect(12);
11028
11029       var expected = lodashStable.map(falsey, stubFalse);
11030
11031       var actual = lodashStable.map(falsey, function(value, index) {
11032         return index ? _.isNative(value) : _.isNative();
11033       });
11034
11035       assert.deepEqual(actual, expected);
11036
11037       assert.strictEqual(_.isNative(args), false);
11038       assert.strictEqual(_.isNative([1, 2, 3]), false);
11039       assert.strictEqual(_.isNative(true), false);
11040       assert.strictEqual(_.isNative(new Date), false);
11041       assert.strictEqual(_.isNative(new Error), false);
11042       assert.strictEqual(_.isNative(_), false);
11043       assert.strictEqual(_.isNative({ 'a': 1 }), false);
11044       assert.strictEqual(_.isNative(1), false);
11045       assert.strictEqual(_.isNative(/x/), false);
11046       assert.strictEqual(_.isNative('a'), false);
11047       assert.strictEqual(_.isNative(symbol), false);
11048     });
11049
11050     QUnit.test('should work with native functions from another realm', function(assert) {
11051       assert.expect(2);
11052
11053       if (realm.element) {
11054         assert.strictEqual(_.isNative(realm.element.cloneNode), true);
11055       }
11056       else {
11057         skipAssert(assert);
11058       }
11059       if (realm.object) {
11060         assert.strictEqual(_.isNative(realm.object.valueOf), true);
11061       }
11062       else {
11063         skipAssert(assert);
11064       }
11065     });
11066
11067     QUnit.test('should throw an error if core-js is detected', function(assert) {
11068       assert.expect(1);
11069
11070       if (!isModularize) {
11071         var lodash = _.runInContext({
11072           '__core-js_shared__': {}
11073         });
11074
11075         assert.raises(function() { lodash.isNative(noop); });
11076       }
11077       else {
11078         skipAssert(assert);
11079       }
11080     });
11081
11082     QUnit.test('should detect methods masquerading as native (test in Node.js)', function(assert) {
11083       assert.expect(2);
11084
11085       if (!amd && _._baseEach) {
11086         var path = require('path'),
11087             basePath = path.dirname(filePath),
11088             uid = 'e0gvgyrad1jor',
11089             coreKey = '__core-js_shared__',
11090             fakeSrcKey = 'Symbol(src)_1.' + uid;
11091
11092         root[coreKey] = { 'keys': { 'IE_PROTO': 'Symbol(IE_PROTO)_3.' + uid } };
11093         emptyObject(require.cache);
11094
11095         var baseIsNative = interopRequire(path.join(basePath, '_baseIsNative'));
11096         assert.strictEqual(baseIsNative(slice), true);
11097
11098         slice[fakeSrcKey] = slice + '';
11099         assert.strictEqual(baseIsNative(slice), false);
11100
11101         delete slice[fakeSrcKey];
11102         delete root[coreKey];
11103       }
11104       else {
11105         skipAssert(assert, 2);
11106       }
11107     });
11108   }());
11109
11110   /*--------------------------------------------------------------------------*/
11111
11112   QUnit.module('lodash.isNil');
11113
11114   (function() {
11115     QUnit.test('should return `true` for nullish values', function(assert) {
11116       assert.expect(3);
11117
11118       assert.strictEqual(_.isNil(null), true);
11119       assert.strictEqual(_.isNil(), true);
11120       assert.strictEqual(_.isNil(undefined), true);
11121     });
11122
11123     QUnit.test('should return `false` for non-nullish values', function(assert) {
11124       assert.expect(13);
11125
11126       var expected = lodashStable.map(falsey, function(value) {
11127         return value == null;
11128       });
11129
11130       var actual = lodashStable.map(falsey, function(value, index) {
11131         return index ? _.isNil(value) : _.isNil();
11132       });
11133
11134       assert.deepEqual(actual, expected);
11135
11136       assert.strictEqual(_.isNil(args), false);
11137       assert.strictEqual(_.isNil([1, 2, 3]), false);
11138       assert.strictEqual(_.isNil(true), false);
11139       assert.strictEqual(_.isNil(new Date), false);
11140       assert.strictEqual(_.isNil(new Error), false);
11141       assert.strictEqual(_.isNil(_), false);
11142       assert.strictEqual(_.isNil(slice), false);
11143       assert.strictEqual(_.isNil({ 'a': 1 }), false);
11144       assert.strictEqual(_.isNil(1), false);
11145       assert.strictEqual(_.isNil(/x/), false);
11146       assert.strictEqual(_.isNil('a'), false);
11147
11148       if (Symbol) {
11149         assert.strictEqual(_.isNil(symbol), false);
11150       }
11151       else {
11152         skipAssert(assert);
11153       }
11154     });
11155
11156     QUnit.test('should work with nils from another realm', function(assert) {
11157       assert.expect(2);
11158
11159       if (realm.object) {
11160         assert.strictEqual(_.isNil(realm.null), true);
11161         assert.strictEqual(_.isNil(realm.undefined), true);
11162       }
11163       else {
11164         skipAssert(assert, 2);
11165       }
11166     });
11167   }());
11168
11169   /*--------------------------------------------------------------------------*/
11170
11171   QUnit.module('lodash.isNull');
11172
11173   (function() {
11174     QUnit.test('should return `true` for `null` values', function(assert) {
11175       assert.expect(1);
11176
11177       assert.strictEqual(_.isNull(null), true);
11178     });
11179
11180     QUnit.test('should return `false` for non `null` values', function(assert) {
11181       assert.expect(13);
11182
11183       var expected = lodashStable.map(falsey, function(value) {
11184         return value === null;
11185       });
11186
11187       var actual = lodashStable.map(falsey, function(value, index) {
11188         return index ? _.isNull(value) : _.isNull();
11189       });
11190
11191       assert.deepEqual(actual, expected);
11192
11193       assert.strictEqual(_.isNull(args), false);
11194       assert.strictEqual(_.isNull([1, 2, 3]), false);
11195       assert.strictEqual(_.isNull(true), false);
11196       assert.strictEqual(_.isNull(new Date), false);
11197       assert.strictEqual(_.isNull(new Error), false);
11198       assert.strictEqual(_.isNull(_), false);
11199       assert.strictEqual(_.isNull(slice), false);
11200       assert.strictEqual(_.isNull({ 'a': 1 }), false);
11201       assert.strictEqual(_.isNull(1), false);
11202       assert.strictEqual(_.isNull(/x/), false);
11203       assert.strictEqual(_.isNull('a'), false);
11204       assert.strictEqual(_.isNull(symbol), false);
11205     });
11206
11207     QUnit.test('should work with nulls from another realm', function(assert) {
11208       assert.expect(1);
11209
11210       if (realm.object) {
11211         assert.strictEqual(_.isNull(realm.null), true);
11212       }
11213       else {
11214         skipAssert(assert);
11215       }
11216     });
11217   }());
11218
11219   /*--------------------------------------------------------------------------*/
11220
11221   QUnit.module('lodash.isNumber');
11222
11223   (function() {
11224     QUnit.test('should return `true` for numbers', function(assert) {
11225       assert.expect(3);
11226
11227       assert.strictEqual(_.isNumber(0), true);
11228       assert.strictEqual(_.isNumber(Object(0)), true);
11229       assert.strictEqual(_.isNumber(NaN), true);
11230     });
11231
11232     QUnit.test('should return `false` for non-numbers', function(assert) {
11233       assert.expect(12);
11234
11235       var expected = lodashStable.map(falsey, function(value) {
11236         return typeof value == 'number';
11237       });
11238
11239       var actual = lodashStable.map(falsey, function(value, index) {
11240         return index ? _.isNumber(value) : _.isNumber();
11241       });
11242
11243       assert.deepEqual(actual, expected);
11244
11245       assert.strictEqual(_.isNumber(args), false);
11246       assert.strictEqual(_.isNumber([1, 2, 3]), false);
11247       assert.strictEqual(_.isNumber(true), false);
11248       assert.strictEqual(_.isNumber(new Date), false);
11249       assert.strictEqual(_.isNumber(new Error), false);
11250       assert.strictEqual(_.isNumber(_), false);
11251       assert.strictEqual(_.isNumber(slice), false);
11252       assert.strictEqual(_.isNumber({ 'a': 1 }), false);
11253       assert.strictEqual(_.isNumber(/x/), false);
11254       assert.strictEqual(_.isNumber('a'), false);
11255       assert.strictEqual(_.isNumber(symbol), false);
11256     });
11257
11258     QUnit.test('should work with numbers from another realm', function(assert) {
11259       assert.expect(1);
11260
11261       if (realm.number) {
11262         assert.strictEqual(_.isNumber(realm.number), true);
11263       }
11264       else {
11265         skipAssert(assert);
11266       }
11267     });
11268   }());
11269
11270   /*--------------------------------------------------------------------------*/
11271
11272   QUnit.module('lodash.isObject');
11273
11274   (function() {
11275     QUnit.test('should return `true` for objects', function(assert) {
11276       assert.expect(13);
11277
11278       assert.strictEqual(_.isObject(args), true);
11279       assert.strictEqual(_.isObject([1, 2, 3]), true);
11280       assert.strictEqual(_.isObject(Object(false)), true);
11281       assert.strictEqual(_.isObject(new Date), true);
11282       assert.strictEqual(_.isObject(new Error), true);
11283       assert.strictEqual(_.isObject(_), true);
11284       assert.strictEqual(_.isObject(slice), true);
11285       assert.strictEqual(_.isObject({ 'a': 1 }), true);
11286       assert.strictEqual(_.isObject(Object(0)), true);
11287       assert.strictEqual(_.isObject(/x/), true);
11288       assert.strictEqual(_.isObject(Object('a')), true);
11289
11290       if (document) {
11291         assert.strictEqual(_.isObject(body), true);
11292       }
11293       else {
11294         skipAssert(assert);
11295       }
11296       if (Symbol) {
11297         assert.strictEqual(_.isObject(Object(symbol)), true);
11298       }
11299       else {
11300         skipAssert(assert);
11301       }
11302     });
11303
11304     QUnit.test('should return `false` for non-objects', function(assert) {
11305       assert.expect(1);
11306
11307       var values = falsey.concat(true, 1, 'a', symbol),
11308           expected = lodashStable.map(values, stubFalse);
11309
11310       var actual = lodashStable.map(values, function(value, index) {
11311         return index ? _.isObject(value) : _.isObject();
11312       });
11313
11314       assert.deepEqual(actual, expected);
11315     });
11316
11317     QUnit.test('should work with objects from another realm', function(assert) {
11318       assert.expect(8);
11319
11320       if (realm.element) {
11321         assert.strictEqual(_.isObject(realm.element), true);
11322       }
11323       else {
11324         skipAssert(assert);
11325       }
11326       if (realm.object) {
11327         assert.strictEqual(_.isObject(realm.boolean), true);
11328         assert.strictEqual(_.isObject(realm.date), true);
11329         assert.strictEqual(_.isObject(realm.function), true);
11330         assert.strictEqual(_.isObject(realm.number), true);
11331         assert.strictEqual(_.isObject(realm.object), true);
11332         assert.strictEqual(_.isObject(realm.regexp), true);
11333         assert.strictEqual(_.isObject(realm.string), true);
11334       }
11335       else {
11336         skipAssert(assert, 7);
11337       }
11338     });
11339   }());
11340
11341   /*--------------------------------------------------------------------------*/
11342
11343   QUnit.module('lodash.isObjectLike');
11344
11345   (function() {
11346     QUnit.test('should return `true` for objects', function(assert) {
11347       assert.expect(9);
11348
11349       assert.strictEqual(_.isObjectLike(args), true);
11350       assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
11351       assert.strictEqual(_.isObjectLike(Object(false)), true);
11352       assert.strictEqual(_.isObjectLike(new Date), true);
11353       assert.strictEqual(_.isObjectLike(new Error), true);
11354       assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
11355       assert.strictEqual(_.isObjectLike(Object(0)), true);
11356       assert.strictEqual(_.isObjectLike(/x/), true);
11357       assert.strictEqual(_.isObjectLike(Object('a')), true);
11358     });
11359
11360     QUnit.test('should return `false` for non-objects', function(assert) {
11361       assert.expect(1);
11362
11363       var values = falsey.concat(true, _, slice, 1, 'a', symbol),
11364           expected = lodashStable.map(values, stubFalse);
11365
11366       var actual = lodashStable.map(values, function(value, index) {
11367         return index ? _.isObjectLike(value) : _.isObjectLike();
11368       });
11369
11370       assert.deepEqual(actual, expected);
11371     });
11372
11373     QUnit.test('should work with objects from another realm', function(assert) {
11374       assert.expect(6);
11375
11376       if (realm.object) {
11377         assert.strictEqual(_.isObjectLike(realm.boolean), true);
11378         assert.strictEqual(_.isObjectLike(realm.date), true);
11379         assert.strictEqual(_.isObjectLike(realm.number), true);
11380         assert.strictEqual(_.isObjectLike(realm.object), true);
11381         assert.strictEqual(_.isObjectLike(realm.regexp), true);
11382         assert.strictEqual(_.isObjectLike(realm.string), true);
11383       }
11384       else {
11385         skipAssert(assert, 6);
11386       }
11387     });
11388   }());
11389
11390   /*--------------------------------------------------------------------------*/
11391
11392   QUnit.module('lodash.isPlainObject');
11393
11394   (function() {
11395     var element = document && document.createElement('div');
11396
11397     QUnit.test('should detect plain objects', function(assert) {
11398       assert.expect(5);
11399
11400       function Foo(a) {
11401         this.a = 1;
11402       }
11403
11404       assert.strictEqual(_.isPlainObject({}), true);
11405       assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
11406       assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
11407       assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
11408       assert.strictEqual(_.isPlainObject(new Foo(1)), false);
11409     });
11410
11411     QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
11412       assert.expect(2);
11413
11414       var object = create(null);
11415       assert.strictEqual(_.isPlainObject(object), true);
11416
11417       object.constructor = objectProto.constructor;
11418       assert.strictEqual(_.isPlainObject(object), true);
11419     });
11420
11421     QUnit.test('should return `true` for objects with a `valueOf` property', function(assert) {
11422       assert.expect(1);
11423
11424       assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
11425     });
11426
11427     QUnit.test('should return `true` for objects with a writable `Symbol.toStringTag` property', function(assert) {
11428       assert.expect(1);
11429
11430       if (Symbol && Symbol.toStringTag) {
11431         var object = {};
11432         object[Symbol.toStringTag] = 'X';
11433
11434         assert.deepEqual(_.isPlainObject(object), true);
11435       }
11436       else {
11437         skipAssert(assert);
11438       }
11439     });
11440
11441     QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
11442       assert.expect(1);
11443
11444       var object = create({ 'a': 1 });
11445       assert.strictEqual(_.isPlainObject(object), false);
11446     });
11447
11448     QUnit.test('should return `false` for DOM elements', function(assert) {
11449       assert.expect(1);
11450
11451       if (element) {
11452         assert.strictEqual(_.isPlainObject(element), false);
11453       } else {
11454         skipAssert(assert);
11455       }
11456     });
11457
11458     QUnit.test('should return `false` for non-Object objects', function(assert) {
11459       assert.expect(3);
11460
11461       assert.strictEqual(_.isPlainObject(arguments), false);
11462       assert.strictEqual(_.isPlainObject(Error), false);
11463       assert.strictEqual(_.isPlainObject(Math), false);
11464     });
11465
11466     QUnit.test('should return `false` for non-objects', function(assert) {
11467       assert.expect(4);
11468
11469       var expected = lodashStable.map(falsey, stubFalse);
11470
11471       var actual = lodashStable.map(falsey, function(value, index) {
11472         return index ? _.isPlainObject(value) : _.isPlainObject();
11473       });
11474
11475       assert.deepEqual(actual, expected);
11476
11477       assert.strictEqual(_.isPlainObject(true), false);
11478       assert.strictEqual(_.isPlainObject('a'), false);
11479       assert.strictEqual(_.isPlainObject(symbol), false);
11480     });
11481
11482     QUnit.test('should return `false` for objects with a read-only `Symbol.toStringTag` property', function(assert) {
11483       assert.expect(1);
11484
11485       if (Symbol && Symbol.toStringTag) {
11486         var object = {};
11487         defineProperty(object, Symbol.toStringTag, {
11488           'configurable': true,
11489           'enumerable': false,
11490           'writable': false,
11491           'value': 'X'
11492         });
11493
11494         assert.deepEqual(_.isPlainObject(object), false);
11495       }
11496       else {
11497         skipAssert(assert);
11498       }
11499     });
11500
11501     QUnit.test('should not mutate `value`', function(assert) {
11502       assert.expect(2);
11503
11504       if (Symbol && Symbol.toStringTag) {
11505         var proto = {};
11506         proto[Symbol.toStringTag] = undefined;
11507         var object = create(proto);
11508
11509         assert.strictEqual(_.isPlainObject(object), false);
11510         assert.notOk(lodashStable.has(object, Symbol.toStringTag));
11511       }
11512       else {
11513         skipAssert(assert, 2);
11514       }
11515     });
11516
11517     QUnit.test('should work with objects from another realm', function(assert) {
11518       assert.expect(1);
11519
11520       if (realm.object) {
11521         assert.strictEqual(_.isPlainObject(realm.object), true);
11522       }
11523       else {
11524         skipAssert(assert);
11525       }
11526     });
11527   }());
11528
11529   /*--------------------------------------------------------------------------*/
11530
11531   QUnit.module('lodash.isRegExp');
11532
11533   (function() {
11534     QUnit.test('should return `true` for regexes', function(assert) {
11535       assert.expect(2);
11536
11537       assert.strictEqual(_.isRegExp(/x/), true);
11538       assert.strictEqual(_.isRegExp(RegExp('x')), true);
11539     });
11540
11541     QUnit.test('should return `false` for non-regexes', function(assert) {
11542       assert.expect(12);
11543
11544       var expected = lodashStable.map(falsey, stubFalse);
11545
11546       var actual = lodashStable.map(falsey, function(value, index) {
11547         return index ? _.isRegExp(value) : _.isRegExp();
11548       });
11549
11550       assert.deepEqual(actual, expected);
11551
11552       assert.strictEqual(_.isRegExp(args), false);
11553       assert.strictEqual(_.isRegExp([1, 2, 3]), false);
11554       assert.strictEqual(_.isRegExp(true), false);
11555       assert.strictEqual(_.isRegExp(new Date), false);
11556       assert.strictEqual(_.isRegExp(new Error), false);
11557       assert.strictEqual(_.isRegExp(_), false);
11558       assert.strictEqual(_.isRegExp(slice), false);
11559       assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
11560       assert.strictEqual(_.isRegExp(1), false);
11561       assert.strictEqual(_.isRegExp('a'), false);
11562       assert.strictEqual(_.isRegExp(symbol), false);
11563     });
11564
11565     QUnit.test('should work with regexes from another realm', function(assert) {
11566       assert.expect(1);
11567
11568       if (realm.regexp) {
11569         assert.strictEqual(_.isRegExp(realm.regexp), true);
11570       }
11571       else {
11572         skipAssert(assert);
11573       }
11574     });
11575   }());
11576
11577   /*--------------------------------------------------------------------------*/
11578
11579   QUnit.module('lodash.isSet');
11580
11581   (function() {
11582     QUnit.test('should return `true` for sets', function(assert) {
11583       assert.expect(1);
11584
11585       if (Set) {
11586         assert.strictEqual(_.isSet(set), true);
11587       }
11588       else {
11589         skipAssert(assert);
11590       }
11591     });
11592
11593     QUnit.test('should return `false` for non-sets', function(assert) {
11594       assert.expect(14);
11595
11596       var expected = lodashStable.map(falsey, stubFalse);
11597
11598       var actual = lodashStable.map(falsey, function(value, index) {
11599         return index ? _.isSet(value) : _.isSet();
11600       });
11601
11602       assert.deepEqual(actual, expected);
11603
11604       assert.strictEqual(_.isSet(args), false);
11605       assert.strictEqual(_.isSet([1, 2, 3]), false);
11606       assert.strictEqual(_.isSet(true), false);
11607       assert.strictEqual(_.isSet(new Date), false);
11608       assert.strictEqual(_.isSet(new Error), false);
11609       assert.strictEqual(_.isSet(_), false);
11610       assert.strictEqual(_.isSet(slice), false);
11611       assert.strictEqual(_.isSet({ 'a': 1 }), false);
11612       assert.strictEqual(_.isSet(1), false);
11613       assert.strictEqual(_.isSet(/x/), false);
11614       assert.strictEqual(_.isSet('a'), false);
11615       assert.strictEqual(_.isSet(symbol), false);
11616       assert.strictEqual(_.isSet(weakSet), false);
11617     });
11618
11619     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11620       assert.expect(1);
11621
11622       var values = [false, true],
11623           expected = lodashStable.map(values, stubFalse);
11624
11625       var actual = lodashStable.map(values, function(value) {
11626         return _.isSet({ 'constructor': value });
11627       });
11628
11629       assert.deepEqual(actual, expected);
11630     });
11631
11632     QUnit.test('should work with weak sets from another realm', function(assert) {
11633       assert.expect(1);
11634
11635       if (realm.set) {
11636         assert.strictEqual(_.isSet(realm.set), true);
11637       }
11638       else {
11639         skipAssert(assert);
11640       }
11641     });
11642   }());
11643
11644   /*--------------------------------------------------------------------------*/
11645
11646   QUnit.module('lodash.isString');
11647
11648   (function() {
11649     QUnit.test('should return `true` for strings', function(assert) {
11650       assert.expect(2);
11651
11652       assert.strictEqual(_.isString('a'), true);
11653       assert.strictEqual(_.isString(Object('a')), true);
11654     });
11655
11656     QUnit.test('should return `false` for non-strings', function(assert) {
11657       assert.expect(12);
11658
11659       var expected = lodashStable.map(falsey, function(value) {
11660         return value === '';
11661       });
11662
11663       var actual = lodashStable.map(falsey, function(value, index) {
11664         return index ? _.isString(value) : _.isString();
11665       });
11666
11667       assert.deepEqual(actual, expected);
11668
11669       assert.strictEqual(_.isString(args), false);
11670       assert.strictEqual(_.isString([1, 2, 3]), false);
11671       assert.strictEqual(_.isString(true), false);
11672       assert.strictEqual(_.isString(new Date), false);
11673       assert.strictEqual(_.isString(new Error), false);
11674       assert.strictEqual(_.isString(_), false);
11675       assert.strictEqual(_.isString(slice), false);
11676       assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
11677       assert.strictEqual(_.isString(1), false);
11678       assert.strictEqual(_.isString(/x/), false);
11679       assert.strictEqual(_.isString(symbol), false);
11680     });
11681
11682     QUnit.test('should work with strings from another realm', function(assert) {
11683       assert.expect(1);
11684
11685       if (realm.string) {
11686         assert.strictEqual(_.isString(realm.string), true);
11687       }
11688       else {
11689         skipAssert(assert);
11690       }
11691     });
11692   }());
11693
11694   /*--------------------------------------------------------------------------*/
11695
11696   QUnit.module('lodash.isSymbol');
11697
11698   (function() {
11699     QUnit.test('should return `true` for symbols', function(assert) {
11700       assert.expect(2);
11701
11702       if (Symbol) {
11703         assert.strictEqual(_.isSymbol(symbol), true);
11704         assert.strictEqual(_.isSymbol(Object(symbol)), true);
11705       }
11706       else {
11707         skipAssert(assert, 2);
11708       }
11709     });
11710
11711     QUnit.test('should return `false` for non-symbols', function(assert) {
11712       assert.expect(12);
11713
11714       var expected = lodashStable.map(falsey, stubFalse);
11715
11716       var actual = lodashStable.map(falsey, function(value, index) {
11717         return index ? _.isSymbol(value) : _.isSymbol();
11718       });
11719
11720       assert.deepEqual(actual, expected);
11721
11722       assert.strictEqual(_.isSymbol(args), false);
11723       assert.strictEqual(_.isSymbol([1, 2, 3]), false);
11724       assert.strictEqual(_.isSymbol(true), false);
11725       assert.strictEqual(_.isSymbol(new Date), false);
11726       assert.strictEqual(_.isSymbol(new Error), false);
11727       assert.strictEqual(_.isSymbol(_), false);
11728       assert.strictEqual(_.isSymbol(slice), false);
11729       assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
11730       assert.strictEqual(_.isSymbol(1), false);
11731       assert.strictEqual(_.isSymbol(/x/), false);
11732       assert.strictEqual(_.isSymbol('a'), false);
11733     });
11734
11735     QUnit.test('should work with symbols from another realm', function(assert) {
11736       assert.expect(1);
11737
11738       if (Symbol && realm.symbol) {
11739         assert.strictEqual(_.isSymbol(realm.symbol), true);
11740       }
11741       else {
11742         skipAssert(assert);
11743       }
11744     });
11745   }());
11746
11747   /*--------------------------------------------------------------------------*/
11748
11749   QUnit.module('lodash.isTypedArray');
11750
11751   (function() {
11752     QUnit.test('should return `true` for typed arrays', function(assert) {
11753       assert.expect(1);
11754
11755       var expected = lodashStable.map(typedArrays, function(type) {
11756         return type in root;
11757       });
11758
11759       var actual = lodashStable.map(typedArrays, function(type) {
11760         var Ctor = root[type];
11761         return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11762       });
11763
11764       assert.deepEqual(actual, expected);
11765     });
11766
11767     QUnit.test('should return `false` for non typed arrays', function(assert) {
11768       assert.expect(13);
11769
11770       var expected = lodashStable.map(falsey, stubFalse);
11771
11772       var actual = lodashStable.map(falsey, function(value, index) {
11773         return index ? _.isTypedArray(value) : _.isTypedArray();
11774       });
11775
11776       assert.deepEqual(actual, expected);
11777
11778       assert.strictEqual(_.isTypedArray(args), false);
11779       assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11780       assert.strictEqual(_.isTypedArray(true), false);
11781       assert.strictEqual(_.isTypedArray(new Date), false);
11782       assert.strictEqual(_.isTypedArray(new Error), false);
11783       assert.strictEqual(_.isTypedArray(_), false);
11784       assert.strictEqual(_.isTypedArray(slice), false);
11785       assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11786       assert.strictEqual(_.isTypedArray(1), false);
11787       assert.strictEqual(_.isTypedArray(/x/), false);
11788       assert.strictEqual(_.isTypedArray('a'), false);
11789       assert.strictEqual(_.isTypedArray(symbol), false);
11790     });
11791
11792     QUnit.test('should work with typed arrays from another realm', function(assert) {
11793       assert.expect(1);
11794
11795       if (realm.object) {
11796         var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11797
11798         var expected = lodashStable.map(props, function(key) {
11799           return realm[key] !== undefined;
11800         });
11801
11802         var actual = lodashStable.map(props, function(key) {
11803           var value = realm[key];
11804           return value ? _.isTypedArray(value) : false;
11805         });
11806
11807         assert.deepEqual(actual, expected);
11808       }
11809       else {
11810         skipAssert(assert);
11811       }
11812     });
11813   }());
11814
11815   /*--------------------------------------------------------------------------*/
11816
11817   QUnit.module('lodash.isUndefined');
11818
11819   (function() {
11820     QUnit.test('should return `true` for `undefined` values', function(assert) {
11821       assert.expect(2);
11822
11823       assert.strictEqual(_.isUndefined(), true);
11824       assert.strictEqual(_.isUndefined(undefined), true);
11825     });
11826
11827     QUnit.test('should return `false` for non `undefined` values', function(assert) {
11828       assert.expect(13);
11829
11830       var expected = lodashStable.map(falsey, function(value) {
11831         return value === undefined;
11832       });
11833
11834       var actual = lodashStable.map(falsey, function(value, index) {
11835         return index ? _.isUndefined(value) : _.isUndefined();
11836       });
11837
11838       assert.deepEqual(actual, expected);
11839
11840       assert.strictEqual(_.isUndefined(args), false);
11841       assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11842       assert.strictEqual(_.isUndefined(true), false);
11843       assert.strictEqual(_.isUndefined(new Date), false);
11844       assert.strictEqual(_.isUndefined(new Error), false);
11845       assert.strictEqual(_.isUndefined(_), false);
11846       assert.strictEqual(_.isUndefined(slice), false);
11847       assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11848       assert.strictEqual(_.isUndefined(1), false);
11849       assert.strictEqual(_.isUndefined(/x/), false);
11850       assert.strictEqual(_.isUndefined('a'), false);
11851
11852       if (Symbol) {
11853         assert.strictEqual(_.isUndefined(symbol), false);
11854       }
11855       else {
11856         skipAssert(assert);
11857       }
11858     });
11859
11860     QUnit.test('should work with `undefined` from another realm', function(assert) {
11861       assert.expect(1);
11862
11863       if (realm.object) {
11864         assert.strictEqual(_.isUndefined(realm.undefined), true);
11865       }
11866       else {
11867         skipAssert(assert);
11868       }
11869     });
11870   }());
11871
11872   /*--------------------------------------------------------------------------*/
11873
11874   QUnit.module('lodash.isWeakMap');
11875
11876   (function() {
11877     QUnit.test('should return `true` for weak maps', function(assert) {
11878       assert.expect(1);
11879
11880       if (WeakMap) {
11881         assert.strictEqual(_.isWeakMap(weakMap), true);
11882       }
11883       else {
11884         skipAssert(assert);
11885       }
11886     });
11887
11888     QUnit.test('should return `false` for non weak maps', function(assert) {
11889       assert.expect(14);
11890
11891       var expected = lodashStable.map(falsey, stubFalse);
11892
11893       var actual = lodashStable.map(falsey, function(value, index) {
11894         return index ? _.isWeakMap(value) : _.isWeakMap();
11895       });
11896
11897       assert.deepEqual(actual, expected);
11898
11899       assert.strictEqual(_.isWeakMap(args), false);
11900       assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
11901       assert.strictEqual(_.isWeakMap(true), false);
11902       assert.strictEqual(_.isWeakMap(new Date), false);
11903       assert.strictEqual(_.isWeakMap(new Error), false);
11904       assert.strictEqual(_.isWeakMap(_), false);
11905       assert.strictEqual(_.isWeakMap(slice), false);
11906       assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
11907       assert.strictEqual(_.isWeakMap(map), false);
11908       assert.strictEqual(_.isWeakMap(1), false);
11909       assert.strictEqual(_.isWeakMap(/x/), false);
11910       assert.strictEqual(_.isWeakMap('a'), false);
11911       assert.strictEqual(_.isWeakMap(symbol), false);
11912     });
11913
11914     QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11915       assert.expect(1);
11916
11917       var values = [false, true],
11918           expected = lodashStable.map(values, stubFalse);
11919
11920       var actual = lodashStable.map(values, function(value) {
11921         return _.isWeakMap({ 'constructor': value });
11922       });
11923
11924       assert.deepEqual(actual, expected);
11925     });
11926
11927     QUnit.test('should work with weak maps from another realm', function(assert) {
11928       assert.expect(1);
11929
11930       if (realm.weakMap) {
11931         assert.strictEqual(_.isWeakMap(realm.weakMap), true);
11932       }
11933       else {
11934         skipAssert(assert);
11935       }
11936     });
11937   }());
11938
11939   /*--------------------------------------------------------------------------*/
11940
11941   QUnit.module('lodash.isWeakSet');
11942
11943   (function() {
11944     QUnit.test('should return `true` for weak sets', function(assert) {
11945       assert.expect(1);
11946
11947       if (WeakSet) {
11948         assert.strictEqual(_.isWeakSet(weakSet), true);
11949       }
11950       else {
11951         skipAssert(assert);
11952       }
11953     });
11954
11955     QUnit.test('should return `false` for non weak sets', function(assert) {
11956       assert.expect(14);
11957
11958       var expected = lodashStable.map(falsey, stubFalse);
11959
11960       var actual = lodashStable.map(falsey, function(value, index) {
11961         return index ? _.isWeakSet(value) : _.isWeakSet();
11962       });
11963
11964       assert.deepEqual(actual, expected);
11965
11966       assert.strictEqual(_.isWeakSet(args), false);
11967       assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
11968       assert.strictEqual(_.isWeakSet(true), false);
11969       assert.strictEqual(_.isWeakSet(new Date), false);
11970       assert.strictEqual(_.isWeakSet(new Error), false);
11971       assert.strictEqual(_.isWeakSet(_), false);
11972       assert.strictEqual(_.isWeakSet(slice), false);
11973       assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
11974       assert.strictEqual(_.isWeakSet(1), false);
11975       assert.strictEqual(_.isWeakSet(/x/), false);
11976       assert.strictEqual(_.isWeakSet('a'), false);
11977       assert.strictEqual(_.isWeakSet(set), false);
11978       assert.strictEqual(_.isWeakSet(symbol), false);
11979     });
11980
11981     QUnit.test('should work with weak sets from another realm', function(assert) {
11982       assert.expect(1);
11983
11984       if (realm.weakSet) {
11985         assert.strictEqual(_.isWeakSet(realm.weakSet), true);
11986       }
11987       else {
11988         skipAssert(assert);
11989       }
11990     });
11991   }());
11992
11993   /*--------------------------------------------------------------------------*/
11994
11995   QUnit.module('isType checks');
11996
11997   (function() {
11998     QUnit.test('should return `false` for subclassed values', function(assert) {
11999       assert.expect(7);
12000
12001       var funcs = [
12002         'isArray', 'isBoolean', 'isDate', 'isFunction',
12003         'isNumber', 'isRegExp', 'isString'
12004       ];
12005
12006       lodashStable.each(funcs, function(methodName) {
12007         function Foo() {}
12008         Foo.prototype = root[methodName.slice(2)].prototype;
12009
12010         var object = new Foo;
12011         if (objToString.call(object) == objectTag) {
12012           assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
12013         }
12014         else {
12015           skipAssert(assert);
12016         }
12017       });
12018     });
12019
12020     QUnit.test('should not error on host objects (test in IE)', function(assert) {
12021       assert.expect(26);
12022
12023       var funcs = [
12024         'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
12025         'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
12026         'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
12027         'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
12028         'isUndefined', 'isWeakMap', 'isWeakSet'
12029       ];
12030
12031       lodashStable.each(funcs, function(methodName) {
12032         if (xml) {
12033           _[methodName](xml);
12034           assert.ok(true, '`_.' + methodName + '` should not error');
12035         }
12036         else {
12037           skipAssert(assert);
12038         }
12039       });
12040     });
12041   }());
12042
12043   /*--------------------------------------------------------------------------*/
12044
12045   QUnit.module('lodash.iteratee');
12046
12047   (function() {
12048     QUnit.test('should provide arguments to `func`', function(assert) {
12049       assert.expect(1);
12050
12051       var fn = function() { return slice.call(arguments); },
12052           iteratee = _.iteratee(fn),
12053           actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
12054
12055       assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
12056     });
12057
12058     QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
12059       assert.expect(1);
12060
12061       var object = {},
12062           values = [, null, undefined],
12063           expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
12064
12065       var actual = lodashStable.map(values, function(value, index) {
12066         var identity = index ? _.iteratee(value) : _.iteratee();
12067         return [!isNpm && identity, identity(object)];
12068       });
12069
12070       assert.deepEqual(actual, expected);
12071     });
12072
12073     QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
12074       assert.expect(2);
12075
12076       var matches = _.iteratee({ 'a': 1, 'b': 2 });
12077       assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
12078       assert.strictEqual(matches({ 'b': 2 }), false);
12079     });
12080
12081     QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
12082       assert.expect(9);
12083
12084       var sources = [
12085         { 'a': { 'b': 2, 'c': 3 } },
12086         { 'a': 1, 'b': 2 },
12087         { 'a': 1 }
12088       ];
12089
12090       lodashStable.each(sources, function(source, index) {
12091         var object = lodashStable.cloneDeep(source),
12092             matches = _.iteratee(source);
12093
12094         assert.strictEqual(matches(object), true);
12095
12096         if (index) {
12097           source.a = 2;
12098           source.b = 1;
12099           source.c = 3;
12100         } else {
12101           source.a.b = 1;
12102           source.a.c = 2;
12103           source.a.d = 3;
12104         }
12105         assert.strictEqual(matches(object), true);
12106         assert.strictEqual(matches(source), false);
12107       });
12108     });
12109
12110     QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
12111       assert.expect(3);
12112
12113       var array = ['a', undefined],
12114           matches = _.iteratee([0, 'a']);
12115
12116       assert.strictEqual(matches(array), true);
12117
12118       matches = _.iteratee(['0', 'a']);
12119       assert.strictEqual(matches(array), true);
12120
12121       matches = _.iteratee([1, undefined]);
12122       assert.strictEqual(matches(array), true);
12123     });
12124
12125     QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
12126       assert.expect(1);
12127
12128       var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
12129           matches = _.iteratee(['a.b', { 'c': 1 }]);
12130
12131       assert.strictEqual(matches(object), true);
12132     });
12133
12134     QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
12135       assert.expect(9);
12136
12137       var sources = [
12138         { 'a': { 'b': 2, 'c': 3 } },
12139         { 'a': 1, 'b': 2 },
12140         { 'a': 1 }
12141       ];
12142
12143       lodashStable.each(sources, function(source, index) {
12144         var object = { 'a': lodashStable.cloneDeep(source) },
12145             matches = _.iteratee(['a', source]);
12146
12147         assert.strictEqual(matches(object), true);
12148
12149         if (index) {
12150           source.a = 2;
12151           source.b = 1;
12152           source.c = 3;
12153         } else {
12154           source.a.b = 1;
12155           source.a.c = 2;
12156           source.a.d = 3;
12157         }
12158         assert.strictEqual(matches(object), true);
12159         assert.strictEqual(matches({ 'a': source }), false);
12160       });
12161     });
12162
12163     QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
12164       assert.expect(2);
12165
12166       var array = ['a'],
12167           prop = _.iteratee(0);
12168
12169       assert.strictEqual(prop(array), 'a');
12170
12171       prop = _.iteratee('0');
12172       assert.strictEqual(prop(array), 'a');
12173     });
12174
12175     QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
12176       assert.expect(1);
12177
12178       var object = { 'a': { 'b': 2 } },
12179           prop = _.iteratee('a.b');
12180
12181       assert.strictEqual(prop(object), 2);
12182     });
12183
12184     QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
12185       assert.expect(2);
12186
12187       var fn = function() {
12188         var result = [this.a];
12189         push.apply(result, arguments);
12190         return result;
12191       };
12192
12193       var expected = [1, 2, 3],
12194           object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
12195
12196       assert.deepEqual(object.iteratee(3), expected);
12197
12198       object.iteratee = _.iteratee(_.partialRight(fn, 3));
12199       assert.deepEqual(object.iteratee(2), expected);
12200     });
12201
12202     QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
12203       assert.expect(1);
12204
12205       var iteratee = _.iteratee;
12206       delete _.iteratee;
12207
12208       assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
12209
12210       _.iteratee = iteratee;
12211     });
12212
12213     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12214       assert.expect(1);
12215
12216       var fn = function() { return this instanceof Number; },
12217           array = [fn, fn, fn],
12218           iteratees = lodashStable.map(array, _.iteratee),
12219           expected = lodashStable.map(array, stubFalse);
12220
12221       var actual = lodashStable.map(iteratees, function(iteratee) {
12222         return iteratee();
12223       });
12224
12225       assert.deepEqual(actual, expected);
12226     });
12227   }());
12228
12229   /*--------------------------------------------------------------------------*/
12230
12231   QUnit.module('custom `_.iteratee` methods');
12232
12233   (function() {
12234     var array = ['one', 'two', 'three'],
12235         getPropA = _.partial(_.property, 'a'),
12236         getPropB = _.partial(_.property, 'b'),
12237         getLength = _.partial(_.property, 'length'),
12238         iteratee = _.iteratee;
12239
12240     var getSum = function() {
12241       return function(result, object) {
12242         return result + object.a;
12243       };
12244     };
12245
12246     var objects = [
12247       { 'a': 0, 'b': 0 },
12248       { 'a': 1, 'b': 0 },
12249       { 'a': 1, 'b': 1 }
12250     ];
12251
12252     QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
12253       assert.expect(1);
12254
12255       if (!isModularize) {
12256         _.iteratee = getLength;
12257         assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
12258         _.iteratee = iteratee;
12259       }
12260       else {
12261         skipAssert(assert);
12262       }
12263     });
12264
12265     QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
12266       assert.expect(1);
12267
12268       if (!isModularize) {
12269         _.iteratee = getPropA;
12270         assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
12271         _.iteratee = iteratee;
12272       }
12273       else {
12274         skipAssert(assert);
12275       }
12276     });
12277
12278     QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
12279       assert.expect(1);
12280
12281       if (!isModularize) {
12282         _.iteratee = getPropB;
12283         assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
12284         _.iteratee = iteratee;
12285       }
12286       else {
12287         skipAssert(assert);
12288       }
12289     });
12290
12291     QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
12292       assert.expect(1);
12293
12294       if (!isModularize) {
12295         _.iteratee = getPropB;
12296         assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
12297         _.iteratee = iteratee;
12298       }
12299       else {
12300         skipAssert(assert);
12301       }
12302     });
12303
12304     QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
12305       assert.expect(1);
12306
12307       if (!isModularize) {
12308         _.iteratee = getPropA;
12309         assert.strictEqual(_.every(objects.slice(1)), true);
12310         _.iteratee = iteratee;
12311       }
12312       else {
12313         skipAssert(assert);
12314       }
12315     });
12316
12317     QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
12318       assert.expect(1);
12319
12320       if (!isModularize) {
12321         var objects = [{ 'a': 0 }, { 'a': 1 }];
12322
12323         _.iteratee = getPropA;
12324         assert.deepEqual(_.filter(objects), [objects[1]]);
12325         _.iteratee = iteratee;
12326       }
12327       else {
12328         skipAssert(assert);
12329       }
12330     });
12331
12332     QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
12333       assert.expect(1);
12334
12335       if (!isModularize) {
12336         _.iteratee = getPropA;
12337         assert.strictEqual(_.find(objects), objects[1]);
12338         _.iteratee = iteratee;
12339       }
12340       else {
12341         skipAssert(assert);
12342       }
12343     });
12344
12345     QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
12346       assert.expect(1);
12347
12348       if (!isModularize) {
12349         _.iteratee = getPropA;
12350         assert.strictEqual(_.findIndex(objects), 1);
12351         _.iteratee = iteratee;
12352       }
12353       else {
12354         skipAssert(assert);
12355       }
12356     });
12357
12358     QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
12359       assert.expect(1);
12360
12361       if (!isModularize) {
12362         _.iteratee = getPropA;
12363         assert.strictEqual(_.findLast(objects), objects[2]);
12364         _.iteratee = iteratee;
12365       }
12366       else {
12367         skipAssert(assert);
12368       }
12369     });
12370
12371     QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
12372       assert.expect(1);
12373
12374       if (!isModularize) {
12375         _.iteratee = getPropA;
12376         assert.strictEqual(_.findLastIndex(objects), 2);
12377         _.iteratee = iteratee;
12378       }
12379       else {
12380         skipAssert(assert);
12381       }
12382     });
12383
12384     QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
12385       assert.expect(1);
12386
12387       if (!isModularize) {
12388         _.iteratee = getPropB;
12389         assert.strictEqual(_.findKey(objects), '2');
12390         _.iteratee = iteratee;
12391       }
12392       else {
12393         skipAssert(assert);
12394       }
12395     });
12396
12397     QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
12398       assert.expect(1);
12399
12400       if (!isModularize) {
12401         _.iteratee = getPropB;
12402         assert.strictEqual(_.findLastKey(objects), '2');
12403         _.iteratee = iteratee;
12404       }
12405       else {
12406         skipAssert(assert);
12407       }
12408     });
12409
12410     QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
12411       assert.expect(1);
12412
12413       if (!isModularize) {
12414         _.iteratee = getLength;
12415         assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
12416         _.iteratee = iteratee;
12417       }
12418       else {
12419         skipAssert(assert);
12420       }
12421     });
12422
12423     QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
12424       assert.expect(1);
12425
12426       if (!isModularize) {
12427         _.iteratee = getPropA;
12428         assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
12429         _.iteratee = iteratee;
12430       }
12431       else {
12432         skipAssert(assert);
12433       }
12434     });
12435
12436     QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
12437       assert.expect(1);
12438
12439       if (!isModularize) {
12440         _.iteratee = getLength;
12441         assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
12442         _.iteratee = iteratee;
12443       }
12444       else {
12445         skipAssert(assert);
12446       }
12447     });
12448
12449     QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
12450       assert.expect(1);
12451
12452       if (!isModularize) {
12453         _.iteratee = getPropA;
12454         assert.deepEqual(_.map(objects), [0, 1, 1]);
12455         _.iteratee = iteratee;
12456       }
12457       else {
12458         skipAssert(assert);
12459       }
12460     });
12461
12462     QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
12463       assert.expect(1);
12464
12465       if (!isModularize) {
12466         _.iteratee = getPropB;
12467         assert.deepEqual(_.mapKeys({ 'a': { 'b': 2 } }), { '2':  { 'b': 2 } });
12468         _.iteratee = iteratee;
12469       }
12470       else {
12471         skipAssert(assert);
12472       }
12473     });
12474
12475     QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
12476       assert.expect(1);
12477
12478       if (!isModularize) {
12479         _.iteratee = getPropB;
12480         assert.deepEqual(_.mapValues({ 'a': { 'b': 2 } }), { 'a': 2 });
12481         _.iteratee = iteratee;
12482       }
12483       else {
12484         skipAssert(assert);
12485       }
12486     });
12487
12488     QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
12489       assert.expect(1);
12490
12491       if (!isModularize) {
12492         _.iteratee = getPropB;
12493         assert.deepEqual(_.maxBy(objects), objects[2]);
12494         _.iteratee = iteratee;
12495       }
12496       else {
12497         skipAssert(assert);
12498       }
12499     });
12500
12501     QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
12502       assert.expect(1);
12503
12504       if (!isModularize) {
12505         _.iteratee = getPropA;
12506         assert.strictEqual(_.meanBy(objects), 2 / 3);
12507         _.iteratee = iteratee;
12508       }
12509       else {
12510         skipAssert(assert);
12511       }
12512     });
12513
12514     QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
12515       assert.expect(1);
12516
12517       if (!isModularize) {
12518         _.iteratee = getPropB;
12519         assert.deepEqual(_.minBy(objects), objects[0]);
12520         _.iteratee = iteratee;
12521       }
12522       else {
12523         skipAssert(assert);
12524       }
12525     });
12526
12527     QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
12528       assert.expect(1);
12529
12530       if (!isModularize) {
12531         var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
12532
12533         _.iteratee = getPropA;
12534         assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
12535         _.iteratee = iteratee;
12536       }
12537       else {
12538         skipAssert(assert);
12539       }
12540     });
12541
12542     QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
12543       assert.expect(1);
12544
12545       if (!isModularize) {
12546         _.iteratee = getPropA;
12547         assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
12548         _.iteratee = iteratee;
12549       }
12550       else {
12551         skipAssert(assert);
12552       }
12553     });
12554
12555     QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
12556       assert.expect(1);
12557
12558       if (!isModularize) {
12559         _.iteratee = getSum;
12560         assert.strictEqual(_.reduce(objects, undefined, 0), 2);
12561         _.iteratee = iteratee;
12562       }
12563       else {
12564         skipAssert(assert);
12565       }
12566     });
12567
12568     QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
12569       assert.expect(1);
12570
12571       if (!isModularize) {
12572         _.iteratee = getSum;
12573         assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
12574         _.iteratee = iteratee;
12575       }
12576       else {
12577         skipAssert(assert);
12578       }
12579     });
12580
12581     QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
12582       assert.expect(1);
12583
12584       if (!isModularize) {
12585         var objects = [{ 'a': 0 }, { 'a': 1 }];
12586
12587         _.iteratee = getPropA;
12588         assert.deepEqual(_.reject(objects), [objects[0]]);
12589         _.iteratee = iteratee;
12590       }
12591       else {
12592         skipAssert(assert);
12593       }
12594     });
12595
12596     QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
12597       assert.expect(1);
12598
12599       if (!isModularize) {
12600         var objects = [{ 'a': 0 }, { 'a': 1 }];
12601
12602         _.iteratee = getPropA;
12603         _.remove(objects);
12604         assert.deepEqual(objects, [{ 'a': 0 }]);
12605         _.iteratee = iteratee;
12606       }
12607       else {
12608         skipAssert(assert);
12609       }
12610     });
12611
12612     QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
12613       assert.expect(1);
12614
12615       if (!isModularize) {
12616         _.iteratee = getPropB;
12617         assert.strictEqual(_.some(objects), true);
12618         _.iteratee = iteratee;
12619       }
12620       else {
12621         skipAssert(assert);
12622       }
12623     });
12624
12625     QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
12626       assert.expect(1);
12627
12628       if (!isModularize) {
12629         _.iteratee = getPropA;
12630         assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
12631         _.iteratee = iteratee;
12632       }
12633       else {
12634         skipAssert(assert);
12635       }
12636     });
12637
12638     QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
12639       assert.expect(1);
12640
12641       if (!isModularize) {
12642         var objects = [{ 'a': 30 }, { 'a': 50 }];
12643
12644         _.iteratee = getPropA;
12645         assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
12646         _.iteratee = iteratee;
12647       }
12648       else {
12649         skipAssert(assert);
12650       }
12651     });
12652
12653     QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
12654       assert.expect(1);
12655
12656       if (!isModularize) {
12657         var objects = [{ 'a': 30 }, { 'a': 50 }];
12658
12659         _.iteratee = getPropA;
12660         assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
12661         _.iteratee = iteratee;
12662       }
12663       else {
12664         skipAssert(assert);
12665       }
12666     });
12667
12668     QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
12669       assert.expect(1);
12670
12671       if (!isModularize) {
12672         _.iteratee = getPropB;
12673         assert.strictEqual(_.sumBy(objects), 1);
12674         _.iteratee = iteratee;
12675       }
12676       else {
12677         skipAssert(assert);
12678       }
12679     });
12680
12681     QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
12682       assert.expect(1);
12683
12684       if (!isModularize) {
12685         _.iteratee = getPropB;
12686         assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
12687         _.iteratee = iteratee;
12688       }
12689       else {
12690         skipAssert(assert);
12691       }
12692     });
12693
12694     QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
12695       assert.expect(1);
12696
12697       if (!isModularize) {
12698         _.iteratee = getPropB;
12699         assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
12700         _.iteratee = iteratee;
12701       }
12702       else {
12703         skipAssert(assert);
12704       }
12705     });
12706
12707     QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
12708       assert.expect(1);
12709
12710       if (!isModularize) {
12711         _.iteratee = function() {
12712           return function(result, object) {
12713             result.sum += object.a;
12714           };
12715         };
12716
12717         assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
12718         _.iteratee = iteratee;
12719       }
12720       else {
12721         skipAssert(assert);
12722       }
12723     });
12724
12725     QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
12726       assert.expect(1);
12727
12728       if (!isModularize) {
12729         _.iteratee = getPropB;
12730         assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
12731         _.iteratee = iteratee;
12732       }
12733       else {
12734         skipAssert(assert);
12735       }
12736     });
12737
12738     QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
12739       assert.expect(1);
12740
12741       if (!isModularize) {
12742         _.iteratee = getPropB;
12743         assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
12744         _.iteratee = iteratee;
12745       }
12746       else {
12747         skipAssert(assert);
12748       }
12749     });
12750
12751     QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
12752       assert.expect(1);
12753
12754       if (!isModularize) {
12755         _.iteratee = getPropA;
12756         assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
12757         _.iteratee = iteratee;
12758       }
12759       else {
12760         skipAssert(assert);
12761       }
12762     });
12763   }());
12764
12765   /*--------------------------------------------------------------------------*/
12766
12767   QUnit.module('lodash.join');
12768
12769   (function() {
12770     var array = ['a', 'b', 'c'];
12771
12772     QUnit.test('should return join all array elements into a string', function(assert) {
12773       assert.expect(1);
12774
12775       assert.strictEqual(_.join(array, '~'), 'a~b~c');
12776     });
12777
12778     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12779       assert.expect(2);
12780
12781       if (!isNpm) {
12782         var wrapped = _(array);
12783         assert.strictEqual(wrapped.join('~'), 'a~b~c');
12784         assert.strictEqual(wrapped.value(), array);
12785       }
12786       else {
12787         skipAssert(assert, 2);
12788       }
12789     });
12790
12791     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12792       assert.expect(1);
12793
12794       if (!isNpm) {
12795         assert.ok(_(array).chain().join('~') instanceof _);
12796       }
12797       else {
12798         skipAssert(assert);
12799       }
12800     });
12801   }());
12802
12803   /*--------------------------------------------------------------------------*/
12804
12805   QUnit.module('lodash.keyBy');
12806
12807   (function() {
12808     var array = [
12809       { 'dir': 'left', 'code': 97 },
12810       { 'dir': 'right', 'code': 100 }
12811     ];
12812
12813     QUnit.test('should transform keys by `iteratee`', function(assert) {
12814       assert.expect(1);
12815
12816       var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12817
12818       var actual = _.keyBy(array, function(object) {
12819         return String.fromCharCode(object.code);
12820       });
12821
12822       assert.deepEqual(actual, expected);
12823     });
12824
12825     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12826       assert.expect(1);
12827
12828       var array = [4, 6, 6],
12829           values = [, null, undefined],
12830           expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12831
12832       var actual = lodashStable.map(values, function(value, index) {
12833         return index ? _.keyBy(array, value) : _.keyBy(array);
12834       });
12835
12836       assert.deepEqual(actual, expected);
12837     });
12838
12839     QUnit.test('should work with `_.property` shorthands', function(assert) {
12840       assert.expect(1);
12841
12842       var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
12843           actual = _.keyBy(array, 'dir');
12844
12845       assert.deepEqual(actual, expected);
12846     });
12847
12848     QUnit.test('should only add values to own, not inherited, properties', function(assert) {
12849       assert.expect(2);
12850
12851       var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
12852         return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
12853       });
12854
12855       assert.deepEqual(actual.constructor, 4.2);
12856       assert.deepEqual(actual.hasOwnProperty, 6.3);
12857     });
12858
12859     QUnit.test('should work with a number for `iteratee`', function(assert) {
12860       assert.expect(2);
12861
12862       var array = [
12863         [1, 'a'],
12864         [2, 'a'],
12865         [2, 'b']
12866       ];
12867
12868       assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
12869       assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
12870     });
12871
12872     QUnit.test('should work with an object for `collection`', function(assert) {
12873       assert.expect(1);
12874
12875       var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
12876       assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
12877     });
12878
12879     QUnit.test('should work in a lazy sequence', function(assert) {
12880       assert.expect(1);
12881
12882       if (!isNpm) {
12883         var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
12884           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
12885           lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
12886         );
12887
12888         var actual = _(array).keyBy().map(square).filter(isEven).take().value();
12889
12890         assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
12891       }
12892       else {
12893         skipAssert(assert);
12894       }
12895     });
12896   }());
12897
12898   /*--------------------------------------------------------------------------*/
12899
12900   QUnit.module('keys methods');
12901
12902   lodashStable.each(['keys', 'keysIn'], function(methodName) {
12903     var func = _[methodName],
12904         isKeys = methodName == 'keys';
12905
12906     QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
12907       assert.expect(1);
12908
12909       var actual = func({ 'a': 1, 'b': 1 }).sort();
12910
12911       assert.deepEqual(actual, ['a', 'b']);
12912     });
12913
12914     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
12915       assert.expect(1);
12916
12917       function Foo() {
12918         this.a = 1;
12919       }
12920       Foo.prototype.b = 2;
12921
12922       var expected = isKeys ? ['a'] : ['a', 'b'],
12923           actual = func(new Foo).sort();
12924
12925       assert.deepEqual(actual, expected);
12926     });
12927
12928     QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
12929       assert.expect(1);
12930
12931       var array = [1];
12932       array[2] = 3;
12933
12934       var actual = func(array).sort();
12935
12936       assert.deepEqual(actual, ['0', '1', '2']);
12937     });
12938
12939     QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
12940       assert.expect(1);
12941
12942       var array = [1];
12943       array.a = 1;
12944
12945       var actual = func(array).sort();
12946
12947       assert.deepEqual(actual, ['0', 'a']);
12948     });
12949
12950     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
12951       assert.expect(1);
12952
12953       arrayProto.a = 1;
12954
12955       var expected = isKeys ? ['0'] : ['0', 'a'],
12956           actual = func([1]).sort();
12957
12958       assert.deepEqual(actual, expected);
12959
12960       delete arrayProto.a;
12961     });
12962
12963     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
12964       assert.expect(1);
12965
12966       var values = [args, strictArgs],
12967           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
12968
12969       var actual = lodashStable.map(values, function(value) {
12970         return func(value).sort();
12971       });
12972
12973       assert.deepEqual(actual, expected);
12974     });
12975
12976     QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
12977       assert.expect(1);
12978
12979       var values = [args, strictArgs],
12980           expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
12981
12982       var actual = lodashStable.map(values, function(value) {
12983         value.a = 1;
12984         var result = func(value).sort();
12985         delete value.a;
12986         return result;
12987       });
12988
12989       assert.deepEqual(actual, expected);
12990     });
12991
12992     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
12993       assert.expect(1);
12994
12995       var values = [args, strictArgs],
12996           expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
12997
12998       var actual = lodashStable.map(values, function(value) {
12999         objectProto.a = 1;
13000         var result = func(value).sort();
13001         delete objectProto.a;
13002         return result;
13003       });
13004
13005       assert.deepEqual(actual, expected);
13006     });
13007
13008     QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
13009       assert.expect(1);
13010
13011       var actual = func(Object('abc')).sort();
13012
13013       assert.deepEqual(actual, ['0', '1', '2']);
13014     });
13015
13016     QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
13017       assert.expect(1);
13018
13019       var object = Object('a');
13020       object.a = 1;
13021
13022       var actual = func(object).sort();
13023
13024       assert.deepEqual(actual, ['0', 'a']);
13025     });
13026
13027     QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
13028       assert.expect(1);
13029
13030       stringProto.a = 1;
13031
13032       var expected = isKeys ? ['0'] : ['0', 'a'],
13033           actual = func(Object('a')).sort();
13034
13035       assert.deepEqual(actual, expected);
13036
13037       delete stringProto.a;
13038     });
13039
13040     QUnit.test('`_.' + methodName + '` should work with array-like objects', function(assert) {
13041       assert.expect(1);
13042
13043       var object = { '0': 'a', 'length': 1 },
13044           actual = func(object).sort();
13045
13046       assert.deepEqual(actual, ['0', 'length']);
13047     });
13048
13049     QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
13050       assert.expect(2);
13051
13052       var expected = lodashStable.map(primitives, function(value) {
13053         return typeof value == 'string' ? ['0'] : [];
13054       });
13055
13056       var actual = lodashStable.map(primitives, func);
13057       assert.deepEqual(actual, expected);
13058
13059       // IE 9 doesn't box numbers in for-in loops.
13060       numberProto.a = 1;
13061       assert.deepEqual(func(0), isKeys ? [] : ['a']);
13062       delete numberProto.a;
13063     });
13064
13065     QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
13066       assert.expect(3);
13067
13068       function Foo() {}
13069       Foo.prototype.a = 1;
13070
13071       var expected = ['a'];
13072       assert.deepEqual(func(Foo.prototype), expected);
13073
13074       Foo.prototype = { 'constructor': Foo, 'a': 1 };
13075       assert.deepEqual(func(Foo.prototype), expected);
13076
13077       var Fake = { 'prototype': {} };
13078       Fake.prototype.constructor = Fake;
13079       assert.deepEqual(func(Fake.prototype), ['constructor']);
13080     });
13081
13082     QUnit.test('`_.' + methodName + '` should return an empty array when `object` is nullish', function(assert) {
13083       var values = [, null, undefined],
13084           expected = lodashStable.map(values, stubArray);
13085
13086       var actual = lodashStable.map(values, function(value, index) {
13087         objectProto.a = 1;
13088         var result = index ? func(value) : func();
13089         delete objectProto.a;
13090         return result;
13091       });
13092
13093       assert.deepEqual(actual, expected);
13094     });
13095   });
13096
13097   /*--------------------------------------------------------------------------*/
13098
13099   QUnit.module('lodash.last');
13100
13101   (function() {
13102     var array = [1, 2, 3, 4];
13103
13104     QUnit.test('should return the last element', function(assert) {
13105       assert.expect(1);
13106
13107       assert.strictEqual(_.last(array), 4);
13108     });
13109
13110     QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
13111       assert.expect(1);
13112
13113       var array = [];
13114       array['-1'] = 1;
13115
13116       assert.strictEqual(_.last([]), undefined);
13117     });
13118
13119     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
13120       assert.expect(1);
13121
13122       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
13123           actual = lodashStable.map(array, _.last);
13124
13125       assert.deepEqual(actual, [3, 6, 9]);
13126     });
13127
13128     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
13129       assert.expect(1);
13130
13131       if (!isNpm) {
13132         assert.strictEqual(_(array).last(), 4);
13133       }
13134       else {
13135         skipAssert(assert);
13136       }
13137     });
13138
13139     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
13140       assert.expect(1);
13141
13142       if (!isNpm) {
13143         assert.ok(_(array).chain().last() instanceof _);
13144       }
13145       else {
13146         skipAssert(assert);
13147       }
13148     });
13149
13150     QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
13151       assert.expect(1);
13152
13153       if (!isNpm) {
13154         var wrapped = _(array).chain().last();
13155         assert.strictEqual(wrapped.__wrapped__, array);
13156       }
13157       else {
13158         skipAssert(assert);
13159       }
13160     });
13161
13162     QUnit.test('should work in a lazy sequence', function(assert) {
13163       assert.expect(2);
13164
13165       if (!isNpm) {
13166         var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
13167             smallArray = array;
13168
13169         lodashStable.times(2, function(index) {
13170           var array = index ? largeArray : smallArray,
13171               wrapped = _(array).filter(isEven);
13172
13173           assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
13174         });
13175       }
13176       else {
13177         skipAssert(assert, 2);
13178       }
13179     });
13180   }());
13181
13182   /*--------------------------------------------------------------------------*/
13183
13184   QUnit.module('lodash.lowerCase');
13185
13186   (function() {
13187     QUnit.test('should lowercase as space-separated words', function(assert) {
13188       assert.expect(3);
13189
13190       assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
13191       assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
13192       assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
13193     });
13194   }());
13195
13196   /*--------------------------------------------------------------------------*/
13197
13198   QUnit.module('lodash.lowerFirst');
13199
13200   (function() {
13201     QUnit.test('should lowercase only the first character', function(assert) {
13202       assert.expect(3);
13203
13204       assert.strictEqual(_.lowerFirst('fred'), 'fred');
13205       assert.strictEqual(_.lowerFirst('Fred'), 'fred');
13206       assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
13207     });
13208   }());
13209
13210   /*--------------------------------------------------------------------------*/
13211
13212   QUnit.module('lodash.lt');
13213
13214   (function() {
13215     QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
13216       assert.expect(2);
13217
13218       assert.strictEqual(_.lt(1, 3), true);
13219       assert.strictEqual(_.lt('abc', 'def'), true);
13220     });
13221
13222     QUnit.test('should return `false` if `value` >= `other`', function(assert) {
13223       assert.expect(4);
13224
13225       assert.strictEqual(_.lt(3, 1), false);
13226       assert.strictEqual(_.lt(3, 3), false);
13227       assert.strictEqual(_.lt('def', 'abc'), false);
13228       assert.strictEqual(_.lt('def', 'def'), false);
13229     });
13230   }());
13231
13232   /*--------------------------------------------------------------------------*/
13233
13234   QUnit.module('lodash.lte');
13235
13236   (function() {
13237     QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
13238       assert.expect(4);
13239
13240       assert.strictEqual(_.lte(1, 3), true);
13241       assert.strictEqual(_.lte(3, 3), true);
13242       assert.strictEqual(_.lte('abc', 'def'), true);
13243       assert.strictEqual(_.lte('def', 'def'), true);
13244     });
13245
13246     QUnit.test('should return `false` if `value` > `other`', function(assert) {
13247       assert.expect(2);
13248
13249       assert.strictEqual(_.lt(3, 1), false);
13250       assert.strictEqual(_.lt('def', 'abc'), false);
13251     });
13252   }());
13253
13254   /*--------------------------------------------------------------------------*/
13255
13256   QUnit.module('lodash.findLastIndex and lodash.lastIndexOf');
13257
13258   lodashStable.each(['findLastIndex', 'lastIndexOf'], function(methodName) {
13259     var array = [1, 2, 3, 1, 2, 3],
13260         func = _[methodName],
13261         resolve = methodName == 'findLastIndex' ? lodashStable.curry(lodashStable.eq) : identity;
13262
13263     QUnit.test('`_.' + methodName + '` should return the index of the last matched value', function(assert) {
13264       assert.expect(1);
13265
13266       assert.strictEqual(func(array, resolve(3)), 5);
13267     });
13268
13269     QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
13270       assert.expect(1);
13271
13272       assert.strictEqual(func(array, resolve(1), 2), 0);
13273     });
13274
13275     QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
13276       assert.expect(1);
13277
13278       var values = [6, 8, Math.pow(2, 32), Infinity],
13279           expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
13280
13281       var actual = lodashStable.map(values, function(fromIndex) {
13282         return [
13283           func(array, resolve(undefined), fromIndex),
13284           func(array, resolve(1), fromIndex),
13285           func(array, resolve(''), fromIndex)
13286         ];
13287       });
13288
13289       assert.deepEqual(actual, expected);
13290     });
13291
13292     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
13293       assert.expect(1);
13294
13295       assert.strictEqual(func(array, resolve(2), -3), 1);
13296     });
13297
13298     QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
13299       assert.expect(1);
13300
13301       var values = [-6, -8, -Infinity],
13302           expected = lodashStable.map(values, stubZero);
13303
13304       var actual = lodashStable.map(values, function(fromIndex) {
13305         return func(array, resolve(1), fromIndex);
13306       });
13307
13308       assert.deepEqual(actual, expected);
13309     });
13310
13311     QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values correctly', function(assert) {
13312       assert.expect(1);
13313
13314       var expected = lodashStable.map(falsey, function(value) {
13315         return value === undefined ? 5 : -1;
13316       });
13317
13318       var actual = lodashStable.map(falsey, function(fromIndex) {
13319         return func(array, resolve(3), fromIndex);
13320       });
13321
13322       assert.deepEqual(actual, expected);
13323     });
13324
13325     QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
13326       assert.expect(1);
13327
13328       assert.strictEqual(func(array, resolve(2), 4.2), 4);
13329     });
13330   });
13331
13332   /*--------------------------------------------------------------------------*/
13333
13334   QUnit.module('indexOf methods');
13335
13336   lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
13337     var func = _[methodName],
13338         isIndexOf = !/last/i.test(methodName),
13339         isSorted = /^sorted/.test(methodName);
13340
13341     QUnit.test('`_.' + methodName + '` should accept a falsey `array`', function(assert) {
13342       assert.expect(1);
13343
13344       var expected = lodashStable.map(falsey, lodashStable.constant(-1));
13345
13346       var actual = lodashStable.map(falsey, function(array, index) {
13347         try {
13348           return index ? func(array) : func();
13349         } catch (e) {}
13350       });
13351
13352       assert.deepEqual(actual, expected);
13353     });
13354
13355     QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
13356       assert.expect(5);
13357
13358       var array = [1, 2, 3],
13359           empty = [];
13360
13361       assert.strictEqual(func(array, 4), -1);
13362       assert.strictEqual(func(array, 4, true), -1);
13363       assert.strictEqual(func(array, undefined, true), -1);
13364
13365       assert.strictEqual(func(empty, undefined), -1);
13366       assert.strictEqual(func(empty, undefined, true), -1);
13367     });
13368
13369     QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
13370       assert.expect(2);
13371
13372       var array = [];
13373       array[-1] = 0;
13374
13375       assert.strictEqual(func(array, undefined), -1);
13376       assert.strictEqual(func(array, 0, true), -1);
13377     });
13378
13379     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
13380       assert.expect(3);
13381
13382       var array = isSorted
13383         ? [1, 2, NaN, NaN]
13384         : [1, NaN, 3, NaN, 5, NaN];
13385
13386       if (isSorted) {
13387         assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
13388         skipAssert(assert, 2);
13389       }
13390       else {
13391         assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
13392         assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
13393         assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
13394       }
13395     });
13396
13397     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13398       assert.expect(2);
13399
13400       assert.strictEqual(func([-0], 0), 0);
13401       assert.strictEqual(func([0], -0), 0);
13402     });
13403   });
13404
13405   /*--------------------------------------------------------------------------*/
13406
13407   QUnit.module('lodash.map');
13408
13409   (function() {
13410     var array = [1, 2];
13411
13412     QUnit.test('should map values in `collection` to a new array', function(assert) {
13413       assert.expect(2);
13414
13415       var object = { 'a': 1, 'b': 2 },
13416           expected = ['1', '2'];
13417
13418       assert.deepEqual(_.map(array, String), expected);
13419       assert.deepEqual(_.map(object, String), expected);
13420     });
13421
13422     QUnit.test('should work with `_.property` shorthands', function(assert) {
13423       assert.expect(1);
13424
13425       var objects = [{ 'a': 'x' }, { 'a': 'y' }];
13426       assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
13427     });
13428
13429     QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
13430       assert.expect(1);
13431
13432       function Foo() {
13433         this.a = 1;
13434       }
13435       Foo.prototype.b = 2;
13436
13437       var actual = _.map(new Foo, identity);
13438       assert.deepEqual(actual, [1]);
13439     });
13440
13441     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13442       assert.expect(2);
13443
13444       var object = { 'a': 1, 'b': 2 },
13445           values = [, null, undefined],
13446           expected = lodashStable.map(values, lodashStable.constant([1, 2]));
13447
13448       lodashStable.each([array, object], function(collection) {
13449         var actual = lodashStable.map(values, function(value, index) {
13450           return index ? _.map(collection, value) : _.map(collection);
13451         });
13452
13453         assert.deepEqual(actual, expected);
13454       });
13455     });
13456
13457     QUnit.test('should accept a falsey `collection`', function(assert) {
13458       assert.expect(1);
13459
13460       var expected = lodashStable.map(falsey, stubArray);
13461
13462       var actual = lodashStable.map(falsey, function(collection, index) {
13463         try {
13464           return index ? _.map(collection) : _.map();
13465         } catch (e) {}
13466       });
13467
13468       assert.deepEqual(actual, expected);
13469     });
13470
13471     QUnit.test('should treat number values for `collection` as empty', function(assert) {
13472       assert.expect(1);
13473
13474       assert.deepEqual(_.map(1), []);
13475     });
13476
13477     QUnit.test('should treat a nodelist as an array-like object', function(assert) {
13478       assert.expect(1);
13479
13480       if (document) {
13481         var actual = _.map(document.getElementsByTagName('body'), function(element) {
13482           return element.nodeName.toLowerCase();
13483         });
13484
13485         assert.deepEqual(actual, ['body']);
13486       }
13487       else {
13488         skipAssert(assert);
13489       }
13490     });
13491
13492     QUnit.test('should work with objects with non-number length properties', function(assert) {
13493       assert.expect(1);
13494
13495       var value = { 'value': 'x' },
13496           object = { 'length': { 'value': 'x' } };
13497
13498       assert.deepEqual(_.map(object, identity), [value]);
13499     });
13500
13501     QUnit.test('should return a wrapped value when chaining', function(assert) {
13502       assert.expect(1);
13503
13504       if (!isNpm) {
13505         assert.ok(_(array).map(noop) instanceof _);
13506       }
13507       else {
13508         skipAssert(assert);
13509       }
13510     });
13511
13512     QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
13513       assert.expect(5);
13514
13515       if (!isNpm) {
13516         var args,
13517             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
13518             expected = [1, 0, _.map(array.slice(1), square)];
13519
13520         _(array).slice(1).map(function(value, index, array) {
13521           args || (args = slice.call(arguments));
13522         }).value();
13523
13524         assert.deepEqual(args, [1, 0, array.slice(1)]);
13525
13526         args = undefined;
13527         _(array).slice(1).map(square).map(function(value, index, array) {
13528           args || (args = slice.call(arguments));
13529         }).value();
13530
13531         assert.deepEqual(args, expected);
13532
13533         args = undefined;
13534         _(array).slice(1).map(square).map(function(value, index) {
13535           args || (args = slice.call(arguments));
13536         }).value();
13537
13538         assert.deepEqual(args, expected);
13539
13540         args = undefined;
13541         _(array).slice(1).map(square).map(function(value) {
13542           args || (args = slice.call(arguments));
13543         }).value();
13544
13545         assert.deepEqual(args, [1]);
13546
13547         args = undefined;
13548         _(array).slice(1).map(square).map(function() {
13549           args || (args = slice.call(arguments));
13550         }).value();
13551
13552         assert.deepEqual(args, expected);
13553       }
13554       else {
13555         skipAssert(assert, 5);
13556       }
13557     });
13558   }());
13559
13560   /*--------------------------------------------------------------------------*/
13561
13562   QUnit.module('lodash.mapKeys');
13563
13564   (function() {
13565     var array = [1, 2],
13566         object = { 'a': 1, 'b': 2 };
13567
13568     QUnit.test('should map keys in `object` to a new object', function(assert) {
13569       assert.expect(1);
13570
13571       var actual = _.mapKeys(object, String);
13572       assert.deepEqual(actual, { '1': 1, '2': 2 });
13573     });
13574
13575     QUnit.test('should treat arrays like objects', function(assert) {
13576       assert.expect(1);
13577
13578       var actual = _.mapKeys(array, String);
13579       assert.deepEqual(actual, { '1': 1, '2': 2 });
13580     });
13581
13582     QUnit.test('should work with `_.property` shorthands', function(assert) {
13583       assert.expect(1);
13584
13585       var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
13586       assert.deepEqual(actual, { 'c': { 'b': 'c' } });
13587     });
13588
13589     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13590       assert.expect(1);
13591
13592       var object = { 'a': 1, 'b': 2 },
13593           values = [, null, undefined],
13594           expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
13595
13596       var actual = lodashStable.map(values, function(value, index) {
13597         return index ? _.mapKeys(object, value) : _.mapKeys(object);
13598       });
13599
13600       assert.deepEqual(actual, expected);
13601     });
13602   }());
13603
13604   /*--------------------------------------------------------------------------*/
13605
13606   QUnit.module('lodash.mapValues');
13607
13608   (function() {
13609     var array = [1, 2],
13610         object = { 'a': 1, 'b': 2 };
13611
13612     QUnit.test('should map values in `object` to a new object', function(assert) {
13613       assert.expect(1);
13614
13615       var actual = _.mapValues(object, String);
13616       assert.deepEqual(actual, { 'a': '1', 'b': '2' });
13617     });
13618
13619     QUnit.test('should treat arrays like objects', function(assert) {
13620       assert.expect(1);
13621
13622       var actual = _.mapValues(array, String);
13623       assert.deepEqual(actual, { '0': '1', '1': '2' });
13624     });
13625
13626     QUnit.test('should work with `_.property` shorthands', function(assert) {
13627       assert.expect(1);
13628
13629       var actual = _.mapValues({ 'a': { 'b': 2 } }, 'b');
13630       assert.deepEqual(actual, { 'a': 2 });
13631     });
13632
13633     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13634       assert.expect(1);
13635
13636       var object = { 'a': 1, 'b': 2 },
13637           values = [, null, undefined],
13638           expected = lodashStable.map(values, lodashStable.constant([true, false]));
13639
13640       var actual = lodashStable.map(values, function(value, index) {
13641         var result = index ? _.mapValues(object, value) : _.mapValues(object);
13642         return [lodashStable.isEqual(result, object), result === object];
13643       });
13644
13645       assert.deepEqual(actual, expected);
13646     });
13647   }());
13648
13649   /*--------------------------------------------------------------------------*/
13650
13651   QUnit.module('lodash.mapKeys and lodash.mapValues');
13652
13653   lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
13654     var func = _[methodName],
13655         object = { 'a': 1, 'b': 2 };
13656
13657     QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
13658       assert.expect(1);
13659
13660       function Foo() {
13661         this.a = 'a';
13662       }
13663       Foo.prototype.b = 'b';
13664
13665       var actual = func(new Foo, function(value, key) { return key; });
13666       assert.deepEqual(actual, { 'a': 'a' });
13667     });
13668
13669     QUnit.test('`_.' + methodName + '` should accept a falsey `object`', function(assert) {
13670       assert.expect(1);
13671
13672       var expected = lodashStable.map(falsey, stubObject);
13673
13674       var actual = lodashStable.map(falsey, function(object, index) {
13675         try {
13676           return index ? func(object) : func();
13677         } catch (e) {}
13678       });
13679
13680       assert.deepEqual(actual, expected);
13681     });
13682
13683     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
13684       assert.expect(1);
13685
13686       if (!isNpm) {
13687         assert.ok(_(object)[methodName](noop) instanceof _);
13688       }
13689       else {
13690         skipAssert(assert);
13691       }
13692     });
13693   });
13694
13695   QUnit.module('lodash.matches');
13696
13697   (function() {
13698     QUnit.test('should not change behavior if `source` is modified', function(assert) {
13699       assert.expect(9);
13700
13701       var sources = [
13702         { 'a': { 'b': 2, 'c': 3 } },
13703         { 'a': 1, 'b': 2 },
13704         { 'a': 1 }
13705       ];
13706
13707       lodashStable.each(sources, function(source, index) {
13708         var object = lodashStable.cloneDeep(source),
13709             par = _.matches(source);
13710
13711         assert.strictEqual(par(object), true);
13712
13713         if (index) {
13714           source.a = 2;
13715           source.b = 1;
13716           source.c = 3;
13717         } else {
13718           source.a.b = 1;
13719           source.a.c = 2;
13720           source.a.d = 3;
13721         }
13722         assert.strictEqual(par(object), true);
13723         assert.strictEqual(par(source), false);
13724       });
13725     });
13726   }());
13727
13728   /*--------------------------------------------------------------------------*/
13729
13730   QUnit.module('matches methods');
13731
13732   lodashStable.each(['matches', 'isMatch'], function(methodName) {
13733     var isMatches = methodName == 'matches';
13734
13735     function matches(source) {
13736       return isMatches ? _.matches(source) : function(object) {
13737         return _.isMatch(object, source);
13738       };
13739     }
13740
13741     QUnit.test('`_.' + methodName + '` should perform a deep comparison between `source` and `object`', function(assert) {
13742       assert.expect(5);
13743
13744       var object = { 'a': 1, 'b': 2, 'c': 3 },
13745           par = matches({ 'a': 1 });
13746
13747       assert.strictEqual(par(object), true);
13748
13749       par = matches({ 'b': 1 });
13750       assert.strictEqual(par(object), false);
13751
13752       par = matches({ 'a': 1, 'c': 3 });
13753       assert.strictEqual(par(object), true);
13754
13755       par = matches({ 'c': 3, 'd': 4 });
13756       assert.strictEqual(par(object), false);
13757
13758       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13759       par = matches({ 'a': { 'b': { 'c': 1 } } });
13760
13761       assert.strictEqual(par(object), true);
13762     });
13763
13764     QUnit.test('`_.' + methodName + '` should match inherited string keyed `object` properties', function(assert) {
13765       assert.expect(1);
13766
13767       function Foo() {
13768         this.a = 1;
13769       }
13770       Foo.prototype.b = 2;
13771
13772       var object = { 'a': new Foo },
13773           par = matches({ 'a': { 'b': 2 } });
13774
13775       assert.strictEqual(par(object), true);
13776     });
13777
13778     QUnit.test('`_.' + methodName + '` should not match by inherited `source` properties', function(assert) {
13779       assert.expect(1);
13780
13781       function Foo() {
13782         this.a = 1;
13783       }
13784       Foo.prototype.b = 2;
13785
13786       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
13787           source = new Foo,
13788           actual = lodashStable.map(objects, matches(source)),
13789           expected = lodashStable.map(objects, stubTrue);
13790
13791       assert.deepEqual(actual, expected);
13792     });
13793
13794     QUnit.test('`_.' + methodName + '` should compare a variety of `source` property values', function(assert) {
13795       assert.expect(2);
13796
13797       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13798           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13799           par = matches(object1);
13800
13801       assert.strictEqual(par(object1), true);
13802       assert.strictEqual(par(object2), false);
13803     });
13804
13805     QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13806       assert.expect(2);
13807
13808       var object1 = { 'a': -0 },
13809           object2 = { 'a': 0 },
13810           par = matches(object1);
13811
13812       assert.strictEqual(par(object2), true);
13813
13814       par = matches(object2);
13815       assert.strictEqual(par(object1), true);
13816     });
13817
13818     QUnit.test('`_.' + methodName + '` should compare functions by reference', function(assert) {
13819       assert.expect(3);
13820
13821       var object1 = { 'a': lodashStable.noop },
13822           object2 = { 'a': noop },
13823           object3 = { 'a': {} },
13824           par = matches(object1);
13825
13826       assert.strictEqual(par(object1), true);
13827       assert.strictEqual(par(object2), false);
13828       assert.strictEqual(par(object3), false);
13829     });
13830
13831     QUnit.test('`_.' + methodName + '` should work with a function for `object`', function(assert) {
13832       assert.expect(1);
13833
13834       function Foo() {}
13835       Foo.a = { 'b': 2, 'c': 3 };
13836
13837       var par = matches({ 'a': { 'b': 2 } });
13838       assert.strictEqual(par(Foo), true);
13839     });
13840
13841     QUnit.test('`_.' + methodName + '` should work with a function for `source`', function(assert) {
13842       assert.expect(1);
13843
13844       function Foo() {}
13845       Foo.a = 1;
13846       Foo.b = function() {};
13847       Foo.c = 3;
13848
13849       var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
13850           actual = lodashStable.map(objects, matches(Foo));
13851
13852       assert.deepEqual(actual, [false, true]);
13853     });
13854
13855     QUnit.test('`_.' + methodName + '` should work with a non-plain `object`', function(assert) {
13856       assert.expect(1);
13857
13858       function Foo(object) { lodashStable.assign(this, object); }
13859
13860       var object = new Foo({ 'a': new Foo({ 'b': 2, 'c': 3 }) }),
13861           par = matches({ 'a': { 'b': 2 } });
13862
13863       assert.strictEqual(par(object), true);
13864     });
13865
13866     QUnit.test('`_.' + methodName + '` should partial match arrays', function(assert) {
13867       assert.expect(3);
13868
13869       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13870           actual = lodashStable.filter(objects, matches({ 'a': ['d'] }));
13871
13872       assert.deepEqual(actual, [objects[1]]);
13873
13874       actual = lodashStable.filter(objects, matches({ 'a': ['b', 'd'] }));
13875       assert.deepEqual(actual, []);
13876
13877       actual = lodashStable.filter(objects, matches({ 'a': ['d', 'b'] }));
13878       assert.deepEqual(actual, []);
13879     });
13880
13881     QUnit.test('`_.' + methodName + '` should partial match arrays with duplicate values', function(assert) {
13882       assert.expect(1);
13883
13884       var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
13885           actual = lodashStable.filter(objects, matches({ 'a': [2, 2] }));
13886
13887       assert.deepEqual(actual, [objects[1]]);
13888     });
13889
13890     QUnit.test('should partial match arrays of objects', function(assert) {
13891       assert.expect(1);
13892
13893       var objects = [
13894         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
13895         { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
13896       ];
13897
13898       var actual = lodashStable.filter(objects, matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
13899       assert.deepEqual(actual, [objects[0]]);
13900     });
13901
13902     QUnit.test('`_.' + methodName + '` should partial match maps', function(assert) {
13903       assert.expect(3);
13904
13905       if (Map) {
13906         var objects = [{ 'a': new Map }, { 'a': new Map }];
13907         objects[0].a.set('a', 1);
13908         objects[1].a.set('a', 1);
13909         objects[1].a.set('b', 2);
13910
13911         var map = new Map;
13912         map.set('b', 2);
13913         var actual = lodashStable.filter(objects, matches({ 'a': map }));
13914
13915         assert.deepEqual(actual, [objects[1]]);
13916
13917         map.delete('b');
13918         actual = lodashStable.filter(objects, matches({ 'a': map }));
13919
13920         assert.deepEqual(actual, objects);
13921
13922         map.set('c', 3);
13923         actual = lodashStable.filter(objects, matches({ 'a': map }));
13924
13925         assert.deepEqual(actual, []);
13926       }
13927       else {
13928         skipAssert(assert, 3);
13929       }
13930     });
13931
13932     QUnit.test('`_.' + methodName + '` should partial match sets', function(assert) {
13933       assert.expect(3);
13934
13935       if (Set) {
13936         var objects = [{ 'a': new Set }, { 'a': new Set }];
13937         objects[0].a.add(1);
13938         objects[1].a.add(1);
13939         objects[1].a.add(2);
13940
13941         var set = new Set;
13942         set.add(2);
13943         var actual = lodashStable.filter(objects, matches({ 'a': set }));
13944
13945         assert.deepEqual(actual, [objects[1]]);
13946
13947         set.delete(2);
13948         actual = lodashStable.filter(objects, matches({ 'a': set }));
13949
13950         assert.deepEqual(actual, objects);
13951
13952         set.add(3);
13953         actual = lodashStable.filter(objects, matches({ 'a': set }));
13954
13955         assert.deepEqual(actual, []);
13956       }
13957       else {
13958         skipAssert(assert, 3);
13959       }
13960     });
13961
13962     QUnit.test('`_.' + methodName + '` should match `undefined` values', function(assert) {
13963       assert.expect(3);
13964
13965       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
13966           actual = lodashStable.map(objects, matches({ 'b': undefined })),
13967           expected = [false, false, true];
13968
13969       assert.deepEqual(actual, expected);
13970
13971       actual = lodashStable.map(objects, matches({ 'a': 1, 'b': undefined }));
13972
13973       assert.deepEqual(actual, expected);
13974
13975       objects = [{ 'a': { 'b': 2 } }, { 'a': { 'b': 2, 'c': 3 } }, { 'a': { 'b': 2, 'c': undefined } }];
13976       actual = lodashStable.map(objects, matches({ 'a': { 'c': undefined } }));
13977
13978       assert.deepEqual(actual, expected);
13979     });
13980
13981     QUnit.test('`_.' + methodName + '` should match `undefined` values on primitives', function(assert) {
13982       assert.expect(3);
13983
13984       numberProto.a = 1;
13985       numberProto.b = undefined;
13986
13987       try {
13988         var par = matches({ 'b': undefined });
13989         assert.strictEqual(par(1), true);
13990       } catch (e) {
13991         assert.ok(false, e.message);
13992       }
13993       try {
13994         par = matches({ 'a': 1, 'b': undefined });
13995         assert.strictEqual(par(1), true);
13996       } catch (e) {
13997         assert.ok(false, e.message);
13998       }
13999       numberProto.a = { 'b': 1, 'c': undefined };
14000       try {
14001         par = matches({ 'a': { 'c': undefined } });
14002         assert.strictEqual(par(1), true);
14003       } catch (e) {
14004         assert.ok(false, e.message);
14005       }
14006       delete numberProto.a;
14007       delete numberProto.b;
14008     });
14009
14010     QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
14011       assert.expect(1);
14012
14013       var values = [, null, undefined],
14014           expected = lodashStable.map(values, stubFalse),
14015           par = matches({ 'a': 1 });
14016
14017       var actual = lodashStable.map(values, function(value, index) {
14018         try {
14019           return index ? par(value) : par();
14020         } catch (e) {}
14021       });
14022
14023       assert.deepEqual(actual, expected);
14024     });
14025
14026     QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source`', function(assert) {
14027       assert.expect(1);
14028
14029       var object = { 'a': 1 },
14030           expected = lodashStable.map(empties, stubTrue);
14031
14032       var actual = lodashStable.map(empties, function(value) {
14033         var par = matches(value);
14034         return par(object);
14035       });
14036
14037       assert.deepEqual(actual, expected);
14038     });
14039
14040     QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
14041       assert.expect(1);
14042
14043       var values = [, null, undefined],
14044           expected = lodashStable.map(values, stubTrue),
14045           par = matches({});
14046
14047       var actual = lodashStable.map(values, function(value, index) {
14048         try {
14049           return index ? par(value) : par();
14050         } catch (e) {}
14051       });
14052
14053       assert.deepEqual(actual, expected);
14054     });
14055
14056     QUnit.test('`_.' + methodName + '` should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
14057       assert.expect(1);
14058
14059       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14060           actual = lodashStable.filter(objects, matches({ 'a': [], 'b': {} }));
14061
14062       assert.deepEqual(actual, objects);
14063     });
14064   });
14065
14066   /*--------------------------------------------------------------------------*/
14067
14068   QUnit.module('lodash.matchesProperty');
14069
14070   (function() {
14071     QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
14072       assert.expect(6);
14073
14074       var object = { 'a': 1, 'b': 2, 'c': 3 },
14075           matches = _.matchesProperty('a', 1);
14076
14077       assert.strictEqual(matches.length, 1);
14078       assert.strictEqual(matches(object), true);
14079
14080       matches = _.matchesProperty('b', 3);
14081       assert.strictEqual(matches(object), false);
14082
14083       matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
14084       assert.strictEqual(matches({ 'a': object }), true);
14085
14086       matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
14087       assert.strictEqual(matches(object), false);
14088
14089       object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
14090       matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
14091
14092       assert.strictEqual(matches(object), true);
14093     });
14094
14095     QUnit.test('should support deep paths', function(assert) {
14096       assert.expect(2);
14097
14098       var object = { 'a': { 'b': 2 } };
14099
14100       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14101         var matches = _.matchesProperty(path, 2);
14102         assert.strictEqual(matches(object), true);
14103       });
14104     });
14105
14106     QUnit.test('should work with a non-string `path`', function(assert) {
14107       assert.expect(2);
14108
14109       var array = [1, 2, 3];
14110
14111       lodashStable.each([1, [1]], function(path) {
14112         var matches = _.matchesProperty(path, 2);
14113         assert.strictEqual(matches(array), true);
14114       });
14115     });
14116
14117     QUnit.test('should preserve the sign of `0`', function(assert) {
14118       assert.expect(1);
14119
14120       var object1 = { '-0': 'a' },
14121           object2 = { '0': 'b' },
14122           pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
14123           props = [-0, Object(-0), 0, Object(0)],
14124           values = ['a', 'a', 'b', 'b'],
14125           expected = lodashStable.map(props, lodashStable.constant([true, false]));
14126
14127       var actual = lodashStable.map(props, function(key, index) {
14128         var matches = _.matchesProperty(key, values[index]),
14129             pair = pairs[index];
14130
14131         return [matches(pair[0]), matches(pair[1])];
14132       });
14133
14134       assert.deepEqual(actual, expected);
14135     });
14136
14137     QUnit.test('should coerce `path` to a string', function(assert) {
14138       assert.expect(2);
14139
14140       function fn() {}
14141       fn.toString = lodashStable.constant('fn');
14142
14143       var object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
14144           paths = [null, undefined, fn, {}],
14145           expected = lodashStable.map(paths, stubTrue);
14146
14147       lodashStable.times(2, function(index) {
14148         var actual = lodashStable.map(paths, function(path) {
14149           var matches = _.matchesProperty(index ? [path] : path, object[path]);
14150           return matches(object);
14151         });
14152
14153         assert.deepEqual(actual, expected);
14154       });
14155     });
14156
14157     QUnit.test('should match a key over a path', function(assert) {
14158       assert.expect(2);
14159
14160       var object = { 'a.b': 1, 'a': { 'b': 2 } };
14161
14162       lodashStable.each(['a.b', ['a.b']], function(path) {
14163         var matches = _.matchesProperty(path, 1);
14164         assert.strictEqual(matches(object), true);
14165       });
14166     });
14167
14168     QUnit.test('should return `false` when `object` is nullish', function(assert) {
14169       assert.expect(2);
14170
14171       var values = [, null, undefined],
14172           expected = lodashStable.map(values, stubFalse);
14173
14174       lodashStable.each(['constructor', ['constructor']], function(path) {
14175         var matches = _.matchesProperty(path, 1);
14176
14177         var actual = lodashStable.map(values, function(value, index) {
14178           try {
14179             return index ? matches(value) : matches();
14180           } catch (e) {}
14181         });
14182
14183         assert.deepEqual(actual, expected);
14184       });
14185     });
14186
14187     QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
14188       assert.expect(2);
14189
14190       var values = [, null, undefined],
14191           expected = lodashStable.map(values, stubFalse);
14192
14193       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
14194         var matches = _.matchesProperty(path, 1);
14195
14196         var actual = lodashStable.map(values, function(value, index) {
14197           try {
14198             return index ? matches(value) : matches();
14199           } catch (e) {}
14200         });
14201
14202         assert.deepEqual(actual, expected);
14203       });
14204     });
14205
14206     QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
14207       assert.expect(4);
14208
14209       var object = {};
14210
14211       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
14212         var matches = _.matchesProperty(path, 1);
14213         assert.strictEqual(matches(object), false);
14214       });
14215     });
14216
14217     QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
14218       assert.expect(2);
14219
14220       function Foo() {}
14221       Foo.prototype.b = 2;
14222
14223       var object = { 'a': new Foo };
14224
14225       lodashStable.each(['a', ['a']], function(path) {
14226         var matches = _.matchesProperty(path, { 'b': 2 });
14227         assert.strictEqual(matches(object), true);
14228       });
14229     });
14230
14231     QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
14232       assert.expect(2);
14233
14234       function Foo() {
14235         this.a = 1;
14236       }
14237       Foo.prototype.b = 2;
14238
14239       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
14240           expected = lodashStable.map(objects, stubTrue);
14241
14242       lodashStable.each(['a', ['a']], function(path) {
14243         assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
14244       });
14245     });
14246
14247     QUnit.test('should compare a variety of values', function(assert) {
14248       assert.expect(2);
14249
14250       var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
14251           object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
14252           matches = _.matchesProperty('a', object1);
14253
14254       assert.strictEqual(matches({ 'a': object1 }), true);
14255       assert.strictEqual(matches({ 'a': object2 }), false);
14256     });
14257
14258     QUnit.test('should match `-0` as `0`', function(assert) {
14259       assert.expect(2);
14260
14261       var matches = _.matchesProperty('a', -0);
14262       assert.strictEqual(matches({ 'a': 0 }), true);
14263
14264       matches = _.matchesProperty('a', 0);
14265       assert.strictEqual(matches({ 'a': -0 }), true);
14266     });
14267
14268     QUnit.test('should compare functions by reference', function(assert) {
14269       assert.expect(3);
14270
14271       var object1 = { 'a': lodashStable.noop },
14272           object2 = { 'a': noop },
14273           object3 = { 'a': {} },
14274           matches = _.matchesProperty('a', object1);
14275
14276       assert.strictEqual(matches({ 'a': object1 }), true);
14277       assert.strictEqual(matches({ 'a': object2 }), false);
14278       assert.strictEqual(matches({ 'a': object3 }), false);
14279     });
14280
14281     QUnit.test('should work with a function for `srcValue`', function(assert) {
14282       assert.expect(1);
14283
14284       function Foo() {}
14285       Foo.a = 1;
14286       Foo.b = function() {};
14287       Foo.c = 3;
14288
14289       var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
14290           actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
14291
14292       assert.deepEqual(actual, [false, true]);
14293     });
14294
14295     QUnit.test('should work with a non-plain `srcValue`', function(assert) {
14296       assert.expect(1);
14297
14298       function Foo(object) { lodashStable.assign(this, object); }
14299
14300       var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
14301           matches = _.matchesProperty('a', { 'b': 1 });
14302
14303       assert.strictEqual(matches(object), true);
14304     });
14305
14306     QUnit.test('should partial match arrays', function(assert) {
14307       assert.expect(3);
14308
14309       var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
14310           actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
14311
14312       assert.deepEqual(actual, [objects[1]]);
14313
14314       actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
14315       assert.deepEqual(actual, []);
14316
14317       actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
14318       assert.deepEqual(actual, []);
14319     });
14320
14321     QUnit.test('should partial match arrays with duplicate values', function(assert) {
14322       assert.expect(1);
14323
14324       var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
14325           actual = lodashStable.filter(objects, _.matchesProperty('a', [2, 2]));
14326
14327       assert.deepEqual(actual, [objects[1]]);
14328     });
14329
14330     QUnit.test('should partial match arrays of objects', function(assert) {
14331       assert.expect(1);
14332
14333       var objects = [
14334         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
14335         { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
14336       ];
14337
14338       var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
14339       assert.deepEqual(actual, [objects[0]]);
14340     });
14341     QUnit.test('should partial match maps', function(assert) {
14342       assert.expect(3);
14343
14344       if (Map) {
14345         var objects = [{ 'a': new Map }, { 'a': new Map }];
14346         objects[0].a.set('a', 1);
14347         objects[1].a.set('a', 1);
14348         objects[1].a.set('b', 2);
14349
14350         var map = new Map;
14351         map.set('b', 2);
14352         var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14353
14354         assert.deepEqual(actual, [objects[1]]);
14355
14356         map.delete('b');
14357         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14358
14359         assert.deepEqual(actual, objects);
14360
14361         map.set('c', 3);
14362         actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14363
14364         assert.deepEqual(actual, []);
14365       }
14366       else {
14367         skipAssert(assert, 3);
14368       }
14369     });
14370
14371     QUnit.test('should partial match sets', function(assert) {
14372       assert.expect(3);
14373
14374       if (Set) {
14375         var objects = [{ 'a': new Set }, { 'a': new Set }];
14376         objects[0].a.add(1);
14377         objects[1].a.add(1);
14378         objects[1].a.add(2);
14379
14380         var set = new Set;
14381         set.add(2);
14382         var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14383
14384         assert.deepEqual(actual, [objects[1]]);
14385
14386         set.delete(2);
14387         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14388
14389         assert.deepEqual(actual, objects);
14390
14391         set.add(3);
14392         actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14393
14394         assert.deepEqual(actual, []);
14395       }
14396       else {
14397         skipAssert(assert, 3);
14398       }
14399     });
14400
14401     QUnit.test('should match `undefined` values', function(assert) {
14402       assert.expect(2);
14403
14404       var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14405           actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
14406           expected = [false, false, true];
14407
14408       assert.deepEqual(actual, expected);
14409
14410       objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
14411       actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
14412
14413       assert.deepEqual(actual, expected);
14414     });
14415
14416     QUnit.test('should match `undefined` values of nested objects', function(assert) {
14417       assert.expect(4);
14418
14419       var object = { 'a': { 'b': undefined } };
14420
14421       lodashStable.each(['a.b', ['a', 'b']], function(path) {
14422         var matches = _.matchesProperty(path, undefined);
14423         assert.strictEqual(matches(object), true);
14424       });
14425
14426       lodashStable.each(['a.a', ['a', 'a']], function(path) {
14427         var matches = _.matchesProperty(path, undefined);
14428         assert.strictEqual(matches(object), false);
14429       });
14430     });
14431
14432     QUnit.test('should match `undefined` values on primitives', function(assert) {
14433       assert.expect(2);
14434
14435       numberProto.a = 1;
14436       numberProto.b = undefined;
14437
14438       try {
14439         var matches = _.matchesProperty('b', undefined);
14440         assert.strictEqual(matches(1), true);
14441       } catch (e) {
14442         assert.ok(false, e.message);
14443       }
14444       numberProto.a = { 'b': 1, 'c': undefined };
14445       try {
14446         matches = _.matchesProperty('a', { 'c': undefined });
14447         assert.strictEqual(matches(1), true);
14448       } catch (e) {
14449         assert.ok(false, e.message);
14450       }
14451       delete numberProto.a;
14452       delete numberProto.b;
14453     });
14454
14455     QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
14456       assert.expect(1);
14457
14458       var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14459           matches = _.matchesProperty('a', { 'a': [], 'b': {} });
14460
14461       var actual = lodashStable.filter(objects, function(object) {
14462         return matches({ 'a': object });
14463       });
14464
14465       assert.deepEqual(actual, objects);
14466     });
14467
14468     QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
14469       assert.expect(9);
14470
14471       lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
14472         var object = lodashStable.cloneDeep(source),
14473             matches = _.matchesProperty('a', source);
14474
14475         assert.strictEqual(matches({ 'a': object }), true);
14476
14477         if (index) {
14478           source.a = 2;
14479           source.b = 1;
14480           source.c = 3;
14481         } else {
14482           source.a.b = 1;
14483           source.a.c = 2;
14484           source.a.d = 3;
14485         }
14486         assert.strictEqual(matches({ 'a': object }), true);
14487         assert.strictEqual(matches({ 'a': source }), false);
14488       });
14489     });
14490   }());
14491
14492   /*--------------------------------------------------------------------------*/
14493
14494   QUnit.module('lodash.max');
14495
14496   (function() {
14497     QUnit.test('should return the largest value from a collection', function(assert) {
14498       assert.expect(1);
14499
14500       assert.strictEqual(_.max([1, 2, 3]), 3);
14501     });
14502
14503     QUnit.test('should return `undefined` for empty collections', function(assert) {
14504       assert.expect(1);
14505
14506       var values = falsey.concat([[]]),
14507           expected = lodashStable.map(values, noop);
14508
14509       var actual = lodashStable.map(values, function(value, index) {
14510         try {
14511           return index ? _.max(value) : _.max();
14512         } catch (e) {}
14513       });
14514
14515       assert.deepEqual(actual, expected);
14516     });
14517
14518     QUnit.test('should work with non-numeric collection values', function(assert) {
14519       assert.expect(1);
14520
14521       assert.strictEqual(_.max(['a', 'b']), 'b');
14522     });
14523   }());
14524
14525   /*--------------------------------------------------------------------------*/
14526
14527   QUnit.module('lodash.mean');
14528
14529   (function() {
14530     QUnit.test('should return the mean of an array of numbers', function(assert) {
14531       assert.expect(1);
14532
14533       var array = [4, 2, 8, 6];
14534       assert.strictEqual(_.mean(array), 5);
14535     });
14536
14537     QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
14538       assert.expect(1);
14539
14540       var expected = lodashStable.map(empties, stubNaN),
14541           actual = lodashStable.map(empties, _.mean);
14542
14543       assert.deepEqual(actual, expected);
14544     });
14545   }());
14546
14547   /*--------------------------------------------------------------------------*/
14548
14549   QUnit.module('lodash.meanBy');
14550
14551   (function() {
14552     var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
14553
14554     QUnit.test('should work with an `iteratee`', function(assert) {
14555       assert.expect(1);
14556
14557       var actual = _.meanBy(objects, function(object) {
14558         return object.a;
14559       });
14560
14561       assert.deepEqual(actual, 2);
14562     });
14563
14564     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
14565       assert.expect(1);
14566
14567       var args;
14568
14569       _.meanBy(objects, function() {
14570         args || (args = slice.call(arguments));
14571       });
14572
14573       assert.deepEqual(args, [{ 'a': 2 }]);
14574     });
14575
14576     QUnit.test('should work with `_.property` shorthands', function(assert) {
14577       assert.expect(2);
14578
14579       var arrays = [[2], [3], [1]];
14580       assert.strictEqual(_.meanBy(arrays, 0), 2);
14581       assert.strictEqual(_.meanBy(objects, 'a'), 2);
14582     });
14583   }());
14584
14585   /*--------------------------------------------------------------------------*/
14586
14587   QUnit.module('lodash.memoize');
14588
14589   (function() {
14590     function CustomCache() {
14591       this.clear();
14592     }
14593
14594     CustomCache.prototype = {
14595       'clear': function() {
14596         this.__data__ = [];
14597         return this;
14598       },
14599       'get': function(key) {
14600         var entry = lodashStable.find(this.__data__, ['key', key]);
14601         return entry && entry.value;
14602       },
14603       'has': function(key) {
14604         return lodashStable.some(this.__data__, ['key', key]);
14605       },
14606       'set': function(key, value) {
14607         this.__data__.push({ 'key': key, 'value': value });
14608         return this;
14609       }
14610     };
14611
14612     function ImmutableCache() {
14613       this.__data__ = [];
14614     }
14615
14616     ImmutableCache.prototype = lodashStable.create(CustomCache.prototype, {
14617       'constructor': ImmutableCache,
14618       'clear': function() {
14619         return new ImmutableCache;
14620       },
14621       'set': function(key, value) {
14622         var result = new ImmutableCache;
14623         result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
14624         return result;
14625       }
14626     });
14627
14628     QUnit.test('should memoize results based on the first argument given', function(assert) {
14629       assert.expect(2);
14630
14631       var memoized = _.memoize(function(a, b, c) {
14632         return a + b + c;
14633       });
14634
14635       assert.strictEqual(memoized(1, 2, 3), 6);
14636       assert.strictEqual(memoized(1, 3, 5), 6);
14637     });
14638
14639     QUnit.test('should support a `resolver`', function(assert) {
14640       assert.expect(2);
14641
14642       var fn = function(a, b, c) { return a + b + c; },
14643           memoized = _.memoize(fn, fn);
14644
14645       assert.strictEqual(memoized(1, 2, 3), 6);
14646       assert.strictEqual(memoized(1, 3, 5), 9);
14647     });
14648
14649     QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
14650       assert.expect(2);
14651
14652       var fn = function(a, b, c) { return a + this.b + this.c; },
14653           memoized = _.memoize(fn, fn);
14654
14655       var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
14656       assert.strictEqual(object.memoized(1), 6);
14657
14658       object.b = 3;
14659       object.c = 5;
14660       assert.strictEqual(object.memoized(1), 9);
14661     });
14662
14663     QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
14664       assert.expect(1);
14665
14666       assert.raises(function() { _.memoize(noop, true); }, TypeError);
14667     });
14668
14669     QUnit.test('should not error if `resolver` is nullish', function(assert) {
14670       assert.expect(1);
14671
14672       var values = [, null, undefined],
14673           expected = lodashStable.map(values, stubTrue);
14674
14675       var actual = lodashStable.map(values, function(resolver, index) {
14676         try {
14677           return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
14678         } catch (e) {}
14679       });
14680
14681       assert.deepEqual(actual, expected);
14682     });
14683
14684     QUnit.test('should check cache for own properties', function(assert) {
14685       assert.expect(1);
14686
14687       var props = [
14688         'constructor',
14689         'hasOwnProperty',
14690         'isPrototypeOf',
14691         'propertyIsEnumerable',
14692         'toLocaleString',
14693         'toString',
14694         'valueOf'
14695       ];
14696
14697       var memoized = _.memoize(identity);
14698
14699       var actual = lodashStable.map(props, function(value) {
14700         return memoized(value);
14701       });
14702
14703       assert.deepEqual(actual, props);
14704     });
14705
14706     QUnit.test('should cache the `__proto__` key', function(assert) {
14707       assert.expect(8);
14708
14709       var array = [],
14710           key = '__proto__';
14711
14712       lodashStable.times(2, function(index) {
14713         var count = 0,
14714             resolver = index ? identity : undefined;
14715
14716         var memoized = _.memoize(function() {
14717           count++;
14718           return array;
14719         }, resolver);
14720
14721         var cache = memoized.cache;
14722
14723         memoized(key);
14724         memoized(key);
14725
14726         assert.strictEqual(count, 1);
14727         assert.strictEqual(cache.get(key), array);
14728         assert.notOk(cache.__data__ instanceof Array);
14729         assert.strictEqual(cache.delete(key), true);
14730       });
14731     });
14732
14733     QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
14734       assert.expect(4);
14735
14736       var oldCache = _.memoize.Cache;
14737       _.memoize.Cache = CustomCache;
14738
14739       var memoized = _.memoize(function(object) {
14740         return object.id;
14741       });
14742
14743       var cache = memoized.cache,
14744           key1 = { 'id': 'a' },
14745           key2 = { 'id': 'b' };
14746
14747       assert.strictEqual(memoized(key1), 'a');
14748       assert.strictEqual(cache.has(key1), true);
14749
14750       assert.strictEqual(memoized(key2), 'b');
14751       assert.strictEqual(cache.has(key2), true);
14752
14753       _.memoize.Cache = oldCache;
14754     });
14755
14756     QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
14757       assert.expect(2);
14758
14759       var oldCache = _.memoize.Cache;
14760       _.memoize.Cache = ImmutableCache;
14761
14762       var memoized = _.memoize(function(object) {
14763         return object.id;
14764       });
14765
14766       var key1 = { 'id': 'a' },
14767           key2 = { 'id': 'b' };
14768
14769       memoized(key1);
14770       memoized(key2);
14771
14772       var cache = memoized.cache;
14773       assert.strictEqual(cache.has(key1), true);
14774       assert.strictEqual(cache.has(key2), true);
14775
14776       _.memoize.Cache = oldCache;
14777     });
14778   }());
14779
14780   /*--------------------------------------------------------------------------*/
14781
14782   QUnit.module('memoizeCapped');
14783
14784   (function() {
14785     var func = _._memoizeCapped;
14786
14787     QUnit.test('should enforce a max cache size of `MAX_MEMOIZE_SIZE`', function(assert) {
14788       assert.expect(2);
14789
14790       if (func) {
14791         var memoized = func(identity),
14792             cache = memoized.cache;
14793
14794         lodashStable.times(MAX_MEMOIZE_SIZE, memoized);
14795         assert.strictEqual(cache.size, MAX_MEMOIZE_SIZE);
14796
14797         memoized(MAX_MEMOIZE_SIZE);
14798         assert.strictEqual(cache.size, 1);
14799       }
14800       else {
14801         skipAssert(assert, 2);
14802       }
14803     });
14804   }());
14805
14806   /*--------------------------------------------------------------------------*/
14807
14808   QUnit.module('lodash.merge');
14809
14810   (function() {
14811     QUnit.test('should merge `source` into `object`', function(assert) {
14812       assert.expect(1);
14813
14814       var names = {
14815         'characters': [
14816           { 'name': 'barney' },
14817           { 'name': 'fred' }
14818         ]
14819       };
14820
14821       var ages = {
14822         'characters': [
14823           { 'age': 36 },
14824           { 'age': 40 }
14825         ]
14826       };
14827
14828       var heights = {
14829         'characters': [
14830           { 'height': '5\'4"' },
14831           { 'height': '5\'5"' }
14832         ]
14833       };
14834
14835       var expected = {
14836         'characters': [
14837           { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
14838           { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
14839         ]
14840       };
14841
14842       assert.deepEqual(_.merge(names, ages, heights), expected);
14843     });
14844
14845     QUnit.test('should merge sources containing circular references', function(assert) {
14846       assert.expect(2);
14847
14848       var object = {
14849         'foo': { 'a': 1 },
14850         'bar': { 'a': 2 }
14851       };
14852
14853       var source = {
14854         'foo': { 'b': { 'c': { 'd': {} } } },
14855         'bar': {}
14856       };
14857
14858       source.foo.b.c.d = source;
14859       source.bar.b = source.foo.b;
14860
14861       var actual = _.merge(object, source);
14862
14863       assert.notStrictEqual(actual.bar.b, actual.foo.b);
14864       assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
14865     });
14866
14867     QUnit.test('should work with four arguments', function(assert) {
14868       assert.expect(1);
14869
14870       var expected = { 'a': 4 },
14871           actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
14872
14873       assert.deepEqual(actual, expected);
14874     });
14875
14876     QUnit.test('should merge onto function `object` values', function(assert) {
14877       assert.expect(2);
14878
14879       function Foo() {}
14880
14881       var source = { 'a': 1 },
14882           actual = _.merge(Foo, source);
14883
14884       assert.strictEqual(actual, Foo);
14885       assert.strictEqual(Foo.a, 1);
14886     });
14887
14888     QUnit.test('should not merge onto function values of sources', function(assert) {
14889       assert.expect(3);
14890
14891       var source1 = { 'a': function() {} },
14892           source2 = { 'a': { 'b': 2 } },
14893           actual = _.merge({}, source1, source2);
14894
14895       assert.deepEqual(actual, { 'a': { 'b': 2 } });
14896
14897       actual = _.merge(source1, source2);
14898
14899       assert.strictEqual(typeof actual.a, 'function');
14900       assert.strictEqual(actual.a.b, 2);
14901     });
14902
14903     QUnit.test('should merge onto non-plain `object` values', function(assert) {
14904       assert.expect(2);
14905
14906       function Foo() {}
14907
14908       var object = new Foo,
14909           actual = _.merge(object, { 'a': 1 });
14910
14911       assert.strictEqual(actual, object);
14912       assert.strictEqual(object.a, 1);
14913     });
14914
14915     QUnit.test('should treat sparse array sources as dense', function(assert) {
14916       assert.expect(2);
14917
14918       var array = [1];
14919       array[2] = 3;
14920
14921       var actual = _.merge([], array),
14922           expected = array.slice();
14923
14924       expected[1] = undefined;
14925
14926       assert.ok('1' in actual);
14927       assert.deepEqual(actual, expected);
14928     });
14929
14930     QUnit.test('should merge `arguments` objects', function(assert) {
14931       assert.expect(7);
14932
14933       var object1 = { 'value': args },
14934           object2 = { 'value': { '3': 4 } },
14935           expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
14936           actual = _.merge(object1, object2);
14937
14938       assert.notOk('3' in args);
14939       assert.notOk(_.isArguments(actual.value));
14940       assert.deepEqual(actual.value, expected);
14941       object1.value = args;
14942
14943       actual = _.merge(object2, object1);
14944       assert.notOk(_.isArguments(actual.value));
14945       assert.deepEqual(actual.value, expected);
14946
14947       expected = { '0': 1, '1': 2, '2': 3 };
14948
14949       actual = _.merge({}, object1);
14950       assert.notOk(_.isArguments(actual.value));
14951       assert.deepEqual(actual.value, expected);
14952     });
14953
14954     QUnit.test('should merge typed arrays', function(assert) {
14955       assert.expect(4);
14956
14957       var array1 = [0],
14958           array2 = [0, 0],
14959           array3 = [0, 0, 0, 0],
14960           array4 = [0, 0, 0, 0, 0, 0, 0, 0];
14961
14962       var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
14963           buffer = ArrayBuffer && new ArrayBuffer(8);
14964
14965       var expected = lodashStable.map(typedArrays, function(type, index) {
14966         var array = arrays[index].slice();
14967         array[0] = 1;
14968         return root[type] ? { 'value': array } : false;
14969       });
14970
14971       var actual = lodashStable.map(typedArrays, function(type) {
14972         var Ctor = root[type];
14973         return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
14974       });
14975
14976       assert.ok(lodashStable.isArray(actual));
14977       assert.deepEqual(actual, expected);
14978
14979       expected = lodashStable.map(typedArrays, function(type, index) {
14980         var array = arrays[index].slice();
14981         array.push(1);
14982         return root[type] ? { 'value': array } : false;
14983       });
14984
14985       actual = lodashStable.map(typedArrays, function(type, index) {
14986         var Ctor = root[type],
14987             array = lodashStable.range(arrays[index].length);
14988
14989         array.push(1);
14990         return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
14991       });
14992
14993       assert.ok(lodashStable.isArray(actual));
14994       assert.deepEqual(actual, expected);
14995     });
14996
14997     QUnit.test('should assign `null` values', function(assert) {
14998       assert.expect(1);
14999
15000       var actual = _.merge({ 'a': 1 }, { 'a': null });
15001       assert.strictEqual(actual.a, null);
15002     });
15003
15004     QUnit.test('should assign non array/buffer/typed-array/plain-object source values directly', function(assert) {
15005       assert.expect(1);
15006
15007       function Foo() {}
15008
15009       var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
15010           expected = lodashStable.map(values, stubTrue);
15011
15012       var actual = lodashStable.map(values, function(value) {
15013         var object = _.merge({}, { 'a': value, 'b': { 'c': value } });
15014         return object.a === value && object.b.c === value;
15015       });
15016
15017       assert.deepEqual(actual, expected);
15018     });
15019
15020     QUnit.test('should clone buffer source values', function(assert) {
15021       assert.expect(3);
15022
15023       if (Buffer) {
15024         var buffer = new Buffer([1]),
15025             actual = _.merge({}, { 'value': buffer }).value;
15026
15027         assert.ok(lodashStable.isBuffer(actual));
15028         assert.strictEqual(actual[0], buffer[0]);
15029         assert.notStrictEqual(actual, buffer);
15030       }
15031       else {
15032         skipAssert(assert, 3);
15033       }
15034     });
15035
15036     QUnit.test('should deep clone array/typed-array/plain-object source values', function(assert) {
15037       assert.expect(1);
15038
15039       var typedArray = Uint8Array
15040         ? new Uint8Array([1])
15041         : { 'buffer': [1] };
15042
15043       var props = ['0', 'buffer', 'a'],
15044           values = [[{ 'a': 1 }], typedArray, { 'a': [1] }],
15045           expected = lodashStable.map(values, stubTrue);
15046
15047       var actual = lodashStable.map(values, function(value, index) {
15048         var key = props[index],
15049             object = _.merge({}, { 'value': value }),
15050             subValue = value[key],
15051             newValue = object.value,
15052             newSubValue = newValue[key];
15053
15054         return (
15055           newValue !== value &&
15056           newSubValue !== subValue &&
15057           lodashStable.isEqual(newValue, value)
15058         );
15059       });
15060
15061       assert.deepEqual(actual, expected);
15062     });
15063
15064     QUnit.test('should not augment source objects', function(assert) {
15065       assert.expect(6);
15066
15067       var source1 = { 'a': [{ 'a': 1 }] },
15068           source2 = { 'a': [{ 'b': 2 }] },
15069           actual = _.merge({}, source1, source2);
15070
15071       assert.deepEqual(source1.a, [{ 'a': 1 }]);
15072       assert.deepEqual(source2.a, [{ 'b': 2 }]);
15073       assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
15074
15075       var source1 = { 'a': [[1, 2, 3]] },
15076           source2 = { 'a': [[3, 4]] },
15077           actual = _.merge({}, source1, source2);
15078
15079       assert.deepEqual(source1.a, [[1, 2, 3]]);
15080       assert.deepEqual(source2.a, [[3, 4]]);
15081       assert.deepEqual(actual.a, [[3, 4, 3]]);
15082     });
15083
15084     QUnit.test('should merge plain objects onto non-plain objects', function(assert) {
15085       assert.expect(4);
15086
15087       function Foo(object) {
15088         lodashStable.assign(this, object);
15089       }
15090
15091       var object = { 'a': 1 },
15092           actual = _.merge(new Foo, object);
15093
15094       assert.ok(actual instanceof Foo);
15095       assert.deepEqual(actual, new Foo(object));
15096
15097       actual = _.merge([new Foo], [object]);
15098       assert.ok(actual[0] instanceof Foo);
15099       assert.deepEqual(actual, [new Foo(object)]);
15100     });
15101
15102     QUnit.test('should not overwrite existing values with `undefined` values of object sources', function(assert) {
15103       assert.expect(1);
15104
15105       var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
15106       assert.deepEqual(actual, { 'a': 1, 'b': undefined });
15107     });
15108
15109     QUnit.test('should not overwrite existing values with `undefined` values of array sources', function(assert) {
15110       assert.expect(2);
15111
15112       var array = [1];
15113       array[2] = 3;
15114
15115       var actual = _.merge([4, 5, 6], array),
15116           expected = [1, 5, 3];
15117
15118       assert.deepEqual(actual, expected);
15119
15120       array = [1, , 3];
15121       array[1] = undefined;
15122
15123       actual = _.merge([4, 5, 6], array);
15124       assert.deepEqual(actual, expected);
15125     });
15126
15127     QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
15128       assert.expect(1);
15129
15130       var object = {},
15131           pass = true;
15132
15133       defineProperty(object, 'a', {
15134         'configurable': true,
15135         'enumerable': true,
15136         'get': function() { pass = false; },
15137         'set': function() { pass = false; }
15138       });
15139
15140       _.merge(object, object);
15141       assert.ok(pass);
15142     });
15143
15144     QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
15145       assert.expect(2);
15146
15147       var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
15148           actual = _.merge(object, { 'a': ['x'] });
15149
15150       assert.deepEqual(actual, { 'a': ['x', 'y'] });
15151
15152       actual = _.merge({ 'a': {} }, { 'a': [] });
15153       assert.deepEqual(actual, { 'a': [] });
15154     });
15155
15156     QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
15157       assert.expect(1);
15158
15159       var object = { 'a': 'abcde' },
15160           actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
15161
15162       assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
15163     });
15164
15165     QUnit.test('should not error on DOM elements', function(assert) {
15166       assert.expect(1);
15167
15168       var object1 = { 'el': document && document.createElement('div') },
15169           object2 = { 'el': document && document.createElement('div') },
15170           pairs = [[{}, object1], [object1, object2]],
15171           expected = lodashStable.map(pairs, stubTrue);
15172
15173       var actual = lodashStable.map(pairs, function(pair) {
15174         try {
15175           return _.merge(pair[0], pair[1]).el === pair[1].el;
15176         } catch (e) {}
15177       });
15178
15179       assert.deepEqual(actual, expected);
15180     });
15181   }());
15182
15183   /*--------------------------------------------------------------------------*/
15184
15185   QUnit.module('lodash.mergeWith');
15186
15187   (function() {
15188     QUnit.test('should handle merging when `customizer` returns `undefined`', function(assert) {
15189       assert.expect(2);
15190
15191       var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
15192       assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
15193
15194       actual = _.mergeWith([], [undefined], identity);
15195       assert.deepEqual(actual, [undefined]);
15196     });
15197
15198     QUnit.test('should clone sources when `customizer` returns `undefined`', function(assert) {
15199       assert.expect(1);
15200
15201       var source1 = { 'a': { 'b': { 'c': 1 } } },
15202           source2 = { 'a': { 'b': { 'd': 2 } } };
15203
15204       _.mergeWith({}, source1, source2, noop);
15205       assert.deepEqual(source1.a.b, { 'c': 1 });
15206     });
15207
15208     QUnit.test('should defer to `customizer` for non `undefined` results', function(assert) {
15209       assert.expect(1);
15210
15211       var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
15212         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15213       });
15214
15215       assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
15216     });
15217
15218     QUnit.test('should provide `stack` to `customizer`', function(assert) {
15219       assert.expect(1);
15220
15221       var actual;
15222
15223       _.mergeWith({}, { 'a': { 'b': 2 } }, function() {
15224         actual = _.last(arguments);
15225       });
15226
15227       assert.ok(isNpm
15228         ? actual.constructor.name == 'Stack'
15229         : actual instanceof mapCaches.Stack
15230       );
15231     });
15232
15233     QUnit.test('should overwrite primitives with source object clones', function(assert) {
15234       assert.expect(1);
15235
15236       var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
15237         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15238       });
15239
15240       assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
15241     });
15242
15243     QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
15244       assert.expect(1);
15245
15246       var array = ['b', 'c'],
15247           object = { 'a': ['a'] },
15248           source = { 'a': array, 'b': array };
15249
15250       var actual = _.mergeWith(object, source, function(a, b) {
15251         return lodashStable.isArray(a) ? a.concat(b) : undefined;
15252       });
15253
15254       assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
15255     });
15256   }());
15257
15258   /*--------------------------------------------------------------------------*/
15259
15260   QUnit.module('lodash.method');
15261
15262   (function() {
15263     QUnit.test('should create a function that calls a method of a given object', function(assert) {
15264       assert.expect(4);
15265
15266       var object = { 'a': stubOne };
15267
15268       lodashStable.each(['a', ['a']], function(path) {
15269         var method = _.method(path);
15270         assert.strictEqual(method.length, 1);
15271         assert.strictEqual(method(object), 1);
15272       });
15273     });
15274
15275     QUnit.test('should work with deep property values', function(assert) {
15276       assert.expect(2);
15277
15278       var object = { 'a': { 'b': stubTwo } };
15279
15280       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15281         var method = _.method(path);
15282         assert.strictEqual(method(object), 2);
15283       });
15284     });
15285
15286     QUnit.test('should work with a non-string `path`', function(assert) {
15287       assert.expect(2);
15288
15289       var array = lodashStable.times(3, _.constant);
15290
15291       lodashStable.each([1, [1]], function(path) {
15292         var method = _.method(path);
15293         assert.strictEqual(method(array), 1);
15294       });
15295     });
15296
15297     QUnit.test('should coerce `path` to a string', function(assert) {
15298       assert.expect(2);
15299
15300       function fn() {}
15301       fn.toString = lodashStable.constant('fn');
15302
15303       var expected = [1, 2, 3, 4],
15304           object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour },
15305           paths = [null, undefined, fn, {}];
15306
15307       lodashStable.times(2, function(index) {
15308         var actual = lodashStable.map(paths, function(path) {
15309           var method = _.method(index ? [path] : path);
15310           return method(object);
15311         });
15312
15313         assert.deepEqual(actual, expected);
15314       });
15315     });
15316
15317     QUnit.test('should work with inherited property values', function(assert) {
15318       assert.expect(2);
15319
15320       function Foo() {}
15321       Foo.prototype.a = stubOne;
15322
15323       lodashStable.each(['a', ['a']], function(path) {
15324         var method = _.method(path);
15325         assert.strictEqual(method(new Foo), 1);
15326       });
15327     });
15328
15329     QUnit.test('should use a key over a path', function(assert) {
15330       assert.expect(2);
15331
15332       var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15333
15334       lodashStable.each(['a.b', ['a.b']], function(path) {
15335         var method = _.method(path);
15336         assert.strictEqual(method(object), 1);
15337       });
15338     });
15339
15340     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15341       assert.expect(2);
15342
15343       var values = [, null, undefined],
15344           expected = lodashStable.map(values, noop);
15345
15346       lodashStable.each(['constructor', ['constructor']], function(path) {
15347         var method = _.method(path);
15348
15349         var actual = lodashStable.map(values, function(value, index) {
15350           return index ? method(value) : method();
15351         });
15352
15353         assert.deepEqual(actual, expected);
15354       });
15355     });
15356
15357     QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
15358       assert.expect(2);
15359
15360       var values = [, null, undefined],
15361           expected = lodashStable.map(values, noop);
15362
15363       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15364         var method = _.method(path);
15365
15366         var actual = lodashStable.map(values, function(value, index) {
15367           return index ? method(value) : method();
15368         });
15369
15370         assert.deepEqual(actual, expected);
15371       });
15372     });
15373
15374     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15375       assert.expect(4);
15376
15377       var object = {};
15378
15379       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15380         var method = _.method(path);
15381         assert.strictEqual(method(object), undefined);
15382       });
15383     });
15384
15385     QUnit.test('should apply partial arguments to function', function(assert) {
15386       assert.expect(2);
15387
15388       var object = {
15389         'fn': function() {
15390           return slice.call(arguments);
15391         }
15392       };
15393
15394       lodashStable.each(['fn', ['fn']], function(path) {
15395         var method = _.method(path, 1, 2, 3);
15396         assert.deepEqual(method(object), [1, 2, 3]);
15397       });
15398     });
15399
15400     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15401       assert.expect(2);
15402
15403       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
15404
15405       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15406         var method = _.method(path);
15407         assert.strictEqual(method(object), 1);
15408       });
15409     });
15410   }());
15411
15412   /*--------------------------------------------------------------------------*/
15413
15414   QUnit.module('lodash.methodOf');
15415
15416   (function() {
15417     QUnit.test('should create a function that calls a method of a given key', function(assert) {
15418       assert.expect(4);
15419
15420       var object = { 'a': stubOne };
15421
15422       lodashStable.each(['a', ['a']], function(path) {
15423         var methodOf = _.methodOf(object);
15424         assert.strictEqual(methodOf.length, 1);
15425         assert.strictEqual(methodOf(path), 1);
15426       });
15427     });
15428
15429     QUnit.test('should work with deep property values', function(assert) {
15430       assert.expect(2);
15431
15432       var object = { 'a': { 'b': stubTwo } };
15433
15434       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15435         var methodOf = _.methodOf(object);
15436         assert.strictEqual(methodOf(path), 2);
15437       });
15438     });
15439
15440     QUnit.test('should work with a non-string `path`', function(assert) {
15441       assert.expect(2);
15442
15443       var array = lodashStable.times(3, _.constant);
15444
15445       lodashStable.each([1, [1]], function(path) {
15446         var methodOf = _.methodOf(array);
15447         assert.strictEqual(methodOf(path), 1);
15448       });
15449     });
15450
15451     QUnit.test('should coerce `path` to a string', function(assert) {
15452       assert.expect(2);
15453
15454       function fn() {}
15455       fn.toString = lodashStable.constant('fn');
15456
15457       var expected = [1, 2, 3, 4],
15458           object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour },
15459           paths = [null, undefined, fn, {}];
15460
15461       lodashStable.times(2, function(index) {
15462         var actual = lodashStable.map(paths, function(path) {
15463           var methodOf = _.methodOf(object);
15464           return methodOf(index ? [path] : path);
15465         });
15466
15467         assert.deepEqual(actual, expected);
15468       });
15469     });
15470
15471     QUnit.test('should work with inherited property values', function(assert) {
15472       assert.expect(2);
15473
15474       function Foo() {}
15475       Foo.prototype.a = stubOne;
15476
15477       lodashStable.each(['a', ['a']], function(path) {
15478         var methodOf = _.methodOf(new Foo);
15479         assert.strictEqual(methodOf(path), 1);
15480       });
15481     });
15482
15483     QUnit.test('should use a key over a path', function(assert) {
15484       assert.expect(2);
15485
15486       var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15487
15488       lodashStable.each(['a.b', ['a.b']], function(path) {
15489         var methodOf = _.methodOf(object);
15490         assert.strictEqual(methodOf(path), 1);
15491       });
15492     });
15493
15494     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15495       assert.expect(2);
15496
15497       var values = [, null, undefined],
15498           expected = lodashStable.map(values, noop);
15499
15500       lodashStable.each(['constructor', ['constructor']], function(path) {
15501         var actual = lodashStable.map(values, function(value, index) {
15502           var methodOf = index ? _.methodOf() : _.methodOf(value);
15503           return methodOf(path);
15504         });
15505
15506         assert.deepEqual(actual, expected);
15507       });
15508     });
15509
15510     QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
15511       assert.expect(2);
15512
15513       var values = [, null, undefined],
15514           expected = lodashStable.map(values, noop);
15515
15516       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15517         var actual = lodashStable.map(values, function(value, index) {
15518           var methodOf = index ? _.methodOf() : _.methodOf(value);
15519           return methodOf(path);
15520         });
15521
15522         assert.deepEqual(actual, expected);
15523       });
15524     });
15525
15526     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15527       assert.expect(4);
15528
15529       var object = {},
15530           methodOf = _.methodOf(object);
15531
15532       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15533         assert.strictEqual(methodOf(path), undefined);
15534       });
15535     });
15536
15537     QUnit.test('should apply partial arguments to function', function(assert) {
15538       assert.expect(2);
15539
15540       var object = {
15541         'fn': function() {
15542           return slice.call(arguments);
15543         }
15544       };
15545
15546       var methodOf = _.methodOf(object, 1, 2, 3);
15547
15548       lodashStable.each(['fn', ['fn']], function(path) {
15549         assert.deepEqual(methodOf(path), [1, 2, 3]);
15550       });
15551     });
15552
15553     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15554       assert.expect(2);
15555
15556       var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
15557           methodOf = _.methodOf(object);
15558
15559       lodashStable.each(['a.b', ['a', 'b']], function(path) {
15560         assert.strictEqual(methodOf(path), 1);
15561       });
15562     });
15563   }());
15564
15565   /*--------------------------------------------------------------------------*/
15566
15567   QUnit.module('lodash.min');
15568
15569   (function() {
15570     QUnit.test('should return the smallest value from a collection', function(assert) {
15571       assert.expect(1);
15572
15573       assert.strictEqual(_.min([1, 2, 3]), 1);
15574     });
15575
15576     QUnit.test('should return `undefined` for empty collections', function(assert) {
15577       assert.expect(1);
15578
15579       var values = falsey.concat([[]]),
15580           expected = lodashStable.map(values, noop);
15581
15582       var actual = lodashStable.map(values, function(value, index) {
15583         try {
15584           return index ? _.min(value) : _.min();
15585         } catch (e) {}
15586       });
15587
15588       assert.deepEqual(actual, expected);
15589     });
15590
15591     QUnit.test('should work with non-numeric collection values', function(assert) {
15592       assert.expect(1);
15593
15594       assert.strictEqual(_.min(['a', 'b']), 'a');
15595     });
15596   }());
15597
15598   /*--------------------------------------------------------------------------*/
15599
15600   QUnit.module('extremum methods');
15601
15602   lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
15603     var func = _[methodName],
15604         isMax = /^max/.test(methodName);
15605
15606     QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
15607       assert.expect(1);
15608
15609       var curr = new Date,
15610           past = new Date(0);
15611
15612       assert.strictEqual(func([curr, past]), isMax ? curr : past);
15613     });
15614
15615     QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
15616       assert.expect(1);
15617
15618       var array = lodashStable.range(0, 5e5);
15619       assert.strictEqual(func(array), isMax ? 499999 : 0);
15620     });
15621
15622     QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
15623       assert.expect(1);
15624
15625       if (!isNpm) {
15626         var actual = _([40])[methodName]();
15627         assert.strictEqual(actual, 40);
15628       }
15629       else {
15630         skipAssert(assert);
15631       }
15632     });
15633   });
15634
15635   lodashStable.each(['maxBy', 'minBy'], function(methodName) {
15636     var array = [1, 2, 3],
15637         func = _[methodName],
15638         isMax = methodName == 'maxBy';
15639
15640     QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) {
15641       assert.expect(1);
15642
15643       var actual = func(array, function(n) {
15644         return -n;
15645       });
15646
15647       assert.strictEqual(actual, isMax ? 1 : 3);
15648     });
15649
15650     QUnit.test('should work with `_.property` shorthands', function(assert) {
15651       assert.expect(2);
15652
15653       var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
15654           actual = func(objects, 'a');
15655
15656       assert.deepEqual(actual, objects[isMax ? 1 : 2]);
15657
15658       var arrays = [[2], [3], [1]];
15659       actual = func(arrays, 0);
15660
15661       assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
15662     });
15663
15664     QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
15665       assert.expect(1);
15666
15667       var value = isMax ? -Infinity : Infinity,
15668           object = { 'a': value };
15669
15670       var actual = func([object, { 'a': value }], function(object) {
15671         return object.a;
15672       });
15673
15674       assert.strictEqual(actual, object);
15675     });
15676   });
15677
15678   /*--------------------------------------------------------------------------*/
15679
15680   QUnit.module('lodash.mixin');
15681
15682   (function() {
15683     function reset(wrapper) {
15684       delete wrapper.a;
15685       delete wrapper.prototype.a;
15686       delete wrapper.b;
15687       delete wrapper.prototype.b;
15688     }
15689
15690     function Wrapper(value) {
15691       if (!(this instanceof Wrapper)) {
15692         return new Wrapper(value);
15693       }
15694       if (_.has(value, '__wrapped__')) {
15695         var actions = slice.call(value.__actions__),
15696             chain = value.__chain__;
15697
15698         value = value.__wrapped__;
15699       }
15700       this.__wrapped__ = value;
15701       this.__actions__ = actions || [];
15702       this.__chain__ = chain || false;
15703     }
15704
15705     Wrapper.prototype.value = function() {
15706       return getUnwrappedValue(this);
15707     };
15708
15709     var array = ['a'],
15710         source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
15711
15712     QUnit.test('should mixin `source` methods into lodash', function(assert) {
15713       assert.expect(4);
15714
15715       if (!isNpm) {
15716         _.mixin(source);
15717
15718         assert.strictEqual(_.a(array), 'a');
15719         assert.strictEqual(_(array).a().value(), 'a');
15720         assert.notOk('b' in _);
15721         assert.notOk('b' in _.prototype);
15722
15723         reset(_);
15724       }
15725       else {
15726         skipAssert(assert, 4);
15727       }
15728     });
15729
15730     QUnit.test('should mixin chaining methods by reference', function(assert) {
15731       assert.expect(2);
15732
15733       if (!isNpm) {
15734         _.mixin(source);
15735         _.a = stubB;
15736
15737         assert.strictEqual(_.a(array), 'b');
15738         assert.strictEqual(_(array).a().value(), 'a');
15739
15740         reset(_);
15741       }
15742       else {
15743         skipAssert(assert, 2);
15744       }
15745     });
15746
15747     QUnit.test('should use a default `object` of `this`', function(assert) {
15748       assert.expect(3);
15749
15750       var object = lodashStable.create(_);
15751       object.mixin(source);
15752
15753       assert.strictEqual(object.a(array), 'a');
15754       assert.notOk('a' in _);
15755       assert.notOk('a' in _.prototype);
15756
15757       reset(_);
15758     });
15759
15760     QUnit.test('should accept an `object`', function(assert) {
15761       assert.expect(1);
15762
15763       var object = {};
15764       _.mixin(object, source);
15765       assert.strictEqual(object.a(array), 'a');
15766     });
15767
15768     QUnit.test('should accept a function `object`', function(assert) {
15769       assert.expect(2);
15770
15771       _.mixin(Wrapper, source);
15772
15773       var wrapped = Wrapper(array),
15774           actual = wrapped.a();
15775
15776       assert.strictEqual(actual.value(), 'a');
15777       assert.ok(actual instanceof Wrapper);
15778
15779       reset(Wrapper);
15780     });
15781
15782     QUnit.test('should return `object`', function(assert) {
15783       assert.expect(3);
15784
15785       var object = {};
15786       assert.strictEqual(_.mixin(object, source), object);
15787       assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
15788       assert.strictEqual(_.mixin(), _);
15789
15790       reset(Wrapper);
15791     });
15792
15793     QUnit.test('should not assign inherited `source` methods', function(assert) {
15794       assert.expect(1);
15795
15796       function Foo() {}
15797       Foo.prototype.a = noop;
15798
15799       var object = {};
15800       assert.strictEqual(_.mixin(object, new Foo), object);
15801     });
15802
15803     QUnit.test('should accept an `options`', function(assert) {
15804       assert.expect(8);
15805
15806       function message(func, chain) {
15807         return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
15808       }
15809
15810       lodashStable.each([_, Wrapper], function(func) {
15811         lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
15812           if (!isNpm) {
15813             if (func === _) {
15814               _.mixin(source, options);
15815             } else {
15816               _.mixin(func, source, options);
15817             }
15818             var wrapped = func(array),
15819                 actual = wrapped.a();
15820
15821             if (options.chain) {
15822               assert.strictEqual(actual.value(), 'a', message(func, true));
15823               assert.ok(actual instanceof func, message(func, true));
15824             } else {
15825               assert.strictEqual(actual, 'a', message(func, false));
15826               assert.notOk(actual instanceof func, message(func, false));
15827             }
15828             reset(func);
15829           }
15830           else {
15831             skipAssert(assert, 2);
15832           }
15833         });
15834       });
15835     });
15836
15837     QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
15838       assert.expect(1);
15839
15840       _.mixin({ 'a': noop }, {});
15841       assert.notOk('a' in _);
15842       reset(_);
15843     });
15844
15845     QUnit.test('should not error for non-object `options` values', function(assert) {
15846       assert.expect(2);
15847
15848       var pass = true;
15849
15850       try {
15851         _.mixin({}, source, 1);
15852       } catch (e) {
15853         pass = false;
15854       }
15855       assert.ok(pass);
15856
15857       pass = true;
15858
15859       try {
15860         _.mixin(source, 1);
15861       } catch (e) {
15862         pass = false;
15863       }
15864       assert.ok(pass);
15865
15866       reset(_);
15867     });
15868
15869     QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
15870       assert.expect(2);
15871
15872       lodashStable.each([_, Wrapper], function(func) {
15873         if (!isNpm) {
15874           if (func === _) {
15875             var wrapped = _(source),
15876                 actual = wrapped.mixin();
15877
15878             assert.strictEqual(actual.value(), _);
15879           }
15880           else {
15881             wrapped = _(func);
15882             actual = wrapped.mixin(source);
15883             assert.notStrictEqual(actual, wrapped);
15884           }
15885           reset(func);
15886         }
15887         else {
15888           skipAssert(assert);
15889         }
15890       });
15891     });
15892
15893     QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
15894       assert.expect(1);
15895
15896       if (!isNpm) {
15897         _.mixin({ 'a': _.countBy, 'b': _.filter });
15898
15899         var array = lodashStable.range(LARGE_ARRAY_SIZE),
15900             actual = _(array).a().map(square).b(isEven).take().value();
15901
15902         assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
15903
15904         reset(_);
15905       }
15906       else {
15907         skipAssert(assert);
15908       }
15909     });
15910   }());
15911
15912   /*--------------------------------------------------------------------------*/
15913
15914   QUnit.module('lodash.multiply');
15915
15916   (function() {
15917     QUnit.test('should multiply two numbers', function(assert) {
15918       assert.expect(3);
15919
15920       assert.strictEqual(_.multiply(6, 4), 24);
15921       assert.strictEqual(_.multiply(-6, 4), -24);
15922       assert.strictEqual(_.multiply(-6, -4), 24);
15923     });
15924
15925     QUnit.test('should coerce arguments to numbers', function(assert) {
15926       assert.expect(2);
15927
15928       assert.strictEqual(_.multiply('6', '4'), 24);
15929       assert.deepEqual(_.multiply('x', 'y'), NaN);
15930     });
15931   }());
15932
15933   /*--------------------------------------------------------------------------*/
15934
15935   QUnit.module('lodash.orderBy');
15936
15937   (function() {
15938     var objects = [
15939       { 'a': 'x', 'b': 3 },
15940       { 'a': 'y', 'b': 4 },
15941       { 'a': 'x', 'b': 1 },
15942       { 'a': 'y', 'b': 2 }
15943     ];
15944
15945     QUnit.test('should sort by a single property by a specified order', function(assert) {
15946       assert.expect(1);
15947
15948       var actual = _.orderBy(objects, 'a', 'desc');
15949       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15950     });
15951
15952     QUnit.test('should sort by multiple properties by specified orders', function(assert) {
15953       assert.expect(1);
15954
15955       var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
15956       assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
15957     });
15958
15959     QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
15960       assert.expect(2);
15961
15962       var expected = [objects[2], objects[0], objects[3], objects[1]],
15963           actual = _.orderBy(objects, ['a', 'b']);
15964
15965       assert.deepEqual(actual, expected);
15966
15967       expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
15968
15969       actual = lodashStable.map(falsey, function(order, index) {
15970         return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
15971       });
15972
15973       assert.deepEqual(actual, expected);
15974     });
15975
15976     QUnit.test('should work with `orders` specified as string objects', function(assert) {
15977       assert.expect(1);
15978
15979       var actual = _.orderBy(objects, ['a'], [Object('desc')]);
15980       assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15981     });
15982   }());
15983
15984   /*--------------------------------------------------------------------------*/
15985
15986   QUnit.module('lodash.overArgs');
15987
15988   (function() {
15989     function fn() {
15990       return slice.call(arguments);
15991     }
15992
15993     QUnit.test('should transform each argument', function(assert) {
15994       assert.expect(1);
15995
15996       var over = _.overArgs(fn, doubled, square);
15997       assert.deepEqual(over(5, 10), [10, 100]);
15998     });
15999
16000     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16001       assert.expect(1);
16002
16003       var over = _.overArgs(fn, undefined, null);
16004       assert.deepEqual(over('a', 'b'), ['a', 'b']);
16005     });
16006
16007     QUnit.test('should work with `_.property` shorthands', function(assert) {
16008       assert.expect(1);
16009
16010       var over = _.overArgs(fn, 'b', 'a');
16011       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
16012     });
16013
16014     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16015       assert.expect(1);
16016
16017       var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
16018       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16019     });
16020
16021     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16022       assert.expect(1);
16023
16024       var over = _.overArgs(fn, [['b', 1], ['a', 1]]);
16025       assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16026     });
16027
16028     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16029       assert.expect(2);
16030
16031       var over = _.overArgs(fn, ['a', 1]);
16032       assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
16033
16034       over = _.overArgs(fn, [['a', 1]]);
16035       assert.deepEqual(over({ 'a': 1 }), [true]);
16036     });
16037
16038     QUnit.test('should flatten `transforms`', function(assert) {
16039       assert.expect(1);
16040
16041       var over = _.overArgs(fn, [doubled, square], String);
16042       assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
16043     });
16044
16045     QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
16046       assert.expect(1);
16047
16048       var over = _.overArgs(fn, doubled, square);
16049       assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
16050     });
16051
16052     QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
16053       assert.expect(1);
16054
16055       var over = _.overArgs(fn);
16056       assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
16057     });
16058
16059     QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
16060       assert.expect(1);
16061
16062       var over = _.overArgs(fn, doubled, identity);
16063       assert.deepEqual(over(5), [10]);
16064     });
16065
16066     QUnit.test('should provide the correct argument to each transform', function(assert) {
16067       assert.expect(1);
16068
16069       var argsList = [],
16070           transform = function() { argsList.push(slice.call(arguments)); },
16071           over = _.overArgs(noop, transform, transform, transform);
16072
16073       over('a', 'b');
16074       assert.deepEqual(argsList, [['a'], ['b']]);
16075     });
16076
16077     QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
16078       assert.expect(1);
16079
16080       var over = _.overArgs(function(x) {
16081         return this[x];
16082       }, function(x) {
16083         return this === x;
16084       });
16085
16086       var object = { 'over': over, 'true': 1 };
16087       assert.strictEqual(object.over(object), 1);
16088     });
16089   }());
16090
16091   /*--------------------------------------------------------------------------*/
16092
16093   QUnit.module('lodash.negate');
16094
16095   (function() {
16096     QUnit.test('should create a function that negates the result of `func`', function(assert) {
16097       assert.expect(2);
16098
16099       var negate = _.negate(isEven);
16100
16101       assert.strictEqual(negate(1), true);
16102       assert.strictEqual(negate(2), false);
16103     });
16104
16105     QUnit.test('should create a function that negates the result of `func`', function(assert) {
16106       assert.expect(2);
16107
16108       var negate = _.negate(isEven);
16109
16110       assert.strictEqual(negate(1), true);
16111       assert.strictEqual(negate(2), false);
16112     });
16113
16114     QUnit.test('should create a function that accepts multiple arguments', function(assert) {
16115       assert.expect(1);
16116
16117       var argCount,
16118           count = 5,
16119           negate = _.negate(function() { argCount = arguments.length; }),
16120           expected = lodashStable.times(count, stubTrue);
16121
16122       var actual = lodashStable.times(count, function(index) {
16123         switch (index) {
16124           case 0: negate(); break;
16125           case 1: negate(1); break;
16126           case 2: negate(1, 2); break;
16127           case 3: negate(1, 2, 3); break;
16128           case 4: negate(1, 2, 3, 4);
16129         }
16130         return argCount == index;
16131       });
16132
16133       assert.deepEqual(actual, expected);
16134     });
16135   }());
16136
16137   /*--------------------------------------------------------------------------*/
16138
16139   QUnit.module('lodash.noConflict');
16140
16141   (function() {
16142     QUnit.test('should return the `lodash` function', function(assert) {
16143       assert.expect(2);
16144
16145       if (!isModularize) {
16146         assert.strictEqual(_.noConflict(), oldDash);
16147         assert.notStrictEqual(root._, oldDash);
16148         root._ = oldDash;
16149       }
16150       else {
16151         skipAssert(assert, 2);
16152       }
16153     });
16154
16155     QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
16156       assert.expect(2);
16157
16158       if (!isModularize) {
16159         var object = root._ = {};
16160         assert.strictEqual(_.noConflict(), oldDash);
16161         assert.strictEqual(root._, object);
16162         root._ = oldDash;
16163       }
16164       else {
16165         skipAssert(assert, 2);
16166       }
16167     });
16168
16169     QUnit.test('should work with a `root` of `this`', function(assert) {
16170       assert.expect(2);
16171
16172       if (!coverage && !document && !isModularize && realm.object) {
16173         var fs = require('fs'),
16174             vm = require('vm'),
16175             expected = {},
16176             context = vm.createContext({ '_': expected, 'console': console }),
16177             source = fs.readFileSync(filePath, 'utf8');
16178
16179         vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
16180
16181         assert.strictEqual(context._, expected);
16182         assert.ok(context.lodash);
16183       }
16184       else {
16185         skipAssert(assert, 2);
16186       }
16187     });
16188   }());
16189
16190   /*--------------------------------------------------------------------------*/
16191
16192   QUnit.module('lodash.now');
16193
16194   (function() {
16195     QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
16196       assert.expect(2);
16197
16198       var done = assert.async();
16199
16200       var stamp = +new Date,
16201           actual = _.now();
16202
16203       assert.ok(actual >= stamp);
16204
16205       setTimeout(function() {
16206         assert.ok(_.now() > actual);
16207         done();
16208       }, 32);
16209     });
16210
16211     QUnit.test('should work with mocked `Date.now`', function(assert) {
16212       assert.expect(1);
16213
16214       var now = Date.now;
16215       Date.now = stubA;
16216
16217       var actual = _.now();
16218       Date.now = now;
16219
16220       assert.strictEqual(actual, 'a');
16221     });
16222   }());
16223
16224   /*--------------------------------------------------------------------------*/
16225
16226   QUnit.module('lodash.nth');
16227
16228   (function() {
16229     var array = ['a', 'b', 'c', 'd'];
16230
16231     QUnit.test('should get the nth element of `array`', function(assert) {
16232       assert.expect(1);
16233
16234       var actual = lodashStable.map(array, function(value, index) {
16235         return _.nth(array, index);
16236       });
16237
16238       assert.deepEqual(actual, array);
16239     });
16240
16241     QUnit.test('should work with a negative `n`', function(assert) {
16242       assert.expect(1);
16243
16244       var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
16245         return _.nth(array, -n);
16246       });
16247
16248       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16249     });
16250
16251     QUnit.test('should coerce `n` to an integer', function(assert) {
16252       assert.expect(2);
16253
16254       var values = falsey,
16255           expected = lodashStable.map(values, stubA);
16256
16257       var actual = lodashStable.map(values, function(n) {
16258         return n ? _.nth(array, n) : _.nth(array);
16259       });
16260
16261       assert.deepEqual(actual, expected);
16262
16263       values = ['1', 1.6];
16264       expected = lodashStable.map(values, stubB);
16265
16266       actual = lodashStable.map(values, function(n) {
16267         return _.nth(array, n);
16268       });
16269
16270       assert.deepEqual(actual, expected);
16271     });
16272
16273     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16274       assert.expect(1);
16275
16276       var values = [null, undefined, []],
16277           expected = lodashStable.map(values, noop);
16278
16279       var actual = lodashStable.map(values, function(array) {
16280         return _.nth(array, 1);
16281       });
16282
16283       assert.deepEqual(actual, expected);
16284     });
16285
16286     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16287       assert.expect(1);
16288
16289       var array = [1, 2],
16290           values = [Infinity, array.length],
16291           expected = lodashStable.map(values, noop);
16292
16293       array[-1] = 3;
16294
16295       var actual = lodashStable.map(values, function(n) {
16296         return _.nth(array, n);
16297       });
16298
16299       assert.deepEqual(actual, expected);
16300     });
16301   }());
16302
16303   /*--------------------------------------------------------------------------*/
16304
16305   QUnit.module('lodash.nthArg');
16306
16307   (function() {
16308     var args = ['a', 'b', 'c', 'd'];
16309
16310     QUnit.test('should create a function that returns its nth argument', function(assert) {
16311       assert.expect(1);
16312
16313       var actual = lodashStable.map(args, function(value, index) {
16314         var func = _.nthArg(index);
16315         return func.apply(undefined, args);
16316       });
16317
16318       assert.deepEqual(actual, args);
16319     });
16320
16321     QUnit.test('should work with a negative `n`', function(assert) {
16322       assert.expect(1);
16323
16324       var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
16325         var func = _.nthArg(-n);
16326         return func.apply(undefined, args);
16327       });
16328
16329       assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16330     });
16331
16332     QUnit.test('should coerce `n` to an integer', function(assert) {
16333       assert.expect(2);
16334
16335       var values = falsey,
16336           expected = lodashStable.map(values, stubA);
16337
16338       var actual = lodashStable.map(values, function(n) {
16339         var func = n ? _.nthArg(n) : _.nthArg();
16340         return func.apply(undefined, args);
16341       });
16342
16343       assert.deepEqual(actual, expected);
16344
16345       values = ['1', 1.6];
16346       expected = lodashStable.map(values, stubB);
16347
16348       actual = lodashStable.map(values, function(n) {
16349         var func = _.nthArg(n);
16350         return func.apply(undefined, args);
16351       });
16352
16353       assert.deepEqual(actual, expected);
16354     });
16355
16356     QUnit.test('should return `undefined` for empty arrays', function(assert) {
16357       assert.expect(1);
16358
16359       var func = _.nthArg(1);
16360       assert.strictEqual(func(), undefined);
16361     });
16362
16363     QUnit.test('should return `undefined` for non-indexes', function(assert) {
16364       assert.expect(1);
16365
16366       var values = [Infinity, args.length],
16367           expected = lodashStable.map(values, noop);
16368
16369       var actual = lodashStable.map(values, function(n) {
16370         var func = _.nthArg(n);
16371         return func.apply(undefined, args);
16372       });
16373
16374       assert.deepEqual(actual, expected);
16375     });
16376   }());
16377
16378   /*--------------------------------------------------------------------------*/
16379
16380   QUnit.module('lodash.omit');
16381
16382   (function() {
16383     var args = toArgs(['a', 'c']),
16384         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16385         nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } };
16386
16387     QUnit.test('should flatten `paths`', function(assert) {
16388       assert.expect(2);
16389
16390       assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
16391       assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
16392     });
16393
16394     QUnit.test('should support deep paths', function(assert) {
16395       assert.expect(1);
16396
16397       assert.deepEqual(_.omit(nested, 'b.c'), { 'a': 1, 'b': { 'd': 3} });
16398     });
16399
16400     QUnit.test('should support path arrays', function(assert) {
16401       assert.expect(1);
16402
16403       var object = { 'a.b': 1, 'a': { 'b': 2 } },
16404           actual = _.omit(object, [['a.b']]);
16405
16406       assert.deepEqual(actual, { 'a': { 'b': 2 } });
16407     });
16408
16409     QUnit.test('should omit a key over a path', function(assert) {
16410       assert.expect(2);
16411
16412       var object = { 'a.b': 1, 'a': { 'b': 2 } };
16413
16414       lodashStable.each(['a.b', ['a.b']], function(path) {
16415         assert.deepEqual(_.omit(object, path), { 'a': { 'b': 2 } });
16416       });
16417     });
16418
16419     QUnit.test('should coerce `paths` to strings', function(assert) {
16420       assert.expect(1);
16421
16422       assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
16423     });
16424
16425     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16426       assert.expect(2);
16427
16428       lodashStable.each([null, undefined], function(value) {
16429         objectProto.a = 1;
16430         var actual = _.omit(value, 'valueOf');
16431         delete objectProto.a;
16432         assert.deepEqual(actual, {});
16433       });
16434     });
16435
16436     QUnit.test('should work with a primitive `object`', function(assert) {
16437       assert.expect(1);
16438
16439       stringProto.a = 1;
16440       stringProto.b = 2;
16441
16442       assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
16443
16444       delete stringProto.a;
16445       delete stringProto.b;
16446     });
16447
16448     QUnit.test('should work with `arguments` object `paths`', function(assert) {
16449       assert.expect(1);
16450
16451       assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
16452     });
16453
16454     QUnit.test('should not mutate `object`', function(assert) {
16455       assert.expect(4);
16456
16457       lodashStable.each(['a', ['a'], 'a.b', ['a.b']], function(path) {
16458         var object = { 'a': { 'b': 2 } };
16459         _.omit(object, path);
16460         assert.deepEqual(object, { 'a': { 'b': 2 } });
16461       });
16462     });
16463   }());
16464
16465   /*--------------------------------------------------------------------------*/
16466
16467   QUnit.module('lodash.omitBy');
16468
16469   (function() {
16470     QUnit.test('should work with a predicate argument', function(assert) {
16471       assert.expect(1);
16472
16473       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16474
16475       var actual = _.omitBy(object, function(n) {
16476         return n != 2 && n != 4;
16477       });
16478
16479       assert.deepEqual(actual, { 'b': 2, 'd': 4 });
16480     });
16481   }());
16482
16483   /*--------------------------------------------------------------------------*/
16484
16485   QUnit.module('omit methods');
16486
16487   lodashStable.each(['omit', 'omitBy'], function(methodName) {
16488     var expected = { 'b': 2, 'd': 4 },
16489         func = _[methodName],
16490         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16491         resolve = lodashStable.nthArg(1);
16492
16493     if (methodName == 'omitBy') {
16494       resolve = function(object, props) {
16495         props = lodashStable.castArray(props);
16496         return function(value) {
16497           return lodashStable.some(props, function(key) {
16498             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
16499             return object[key] === value;
16500           });
16501         };
16502       };
16503     }
16504     QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
16505       assert.expect(2);
16506
16507       assert.deepEqual(func(object, resolve(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
16508       assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
16509     });
16510
16511     QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
16512       assert.expect(1);
16513
16514       function Foo() {}
16515       Foo.prototype = object;
16516
16517       assert.deepEqual(func(new Foo, resolve(object, ['a', 'c'])), expected);
16518     });
16519
16520     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
16521       assert.expect(1);
16522
16523       var object = { '-0': 'a', '0': 'b' },
16524           props = [-0, Object(-0), 0, Object(0)],
16525           expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
16526
16527       var actual = lodashStable.map(props, function(key) {
16528         return func(object, resolve(object, key));
16529       });
16530
16531       assert.deepEqual(actual, expected);
16532     });
16533
16534     QUnit.test('`_.' + methodName + '` should include symbols', function(assert) {
16535       assert.expect(3);
16536
16537       function Foo() {
16538         this.a = 0;
16539         this[symbol] = 1;
16540       }
16541
16542       if (Symbol) {
16543         var symbol2 = Symbol('b');
16544         Foo.prototype[symbol2] = 2;
16545
16546         var symbol3 = Symbol('c');
16547         defineProperty(Foo.prototype, symbol3, {
16548           'configurable': true,
16549           'enumerable': false,
16550           'writable': true,
16551           'value': 3
16552         });
16553
16554         var foo = new Foo,
16555             actual = func(foo, resolve(foo, 'a'));
16556
16557         assert.strictEqual(actual[symbol], 1);
16558         assert.strictEqual(actual[symbol2], 2);
16559         assert.notOk(symbol3 in actual);
16560       }
16561       else {
16562         skipAssert(assert, 3);
16563       }
16564     });
16565
16566     QUnit.test('`_.' + methodName + '` should create an object with omitted symbols', function(assert) {
16567       assert.expect(8);
16568
16569       function Foo() {
16570         this.a = 0;
16571         this[symbol] = 1;
16572       }
16573
16574       if (Symbol) {
16575         var symbol2 = Symbol('b');
16576         Foo.prototype[symbol2] = 2;
16577
16578         var symbol3 = Symbol('c');
16579         defineProperty(Foo.prototype, symbol3, {
16580           'configurable': true,
16581           'enumerable': false,
16582           'writable': true,
16583           'value': 3
16584         });
16585
16586         var foo = new Foo,
16587             actual = func(foo, resolve(foo, symbol));
16588
16589         assert.strictEqual(actual.a, 0);
16590         assert.notOk(symbol in actual);
16591         assert.strictEqual(actual[symbol2], 2);
16592         assert.notOk(symbol3 in actual);
16593
16594         actual = func(foo, resolve(foo, symbol2));
16595
16596         assert.strictEqual(actual.a, 0);
16597         assert.strictEqual(actual[symbol], 1);
16598         assert.notOk(symbol2 in actual);
16599         assert.notOk(symbol3 in actual);
16600       }
16601       else {
16602         skipAssert(assert, 8);
16603       }
16604     });
16605
16606     QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) {
16607       assert.expect(1);
16608
16609       var array = [1, 2, 3];
16610       assert.deepEqual(func(array, resolve(array, ['0', '2'])), { '1': 2 });
16611     });
16612   });
16613
16614   /*--------------------------------------------------------------------------*/
16615
16616   QUnit.module('lodash.once');
16617
16618   (function() {
16619     QUnit.test('should invoke `func` once', function(assert) {
16620       assert.expect(2);
16621
16622       var count = 0,
16623           once = _.once(function() { return ++count; });
16624
16625       once();
16626       assert.strictEqual(once(), 1);
16627       assert.strictEqual(count, 1);
16628     });
16629
16630     QUnit.test('should ignore recursive calls', function(assert) {
16631       assert.expect(2);
16632
16633       var count = 0;
16634
16635       var once = _.once(function() {
16636         once();
16637         return ++count;
16638       });
16639
16640       assert.strictEqual(once(), 1);
16641       assert.strictEqual(count, 1);
16642     });
16643
16644     QUnit.test('should not throw more than once', function(assert) {
16645       assert.expect(2);
16646
16647       var once = _.once(function() {
16648         throw new Error;
16649       });
16650
16651       assert.raises(once);
16652
16653       once();
16654       assert.ok(true);
16655     });
16656   }());
16657
16658   /*--------------------------------------------------------------------------*/
16659
16660   QUnit.module('lodash.over');
16661
16662   (function() {
16663     QUnit.test('should create a function that invokes `iteratees`', function(assert) {
16664       assert.expect(1);
16665
16666       var over = _.over(Math.max, Math.min);
16667       assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
16668     });
16669
16670     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16671       assert.expect(1);
16672
16673       var over = _.over(undefined, null);
16674       assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
16675     });
16676
16677     QUnit.test('should work with `_.property` shorthands', function(assert) {
16678       assert.expect(1);
16679
16680       var over = _.over('b', 'a');
16681       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
16682     });
16683
16684     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16685       assert.expect(1);
16686
16687       var over = _.over({ 'b': 1 }, { 'a': 1 });
16688       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
16689     });
16690
16691     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16692       assert.expect(2);
16693
16694       var over = _.over([['b', 2], ['a', 2]]);
16695
16696       assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
16697       assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
16698     });
16699
16700     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16701       assert.expect(4);
16702
16703       var over = _.over(['a', 1]);
16704
16705       assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
16706       assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
16707
16708       over = _.over([['a', 1]]);
16709
16710       assert.deepEqual(over({ 'a': 1 }), [true]);
16711       assert.deepEqual(over({ 'a': 2 }), [false]);
16712     });
16713
16714     QUnit.test('should provide arguments to predicates', function(assert) {
16715       assert.expect(1);
16716
16717       var over = _.over(function() {
16718         return slice.call(arguments);
16719       });
16720
16721       assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
16722     });
16723
16724     QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
16725       assert.expect(1);
16726
16727       var over = _.over(function() { return this.b; }, function() { return this.a; }),
16728           object = { 'over': over, 'a': 1, 'b': 2 };
16729
16730       assert.deepEqual(object.over(), [2, 1]);
16731     });
16732   }());
16733
16734   /*--------------------------------------------------------------------------*/
16735
16736   QUnit.module('lodash.overEvery');
16737
16738   (function() {
16739     QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
16740       assert.expect(1);
16741
16742       var over = _.overEvery(stubTrue, stubOne, stubA);
16743       assert.strictEqual(over(), true);
16744     });
16745
16746     QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
16747       assert.expect(2);
16748
16749       var count = 0,
16750           countFalse = function() { count++; return false; },
16751           countTrue = function() { count++; return true; },
16752           over = _.overEvery(countTrue, countFalse, countTrue);
16753
16754       assert.strictEqual(over(), false);
16755       assert.strictEqual(count, 2);
16756     });
16757
16758     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16759       assert.expect(2);
16760
16761       var over = _.overEvery(undefined, null);
16762
16763       assert.strictEqual(over(true), true);
16764       assert.strictEqual(over(false), false);
16765     });
16766
16767     QUnit.test('should work with `_.property` shorthands', function(assert) {
16768       assert.expect(2);
16769
16770       var over = _.overEvery('b', 'a');
16771
16772       assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
16773       assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
16774     });
16775
16776     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16777       assert.expect(2);
16778
16779       var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
16780
16781       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16782       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16783     });
16784
16785     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16786       assert.expect(2);
16787
16788       var over = _.overEvery([['b', 2], ['a', 1]]);
16789
16790       assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16791       assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16792     });
16793
16794     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16795       assert.expect(5);
16796
16797       var over = _.overEvery(['a', 1]);
16798
16799       assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
16800       assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
16801       assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
16802
16803       over = _.overEvery([['a', 1]]);
16804
16805       assert.strictEqual(over({ 'a': 1 }), true);
16806       assert.strictEqual(over({ 'a': 2 }), false);
16807     });
16808
16809     QUnit.test('should flatten `predicates`', function(assert) {
16810       assert.expect(1);
16811
16812       var over = _.overEvery(stubTrue, [stubFalse]);
16813       assert.strictEqual(over(), false);
16814     });
16815
16816     QUnit.test('should provide arguments to predicates', function(assert) {
16817       assert.expect(1);
16818
16819       var args;
16820
16821       var over = _.overEvery(function() {
16822         args = slice.call(arguments);
16823       });
16824
16825       over('a', 'b', 'c');
16826       assert.deepEqual(args, ['a', 'b', 'c']);
16827     });
16828
16829     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16830       assert.expect(2);
16831
16832       var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
16833           object = { 'over': over, 'a': 1, 'b': 2 };
16834
16835       assert.strictEqual(object.over(), true);
16836
16837       object.a = 0;
16838       assert.strictEqual(object.over(), false);
16839     });
16840   }());
16841
16842   /*--------------------------------------------------------------------------*/
16843
16844   QUnit.module('lodash.overSome');
16845
16846   (function() {
16847     QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
16848       assert.expect(2);
16849
16850       var over = _.overSome(stubFalse, stubOne, stubString);
16851       assert.strictEqual(over(), true);
16852
16853       over = _.overSome(stubNull, stubA, stubZero);
16854       assert.strictEqual(over(), true);
16855     });
16856
16857     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
16858       assert.expect(2);
16859
16860       var count = 0,
16861           countFalse = function() { count++; return false; },
16862           countTrue = function() { count++; return true; },
16863           over = _.overSome(countFalse, countTrue, countFalse);
16864
16865       assert.strictEqual(over(), true);
16866       assert.strictEqual(count, 2);
16867     });
16868
16869     QUnit.test('should return `false` if all predicates return falsey', function(assert) {
16870       assert.expect(2);
16871
16872       var over = _.overSome(stubFalse, stubFalse, stubFalse);
16873       assert.strictEqual(over(), false);
16874
16875       over = _.overSome(stubNull, stubZero, stubString);
16876       assert.strictEqual(over(), false);
16877     });
16878
16879     QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16880       assert.expect(2);
16881
16882       var over = _.overSome(undefined, null);
16883
16884       assert.strictEqual(over(true), true);
16885       assert.strictEqual(over(false), false);
16886     });
16887
16888     QUnit.test('should work with `_.property` shorthands', function(assert) {
16889       assert.expect(2);
16890
16891       var over = _.overSome('b', 'a');
16892
16893       assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
16894       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16895     });
16896
16897     QUnit.test('should work with `_.matches` shorthands', function(assert) {
16898       assert.expect(2);
16899
16900       var over = _.overSome({ 'b': 2 }, { 'a': 1 });
16901
16902       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16903       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16904     });
16905
16906     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16907       assert.expect(2);
16908
16909       var over = _.overSome([['b', 2], ['a', 1]]);
16910
16911       assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16912       assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16913     });
16914
16915     QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16916       assert.expect(5);
16917
16918       var over = _.overSome(['a', 1]);
16919
16920       assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
16921       assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
16922       assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
16923
16924       over = _.overSome([['a', 1]]);
16925
16926       assert.strictEqual(over({ 'a': 1 }), true);
16927       assert.strictEqual(over({ 'a': 2 }), false);
16928     });
16929
16930     QUnit.test('should flatten `predicates`', function(assert) {
16931       assert.expect(1);
16932
16933       var over = _.overSome(stubFalse, [stubTrue]);
16934       assert.strictEqual(over(), true);
16935     });
16936
16937     QUnit.test('should provide arguments to predicates', function(assert) {
16938       assert.expect(1);
16939
16940       var args;
16941
16942       var over = _.overSome(function() {
16943         args = slice.call(arguments);
16944       });
16945
16946       over('a', 'b', 'c');
16947       assert.deepEqual(args, ['a', 'b', 'c']);
16948     });
16949
16950     QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16951       assert.expect(2);
16952
16953       var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
16954           object = { 'over': over, 'a': 1, 'b': 2 };
16955
16956       assert.strictEqual(object.over(), true);
16957
16958       object.a = object.b = 0;
16959       assert.strictEqual(object.over(), false);
16960     });
16961   }());
16962
16963   /*--------------------------------------------------------------------------*/
16964
16965   QUnit.module('lodash.pad');
16966
16967   (function() {
16968     var string = 'abc';
16969
16970     QUnit.test('should pad a string to a given length', function(assert) {
16971       assert.expect(1);
16972
16973       var values = [, undefined],
16974           expected = lodashStable.map(values, lodashStable.constant(' abc  '));
16975
16976       var actual = lodashStable.map(values, function(value, index) {
16977         return index ? _.pad(string, 6, value) : _.pad(string, 6);
16978       });
16979
16980       assert.deepEqual(actual, expected);
16981     });
16982
16983     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16984       assert.expect(2);
16985
16986       assert.strictEqual(_.pad(string, 8), '  abc   ');
16987       assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
16988     });
16989
16990     QUnit.test('should coerce `string` to a string', function(assert) {
16991       assert.expect(1);
16992
16993       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16994           expected = lodashStable.map(values, stubTrue);
16995
16996       var actual = lodashStable.map(values, function(value) {
16997         return _.pad(value, 6) === ' abc  ';
16998       });
16999
17000       assert.deepEqual(actual, expected);
17001     });
17002   }());
17003
17004   /*--------------------------------------------------------------------------*/
17005
17006   QUnit.module('lodash.padEnd');
17007
17008   (function() {
17009     var string = 'abc';
17010
17011     QUnit.test('should pad a string to a given length', function(assert) {
17012       assert.expect(1);
17013
17014       var values = [, undefined],
17015           expected = lodashStable.map(values, lodashStable.constant('abc   '));
17016
17017       var actual = lodashStable.map(values, function(value, index) {
17018         return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
17019       });
17020
17021       assert.deepEqual(actual, expected);
17022     });
17023
17024     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17025       assert.expect(1);
17026
17027       assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
17028     });
17029
17030     QUnit.test('should coerce `string` to a string', function(assert) {
17031       assert.expect(1);
17032
17033       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17034           expected = lodashStable.map(values, stubTrue);
17035
17036       var actual = lodashStable.map(values, function(value) {
17037         return _.padEnd(value, 6) === 'abc   ';
17038       });
17039
17040       assert.deepEqual(actual, expected);
17041     });
17042   }());
17043
17044   /*--------------------------------------------------------------------------*/
17045
17046   QUnit.module('lodash.padStart');
17047
17048   (function() {
17049     var string = 'abc';
17050
17051     QUnit.test('should pad a string to a given length', function(assert) {
17052       assert.expect(1);
17053
17054       var values = [, undefined],
17055           expected = lodashStable.map(values, lodashStable.constant('   abc'));
17056
17057       var actual = lodashStable.map(values, function(value, index) {
17058         return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
17059       });
17060
17061       assert.deepEqual(actual, expected);
17062     });
17063
17064     QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17065       assert.expect(1);
17066
17067       assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
17068     });
17069
17070     QUnit.test('should coerce `string` to a string', function(assert) {
17071       assert.expect(1);
17072
17073       var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17074           expected = lodashStable.map(values, stubTrue);
17075
17076       var actual = lodashStable.map(values, function(value) {
17077         return _.padStart(value, 6) === '   abc';
17078       });
17079
17080       assert.deepEqual(actual, expected);
17081     });
17082   }());
17083
17084   /*--------------------------------------------------------------------------*/
17085
17086   QUnit.module('pad methods');
17087
17088   lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
17089     var func = _[methodName],
17090         isPad = methodName == 'pad',
17091         isStart = methodName == 'padStart',
17092         string = 'abc';
17093
17094     QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
17095       assert.expect(2);
17096
17097       assert.strictEqual(func(string, 2), string);
17098       assert.strictEqual(func(string, 3), string);
17099     });
17100
17101     QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
17102       assert.expect(2);
17103
17104       lodashStable.each([0, -2], function(length) {
17105         assert.strictEqual(func(string, length), string);
17106       });
17107     });
17108
17109     QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
17110       assert.expect(2);
17111
17112       lodashStable.each(['', '4'], function(length) {
17113         var actual = length ? (isStart ? ' abc' : 'abc ') : string;
17114         assert.strictEqual(func(string, length), actual);
17115       });
17116     });
17117
17118     QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
17119       assert.expect(6);
17120
17121       lodashStable.each([undefined, '_-'], function(chars) {
17122         var expected = chars ? (isPad ? '__' : chars) : '  ';
17123         assert.strictEqual(func(null, 2, chars), expected);
17124         assert.strictEqual(func(undefined, 2, chars), expected);
17125         assert.strictEqual(func('', 2, chars), expected);
17126       });
17127     });
17128
17129     QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
17130       assert.expect(1);
17131
17132       var values = ['', Object('')],
17133           expected = lodashStable.map(values, lodashStable.constant(string));
17134
17135       var actual = lodashStable.map(values, function(value) {
17136         return _.pad(string, 6, value);
17137       });
17138
17139       assert.deepEqual(actual, expected);
17140     });
17141   });
17142
17143   /*--------------------------------------------------------------------------*/
17144
17145   QUnit.module('lodash.parseInt');
17146
17147   (function() {
17148     QUnit.test('should accept a `radix`', function(assert) {
17149       assert.expect(1);
17150
17151       var expected = lodashStable.range(2, 37);
17152
17153       var actual = lodashStable.map(expected, function(radix) {
17154         return _.parseInt('10', radix);
17155       });
17156
17157       assert.deepEqual(actual, expected);
17158     });
17159
17160     QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17161       assert.expect(4);
17162
17163       assert.strictEqual(_.parseInt('10'), 10);
17164       assert.strictEqual(_.parseInt('10', 0), 10);
17165       assert.strictEqual(_.parseInt('10', 10), 10);
17166       assert.strictEqual(_.parseInt('10', undefined), 10);
17167     });
17168
17169     QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17170       assert.expect(8);
17171
17172       lodashStable.each(['0x20', '0X20'], function(string) {
17173         assert.strictEqual(_.parseInt(string), 32);
17174         assert.strictEqual(_.parseInt(string, 0), 32);
17175         assert.strictEqual(_.parseInt(string, 16), 32);
17176         assert.strictEqual(_.parseInt(string, undefined), 32);
17177       });
17178     });
17179
17180     QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
17181       assert.expect(2);
17182
17183       assert.strictEqual(_.parseInt('08'), 8);
17184       assert.strictEqual(_.parseInt('08', 10), 8);
17185     });
17186
17187     QUnit.test('should parse strings with leading whitespace', function(assert) {
17188       assert.expect(2);
17189
17190       var expected = [8, 8, 10, 10, 32, 32, 32, 32];
17191
17192       lodashStable.times(2, function(index) {
17193         var actual = [],
17194             func = (index ? (lodashBizarro || {}) : _).parseInt;
17195
17196         if (func) {
17197           lodashStable.times(2, function(otherIndex) {
17198             var string = otherIndex ? '10' : '08';
17199             actual.push(
17200               func(whitespace + string, 10),
17201               func(whitespace + string)
17202             );
17203           });
17204
17205           lodashStable.each(['0x20', '0X20'], function(string) {
17206             actual.push(
17207               func(whitespace + string),
17208               func(whitespace + string, 16)
17209             );
17210           });
17211
17212           assert.deepEqual(actual, expected);
17213         }
17214         else {
17215           skipAssert(assert);
17216         }
17217       });
17218     });
17219
17220     QUnit.test('should coerce `radix` to a number', function(assert) {
17221       assert.expect(2);
17222
17223       var object = { 'valueOf': stubZero };
17224       assert.strictEqual(_.parseInt('08', object), 8);
17225       assert.strictEqual(_.parseInt('0x20', object), 32);
17226     });
17227
17228     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17229       assert.expect(2);
17230
17231       var strings = lodashStable.map(['6', '08', '10'], Object),
17232           actual = lodashStable.map(strings, _.parseInt);
17233
17234       assert.deepEqual(actual, [6, 8, 10]);
17235
17236       actual = lodashStable.map('123', _.parseInt);
17237       assert.deepEqual(actual, [1, 2, 3]);
17238     });
17239   }());
17240
17241   /*--------------------------------------------------------------------------*/
17242
17243   QUnit.module('partial methods');
17244
17245   lodashStable.each(['partial', 'partialRight'], function(methodName) {
17246     var func = _[methodName],
17247         isPartial = methodName == 'partial',
17248         ph = func.placeholder;
17249
17250     QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
17251       assert.expect(1);
17252
17253       var par = func(identity, 'a');
17254       assert.strictEqual(par(), 'a');
17255     });
17256
17257     QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
17258       assert.expect(1);
17259
17260       var fn = function(a, b) { return [a, b]; },
17261           par = func(fn, 'a'),
17262           expected = isPartial ? ['a', 'b'] : ['b', 'a'];
17263
17264       assert.deepEqual(par('b'), expected);
17265     });
17266
17267     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
17268       assert.expect(1);
17269
17270       var fn = function() { return arguments.length; },
17271           par = func(fn);
17272
17273       assert.strictEqual(par(), 0);
17274     });
17275
17276     QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
17277       assert.expect(1);
17278
17279       var par = func(identity);
17280       assert.strictEqual(par('a'), 'a');
17281     });
17282
17283     QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
17284       assert.expect(4);
17285
17286       var fn = function() { return slice.call(arguments); },
17287           par = func(fn, ph, 'b', ph);
17288
17289       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
17290       assert.deepEqual(par('a'), ['a', 'b', undefined]);
17291       assert.deepEqual(par(), [undefined, 'b', undefined]);
17292
17293       if (isPartial) {
17294         assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
17295       } else {
17296         par = func(fn, ph, 'c', ph);
17297         assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
17298       }
17299     });
17300
17301     QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
17302       assert.expect(1);
17303
17304       if (!isModularize) {
17305         var _ph = _.placeholder = {},
17306             fn = function() { return slice.call(arguments); },
17307             par = func(fn, _ph, 'b', ph),
17308             expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
17309
17310         assert.deepEqual(par('a', 'c'), expected);
17311         delete _.placeholder;
17312       }
17313       else {
17314         skipAssert(assert);
17315       }
17316     });
17317
17318     QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
17319       assert.expect(1);
17320
17321       var fn = function(a, b, c) {},
17322           par = func(fn, 'a');
17323
17324       assert.strictEqual(par.length, 0);
17325     });
17326
17327     QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
17328       assert.expect(2);
17329
17330       function Foo(value) {
17331         return value && object;
17332       }
17333
17334       var object = {},
17335           par = func(Foo);
17336
17337       assert.ok(new par instanceof Foo);
17338       assert.strictEqual(new par(true), object);
17339     });
17340
17341     QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
17342       assert.expect(3);
17343
17344       function greet(greeting, name) {
17345         return greeting + ' ' + name;
17346       }
17347
17348       var par1 = func(greet, 'hi'),
17349           par2 = func(par1, 'barney'),
17350           par3 = func(par1, 'pebbles');
17351
17352       assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
17353       assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
17354       assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
17355     });
17356
17357     QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
17358       assert.expect(2);
17359
17360       var fn = function(a, b, c) { return a + b + c; },
17361           curried = _.curry(func(fn, 1), 2);
17362
17363       assert.strictEqual(curried(2, 3), 6);
17364       assert.strictEqual(curried(2)(3), 6);
17365     });
17366
17367     QUnit.test('should work with placeholders and curried functions', function(assert) {
17368       assert.expect(1);
17369
17370       var fn = function() { return slice.call(arguments); },
17371           curried = _.curry(fn),
17372           par = func(curried, ph, 'b', ph, 'd');
17373
17374       assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
17375     });
17376   });
17377
17378   /*--------------------------------------------------------------------------*/
17379
17380   QUnit.module('lodash.partialRight');
17381
17382   (function() {
17383     QUnit.test('should work as a deep `_.defaults`', function(assert) {
17384       assert.expect(1);
17385
17386       var object = { 'a': { 'b': 2 } },
17387           source = { 'a': { 'b': 3, 'c': 3 } },
17388           expected = { 'a': { 'b': 2, 'c': 3 } };
17389
17390       var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
17391         return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
17392       });
17393
17394       assert.deepEqual(defaultsDeep(object, source), expected);
17395     });
17396   }());
17397
17398   /*--------------------------------------------------------------------------*/
17399
17400   QUnit.module('methods using `createWrapper`');
17401
17402   (function() {
17403     function fn() {
17404       return slice.call(arguments);
17405     }
17406
17407     var ph1 = _.bind.placeholder,
17408         ph2 = _.bindKey.placeholder,
17409         ph3 = _.partial.placeholder,
17410         ph4 = _.partialRight.placeholder;
17411
17412     QUnit.test('should work with combinations of partial functions', function(assert) {
17413       assert.expect(1);
17414
17415       var a = _.partial(fn),
17416           b = _.partialRight(a, 3),
17417           c = _.partial(b, 1);
17418
17419       assert.deepEqual(c(2), [1, 2, 3]);
17420     });
17421
17422     QUnit.test('should work with combinations of bound and partial functions', function(assert) {
17423       assert.expect(3);
17424
17425       var fn = function() {
17426         var result = [this.a];
17427         push.apply(result, arguments);
17428         return result;
17429       };
17430
17431       var expected = [1, 2, 3, 4],
17432           object = { 'a': 1, 'fn': fn };
17433
17434       var a = _.bindKey(object, 'fn'),
17435           b = _.partialRight(a, 4),
17436           c = _.partial(b, 2);
17437
17438       assert.deepEqual(c(3), expected);
17439
17440       a = _.bind(fn, object);
17441       b = _.partialRight(a, 4);
17442       c = _.partial(b, 2);
17443
17444       assert.deepEqual(c(3), expected);
17445
17446       a = _.partial(fn, 2);
17447       b = _.bind(a, object);
17448       c = _.partialRight(b, 4);
17449
17450       assert.deepEqual(c(3), expected);
17451     });
17452
17453     QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
17454       assert.expect(2);
17455
17456       function Foo(a, b, c) {
17457         return b === 0 && object;
17458       }
17459
17460       var combo = _.partial(_.partialRight(Foo, 3), 1),
17461           object = {};
17462
17463       assert.ok(new combo(2) instanceof Foo);
17464       assert.strictEqual(new combo(0), object);
17465     });
17466
17467     QUnit.test('should work with combinations of functions with placeholders', function(assert) {
17468       assert.expect(3);
17469
17470       var expected = [1, 2, 3, 4, 5, 6],
17471           object = { 'fn': fn };
17472
17473       var a = _.bindKey(object, 'fn', ph2, 2),
17474           b = _.partialRight(a, ph4, 6),
17475           c = _.partial(b, 1, ph3, 4);
17476
17477       assert.deepEqual(c(3, 5), expected);
17478
17479       a = _.bind(fn, object, ph1, 2);
17480       b = _.partialRight(a, ph4, 6);
17481       c = _.partial(b, 1, ph3, 4);
17482
17483       assert.deepEqual(c(3, 5), expected);
17484
17485       a = _.partial(fn, ph3, 2);
17486       b = _.bind(a, object, 1, ph1, 4);
17487       c = _.partialRight(b, ph4, 6);
17488
17489       assert.deepEqual(c(3, 5), expected);
17490     });
17491
17492     QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
17493       assert.expect(3);
17494
17495       var expected = [1, 2, 3, 4],
17496           object = { 'fn': fn };
17497
17498       var a = _.bindKey(object, 'fn', ph2, 2),
17499           b = _.partialRight(a, ph4, 4),
17500           c = _.partial(b, ph3, 3);
17501
17502       assert.deepEqual(c(1), expected);
17503
17504       a = _.bind(fn, object, ph1, 2);
17505       b = _.partialRight(a, ph4, 4);
17506       c = _.partial(b, ph3, 3);
17507
17508       assert.deepEqual(c(1), expected);
17509
17510       a = _.partial(fn, ph3, 2);
17511       b = _.bind(a, object, ph1, 3);
17512       c = _.partialRight(b, ph4, 4);
17513
17514       assert.deepEqual(c(1), expected);
17515     });
17516
17517     QUnit.test('should work with recursively bound functions', function(assert) {
17518       assert.expect(1);
17519
17520       var fn = function() {
17521         return this.a;
17522       };
17523
17524       var a = _.bind(fn, { 'a': 1 }),
17525           b = _.bind(a,  { 'a': 2 }),
17526           c = _.bind(b,  { 'a': 3 });
17527
17528       assert.strictEqual(c(), 1);
17529     });
17530
17531     QUnit.test('should work when hot', function(assert) {
17532       assert.expect(12);
17533
17534       lodashStable.times(2, function(index) {
17535         var fn = function() {
17536           var result = [this];
17537           push.apply(result, arguments);
17538           return result;
17539         };
17540
17541         var object = {},
17542             bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17543             expected = [object, 1, 2, 3];
17544
17545         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17546           var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17547           return index ? bound2(3) : bound2(1, 2, 3);
17548         }));
17549
17550         assert.deepEqual(actual, expected);
17551
17552         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17553           var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17554               bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17555
17556           return index ? bound2(3) : bound2(1, 2, 3);
17557         }));
17558
17559         assert.deepEqual(actual, expected);
17560       });
17561
17562       lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
17563         var fn = function(a, b, c) { return [a, b, c]; },
17564             curried = _[methodName](fn),
17565             expected = index ? [3, 2, 1] :  [1, 2, 3];
17566
17567         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17568           return curried(1)(2)(3);
17569         }));
17570
17571         assert.deepEqual(actual, expected);
17572
17573         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17574           var curried = _[methodName](fn);
17575           return curried(1)(2)(3);
17576         }));
17577
17578         assert.deepEqual(actual, expected);
17579       });
17580
17581       lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
17582         var func = _[methodName],
17583             fn = function() { return slice.call(arguments); },
17584             par1 = func(fn, 1),
17585             expected = index ? [3, 2, 1] : [1, 2, 3];
17586
17587         var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17588           var par2 = func(par1, 2);
17589           return par2(3);
17590         }));
17591
17592         assert.deepEqual(actual, expected);
17593
17594         actual = _.last(lodashStable.times(HOT_COUNT, function() {
17595           var par1 = func(fn, 1),
17596               par2 = func(par1, 2);
17597
17598           return par2(3);
17599         }));
17600
17601         assert.deepEqual(actual, expected);
17602       });
17603     });
17604   }());
17605
17606   /*--------------------------------------------------------------------------*/
17607
17608   QUnit.module('lodash.partition');
17609
17610   (function() {
17611     var array = [1, 0, 1];
17612
17613     QUnit.test('should split elements into two groups by `predicate`', function(assert) {
17614       assert.expect(3);
17615
17616       assert.deepEqual(_.partition([], identity), [[], []]);
17617       assert.deepEqual(_.partition(array, stubTrue), [array, []]);
17618       assert.deepEqual(_.partition(array, stubFalse), [[], array]);
17619     });
17620
17621     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17622       assert.expect(1);
17623
17624       var values = [, null, undefined],
17625           expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
17626
17627       var actual = lodashStable.map(values, function(value, index) {
17628         return index ? _.partition(array, value) : _.partition(array);
17629       });
17630
17631       assert.deepEqual(actual, expected);
17632     });
17633
17634     QUnit.test('should work with `_.property` shorthands', function(assert) {
17635       assert.expect(1);
17636
17637       var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
17638           actual = _.partition(objects, 'a');
17639
17640       assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
17641     });
17642
17643     QUnit.test('should work with a number for `predicate`', function(assert) {
17644       assert.expect(2);
17645
17646       var array = [
17647         [1, 0],
17648         [0, 1],
17649         [1, 0]
17650       ];
17651
17652       assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
17653       assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
17654     });
17655
17656     QUnit.test('should work with an object for `collection`', function(assert) {
17657       assert.expect(1);
17658
17659       var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
17660       assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
17661     });
17662   }());
17663
17664   /*--------------------------------------------------------------------------*/
17665
17666   QUnit.module('lodash.pick');
17667
17668   (function() {
17669     var args = toArgs(['a', 'c']),
17670         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17671         nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } };
17672
17673     QUnit.test('should flatten `paths`', function(assert) {
17674       assert.expect(2);
17675
17676       assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
17677       assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
17678     });
17679
17680     QUnit.test('should support deep paths', function(assert) {
17681       assert.expect(1);
17682
17683       assert.deepEqual(_.pick(nested, 'b.c'), { 'b': { 'c': 2 } });
17684     });
17685
17686     QUnit.test('should support path arrays', function(assert) {
17687       assert.expect(1);
17688
17689       var object = { 'a.b': 1, 'a': { 'b': 2 } },
17690           actual = _.pick(object, [['a.b']]);
17691
17692       assert.deepEqual(actual, { 'a.b': 1 });
17693     });
17694
17695     QUnit.test('should pick a key over a path', function(assert) {
17696       assert.expect(2);
17697
17698       var object = { 'a.b': 1, 'a': { 'b': 2 } };
17699
17700       lodashStable.each(['a.b', ['a.b']], function(path) {
17701         assert.deepEqual(_.pick(object, path), { 'a.b': 1 });
17702       });
17703     });
17704
17705     QUnit.test('should coerce `paths` to strings', function(assert) {
17706       assert.expect(1);
17707
17708       assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
17709     });
17710
17711     QUnit.test('should return an empty object when `object` is nullish', function(assert) {
17712       assert.expect(2);
17713
17714       lodashStable.each([null, undefined], function(value) {
17715         assert.deepEqual(_.pick(value, 'valueOf'), {});
17716       });
17717     });
17718
17719     QUnit.test('should work with a primitive `object`', function(assert) {
17720       assert.expect(1);
17721
17722       assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
17723     });
17724
17725     QUnit.test('should work with `arguments` object `paths`', function(assert) {
17726       assert.expect(1);
17727
17728       assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
17729     });
17730   }());
17731
17732   /*--------------------------------------------------------------------------*/
17733
17734   QUnit.module('lodash.pickBy');
17735
17736   (function() {
17737     QUnit.test('should work with a predicate argument', function(assert) {
17738       assert.expect(1);
17739
17740       var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17741
17742       var actual = _.pickBy(object, function(n) {
17743         return n == 1 || n == 3;
17744       });
17745
17746       assert.deepEqual(actual, { 'a': 1, 'c': 3 });
17747     });
17748
17749     QUnit.test('should not treat keys with dots as deep paths', function(assert) {
17750       assert.expect(1);
17751
17752       var object = { 'a.b.c': 1 },
17753           actual = _.pickBy(object, stubTrue);
17754
17755       assert.deepEqual(actual, { 'a.b.c': 1 });
17756     });
17757   }());
17758
17759   /*--------------------------------------------------------------------------*/
17760
17761   QUnit.module('pick methods');
17762
17763   lodashStable.each(['pick', 'pickBy'], function(methodName) {
17764     var expected = { 'a': 1, 'c': 3 },
17765         func = _[methodName],
17766         isPick = methodName == 'pick',
17767         object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17768         resolve = lodashStable.nthArg(1);
17769
17770     if (methodName == 'pickBy') {
17771       resolve = function(object, props) {
17772         props = lodashStable.castArray(props);
17773         return function(value) {
17774           return lodashStable.some(props, function(key) {
17775             key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
17776             return object[key] === value;
17777           });
17778         };
17779       };
17780     }
17781     QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
17782       assert.expect(2);
17783
17784       assert.deepEqual(func(object, resolve(object, 'a')), { 'a': 1 });
17785       assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
17786     });
17787
17788     QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
17789       assert.expect(1);
17790
17791       function Foo() {}
17792       Foo.prototype = object;
17793
17794       var foo = new Foo;
17795       assert.deepEqual(func(foo, resolve(foo, ['a', 'c'])), expected);
17796     });
17797
17798     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
17799       assert.expect(1);
17800
17801       var object = { '-0': 'a', '0': 'b' },
17802           props = [-0, Object(-0), 0, Object(0)],
17803           expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
17804
17805       var actual = lodashStable.map(props, function(key) {
17806         return func(object, resolve(object, key));
17807       });
17808
17809       assert.deepEqual(actual, expected);
17810     });
17811
17812     QUnit.test('`_.' + methodName + '` should pick symbols', function(assert) {
17813       assert.expect(3);
17814
17815       function Foo() {
17816         this[symbol] = 1;
17817       }
17818
17819       if (Symbol) {
17820         var symbol2 = Symbol('b');
17821         Foo.prototype[symbol2] = 2;
17822
17823         var symbol3 = Symbol('c');
17824         defineProperty(Foo.prototype, symbol3, {
17825           'configurable': true,
17826           'enumerable': false,
17827           'writable': true,
17828           'value': 3
17829         });
17830
17831         var foo = new Foo,
17832             actual = func(foo, resolve(foo, [symbol, symbol2, symbol3]));
17833
17834         assert.strictEqual(actual[symbol], 1);
17835         assert.strictEqual(actual[symbol2], 2);
17836
17837         if (isPick) {
17838           assert.strictEqual(actual[symbol3], 3);
17839         } else {
17840           assert.notOk(symbol3 in actual);
17841         }
17842       }
17843       else {
17844         skipAssert(assert, 3);
17845       }
17846     });
17847
17848     QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) {
17849       assert.expect(1);
17850
17851       var array = [1, 2, 3];
17852       assert.deepEqual(func(array, resolve(array, '1')), { '1': 2 });
17853     });
17854   });
17855
17856   /*--------------------------------------------------------------------------*/
17857
17858   QUnit.module('lodash.property');
17859
17860   (function() {
17861     QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
17862       assert.expect(4);
17863
17864       var object = { 'a': 1 };
17865
17866       lodashStable.each(['a', ['a']], function(path) {
17867         var prop = _.property(path);
17868         assert.strictEqual(prop.length, 1);
17869         assert.strictEqual(prop(object), 1);
17870       });
17871     });
17872
17873     QUnit.test('should pluck deep property values', function(assert) {
17874       assert.expect(2);
17875
17876       var object = { 'a': { 'b': 2 } };
17877
17878       lodashStable.each(['a.b', ['a', 'b']], function(path) {
17879         var prop = _.property(path);
17880         assert.strictEqual(prop(object), 2);
17881       });
17882     });
17883
17884     QUnit.test('should pluck inherited property values', function(assert) {
17885       assert.expect(2);
17886
17887       function Foo() {}
17888       Foo.prototype.a = 1;
17889
17890       lodashStable.each(['a', ['a']], function(path) {
17891         var prop = _.property(path);
17892         assert.strictEqual(prop(new Foo), 1);
17893       });
17894     });
17895
17896     QUnit.test('should work with a non-string `path`', function(assert) {
17897       assert.expect(2);
17898
17899       var array = [1, 2, 3];
17900
17901       lodashStable.each([1, [1]], function(path) {
17902         var prop = _.property(path);
17903         assert.strictEqual(prop(array), 2);
17904       });
17905     });
17906
17907     QUnit.test('should preserve the sign of `0`', function(assert) {
17908       assert.expect(1);
17909
17910       var object = { '-0': 'a', '0': 'b' },
17911           props = [-0, Object(-0), 0, Object(0)];
17912
17913       var actual = lodashStable.map(props, function(key) {
17914         var prop = _.property(key);
17915         return prop(object);
17916       });
17917
17918       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17919     });
17920
17921     QUnit.test('should coerce `path` to a string', function(assert) {
17922       assert.expect(2);
17923
17924       function fn() {}
17925       fn.toString = lodashStable.constant('fn');
17926
17927       var expected = [1, 2, 3, 4],
17928           object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
17929           paths = [null, undefined, fn, {}];
17930
17931       lodashStable.times(2, function(index) {
17932         var actual = lodashStable.map(paths, function(path) {
17933           var prop = _.property(index ? [path] : path);
17934           return prop(object);
17935         });
17936
17937         assert.deepEqual(actual, expected);
17938       });
17939     });
17940
17941     QUnit.test('should pluck a key over a path', function(assert) {
17942       assert.expect(2);
17943
17944       var object = { 'a.b': 1, 'a': { 'b': 2 } };
17945
17946       lodashStable.each(['a.b', ['a.b']], function(path) {
17947         var prop = _.property(path);
17948         assert.strictEqual(prop(object), 1);
17949       });
17950     });
17951
17952     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17953       assert.expect(2);
17954
17955       var values = [, null, undefined],
17956           expected = lodashStable.map(values, noop);
17957
17958       lodashStable.each(['constructor', ['constructor']], function(path) {
17959         var prop = _.property(path);
17960
17961         var actual = lodashStable.map(values, function(value, index) {
17962           return index ? prop(value) : prop();
17963         });
17964
17965         assert.deepEqual(actual, expected);
17966       });
17967     });
17968
17969     QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
17970       assert.expect(2);
17971
17972       var values = [, null, undefined],
17973           expected = lodashStable.map(values, noop);
17974
17975       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17976         var prop = _.property(path);
17977
17978         var actual = lodashStable.map(values, function(value, index) {
17979           return index ? prop(value) : prop();
17980         });
17981
17982         assert.deepEqual(actual, expected);
17983       });
17984     });
17985
17986     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17987       assert.expect(4);
17988
17989       var object = {};
17990
17991       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17992         var prop = _.property(path);
17993         assert.strictEqual(prop(object), undefined);
17994       });
17995     });
17996   }());
17997
17998   /*--------------------------------------------------------------------------*/
17999
18000   QUnit.module('lodash.propertyOf');
18001
18002   (function() {
18003     QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
18004       assert.expect(3);
18005
18006       var object = { 'a': 1 },
18007           propOf = _.propertyOf(object);
18008
18009       assert.strictEqual(propOf.length, 1);
18010       lodashStable.each(['a', ['a']], function(path) {
18011         assert.strictEqual(propOf(path), 1);
18012       });
18013     });
18014
18015     QUnit.test('should pluck deep property values', function(assert) {
18016       assert.expect(2);
18017
18018       var object = { 'a': { 'b': 2 } },
18019           propOf = _.propertyOf(object);
18020
18021       lodashStable.each(['a.b', ['a', 'b']], function(path) {
18022         assert.strictEqual(propOf(path), 2);
18023       });
18024     });
18025
18026     QUnit.test('should pluck inherited property values', function(assert) {
18027       assert.expect(2);
18028
18029       function Foo() {
18030         this.a = 1;
18031       }
18032       Foo.prototype.b = 2;
18033
18034       var propOf = _.propertyOf(new Foo);
18035
18036       lodashStable.each(['b', ['b']], function(path) {
18037         assert.strictEqual(propOf(path), 2);
18038       });
18039     });
18040
18041     QUnit.test('should work with a non-string `path`', function(assert) {
18042       assert.expect(2);
18043
18044       var array = [1, 2, 3],
18045           propOf = _.propertyOf(array);
18046
18047       lodashStable.each([1, [1]], function(path) {
18048         assert.strictEqual(propOf(path), 2);
18049       });
18050     });
18051
18052     QUnit.test('should preserve the sign of `0`', function(assert) {
18053       assert.expect(1);
18054
18055       var object = { '-0': 'a', '0': 'b' },
18056           props = [-0, Object(-0), 0, Object(0)];
18057
18058       var actual = lodashStable.map(props, function(key) {
18059         var propOf = _.propertyOf(object);
18060         return propOf(key);
18061       });
18062
18063       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
18064     });
18065
18066     QUnit.test('should coerce `path` to a string', function(assert) {
18067       assert.expect(2);
18068
18069       function fn() {}
18070       fn.toString = lodashStable.constant('fn');
18071
18072       var expected = [1, 2, 3, 4],
18073           object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
18074           paths = [null, undefined, fn, {}];
18075
18076       lodashStable.times(2, function(index) {
18077         var actual = lodashStable.map(paths, function(path) {
18078           var propOf = _.propertyOf(object);
18079           return propOf(index ? [path] : path);
18080         });
18081
18082         assert.deepEqual(actual, expected);
18083       });
18084     });
18085
18086     QUnit.test('should pluck a key over a path', function(assert) {
18087       assert.expect(2);
18088
18089       var object = { 'a.b': 1, 'a': { 'b': 2 } },
18090           propOf = _.propertyOf(object);
18091
18092       lodashStable.each(['a.b', ['a.b']], function(path) {
18093         assert.strictEqual(propOf(path), 1);
18094       });
18095     });
18096
18097     QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
18098       assert.expect(2);
18099
18100       var values = [, null, undefined],
18101           expected = lodashStable.map(values, noop);
18102
18103       lodashStable.each(['constructor', ['constructor']], function(path) {
18104         var actual = lodashStable.map(values, function(value, index) {
18105           var propOf = index ? _.propertyOf(value) : _.propertyOf();
18106           return propOf(path);
18107         });
18108
18109         assert.deepEqual(actual, expected);
18110       });
18111     });
18112
18113     QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
18114       assert.expect(2);
18115
18116       var values = [, null, undefined],
18117           expected = lodashStable.map(values, noop);
18118
18119       lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
18120         var actual = lodashStable.map(values, function(value, index) {
18121           var propOf = index ? _.propertyOf(value) : _.propertyOf();
18122           return propOf(path);
18123         });
18124
18125         assert.deepEqual(actual, expected);
18126       });
18127     });
18128
18129     QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
18130       assert.expect(4);
18131
18132       var propOf = _.propertyOf({});
18133
18134       lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
18135         assert.strictEqual(propOf(path), undefined);
18136       });
18137     });
18138   }());
18139
18140   /*--------------------------------------------------------------------------*/
18141
18142   QUnit.module('lodash.pullAll');
18143
18144   (function() {
18145     QUnit.test('should work with the same value for `array` and `values`', function(assert) {
18146       assert.expect(1);
18147
18148       var array = [{ 'a': 1 }, { 'b': 2 }],
18149           actual = _.pullAll(array, array);
18150
18151       assert.deepEqual(actual, []);
18152     });
18153   }());
18154
18155   /*--------------------------------------------------------------------------*/
18156
18157   QUnit.module('lodash.pullAllBy');
18158
18159   (function() {
18160     QUnit.test('should accept an `iteratee`', function(assert) {
18161       assert.expect(1);
18162
18163       var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18164
18165       var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
18166         return object.x;
18167       });
18168
18169       assert.deepEqual(actual, [{ 'x': 2 }]);
18170     });
18171
18172     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
18173       assert.expect(1);
18174
18175       var args,
18176           array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18177
18178       _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
18179         args || (args = slice.call(arguments));
18180       });
18181
18182       assert.deepEqual(args, [{ 'x': 1 }]);
18183     });
18184   }());
18185
18186   /*--------------------------------------------------------------------------*/
18187
18188   QUnit.module('lodash.pullAllWith');
18189
18190   (function() {
18191     QUnit.test('should work with a `comparator`', function(assert) {
18192       assert.expect(1);
18193
18194       var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
18195           expected = [objects[0], objects[2]],
18196           actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
18197
18198       assert.deepEqual(actual, expected);
18199     });
18200   }());
18201
18202   /*--------------------------------------------------------------------------*/
18203
18204   QUnit.module('pull methods');
18205
18206   lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
18207     var func = _[methodName],
18208         isPull = methodName == 'pull';
18209
18210     function pull(array, values) {
18211       return isPull
18212         ? func.apply(undefined, [array].concat(values))
18213         : func(array, values);
18214     }
18215
18216     QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
18217       assert.expect(2);
18218
18219       var array = [1, 2, 3],
18220           actual = pull(array, [1, 3]);
18221
18222       assert.strictEqual(actual, array);
18223       assert.deepEqual(array, [2]);
18224     });
18225
18226     QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
18227       assert.expect(2);
18228
18229       var array = [1, 2, 3, 4];
18230       delete array[1];
18231       delete array[3];
18232
18233       pull(array, [1]);
18234       assert.notOk('0' in array);
18235       assert.notOk('2' in array);
18236     });
18237
18238     QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
18239       assert.expect(1);
18240
18241       var array = [1, 2, 3];
18242       delete array[1];
18243
18244       pull(array, [undefined]);
18245       assert.deepEqual(array, [1, 3]);
18246     });
18247
18248     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
18249       assert.expect(1);
18250
18251       var array = [1, NaN, 3, NaN];
18252
18253       pull(array, [NaN]);
18254       assert.deepEqual(array, [1, 3]);
18255     });
18256   });
18257
18258   /*--------------------------------------------------------------------------*/
18259
18260   QUnit.module('lodash.pullAt');
18261
18262   (function() {
18263     QUnit.test('should modify the array and return removed elements', function(assert) {
18264       assert.expect(2);
18265
18266       var array = [1, 2, 3],
18267           actual = _.pullAt(array, [0, 1]);
18268
18269       assert.deepEqual(array, [3]);
18270       assert.deepEqual(actual, [1, 2]);
18271     });
18272
18273     QUnit.test('should work with unsorted indexes', function(assert) {
18274       assert.expect(2);
18275
18276       var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
18277           actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
18278
18279       assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
18280       assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
18281     });
18282
18283     QUnit.test('should work with repeated indexes', function(assert) {
18284       assert.expect(2);
18285
18286       var array = [1, 2, 3, 4],
18287           actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
18288
18289       assert.deepEqual(array, [4]);
18290       assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
18291     });
18292
18293     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18294       assert.expect(2);
18295
18296       var array = ['a', 'b', 'c'],
18297           actual = _.pullAt(array, [2, 4, 0]);
18298
18299       assert.deepEqual(array, ['b']);
18300       assert.deepEqual(actual, ['c', undefined, 'a']);
18301     });
18302
18303     QUnit.test('should flatten `indexes`', function(assert) {
18304       assert.expect(4);
18305
18306       var array = ['a', 'b', 'c'];
18307       assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
18308       assert.deepEqual(array, ['b']);
18309
18310       array = ['a', 'b', 'c', 'd'];
18311       assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
18312       assert.deepEqual(array, ['b']);
18313     });
18314
18315     QUnit.test('should return an empty array when no indexes are given', function(assert) {
18316       assert.expect(4);
18317
18318       var array = ['a', 'b', 'c'],
18319           actual = _.pullAt(array);
18320
18321       assert.deepEqual(array, ['a', 'b', 'c']);
18322       assert.deepEqual(actual, []);
18323
18324       actual = _.pullAt(array, [], []);
18325
18326       assert.deepEqual(array, ['a', 'b', 'c']);
18327       assert.deepEqual(actual, []);
18328     });
18329
18330     QUnit.test('should work with non-index paths', function(assert) {
18331       assert.expect(2);
18332
18333       var values = lodashStable.reject(empties, function(value) {
18334         return (value === 0) || lodashStable.isArray(value);
18335       }).concat(-1, 1.1);
18336
18337       var array = lodashStable.transform(values, function(result, value) {
18338         result[value] = 1;
18339       }, []);
18340
18341       var expected = lodashStable.map(values, stubOne),
18342           actual = _.pullAt(array, values);
18343
18344       assert.deepEqual(actual, expected);
18345
18346       expected = lodashStable.map(values, noop);
18347       actual = lodashStable.at(array, values);
18348
18349       assert.deepEqual(actual, expected);
18350     });
18351
18352     QUnit.test('should preserve the sign of `0`', function(assert) {
18353       assert.expect(1);
18354
18355       var props = [-0, Object(-0), 0, Object(0)];
18356
18357       var actual = lodashStable.map(props, function(key) {
18358         var array = [-1];
18359         array['-0'] = -2;
18360         return _.pullAt(array, key);
18361       });
18362
18363       assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
18364     });
18365
18366     QUnit.test('should support deep paths', function(assert) {
18367       assert.expect(3);
18368
18369       var array = [];
18370       array.a = { 'b': 2 };
18371
18372       var actual = _.pullAt(array, 'a.b');
18373
18374       assert.deepEqual(actual, [2]);
18375       assert.deepEqual(array.a, {});
18376
18377       try {
18378         actual = _.pullAt(array, 'a.b.c');
18379       } catch (e) {}
18380
18381       assert.deepEqual(actual, [undefined]);
18382     });
18383
18384     QUnit.test('should work with a falsey `array` when keys are given', function(assert) {
18385       assert.expect(1);
18386
18387       var values = falsey.slice(),
18388           expected = lodashStable.map(values, lodashStable.constant(Array(4)));
18389
18390       var actual = lodashStable.map(values, function(array) {
18391         try {
18392           return _.pullAt(array, 0, 1, 'pop', 'push');
18393         } catch (e) {}
18394       });
18395
18396       assert.deepEqual(actual, expected);
18397     });
18398   }());
18399
18400   /*--------------------------------------------------------------------------*/
18401
18402   QUnit.module('lodash.random');
18403
18404   (function() {
18405     var array = Array(1000);
18406
18407     QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
18408       assert.expect(1);
18409
18410       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18411         return _.random();
18412       })).sort();
18413
18414       assert.deepEqual(actual, [0, 1]);
18415     });
18416
18417     QUnit.test('should support a `min` and `max`', function(assert) {
18418       assert.expect(1);
18419
18420       var min = 5,
18421           max = 10;
18422
18423       assert.ok(lodashStable.some(array, function() {
18424         var result = _.random(min, max);
18425         return result >= min && result <= max;
18426       }));
18427     });
18428
18429     QUnit.test('should support not providing a `max`', function(assert) {
18430       assert.expect(1);
18431
18432       var min = 0,
18433           max = 5;
18434
18435       assert.ok(lodashStable.some(array, function() {
18436         var result = _.random(max);
18437         return result >= min && result <= max;
18438       }));
18439     });
18440
18441     QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
18442       assert.expect(1);
18443
18444       var min = 4,
18445           max = 2,
18446           expected = [2, 3, 4];
18447
18448       var actual = lodashStable.uniq(lodashStable.map(array, function() {
18449         return _.random(min, max);
18450       })).sort();
18451
18452       assert.deepEqual(actual, expected);
18453     });
18454
18455     QUnit.test('should support large integer values', function(assert) {
18456       assert.expect(2);
18457
18458       var min = Math.pow(2, 31),
18459           max = Math.pow(2, 62);
18460
18461       assert.ok(lodashStable.every(array, function() {
18462         var result = _.random(min, max);
18463         return result >= min && result <= max;
18464       }));
18465
18466       assert.ok(lodashStable.some(array, function() {
18467         return _.random(MAX_INTEGER);
18468       }));
18469     });
18470
18471     QUnit.test('should coerce arguments to finite numbers', function(assert) {
18472       assert.expect(1);
18473
18474       var actual = [
18475         _.random(NaN, NaN),
18476         _.random('1', '1'),
18477         _.random(Infinity, Infinity)
18478       ];
18479
18480       assert.deepEqual(actual, [0, 1, MAX_INTEGER]);
18481     });
18482
18483     QUnit.test('should support floats', function(assert) {
18484       assert.expect(2);
18485
18486       var min = 1.5,
18487           max = 1.6,
18488           actual = _.random(min, max);
18489
18490       assert.ok(actual % 1);
18491       assert.ok(actual >= min && actual <= max);
18492     });
18493
18494     QUnit.test('should support providing a `floating`', function(assert) {
18495       assert.expect(3);
18496
18497       var actual = _.random(true);
18498       assert.ok(actual % 1 && actual >= 0 && actual <= 1);
18499
18500       actual = _.random(2, true);
18501       assert.ok(actual % 1 && actual >= 0 && actual <= 2);
18502
18503       actual = _.random(2, 4, true);
18504       assert.ok(actual % 1 && actual >= 2 && actual <= 4);
18505     });
18506
18507     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18508       assert.expect(1);
18509
18510       var array = [1, 2, 3],
18511           expected = lodashStable.map(array, stubTrue),
18512           randoms = lodashStable.map(array, _.random);
18513
18514       var actual = lodashStable.map(randoms, function(result, index) {
18515         return result >= 0 && result <= array[index] && (result % 1) == 0;
18516       });
18517
18518       assert.deepEqual(actual, expected);
18519     });
18520   }());
18521
18522   /*--------------------------------------------------------------------------*/
18523
18524   QUnit.module('range methods');
18525
18526   lodashStable.each(['range', 'rangeRight'], function(methodName) {
18527     var func = _[methodName],
18528         isRange = methodName == 'range';
18529
18530     function resolve(range) {
18531       return isRange ? range : range.reverse();
18532     }
18533
18534     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
18535       assert.expect(2);
18536
18537       assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
18538       assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
18539     });
18540
18541     QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
18542       assert.expect(2);
18543
18544       assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
18545       assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
18546     });
18547
18548     QUnit.test('`_.' + methodName + '` should work with a `start`, `end`, and `step`', function(assert) {
18549       assert.expect(3);
18550
18551       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18552       assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
18553       assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
18554     });
18555
18556     QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
18557       assert.expect(1);
18558
18559       assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
18560     });
18561
18562     QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
18563       assert.expect(1);
18564
18565       assert.deepEqual(func(1, 5, 20), [1]);
18566     });
18567
18568     QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
18569       assert.expect(2);
18570
18571       assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18572       assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
18573     });
18574
18575     QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
18576       assert.expect(1);
18577
18578       var actual = func(-0, 1);
18579       assert.strictEqual(1 / actual[0], -Infinity);
18580     });
18581
18582     QUnit.test('`_.' + methodName + '` should treat falsey `start` as `0`', function(assert) {
18583       assert.expect(13);
18584
18585       lodashStable.each(falsey, function(value, index) {
18586         if (index) {
18587           assert.deepEqual(func(value), []);
18588           assert.deepEqual(func(value, 1), [0]);
18589         } else {
18590           assert.deepEqual(func(), []);
18591         }
18592       });
18593     });
18594
18595     QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
18596       assert.expect(1);
18597
18598       var actual = [
18599         func('1'),
18600         func('0', 1),
18601         func(0, 1, '1'),
18602         func(NaN),
18603         func(NaN, NaN)
18604       ];
18605
18606       assert.deepEqual(actual, [[0], [0], [0], [], []]);
18607     });
18608
18609     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
18610       assert.expect(2);
18611
18612       var array = [1, 2, 3],
18613           object = { 'a': 1, 'b': 2, 'c': 3 },
18614           expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
18615
18616       lodashStable.each([array, object], function(collection) {
18617         var actual = lodashStable.map(collection, func);
18618         assert.deepEqual(actual, expected);
18619       });
18620     });
18621   });
18622
18623   /*--------------------------------------------------------------------------*/
18624
18625   QUnit.module('lodash.rearg');
18626
18627   (function() {
18628     function fn() {
18629       return slice.call(arguments);
18630     }
18631
18632     QUnit.test('should reorder arguments provided to `func`', function(assert) {
18633       assert.expect(1);
18634
18635       var rearged = _.rearg(fn, [2, 0, 1]);
18636       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18637     });
18638
18639     QUnit.test('should work with repeated indexes', function(assert) {
18640       assert.expect(1);
18641
18642       var rearged = _.rearg(fn, [1, 1, 1]);
18643       assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
18644     });
18645
18646     QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18647       assert.expect(1);
18648
18649       var rearged = _.rearg(fn, [1, 4]);
18650       assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
18651     });
18652
18653     QUnit.test('should use `undefined` for non-index values', function(assert) {
18654       assert.expect(1);
18655
18656       var values = lodashStable.reject(empties, function(value) {
18657         return (value === 0) || lodashStable.isArray(value);
18658       }).concat(-1, 1.1);
18659
18660       var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
18661
18662       var actual = lodashStable.map(values, function(value) {
18663         var rearged = _.rearg(fn, [value]);
18664         return rearged('a', 'b', 'c');
18665       });
18666
18667       assert.deepEqual(actual, expected);
18668     });
18669
18670     QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
18671       assert.expect(2);
18672
18673       var rearged = _.rearg(fn);
18674       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18675
18676       rearged = _.rearg(fn, [], []);
18677       assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18678     });
18679
18680     QUnit.test('should accept multiple index arguments', function(assert) {
18681       assert.expect(1);
18682
18683       var rearged = _.rearg(fn, 2, 0, 1);
18684       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18685     });
18686
18687     QUnit.test('should accept multiple arrays of indexes', function(assert) {
18688       assert.expect(1);
18689
18690       var rearged = _.rearg(fn, [2], [0, 1]);
18691       assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18692     });
18693
18694     QUnit.test('should work with fewer indexes than arguments', function(assert) {
18695       assert.expect(1);
18696
18697       var rearged = _.rearg(fn, [1, 0]);
18698       assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
18699     });
18700
18701     QUnit.test('should work on functions that have been rearged', function(assert) {
18702       assert.expect(1);
18703
18704       var rearged1 = _.rearg(fn, 2, 1, 0),
18705           rearged2 = _.rearg(rearged1, 1, 0, 2);
18706
18707       assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
18708     });
18709   }());
18710
18711   /*--------------------------------------------------------------------------*/
18712
18713   QUnit.module('lodash.reduce');
18714
18715   (function() {
18716     var array = [1, 2, 3];
18717
18718     QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
18719       assert.expect(1);
18720
18721       assert.strictEqual(_.reduce(array), 1);
18722     });
18723
18724     QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) {
18725       assert.expect(2);
18726
18727       var args;
18728
18729       _.reduce(array, function() {
18730         args || (args = slice.call(arguments));
18731       }, 0);
18732
18733       assert.deepEqual(args, [0, 1, 0, array]);
18734
18735       args = undefined;
18736       _.reduce(array, function() {
18737         args || (args = slice.call(arguments));
18738       });
18739
18740       assert.deepEqual(args, [1, 2, 1, array]);
18741     });
18742
18743     QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) {
18744       assert.expect(2);
18745
18746       var args,
18747           object = { 'a': 1, 'b': 2 },
18748           firstKey = _.head(_.keys(object));
18749
18750       var expected = firstKey == 'a'
18751         ? [0, 1, 'a', object]
18752         : [0, 2, 'b', object];
18753
18754       _.reduce(object, function() {
18755         args || (args = slice.call(arguments));
18756       }, 0);
18757
18758       assert.deepEqual(args, expected);
18759
18760       args = undefined;
18761       expected = firstKey == 'a'
18762         ? [1, 2, 'b', object]
18763         : [2, 1, 'a', object];
18764
18765       _.reduce(object, function() {
18766         args || (args = slice.call(arguments));
18767       });
18768
18769       assert.deepEqual(args, expected);
18770     });
18771   }());
18772
18773   /*--------------------------------------------------------------------------*/
18774
18775   QUnit.module('lodash.reduceRight');
18776
18777   (function() {
18778     var array = [1, 2, 3];
18779
18780     QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
18781       assert.expect(1);
18782
18783       assert.strictEqual(_.reduceRight(array), 3);
18784     });
18785
18786     QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) {
18787       assert.expect(2);
18788
18789       var args;
18790
18791       _.reduceRight(array, function() {
18792         args || (args = slice.call(arguments));
18793       }, 0);
18794
18795       assert.deepEqual(args, [0, 3, 2, array]);
18796
18797       args = undefined;
18798       _.reduceRight(array, function() {
18799         args || (args = slice.call(arguments));
18800       });
18801
18802       assert.deepEqual(args, [3, 2, 1, array]);
18803     });
18804
18805     QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) {
18806       assert.expect(2);
18807
18808       var args,
18809           object = { 'a': 1, 'b': 2 },
18810           isFIFO = lodashStable.keys(object)[0] == 'a';
18811
18812       var expected = isFIFO
18813         ? [0, 2, 'b', object]
18814         : [0, 1, 'a', object];
18815
18816       _.reduceRight(object, function() {
18817         args || (args = slice.call(arguments));
18818       }, 0);
18819
18820       assert.deepEqual(args, expected);
18821
18822       args = undefined;
18823       expected = isFIFO
18824         ? [2, 1, 'a', object]
18825         : [1, 2, 'b', object];
18826
18827       _.reduceRight(object, function() {
18828         args || (args = slice.call(arguments));
18829       });
18830
18831       assert.deepEqual(args, expected);
18832     });
18833   }());
18834
18835   /*--------------------------------------------------------------------------*/
18836
18837   QUnit.module('reduce methods');
18838
18839   lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
18840     var func = _[methodName],
18841         array = [1, 2, 3],
18842         isReduce = methodName == 'reduce';
18843
18844     QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
18845       assert.expect(1);
18846
18847       var actual = func(['a', 'b', 'c'], function(accumulator, value) {
18848         return accumulator + value;
18849       }, '');
18850
18851       assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
18852     });
18853
18854     QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
18855       assert.expect(1);
18856
18857       var actual = [],
18858           expected = lodashStable.map(empties, noop);
18859
18860       lodashStable.each(empties, function(value) {
18861         try {
18862           actual.push(func(value, noop));
18863         } catch (e) {}
18864       });
18865
18866       assert.deepEqual(actual, expected);
18867     });
18868
18869     QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
18870       assert.expect(1);
18871
18872       var expected = lodashStable.map(empties, lodashStable.constant('x'));
18873
18874       var actual = lodashStable.map(empties, function(value) {
18875         try {
18876           return func(value, noop, 'x');
18877         } catch (e) {}
18878       });
18879
18880       assert.deepEqual(actual, expected);
18881     });
18882
18883     QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
18884       assert.expect(1);
18885
18886       var actual = func([], noop, undefined);
18887       assert.strictEqual(actual, undefined);
18888     });
18889
18890     QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
18891       assert.expect(2);
18892
18893       var array = [],
18894           object = { '0': 1, 'length': 0 };
18895
18896       if ('__proto__' in array) {
18897         array.__proto__ = object;
18898         assert.strictEqual(func(array, noop), undefined);
18899       }
18900       else {
18901         skipAssert(assert);
18902       }
18903       assert.strictEqual(func(object, noop), undefined);
18904     });
18905
18906     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
18907       assert.expect(1);
18908
18909       if (!isNpm) {
18910         assert.strictEqual(_(array)[methodName](add), 6);
18911       }
18912       else {
18913         skipAssert(assert);
18914       }
18915     });
18916
18917     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
18918       assert.expect(1);
18919
18920       if (!isNpm) {
18921         assert.ok(_(array).chain()[methodName](add) instanceof _);
18922       }
18923       else {
18924         skipAssert(assert);
18925       }
18926     });
18927   });
18928
18929   /*--------------------------------------------------------------------------*/
18930
18931   QUnit.module('lodash.reject');
18932
18933   (function() {
18934     var array = [1, 2, 3];
18935
18936     QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
18937       assert.expect(1);
18938
18939       assert.deepEqual(_.reject(array, isEven), [1, 3]);
18940     });
18941   }());
18942
18943   /*--------------------------------------------------------------------------*/
18944
18945   QUnit.module('filter methods');
18946
18947   lodashStable.each(['filter', 'reject'], function(methodName) {
18948     var array = [1, 2, 3, 4],
18949         func = _[methodName],
18950         isFilter = methodName == 'filter',
18951         objects = [{ 'a': 0 }, { 'a': 1 }];
18952
18953     QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
18954       assert.expect(1);
18955
18956       var actual = func([0], function(value, index, array) {
18957         array[index] = 1;
18958         return isFilter;
18959       });
18960
18961       assert.deepEqual(actual, [0]);
18962     });
18963
18964     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
18965       assert.expect(1);
18966
18967       assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
18968     });
18969
18970     QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
18971       assert.expect(1);
18972
18973       assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
18974     });
18975
18976     QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
18977       assert.expect(2);
18978
18979       if (!isNpm) {
18980         var wrapped = _(array);
18981
18982         var actual = wrapped[methodName](function(n) {
18983           return n < 3;
18984         });
18985
18986         assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
18987
18988         actual = wrapped[methodName](function(n) {
18989           return n > 2;
18990         });
18991
18992         assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
18993       }
18994       else {
18995         skipAssert(assert, 2);
18996       }
18997     });
18998
18999     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
19000       assert.expect(2);
19001
19002       if (!isNpm) {
19003         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19004             predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); };
19005
19006         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
19007           return ['key' + index, index];
19008         }));
19009
19010         var actual = _(array).slice(1).map(square)[methodName](predicate).value();
19011         assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
19012
19013         actual = _(object).mapValues(square)[methodName](predicate).value();
19014         assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
19015       }
19016       else {
19017         skipAssert(assert, 2);
19018       }
19019     });
19020
19021     QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments in a lazy sequence', function(assert) {
19022       assert.expect(5);
19023
19024       if (!isNpm) {
19025         var args,
19026             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19027             expected = [1, 0, lodashStable.map(array.slice(1), square)];
19028
19029         _(array).slice(1)[methodName](function(value, index, array) {
19030           args || (args = slice.call(arguments));
19031         }).value();
19032
19033         assert.deepEqual(args, [1, 0, array.slice(1)]);
19034
19035         args = undefined;
19036         _(array).slice(1).map(square)[methodName](function(value, index, array) {
19037           args || (args = slice.call(arguments));
19038         }).value();
19039
19040         assert.deepEqual(args, expected);
19041
19042         args = undefined;
19043         _(array).slice(1).map(square)[methodName](function(value, index) {
19044           args || (args = slice.call(arguments));
19045         }).value();
19046
19047         assert.deepEqual(args, expected);
19048
19049         args = undefined;
19050         _(array).slice(1).map(square)[methodName](function(value) {
19051           args || (args = slice.call(arguments));
19052         }).value();
19053
19054         assert.deepEqual(args, [1]);
19055
19056         args = undefined;
19057         _(array).slice(1).map(square)[methodName](function() {
19058           args || (args = slice.call(arguments));
19059         }).value();
19060
19061         assert.deepEqual(args, expected);
19062       }
19063       else {
19064         skipAssert(assert, 5);
19065       }
19066     });
19067   });
19068
19069   /*--------------------------------------------------------------------------*/
19070
19071   QUnit.module('lodash.remove');
19072
19073   (function() {
19074     QUnit.test('should modify the array and return removed elements', function(assert) {
19075       assert.expect(2);
19076
19077       var array = [1, 2, 3, 4],
19078           actual = _.remove(array, isEven);
19079
19080       assert.deepEqual(array, [1, 3]);
19081       assert.deepEqual(actual, [2, 4]);
19082     });
19083
19084     QUnit.test('should provide correct `predicate` arguments', function(assert) {
19085       assert.expect(1);
19086
19087       var argsList = [],
19088           array = [1, 2, 3],
19089           clone = array.slice();
19090
19091       _.remove(array, function(n, index) {
19092         var args = slice.call(arguments);
19093         args[2] = args[2].slice();
19094         argsList.push(args);
19095         return isEven(index);
19096       });
19097
19098       assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
19099     });
19100
19101     QUnit.test('should work with `_.matches` shorthands', function(assert) {
19102       assert.expect(1);
19103
19104       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19105       _.remove(objects, { 'a': 1 });
19106       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19107     });
19108
19109     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
19110       assert.expect(1);
19111
19112       var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19113       _.remove(objects, ['a', 1]);
19114       assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19115     });
19116
19117     QUnit.test('should work with `_.property` shorthands', function(assert) {
19118       assert.expect(1);
19119
19120       var objects = [{ 'a': 0 }, { 'a': 1 }];
19121       _.remove(objects, 'a');
19122       assert.deepEqual(objects, [{ 'a': 0 }]);
19123     });
19124
19125     QUnit.test('should preserve holes in arrays', function(assert) {
19126       assert.expect(2);
19127
19128       var array = [1, 2, 3, 4];
19129       delete array[1];
19130       delete array[3];
19131
19132       _.remove(array, function(n) {
19133         return n === 1;
19134       });
19135
19136       assert.notOk('0' in array);
19137       assert.notOk('2' in array);
19138     });
19139
19140     QUnit.test('should treat holes as `undefined`', function(assert) {
19141       assert.expect(1);
19142
19143       var array = [1, 2, 3];
19144       delete array[1];
19145
19146       _.remove(array, function(n) {
19147         return n == null;
19148       });
19149
19150       assert.deepEqual(array, [1, 3]);
19151     });
19152
19153     QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
19154       assert.expect(1);
19155
19156       var array = [1, 2, 3];
19157
19158       _.remove(array, function(n, index) {
19159         return isEven(index);
19160       });
19161
19162       assert.deepEqual(array, [2]);
19163     });
19164   }());
19165
19166   /*--------------------------------------------------------------------------*/
19167
19168   QUnit.module('lodash.repeat');
19169
19170   (function() {
19171     var string = 'abc';
19172
19173     QUnit.test('should repeat a string `n` times', function(assert) {
19174       assert.expect(2);
19175
19176       assert.strictEqual(_.repeat('*', 3), '***');
19177       assert.strictEqual(_.repeat(string, 2), 'abcabc');
19178     });
19179
19180     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
19181       assert.expect(1);
19182
19183       var expected = lodashStable.map(falsey, function(value) {
19184         return value === undefined ? string : '';
19185       });
19186
19187       var actual = lodashStable.map(falsey, function(n, index) {
19188         return index ? _.repeat(string, n) : _.repeat(string);
19189       });
19190
19191       assert.deepEqual(actual, expected);
19192     });
19193
19194     QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
19195       assert.expect(2);
19196
19197       assert.strictEqual(_.repeat(string, 0), '');
19198       assert.strictEqual(_.repeat(string, -2), '');
19199     });
19200
19201     QUnit.test('should coerce `n` to an integer', function(assert) {
19202       assert.expect(3);
19203
19204       assert.strictEqual(_.repeat(string, '2'), 'abcabc');
19205       assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
19206       assert.strictEqual(_.repeat('*', { 'valueOf': stubThree }), '***');
19207     });
19208
19209     QUnit.test('should coerce `string` to a string', function(assert) {
19210       assert.expect(2);
19211
19212       assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
19213       assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
19214     });
19215
19216     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19217       assert.expect(1);
19218
19219       var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
19220       assert.deepEqual(actual, ['a', 'b', 'c']);
19221     });
19222   }());
19223
19224   /*--------------------------------------------------------------------------*/
19225
19226   QUnit.module('lodash.replace');
19227
19228   (function() {
19229     QUnit.test('should replace the matched pattern', function(assert) {
19230       assert.expect(2);
19231
19232       var string = 'abcde';
19233       assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
19234       assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
19235     });
19236   }());
19237
19238   /*--------------------------------------------------------------------------*/
19239
19240   QUnit.module('lodash.result');
19241
19242   (function() {
19243     var object = { 'a': 1, 'b': stubB };
19244
19245     QUnit.test('should invoke function values', function(assert) {
19246       assert.expect(1);
19247
19248       assert.strictEqual(_.result(object, 'b'), 'b');
19249     });
19250
19251     QUnit.test('should invoke default function values', function(assert) {
19252       assert.expect(1);
19253
19254       var actual = _.result(object, 'c', object.b);
19255       assert.strictEqual(actual, 'b');
19256     });
19257
19258     QUnit.test('should invoke nested function values', function(assert) {
19259       assert.expect(2);
19260
19261       var value = { 'a': lodashStable.constant({ 'b': stubB }) };
19262
19263       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19264         assert.strictEqual(_.result(value, path), 'b');
19265       });
19266     });
19267
19268     QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
19269       assert.expect(2);
19270
19271       var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
19272
19273       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19274         assert.strictEqual(_.result(value, path), 1);
19275       });
19276     });
19277   }());
19278
19279   /*--------------------------------------------------------------------------*/
19280
19281   QUnit.module('lodash.get and lodash.result');
19282
19283   lodashStable.each(['get', 'result'], function(methodName) {
19284     var func = _[methodName];
19285
19286     QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
19287       assert.expect(2);
19288
19289       var object = { 'a': 1 };
19290
19291       lodashStable.each(['a', ['a']], function(path) {
19292         assert.strictEqual(func(object, path), 1);
19293       });
19294     });
19295
19296     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19297       assert.expect(1);
19298
19299       var object = { '-0': 'a', '0': 'b' },
19300           props = [-0, Object(-0), 0, Object(0)];
19301
19302       var actual = lodashStable.map(props, function(key) {
19303         return func(object, key);
19304       });
19305
19306       assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
19307     });
19308
19309     QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
19310       assert.expect(1);
19311
19312       if (Symbol) {
19313         var object = {};
19314         object[symbol] = 1;
19315
19316         assert.strictEqual(func(object, symbol), 1);
19317       }
19318       else {
19319         skipAssert(assert);
19320       }
19321     });
19322
19323     QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
19324       assert.expect(2);
19325
19326       var object = { 'a': { 'b': 2 } };
19327
19328       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19329         assert.strictEqual(func(object, path), 2);
19330       });
19331     });
19332
19333     QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
19334       assert.expect(2);
19335
19336       var object = { 'a.b': 1, 'a': { 'b': 2 } };
19337
19338       lodashStable.each(['a.b', ['a.b']], function(path) {
19339         assert.strictEqual(func(object, path), 1);
19340       });
19341     });
19342
19343     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
19344       assert.expect(1);
19345
19346       var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
19347       assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
19348     });
19349
19350     QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
19351       assert.expect(1);
19352
19353       var object = { 'a': { '': 1 } };
19354       assert.strictEqual(func(object, 'a[]'), 1);
19355     });
19356
19357     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
19358       assert.expect(4);
19359
19360       lodashStable.each([['', ''], [[], ['']]], function(pair) {
19361         assert.strictEqual(func({}, pair[0]), undefined);
19362         assert.strictEqual(func({ '': 3 }, pair[1]), 3);
19363       });
19364     });
19365
19366     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
19367       assert.expect(2);
19368
19369       var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
19370
19371       var paths = [
19372         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19373         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19374       ];
19375
19376       lodashStable.each(paths, function(path) {
19377         assert.strictEqual(func(object, path), 8);
19378       });
19379     });
19380
19381     QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
19382       assert.expect(4);
19383
19384       lodashStable.each(['constructor', ['constructor']], function(path) {
19385         assert.strictEqual(func(null, path), undefined);
19386         assert.strictEqual(func(undefined, path), undefined);
19387       });
19388     });
19389
19390     QUnit.test('`_.' + methodName + '` should return `undefined` for deep paths when `object` is nullish', function(assert) {
19391       assert.expect(2);
19392
19393       var values = [null, undefined],
19394           expected = lodashStable.map(values, noop),
19395           paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
19396
19397       lodashStable.each(paths, function(path) {
19398         var actual = lodashStable.map(values, function(value) {
19399           return func(value, path);
19400         });
19401
19402         assert.deepEqual(actual, expected);
19403       });
19404     });
19405
19406     QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
19407       assert.expect(2);
19408
19409       var object = { 'a': [, null] };
19410
19411       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19412         assert.strictEqual(func(object, path), undefined);
19413       });
19414     });
19415
19416     QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
19417       assert.expect(2);
19418
19419       var object = { 'a': { 'b': null } };
19420
19421       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19422         assert.strictEqual(func(object, path), null);
19423       });
19424     });
19425
19426     QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19427       assert.expect(2);
19428
19429       var paths = ['a.b', ['a', 'b']];
19430
19431       lodashStable.each(paths, function(path) {
19432         numberProto.a = { 'b': 2 };
19433         assert.strictEqual(func(0, path), 2);
19434         delete numberProto.a;
19435       });
19436     });
19437
19438     QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
19439       assert.expect(2);
19440
19441       var object = { 'a': {} },
19442           values = empties.concat(true, new Date, 1, /x/, 'a'),
19443           expected = lodashStable.map(values, function(value) { return [value, value]; });
19444
19445       lodashStable.each(['a.b', ['a', 'b']], function(path) {
19446         var actual = lodashStable.map(values, function(value) {
19447           return [func(object, path, value), func(null, path, value)];
19448         });
19449
19450         assert.deepEqual(actual, expected);
19451       });
19452     });
19453
19454     QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
19455       assert.expect(1);
19456
19457       assert.strictEqual(func({}, [], 'a'), 'a');
19458     });
19459   });
19460
19461   /*--------------------------------------------------------------------------*/
19462
19463   QUnit.module('lodash.rest');
19464
19465   (function() {
19466     function fn(a, b, c) {
19467       return slice.call(arguments);
19468     }
19469
19470     QUnit.test('should apply a rest parameter to `func`', function(assert) {
19471       assert.expect(1);
19472
19473       var rest = _.rest(fn);
19474       assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
19475     });
19476
19477     QUnit.test('should work with `start`', function(assert) {
19478       assert.expect(1);
19479
19480       var rest = _.rest(fn, 1);
19481       assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
19482     });
19483
19484     QUnit.test('should treat `start` as `0` for `NaN` or negative values', function(assert) {
19485       assert.expect(1);
19486
19487       var values = [-1, NaN, 'a'],
19488           expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
19489
19490       var actual = lodashStable.map(values, function(value) {
19491         var rest = _.rest(fn, value);
19492         return rest(1, 2, 3, 4);
19493       });
19494
19495       assert.deepEqual(actual, expected);
19496     });
19497
19498     QUnit.test('should coerce `start` to an integer', function(assert) {
19499       assert.expect(1);
19500
19501       var rest = _.rest(fn, 1.6);
19502       assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
19503     });
19504
19505     QUnit.test('should use an empty array when `start` is not reached', function(assert) {
19506       assert.expect(1);
19507
19508       var rest = _.rest(fn);
19509       assert.deepEqual(rest(1), [1, undefined, []]);
19510     });
19511
19512     QUnit.test('should work on functions with more than three parameters', function(assert) {
19513       assert.expect(1);
19514
19515       var rest = _.rest(function(a, b, c, d) {
19516         return slice.call(arguments);
19517       });
19518
19519       assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
19520     });
19521   }());
19522
19523   /*--------------------------------------------------------------------------*/
19524
19525   QUnit.module('lodash.reverse');
19526
19527   (function() {
19528     var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
19529         smallArray = [0, 1, 2, null];
19530
19531     QUnit.test('should reverse `array`', function(assert) {
19532       assert.expect(2);
19533
19534       var array = [1, 2, 3],
19535           actual = _.reverse(array);
19536
19537       assert.strictEqual(actual, array);
19538       assert.deepEqual(array, [3, 2, 1]);
19539     });
19540
19541     QUnit.test('should return the wrapped reversed `array`', function(assert) {
19542       assert.expect(6);
19543
19544       if (!isNpm) {
19545         lodashStable.times(2, function(index) {
19546           var array = (index ? largeArray : smallArray).slice(),
19547               clone = array.slice(),
19548               wrapped = _(array).reverse(),
19549               actual = wrapped.value();
19550
19551           assert.ok(wrapped instanceof _);
19552           assert.strictEqual(actual, array);
19553           assert.deepEqual(actual, clone.slice().reverse());
19554         });
19555       }
19556       else {
19557         skipAssert(assert, 6);
19558       }
19559     });
19560
19561     QUnit.test('should work in a lazy sequence', function(assert) {
19562       assert.expect(4);
19563
19564       if (!isNpm) {
19565         lodashStable.times(2, function(index) {
19566           var array = (index ? largeArray : smallArray).slice(),
19567               expected = array.slice(),
19568               actual = _(array).slice(1).reverse().value();
19569
19570           assert.deepEqual(actual, expected.slice(1).reverse());
19571           assert.deepEqual(array, expected);
19572         });
19573       }
19574       else {
19575         skipAssert(assert, 4);
19576       }
19577     });
19578
19579     QUnit.test('should be lazy when in a lazy sequence', function(assert) {
19580       assert.expect(3);
19581
19582       if (!isNpm) {
19583         var spy = {
19584           'toString': function() {
19585             throw new Error('spy was revealed');
19586           }
19587         };
19588
19589         var array = largeArray.concat(spy),
19590             expected = array.slice();
19591
19592         try {
19593           var wrapped = _(array).slice(1).map(String).reverse(),
19594               actual = wrapped.last();
19595         } catch (e) {}
19596
19597         assert.ok(wrapped instanceof _);
19598         assert.strictEqual(actual, '1');
19599         assert.deepEqual(array, expected);
19600       }
19601       else {
19602         skipAssert(assert, 3);
19603       }
19604     });
19605
19606     QUnit.test('should work in a hybrid sequence', function(assert) {
19607       assert.expect(8);
19608
19609       if (!isNpm) {
19610         lodashStable.times(2, function(index) {
19611           var clone = (index ? largeArray : smallArray).slice();
19612
19613           lodashStable.each(['map', 'filter'], function(methodName) {
19614             var array = clone.slice(),
19615                 expected = clone.slice(1, -1).reverse(),
19616                 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
19617
19618             assert.deepEqual(actual, expected);
19619
19620             array = clone.slice();
19621             actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
19622
19623             assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
19624           });
19625         });
19626       }
19627       else {
19628         skipAssert(assert, 8);
19629       }
19630     });
19631
19632     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
19633       assert.expect(6);
19634
19635       if (!isNpm) {
19636         lodashStable.times(2, function(index) {
19637           var array = (index ? largeArray : smallArray).slice(),
19638               expected = array.slice().reverse(),
19639               wrapped = _(array).chain().reverse().head();
19640
19641           assert.ok(wrapped instanceof _);
19642           assert.strictEqual(wrapped.value(), _.head(expected));
19643           assert.deepEqual(array, expected);
19644         });
19645       }
19646       else {
19647         skipAssert(assert, 6);
19648       }
19649     });
19650   }());
19651
19652   /*--------------------------------------------------------------------------*/
19653
19654   QUnit.module('round methods');
19655
19656   lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
19657     var func = _[methodName],
19658         isCeil = methodName == 'ceil',
19659         isFloor = methodName == 'floor';
19660
19661     QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
19662       assert.expect(1);
19663
19664       var actual = func(4.006);
19665       assert.strictEqual(actual, isCeil ? 5 : 4);
19666     });
19667
19668     QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
19669       assert.expect(1);
19670
19671       var actual = func(4.006, 0);
19672       assert.strictEqual(actual, isCeil ? 5 : 4);
19673     });
19674
19675     QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
19676       assert.expect(2);
19677
19678       var actual = func(4.016, 2);
19679       assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
19680
19681       actual = func(4.1, 2);
19682       assert.strictEqual(actual, 4.1);
19683     });
19684
19685     QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
19686       assert.expect(1);
19687
19688       var actual = func(4160, -2);
19689       assert.strictEqual(actual, isFloor ? 4100 : 4200);
19690     });
19691
19692     QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
19693       assert.expect(3);
19694
19695       var actual = func(4.006, NaN);
19696       assert.strictEqual(actual, isCeil ? 5 : 4);
19697
19698       var expected = isFloor ? 4.01 : 4.02;
19699
19700       actual = func(4.016, 2.6);
19701       assert.strictEqual(actual, expected);
19702
19703       actual = func(4.016, '+2');
19704       assert.strictEqual(actual, expected);
19705     });
19706
19707     QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
19708       assert.expect(3);
19709
19710       var actual = func(5e1, 2);
19711       assert.deepEqual(actual, 50);
19712
19713       actual = func('5e', 1);
19714       assert.deepEqual(actual, NaN);
19715
19716       actual = func('5e1e1', 1);
19717       assert.deepEqual(actual, NaN);
19718     });
19719
19720     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19721       assert.expect(1);
19722
19723       var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
19724           expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
19725
19726       var actual = lodashStable.map(values, function(args) {
19727         return 1 / func.apply(undefined, args);
19728       });
19729
19730       assert.deepEqual(actual, expected);
19731     });
19732
19733     QUnit.test('`_.' + methodName + '` should not return `NaN` for large `precision` values', function(assert) {
19734       assert.expect(1);
19735
19736       var results = [
19737         _.round(10.0000001, 1000),
19738         _.round(MAX_SAFE_INTEGER, 293)
19739       ];
19740
19741       var expected = lodashStable.map(results, stubFalse),
19742           actual = lodashStable.map(results, lodashStable.isNaN);
19743
19744       assert.deepEqual(actual, expected);
19745     });
19746   });
19747
19748   /*--------------------------------------------------------------------------*/
19749
19750   QUnit.module('lodash.runInContext');
19751
19752   (function() {
19753     QUnit.test('should not require a fully populated `context` object', function(assert) {
19754       assert.expect(1);
19755
19756       if (!isModularize) {
19757         var lodash = _.runInContext({
19758           'setTimeout': function(func) { func(); }
19759         });
19760
19761         var pass = false;
19762         lodash.delay(function() { pass = true; }, 32);
19763         assert.ok(pass);
19764       }
19765       else {
19766         skipAssert(assert);
19767       }
19768     });
19769
19770     QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
19771       assert.expect(3);
19772
19773       if (!isModularize) {
19774         lodashStable.times(2, _.uniqueId);
19775
19776         var oldId = Number(_.uniqueId()),
19777             lodash = _.runInContext();
19778
19779         assert.ok(_.uniqueId() > oldId);
19780
19781         var id = lodash.uniqueId();
19782         assert.strictEqual(id, '1');
19783         assert.ok(id < oldId);
19784       }
19785       else {
19786         skipAssert(assert, 3);
19787       }
19788     });
19789   }());
19790
19791   /*--------------------------------------------------------------------------*/
19792
19793   QUnit.module('lodash.sample');
19794
19795   (function() {
19796     var array = [1, 2, 3];
19797
19798     QUnit.test('should return a random element', function(assert) {
19799       assert.expect(1);
19800
19801       var actual = _.sample(array);
19802       assert.ok(lodashStable.includes(array, actual));
19803     });
19804
19805     QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
19806       assert.expect(1);
19807
19808       var expected = lodashStable.map(empties, noop);
19809
19810       var actual = lodashStable.transform(empties, function(result, value) {
19811         try {
19812           result.push(_.sample(value));
19813         } catch (e) {}
19814       });
19815
19816       assert.deepEqual(actual, expected);
19817     });
19818
19819     QUnit.test('should sample an object', function(assert) {
19820       assert.expect(1);
19821
19822       var object = { 'a': 1, 'b': 2, 'c': 3 },
19823           actual = _.sample(object);
19824
19825       assert.ok(lodashStable.includes(array, actual));
19826     });
19827   }());
19828
19829   /*--------------------------------------------------------------------------*/
19830
19831   QUnit.module('lodash.sampleSize');
19832
19833   (function() {
19834     var array = [1, 2, 3];
19835
19836     QUnit.test('should return an array of random elements', function(assert) {
19837       assert.expect(2);
19838
19839       var actual = _.sampleSize(array, 2);
19840
19841       assert.strictEqual(actual.length, 2);
19842       assert.deepEqual(lodashStable.difference(actual, array), []);
19843     });
19844
19845     QUnit.test('should contain elements of the collection', function(assert) {
19846       assert.expect(1);
19847
19848       var actual = _.sampleSize(array, array.length).sort();
19849
19850       assert.deepEqual(actual, array);
19851     });
19852
19853     QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
19854       assert.expect(1);
19855
19856       var expected = lodashStable.map(falsey, function(value) {
19857         return value === undefined ? ['a'] : [];
19858       });
19859
19860       var actual = lodashStable.map(falsey, function(size, index) {
19861         return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
19862       });
19863
19864       assert.deepEqual(actual, expected);
19865     });
19866
19867     QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
19868       assert.expect(3);
19869
19870       lodashStable.each([0, -1, -Infinity], function(n) {
19871         assert.deepEqual(_.sampleSize(array, n), []);
19872       });
19873     });
19874
19875     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
19876       assert.expect(4);
19877
19878       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19879         var actual = _.sampleSize(array, n).sort();
19880         assert.deepEqual(actual, array);
19881       });
19882     });
19883
19884     QUnit.test('should coerce `n` to an integer', function(assert) {
19885       assert.expect(1);
19886
19887       var actual = _.sampleSize(array, 1.6);
19888       assert.strictEqual(actual.length, 1);
19889     });
19890
19891     QUnit.test('should return an empty array for empty collections', function(assert) {
19892       assert.expect(1);
19893
19894       var expected = lodashStable.map(empties, stubArray);
19895
19896       var actual = lodashStable.transform(empties, function(result, value) {
19897         try {
19898           result.push(_.sampleSize(value, 1));
19899         } catch (e) {}
19900       });
19901
19902       assert.deepEqual(actual, expected);
19903     });
19904
19905     QUnit.test('should sample an object', function(assert) {
19906       assert.expect(2);
19907
19908       var object = { 'a': 1, 'b': 2, 'c': 3 },
19909           actual = _.sampleSize(object, 2);
19910
19911       assert.strictEqual(actual.length, 2);
19912       assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
19913     });
19914
19915     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19916       assert.expect(1);
19917
19918       var actual = lodashStable.map([['a']], _.sampleSize);
19919       assert.deepEqual(actual, [['a']]);
19920     });
19921   }());
19922
19923   /*--------------------------------------------------------------------------*/
19924
19925   QUnit.module('lodash.setWith');
19926
19927   (function() {
19928     QUnit.test('should work with a `customizer` callback', function(assert) {
19929       assert.expect(1);
19930
19931       var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
19932         return lodashStable.isObject(value) ? undefined : {};
19933       });
19934
19935       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
19936     });
19937
19938     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
19939       assert.expect(1);
19940
19941       var actual = _.setWith({}, 'a[0].b.c', 4, noop);
19942       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
19943     });
19944   }());
19945
19946   /*--------------------------------------------------------------------------*/
19947
19948   QUnit.module('set methods');
19949
19950   lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
19951     var func = _[methodName],
19952         isUpdate = /^update/.test(methodName);
19953
19954     var oldValue = 1,
19955         value = 2,
19956         updater = isUpdate ? lodashStable.constant(value) : value;
19957
19958     QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
19959       assert.expect(4);
19960
19961       lodashStable.each(['a', ['a']], function(path) {
19962         var object = { 'a': oldValue },
19963             actual = func(object, path, updater);
19964
19965         assert.strictEqual(actual, object);
19966         assert.strictEqual(object.a, value);
19967       });
19968     });
19969
19970     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19971       assert.expect(1);
19972
19973       var props = [-0, Object(-0), 0, Object(0)],
19974           expected = lodashStable.map(props, lodashStable.constant(value));
19975
19976       var actual = lodashStable.map(props, function(key) {
19977         var object = { '-0': 'a', '0': 'b' };
19978         func(object, key, updater);
19979         return object[lodashStable.toString(key)];
19980       });
19981
19982       assert.deepEqual(actual, expected);
19983     });
19984
19985     QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
19986       assert.expect(2);
19987
19988       if (Symbol) {
19989         var object = {};
19990         object[symbol] = 1;
19991
19992         assert.strictEqual(_.unset(object, symbol), true);
19993         assert.notOk(symbol in object);
19994       }
19995       else {
19996         skipAssert(assert, 2);
19997       }
19998     });
19999
20000     QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
20001       assert.expect(4);
20002
20003       lodashStable.each(['a.b', ['a', 'b']], function(path) {
20004         var object = { 'a': { 'b': oldValue } },
20005             actual = func(object, path, updater);
20006
20007         assert.strictEqual(actual, object);
20008         assert.strictEqual(object.a.b, value);
20009       });
20010     });
20011
20012     QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
20013       assert.expect(4);
20014
20015       lodashStable.each(['a.b', ['a.b']], function(path) {
20016         var object = { 'a.b': oldValue },
20017             actual = func(object, path, updater);
20018
20019         assert.strictEqual(actual, object);
20020         assert.deepEqual(object, { 'a.b': value });
20021       });
20022     });
20023
20024     QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
20025       assert.expect(1);
20026
20027       var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
20028
20029       func(object, ['a', 'b', 'c'], updater);
20030       assert.strictEqual(object.a.b.c, value);
20031     });
20032
20033     QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
20034       assert.expect(1);
20035
20036       var object = {};
20037
20038       func(object, 'a[]', updater);
20039       assert.deepEqual(object, { 'a': { '': value } });
20040     });
20041
20042     QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
20043       assert.expect(4);
20044
20045       lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
20046         var object = {};
20047
20048         func(object, pair[0], updater);
20049         assert.deepEqual(object, index ? {} : { '': value });
20050
20051         func(object, pair[1], updater);
20052         assert.deepEqual(object, { '': value });
20053       });
20054     });
20055
20056     QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
20057       assert.expect(2);
20058
20059       var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
20060
20061       var paths = [
20062         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
20063         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
20064       ];
20065
20066       lodashStable.each(paths, function(path) {
20067         func(object, path, updater);
20068         assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
20069         object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
20070       });
20071     });
20072
20073     QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
20074       assert.expect(6);
20075
20076       var object = {};
20077
20078       lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
20079         var actual = func(object, path, updater);
20080
20081         assert.strictEqual(actual, object);
20082         assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
20083         assert.notOk('0' in object.a);
20084
20085         delete object.a;
20086       });
20087     });
20088
20089     QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
20090       assert.expect(1);
20091
20092       var values = [null, undefined],
20093           expected = [[null, null], [undefined, undefined]];
20094
20095       var actual = lodashStable.map(values, function(value) {
20096         try {
20097           return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
20098         } catch (e) {
20099           return e.message;
20100         }
20101       });
20102
20103       assert.deepEqual(actual, expected);
20104     });
20105
20106     QUnit.test('`_.' + methodName + '` should overwrite primitives in the path', function(assert) {
20107       assert.expect(2);
20108
20109       lodashStable.each(['a.b', ['a', 'b']], function(path) {
20110         var object = { 'a': '' };
20111
20112         func(object, path, updater);
20113         assert.deepEqual(object, { 'a': { 'b': 2 } });
20114       });;
20115     });
20116
20117     QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
20118       assert.expect(1);
20119
20120       var object = {};
20121
20122       func(object, ['1a', '2b', '3c'], updater);
20123       assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
20124     });
20125
20126     QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
20127       assert.expect(4);
20128
20129       lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
20130         var object = {},
20131             pass = true,
20132             updater = isUpdate ? lodashStable.constant(value) : value;
20133
20134         defineProperty(object, 'a', {
20135           'configurable': true,
20136           'enumerable': true,
20137           'get': lodashStable.constant(value),
20138           'set': function() { pass = false; }
20139         });
20140
20141         func(object, 'a', updater);
20142         assert.ok(pass);
20143       });
20144     });
20145   });
20146
20147   /*--------------------------------------------------------------------------*/
20148
20149   QUnit.module('lodash.shuffle');
20150
20151   (function() {
20152     var array = [1, 2, 3],
20153         object = { 'a': 1, 'b': 2, 'c': 3 };
20154
20155     QUnit.test('should return a new array', function(assert) {
20156       assert.expect(1);
20157
20158       assert.notStrictEqual(_.shuffle(array), array);
20159     });
20160
20161     QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
20162       assert.expect(2);
20163
20164       assert.deepEqual(_.shuffle(array).sort(), array);
20165       assert.deepEqual(_.shuffle(object).sort(), array);
20166     });
20167
20168     QUnit.test('should shuffle small collections', function(assert) {
20169       assert.expect(1);
20170
20171       var actual = lodashStable.times(1000, function(assert) {
20172         return _.shuffle([1, 2]);
20173       });
20174
20175       assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
20176     });
20177
20178     QUnit.test('should treat number values for `collection` as empty', function(assert) {
20179       assert.expect(1);
20180
20181       assert.deepEqual(_.shuffle(1), []);
20182     });
20183   }());
20184
20185   /*--------------------------------------------------------------------------*/
20186
20187   QUnit.module('lodash.size');
20188
20189   (function() {
20190     var array = [1, 2, 3];
20191
20192     QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
20193       assert.expect(1);
20194
20195       assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
20196     });
20197
20198     QUnit.test('should return the length of an array', function(assert) {
20199       assert.expect(1);
20200
20201       assert.strictEqual(_.size(array), 3);
20202     });
20203
20204     QUnit.test('should accept a falsey `object`', function(assert) {
20205       assert.expect(1);
20206
20207       var expected = lodashStable.map(falsey, stubZero);
20208
20209       var actual = lodashStable.map(falsey, function(object, index) {
20210         try {
20211           return index ? _.size(object) : _.size();
20212         } catch (e) {}
20213       });
20214
20215       assert.deepEqual(actual, expected);
20216     });
20217
20218     QUnit.test('should work with `arguments` objects', function(assert) {
20219       assert.expect(1);
20220
20221       assert.strictEqual(_.size(args), 3);
20222     });
20223
20224     QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
20225       assert.expect(1);
20226
20227       function Foo(elements) {
20228         push.apply(this, elements);
20229       }
20230       Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
20231
20232       assert.strictEqual(_.size(new Foo(array)), 3);
20233     });
20234
20235     QUnit.test('should work with maps', function(assert) {
20236       assert.expect(2);
20237
20238       if (Map) {
20239         lodashStable.each([new Map, realm.map], function(map) {
20240           map.set('a', 1);
20241           map.set('b', 2);
20242           assert.strictEqual(_.size(map), 2);
20243           map.clear();
20244         });
20245       }
20246       else {
20247         skipAssert(assert, 2);
20248       }
20249     });
20250
20251     QUnit.test('should work with sets', function(assert) {
20252       assert.expect(2);
20253
20254       if (Set) {
20255         lodashStable.each([new Set, realm.set], function(set) {
20256           set.add(1);
20257           set.add(2);
20258           assert.strictEqual(_.size(set), 2);
20259           set.clear();
20260         });
20261       }
20262       else {
20263         skipAssert(assert, 2);
20264       }
20265     });
20266
20267     QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
20268       assert.expect(1);
20269
20270       assert.strictEqual(_.size({ 'length': -1 }), 1);
20271     });
20272
20273     QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
20274       assert.expect(1);
20275
20276       assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
20277     });
20278
20279     QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
20280       assert.expect(1);
20281
20282       assert.strictEqual(_.size({ 'length': '0' }), 1);
20283     });
20284   }());
20285
20286   /*--------------------------------------------------------------------------*/
20287
20288   QUnit.module('lodash.slice');
20289
20290   (function() {
20291     var array = [1, 2, 3];
20292
20293     QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
20294       assert.expect(2);
20295
20296       var actual = _.slice(array);
20297       assert.deepEqual(actual, array);
20298       assert.notStrictEqual(actual, array);
20299     });
20300
20301     QUnit.test('should work with a positive `start`', function(assert) {
20302       assert.expect(2);
20303
20304       assert.deepEqual(_.slice(array, 1), [2, 3]);
20305       assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
20306     });
20307
20308     QUnit.test('should work with a `start` >= `length`', function(assert) {
20309       assert.expect(4);
20310
20311       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
20312         assert.deepEqual(_.slice(array, start), []);
20313       });
20314     });
20315
20316     QUnit.test('should treat falsey `start` values as `0`', function(assert) {
20317       assert.expect(1);
20318
20319       var expected = lodashStable.map(falsey, lodashStable.constant(array));
20320
20321       var actual = lodashStable.map(falsey, function(start) {
20322         return _.slice(array, start);
20323       });
20324
20325       assert.deepEqual(actual, expected);
20326     });
20327
20328     QUnit.test('should work with a negative `start`', function(assert) {
20329       assert.expect(1);
20330
20331       assert.deepEqual(_.slice(array, -1), [3]);
20332     });
20333
20334     QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
20335       assert.expect(3);
20336
20337       lodashStable.each([-3, -4, -Infinity], function(start) {
20338         assert.deepEqual(_.slice(array, start), array);
20339       });
20340     });
20341
20342     QUnit.test('should work with `start` >= `end`', function(assert) {
20343       assert.expect(2);
20344
20345       lodashStable.each([2, 3], function(start) {
20346         assert.deepEqual(_.slice(array, start, 2), []);
20347       });
20348     });
20349
20350     QUnit.test('should work with a positive `end`', function(assert) {
20351       assert.expect(1);
20352
20353       assert.deepEqual(_.slice(array, 0, 1), [1]);
20354     });
20355
20356     QUnit.test('should work with a `end` >= `length`', function(assert) {
20357       assert.expect(4);
20358
20359       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
20360         assert.deepEqual(_.slice(array, 0, end), array);
20361       });
20362     });
20363
20364     QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
20365       assert.expect(1);
20366
20367       var expected = lodashStable.map(falsey, function(value) {
20368         return value === undefined ? array : [];
20369       });
20370
20371       var actual = lodashStable.map(falsey, function(end, index) {
20372         return index ? _.slice(array, 0, end) : _.slice(array, 0);
20373       });
20374
20375       assert.deepEqual(actual, expected);
20376     });
20377
20378     QUnit.test('should work with a negative `end`', function(assert) {
20379       assert.expect(1);
20380
20381       assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
20382     });
20383
20384     QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
20385       assert.expect(3);
20386
20387       lodashStable.each([-3, -4, -Infinity], function(end) {
20388         assert.deepEqual(_.slice(array, 0, end), []);
20389       });
20390     });
20391
20392     QUnit.test('should coerce `start` and `end` to integers', function(assert) {
20393       assert.expect(1);
20394
20395       var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
20396
20397       var actual = lodashStable.map(positions, function(pos) {
20398         return _.slice.apply(_, [array].concat(pos));
20399       });
20400
20401       assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
20402     });
20403
20404     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20405       assert.expect(2);
20406
20407       var array = [[1], [2, 3]],
20408           actual = lodashStable.map(array, _.slice);
20409
20410       assert.deepEqual(actual, array);
20411       assert.notStrictEqual(actual, array);
20412     });
20413
20414     QUnit.test('should work in a lazy sequence', function(assert) {
20415       assert.expect(38);
20416
20417       if (!isNpm) {
20418         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
20419             length = array.length,
20420             wrapped = _(array);
20421
20422         lodashStable.each(['map', 'filter'], function(methodName) {
20423           assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
20424           assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
20425           assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
20426           assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
20427
20428           assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
20429           assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
20430           assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
20431           assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
20432
20433           assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
20434           assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
20435           assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
20436
20437           assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
20438           assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
20439
20440           assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
20441           assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
20442           assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
20443           assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
20444           assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
20445           assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
20446         });
20447       }
20448       else {
20449         skipAssert(assert, 38);
20450       }
20451     });
20452   }());
20453
20454   /*--------------------------------------------------------------------------*/
20455
20456   QUnit.module('lodash.some');
20457
20458   (function() {
20459     QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
20460       assert.expect(2);
20461
20462       assert.strictEqual(_.some([false, 1, ''], identity), true);
20463       assert.strictEqual(_.some([null, 'a', 0], identity), true);
20464     });
20465
20466     QUnit.test('should return `false` for empty collections', function(assert) {
20467       assert.expect(1);
20468
20469       var expected = lodashStable.map(empties, stubFalse);
20470
20471       var actual = lodashStable.map(empties, function(value) {
20472         try {
20473           return _.some(value, identity);
20474         } catch (e) {}
20475       });
20476
20477       assert.deepEqual(actual, expected);
20478     });
20479
20480     QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
20481       assert.expect(2);
20482
20483       var count = 0;
20484
20485       assert.strictEqual(_.some([null, true, null], function(value) {
20486         count++;
20487         return value;
20488       }), true);
20489
20490       assert.strictEqual(count, 2);
20491     });
20492
20493     QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
20494       assert.expect(2);
20495
20496       assert.strictEqual(_.some([false, false, false], identity), false);
20497       assert.strictEqual(_.some([null, 0, ''], identity), false);
20498     });
20499
20500     QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
20501       assert.expect(2);
20502
20503       var values = [, null, undefined],
20504           expected = lodashStable.map(values, stubFalse);
20505
20506       var actual = lodashStable.map(values, function(value, index) {
20507         var array = [0, 0];
20508         return index ? _.some(array, value) : _.some(array);
20509       });
20510
20511       assert.deepEqual(actual, expected);
20512
20513       expected = lodashStable.map(values, stubTrue);
20514       actual = lodashStable.map(values, function(value, index) {
20515         var array = [0, 1];
20516         return index ? _.some(array, value) : _.some(array);
20517       });
20518
20519       assert.deepEqual(actual, expected);
20520     });
20521
20522     QUnit.test('should work with `_.property` shorthands', function(assert) {
20523       assert.expect(2);
20524
20525       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
20526       assert.strictEqual(_.some(objects, 'a'), false);
20527       assert.strictEqual(_.some(objects, 'b'), true);
20528     });
20529
20530     QUnit.test('should work with `_.matches` shorthands', function(assert) {
20531       assert.expect(2);
20532
20533       var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
20534       assert.strictEqual(_.some(objects, { 'a': 0 }), true);
20535       assert.strictEqual(_.some(objects, { 'b': 2 }), false);
20536     });
20537
20538     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20539       assert.expect(1);
20540
20541       var actual = lodashStable.map([[1]], _.some);
20542       assert.deepEqual(actual, [true]);
20543     });
20544   }());
20545
20546   /*--------------------------------------------------------------------------*/
20547
20548   QUnit.module('lodash.sortBy');
20549
20550   (function() {
20551     var objects = [
20552       { 'a': 'x', 'b': 3 },
20553       { 'a': 'y', 'b': 4 },
20554       { 'a': 'x', 'b': 1 },
20555       { 'a': 'y', 'b': 2 }
20556     ];
20557
20558     QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
20559       assert.expect(1);
20560
20561       var actual = lodashStable.map(_.sortBy(objects, function(object) {
20562         return object.b;
20563       }), 'b');
20564
20565       assert.deepEqual(actual, [1, 2, 3, 4]);
20566     });
20567
20568     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20569       assert.expect(1);
20570
20571       var array = [3, 2, 1],
20572           values = [, null, undefined],
20573           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
20574
20575       var actual = lodashStable.map(values, function(value, index) {
20576         return index ? _.sortBy(array, value) : _.sortBy(array);
20577       });
20578
20579       assert.deepEqual(actual, expected);
20580     });
20581
20582     QUnit.test('should work with `_.property` shorthands', function(assert) {
20583       assert.expect(1);
20584
20585       var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
20586       assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
20587     });
20588
20589     QUnit.test('should work with an object for `collection`', function(assert) {
20590       assert.expect(1);
20591
20592       var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
20593       assert.deepEqual(actual, [3, 1, 2]);
20594     });
20595
20596     QUnit.test('should move `NaN`, nullish, and symbol values to the end', function(assert) {
20597       assert.expect(2);
20598
20599       var symbol1 = Symbol ? Symbol('a') : null,
20600           symbol2 = Symbol ? Symbol('b') : null,
20601           array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
20602           expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20603
20604       assert.deepEqual(_.sortBy(array), expected);
20605
20606       array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
20607       expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20608
20609       assert.deepEqual(_.sortBy(array), expected);
20610     });
20611
20612     QUnit.test('should treat number values for `collection` as empty', function(assert) {
20613       assert.expect(1);
20614
20615       assert.deepEqual(_.sortBy(1), []);
20616     });
20617
20618     QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
20619       assert.expect(1);
20620
20621       var actual = _.sortBy(objects, function(object) {
20622         var result = [object.a, object.b];
20623         result.toString = function() { return String(this[0]); };
20624         return result;
20625       });
20626
20627       assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
20628     });
20629
20630     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20631       assert.expect(1);
20632
20633       var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
20634       assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
20635     });
20636   }());
20637
20638   /*--------------------------------------------------------------------------*/
20639
20640   QUnit.module('sortBy methods');
20641
20642   lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
20643     var func = _[methodName];
20644
20645     function Pair(a, b, c) {
20646       this.a = a;
20647       this.b = b;
20648       this.c = c;
20649     }
20650
20651     var objects = [
20652       { 'a': 'x', 'b': 3 },
20653       { 'a': 'y', 'b': 4 },
20654       { 'a': 'x', 'b': 1 },
20655       { 'a': 'y', 'b': 2 }
20656     ];
20657
20658     var stableArray = [
20659       new Pair(1, 1, 1), new Pair(1, 2, 1),
20660       new Pair(1, 1, 1), new Pair(1, 2, 1),
20661       new Pair(1, 3, 1), new Pair(1, 4, 1),
20662       new Pair(1, 5, 1), new Pair(1, 6, 1),
20663       new Pair(2, 1, 2), new Pair(2, 2, 2),
20664       new Pair(2, 3, 2), new Pair(2, 4, 2),
20665       new Pair(2, 5, 2), new Pair(2, 6, 2),
20666       new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
20667       new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
20668       new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
20669     ];
20670
20671     var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
20672
20673     QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
20674       assert.expect(1);
20675
20676       var actual = func(objects, ['a', 'b']);
20677       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20678     });
20679
20680     QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
20681       assert.expect(1);
20682
20683       var actual = func(objects, ['a', function(object) { return object.b; }]);
20684       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20685     });
20686
20687     QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
20688       assert.expect(2);
20689
20690       lodashStable.each([stableArray, stableObject], function(value, index) {
20691         var actual = func(value, ['a', 'c']);
20692         assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
20693       });
20694     });
20695
20696     QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
20697       assert.expect(1);
20698
20699       try {
20700         var actual = func(objects.concat(null, undefined), ['a', 'b']);
20701       } catch (e) {}
20702
20703       assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
20704     });
20705
20706     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
20707       assert.expect(3);
20708
20709       var objects = [
20710         { 'a': 'x', '0': 3 },
20711         { 'a': 'y', '0': 4 },
20712         { 'a': 'x', '0': 1 },
20713         { 'a': 'y', '0': 2 }
20714       ];
20715
20716       var funcs = [func, lodashStable.partialRight(func, 'bogus')];
20717
20718       lodashStable.each(['a', 0, [0]], function(props, index) {
20719         var expected = lodashStable.map(funcs, lodashStable.constant(
20720           index
20721             ? [objects[2], objects[3], objects[0], objects[1]]
20722             : [objects[0], objects[2], objects[1], objects[3]]
20723         ));
20724
20725         var actual = lodashStable.map(funcs, function(func) {
20726           return lodashStable.reduce([props], func, objects);
20727         });
20728
20729         assert.deepEqual(actual, expected);
20730       });
20731     });
20732   });
20733
20734   /*--------------------------------------------------------------------------*/
20735
20736   QUnit.module('sortedIndex methods');
20737
20738   lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
20739     var func = _[methodName],
20740         isSortedIndex = methodName == 'sortedIndex';
20741
20742     QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
20743       assert.expect(1);
20744
20745       var array = [30, 50],
20746           values = [30, 40, 50],
20747           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20748
20749       var actual = lodashStable.map(values, function(value) {
20750         return func(array, value);
20751       });
20752
20753       assert.deepEqual(actual, expected);
20754     });
20755
20756     QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
20757       assert.expect(1);
20758
20759       var array = ['a', 'c'],
20760           values = ['a', 'b', 'c'],
20761           expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20762
20763       var actual = lodashStable.map(values, function(value) {
20764         return func(array, value);
20765       });
20766
20767       assert.deepEqual(actual, expected);
20768     });
20769
20770     QUnit.test('`_.' + methodName + '` should accept a nullish `array` and a `value`', function(assert) {
20771       assert.expect(1);
20772
20773       var values = [null, undefined],
20774           expected = lodashStable.map(values, lodashStable.constant([0, 0, 0]));
20775
20776       var actual = lodashStable.map(values, function(array) {
20777         return [func(array, 1), func(array, undefined), func(array, NaN)];
20778       });
20779
20780       assert.deepEqual(actual, expected);
20781     });
20782
20783     QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
20784       assert.expect(12);
20785
20786       var symbol1 = Symbol ? Symbol('a') : null,
20787           symbol2 = Symbol ? Symbol('b') : null,
20788           symbol3 = Symbol ? Symbol('c') : null,
20789           expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
20790
20791       lodashStable.each([
20792         [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
20793         ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
20794       ], function(array) {
20795         assert.deepEqual(_.sortBy(array), expected);
20796         assert.strictEqual(func(expected, 3), 2);
20797         assert.strictEqual(func(expected, symbol3), isSortedIndex ? 3 : (Symbol ? 5 : 6));
20798         assert.strictEqual(func(expected, null), isSortedIndex ? (Symbol ? 5 : 3) : 6);
20799         assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
20800         assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
20801       });
20802     });
20803
20804     QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for nulls', function(assert) {
20805       assert.expect(3);
20806
20807       var array = [null, null];
20808
20809       assert.strictEqual(func(array, null), isSortedIndex ? 0 : 2);
20810       assert.strictEqual(func(array, 1), 0);
20811       assert.strictEqual(func(array, 'a'), 0);
20812     });
20813
20814     QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for symbols', function(assert) {
20815       assert.expect(3);
20816
20817       var symbol1 = Symbol ? Symbol('a') : null,
20818           symbol2 = Symbol ? Symbol('b') : null,
20819           symbol3 = Symbol ? Symbol('c') : null,
20820           array = [symbol1, symbol2];
20821
20822       assert.strictEqual(func(array, symbol3), isSortedIndex ? 0 : 2);
20823       assert.strictEqual(func(array, 1), 0);
20824       assert.strictEqual(func(array, 'a'), 0);
20825     });
20826   });
20827
20828   /*--------------------------------------------------------------------------*/
20829
20830   QUnit.module('sortedIndexBy methods');
20831
20832   lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
20833     var func = _[methodName],
20834         isSortedIndexBy = methodName == 'sortedIndexBy';
20835
20836     QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) {
20837       assert.expect(1);
20838
20839       var args;
20840
20841       func([30, 50], 40, function(assert) {
20842         args || (args = slice.call(arguments));
20843       });
20844
20845       assert.deepEqual(args, [40]);
20846     });
20847
20848     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
20849       assert.expect(1);
20850
20851       var objects = [{ 'x': 30 }, { 'x': 50 }],
20852           actual = func(objects, { 'x': 40 }, 'x');
20853
20854       assert.strictEqual(actual, 1);
20855     });
20856
20857     QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
20858       assert.expect(12);
20859
20860       lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
20861         var array = [],
20862             values = [MAX_ARRAY_LENGTH, NaN, undefined];
20863
20864         array.length = length;
20865
20866         lodashStable.each(values, function(value) {
20867           var steps = 0;
20868
20869           var actual = func(array, value, function(value) {
20870             steps++;
20871             return value;
20872           });
20873
20874           var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
20875             ? 0
20876             : Math.min(length, MAX_ARRAY_INDEX);
20877
20878           assert.ok(steps == 32 || steps == 33);
20879           assert.strictEqual(actual, expected);
20880         });
20881       });
20882     });
20883   });
20884
20885   /*--------------------------------------------------------------------------*/
20886
20887   QUnit.module('sortedIndexOf methods');
20888
20889   lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
20890     var func = _[methodName],
20891         isSortedIndexOf = methodName == 'sortedIndexOf';
20892
20893     QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
20894       assert.expect(1);
20895
20896       var sorted = [4, 4, 5, 5, 6, 6];
20897       assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
20898     });
20899   });
20900
20901   /*--------------------------------------------------------------------------*/
20902
20903   QUnit.module('lodash.sortedUniq');
20904
20905   (function() {
20906     QUnit.test('should return unique values of a sorted array', function(assert) {
20907       assert.expect(3);
20908
20909       var expected = [1, 2, 3];
20910
20911       lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
20912         assert.deepEqual(_.sortedUniq(array), expected);
20913       });
20914     });
20915   }());
20916
20917   /*--------------------------------------------------------------------------*/
20918
20919   QUnit.module('lodash.split');
20920
20921   (function() {
20922     QUnit.test('should split a string by `separator`', function(assert) {
20923       assert.expect(3);
20924
20925       var string = 'abcde';
20926       assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
20927       assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
20928       assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
20929     });
20930
20931     QUnit.test('should return an array containing an empty string for empty values', function(assert) {
20932       assert.expect(1);
20933
20934       var values = [, null, undefined, ''],
20935           expected = lodashStable.map(values, lodashStable.constant(['']));
20936
20937       var actual = lodashStable.map(values, function(value, index) {
20938         return index ? _.split(value) : _.split();
20939       });
20940
20941       assert.deepEqual(actual, expected);
20942     });
20943
20944     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20945       assert.expect(1);
20946
20947       var strings = ['abc', 'def', 'ghi'],
20948           actual = lodashStable.map(strings, _.split);
20949
20950       assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
20951     });
20952
20953     QUnit.test('should allow mixed string and array prototype methods', function(assert) {
20954       assert.expect(1);
20955
20956       if (!isNpm) {
20957         var wrapped = _('abc');
20958         assert.strictEqual(wrapped.split('b').join(','), 'a,c');
20959       }
20960       else {
20961         skipAssert(assert);
20962       }
20963     });
20964   }());
20965
20966   /*--------------------------------------------------------------------------*/
20967
20968   QUnit.module('lodash.spread');
20969
20970   (function() {
20971     function fn(a, b, c) {
20972       return slice.call(arguments);
20973     }
20974
20975     QUnit.test('should spread arguments to `func`', function(assert) {
20976       assert.expect(2);
20977
20978       var spread = _.spread(fn),
20979           expected = [1, 2];
20980
20981       assert.deepEqual(spread([1, 2]), expected);
20982       assert.deepEqual(spread([1, 2], 3), expected);
20983     });
20984
20985     QUnit.test('should accept a falsey `array`', function(assert) {
20986       assert.expect(1);
20987
20988       var spread = _.spread(stubTrue),
20989           expected = lodashStable.map(falsey, stubTrue);
20990
20991       var actual = lodashStable.map(falsey, function(array, index) {
20992         try {
20993           return index ? spread(array) : spread();
20994         } catch (e) {}
20995       });
20996
20997       assert.deepEqual(actual, expected);
20998     });
20999
21000     QUnit.test('should work with `start`', function(assert) {
21001       assert.expect(2);
21002
21003       var spread = _.spread(fn, 1),
21004           expected = [1, 2, 3];
21005
21006       assert.deepEqual(spread(1, [2, 3]), expected);
21007       assert.deepEqual(spread(1, [2, 3], 4), expected);
21008     });
21009
21010     QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
21011       assert.expect(1);
21012
21013       var values = [-1, NaN, 'a'],
21014           expected = lodashStable.map(values, lodashStable.constant([1, 2]));
21015
21016       var actual = lodashStable.map(values, function(value) {
21017         var spread = _.spread(fn, value);
21018         return spread([1, 2]);
21019       });
21020
21021       assert.deepEqual(actual, expected);
21022     });
21023
21024     QUnit.test('should coerce `start` to an integer', function(assert) {
21025       assert.expect(2);
21026
21027       var spread = _.spread(fn, 1.6),
21028           expected = [1, 2, 3];
21029
21030       assert.deepEqual(spread(1, [2, 3]), expected);
21031       assert.deepEqual(spread(1, [2, 3], 4), expected);
21032     });
21033   }());
21034
21035   /*--------------------------------------------------------------------------*/
21036
21037   QUnit.module('lodash.startCase');
21038
21039   (function() {
21040     QUnit.test('should uppercase only the first character of each word', function(assert) {
21041       assert.expect(3);
21042
21043       assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
21044       assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
21045       assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
21046     });
21047   }());
21048
21049   /*--------------------------------------------------------------------------*/
21050
21051   QUnit.module('lodash.startsWith');
21052
21053   (function() {
21054     var string = 'abc';
21055
21056     QUnit.test('should return `true` if a string starts with `target`', function(assert) {
21057       assert.expect(1);
21058
21059       assert.strictEqual(_.startsWith(string, 'a'), true);
21060     });
21061
21062     QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
21063       assert.expect(1);
21064
21065       assert.strictEqual(_.startsWith(string, 'b'), false);
21066     });
21067
21068     QUnit.test('should work with a `position`', function(assert) {
21069       assert.expect(1);
21070
21071       assert.strictEqual(_.startsWith(string, 'b', 1), true);
21072     });
21073
21074     QUnit.test('should work with `position` >= `length`', function(assert) {
21075       assert.expect(4);
21076
21077       lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
21078         assert.strictEqual(_.startsWith(string, 'a', position), false);
21079       });
21080     });
21081
21082     QUnit.test('should treat falsey `position` values as `0`', function(assert) {
21083       assert.expect(1);
21084
21085       var expected = lodashStable.map(falsey, stubTrue);
21086
21087       var actual = lodashStable.map(falsey, function(position) {
21088         return _.startsWith(string, 'a', position);
21089       });
21090
21091       assert.deepEqual(actual, expected);
21092     });
21093
21094     QUnit.test('should treat a negative `position` as `0`', function(assert) {
21095       assert.expect(6);
21096
21097       lodashStable.each([-1, -3, -Infinity], function(position) {
21098         assert.strictEqual(_.startsWith(string, 'a', position), true);
21099         assert.strictEqual(_.startsWith(string, 'b', position), false);
21100       });
21101     });
21102
21103     QUnit.test('should coerce `position` to an integer', function(assert) {
21104       assert.expect(1);
21105
21106       assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
21107     });
21108   }());
21109
21110   /*--------------------------------------------------------------------------*/
21111
21112   QUnit.module('lodash.startsWith and lodash.endsWith');
21113
21114   lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
21115     var func = _[methodName],
21116         isStartsWith = methodName == 'startsWith';
21117
21118     var string = 'abc',
21119         chr = isStartsWith ? 'a' : 'c';
21120
21121     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
21122       assert.expect(2);
21123
21124       assert.strictEqual(func(Object(string), chr), true);
21125       assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
21126     });
21127
21128     QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
21129       assert.expect(2);
21130
21131       assert.strictEqual(func(string, Object(chr)), true);
21132       assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
21133     });
21134
21135     QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
21136       assert.expect(2);
21137
21138       var position = isStartsWith ? 1 : 2;
21139
21140       assert.strictEqual(func(string, 'b', Object(position)), true);
21141       assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
21142     });
21143
21144     QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
21145       assert.expect(1);
21146
21147       var positions = [-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity];
21148
21149       assert.ok(lodashStable.every(positions, function(position) {
21150         return func(string, '', position);
21151       }));
21152     });
21153   });
21154
21155   /*--------------------------------------------------------------------------*/
21156
21157   QUnit.module('stub methods');
21158
21159   lodashStable.each(['noop', 'stubTrue', 'stubFalse', 'stubArray', 'stubObject', 'stubString'], function(methodName) {
21160     var func = _[methodName];
21161
21162     var pair = ({
21163       'stubArray': [[], 'an empty array'],
21164       'stubFalse': [false, '`false`'],
21165       'stubObject': [{}, 'an empty object'],
21166       'stubString': ['', 'an empty string'],
21167       'stubTrue': [true, '`true`'],
21168       'noop': [undefined, '`undefined`']
21169     })[methodName];
21170
21171     var values = Array(2).concat(empties, true, 1, 'a'),
21172         expected = lodashStable.map(values, lodashStable.constant(pair[0]));
21173
21174     QUnit.test('`_.' + methodName + '` should return ' + pair[1], function(assert) {
21175       assert.expect(1);
21176
21177       var actual = lodashStable.map(values, function(value, index) {
21178         if (index < 2) {
21179           return index ? func.call({}) : func();
21180         }
21181         return func(value);
21182       });
21183
21184       assert.deepEqual(actual, expected);
21185     });
21186   });
21187
21188   /*--------------------------------------------------------------------------*/
21189
21190   QUnit.module('lodash.subtract');
21191
21192   (function() {
21193     QUnit.test('should subtract two numbers', function(assert) {
21194       assert.expect(3);
21195
21196       assert.strictEqual(_.subtract(6, 4), 2);
21197       assert.strictEqual(_.subtract(-6, 4), -10);
21198       assert.strictEqual(_.subtract(-6, -4), -2);
21199     });
21200
21201     QUnit.test('should coerce arguments to numbers', function(assert) {
21202       assert.expect(2);
21203
21204       assert.strictEqual(_.subtract('6', '4'), 2);
21205       assert.deepEqual(_.subtract('x', 'y'), NaN);
21206     });
21207   }());
21208
21209   /*--------------------------------------------------------------------------*/
21210
21211   QUnit.module('math operator methods');
21212
21213   lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
21214     var func = _[methodName],
21215         isAddSub = methodName == 'add' || methodName == 'subtract';
21216
21217     QUnit.test('`_.' + methodName + '` should return `' + (isAddSub ? 0 : 1) + '` when no arguments are given', function(assert) {
21218       assert.expect(1);
21219
21220       assert.strictEqual(func(), isAddSub ? 0 : 1);
21221     });
21222
21223     QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
21224       assert.expect(3);
21225
21226       assert.strictEqual(func(6), 6);
21227       assert.strictEqual(func(6, undefined), 6);
21228       assert.strictEqual(func(undefined, 4), 4);
21229     });
21230
21231     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
21232       assert.expect(2);
21233
21234       var values = [0, '0', -0, '-0'],
21235           expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
21236
21237       lodashStable.times(2, function(index) {
21238         var actual = lodashStable.map(values, function(value) {
21239           var result = index ? func(undefined, value) : func(value);
21240           return [result, 1 / result];
21241         });
21242
21243         assert.deepEqual(actual, expected);
21244       });
21245     });
21246
21247     QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
21248       assert.expect(2);
21249
21250       assert.deepEqual(func(0, {}), NaN);
21251       assert.deepEqual(func({}, 0), NaN);
21252     });
21253
21254     QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
21255       assert.expect(2);
21256
21257       if (Symbol) {
21258         assert.deepEqual(func(0, symbol), NaN);
21259         assert.deepEqual(func(symbol, 0), NaN);
21260       }
21261       else {
21262         skipAssert(assert, 2);
21263       }
21264     });
21265
21266     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
21267       assert.expect(1);
21268
21269       if (!isNpm) {
21270         var actual = _(1)[methodName](2);
21271         assert.notOk(actual instanceof _);
21272       }
21273       else {
21274         skipAssert(assert);
21275       }
21276     });
21277
21278     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
21279       assert.expect(1);
21280
21281       if (!isNpm) {
21282         var actual = _(1).chain()[methodName](2);
21283         assert.ok(actual instanceof _);
21284       }
21285       else {
21286         skipAssert(assert);
21287       }
21288     });
21289   });
21290
21291   /*--------------------------------------------------------------------------*/
21292
21293   QUnit.module('lodash.sumBy');
21294
21295   (function() {
21296     var array = [6, 4, 2],
21297         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
21298
21299     QUnit.test('should work with an `iteratee`', function(assert) {
21300       assert.expect(1);
21301
21302       var actual = _.sumBy(objects, function(object) {
21303         return object.a;
21304       });
21305
21306       assert.deepEqual(actual, 6);
21307     });
21308
21309     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
21310       assert.expect(1);
21311
21312       var args;
21313
21314       _.sumBy(array, function() {
21315         args || (args = slice.call(arguments));
21316       });
21317
21318       assert.deepEqual(args, [6]);
21319     });
21320
21321     QUnit.test('should work with `_.property` shorthands', function(assert) {
21322       assert.expect(2);
21323
21324       var arrays = [[2], [3], [1]];
21325       assert.strictEqual(_.sumBy(arrays, 0), 6);
21326       assert.strictEqual(_.sumBy(objects, 'a'), 6);
21327     });
21328   }());
21329
21330   /*--------------------------------------------------------------------------*/
21331
21332   QUnit.module('sum methods');
21333
21334   lodashStable.each(['sum', 'sumBy'], function(methodName) {
21335     var array = [6, 4, 2],
21336         func = _[methodName];
21337
21338     QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
21339       assert.expect(1);
21340
21341       assert.strictEqual(func(array), 12);
21342     });
21343
21344     QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
21345       assert.expect(1);
21346
21347       var expected = lodashStable.map(empties, stubZero);
21348
21349       var actual = lodashStable.map(empties, function(value) {
21350         return func(value);
21351       });
21352
21353       assert.deepEqual(actual, expected);
21354     });
21355
21356     QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
21357       assert.expect(1);
21358
21359       assert.strictEqual(func([1, undefined]), 1);
21360     });
21361
21362     QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
21363       assert.expect(1);
21364
21365       assert.deepEqual(func([1, NaN]), NaN);
21366     });
21367
21368     QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
21369       assert.expect(1);
21370
21371       assert.strictEqual(func(['1', '2']), '12');
21372     });
21373   });
21374
21375   /*--------------------------------------------------------------------------*/
21376
21377   QUnit.module('lodash.tail');
21378
21379   (function() {
21380     var array = [1, 2, 3];
21381
21382     QUnit.test('should accept a falsey `array`', function(assert) {
21383       assert.expect(1);
21384
21385       var expected = lodashStable.map(falsey, stubArray);
21386
21387       var actual = lodashStable.map(falsey, function(array, index) {
21388         try {
21389           return index ? _.tail(array) : _.tail();
21390         } catch (e) {}
21391       });
21392
21393       assert.deepEqual(actual, expected);
21394     });
21395
21396     QUnit.test('should exclude the first element', function(assert) {
21397       assert.expect(1);
21398
21399       assert.deepEqual(_.tail(array), [2, 3]);
21400     });
21401
21402     QUnit.test('should return an empty when querying empty arrays', function(assert) {
21403       assert.expect(1);
21404
21405       assert.deepEqual(_.tail([]), []);
21406     });
21407
21408     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21409       assert.expect(1);
21410
21411       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21412           actual = lodashStable.map(array, _.tail);
21413
21414       assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
21415     });
21416
21417     QUnit.test('should work in a lazy sequence', function(assert) {
21418       assert.expect(4);
21419
21420       if (!isNpm) {
21421         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21422             values = [];
21423
21424         var actual = _(array).tail().filter(function(value) {
21425           values.push(value);
21426           return false;
21427         })
21428         .value();
21429
21430         assert.deepEqual(actual, []);
21431         assert.deepEqual(values, array.slice(1));
21432
21433         values = [];
21434
21435         actual = _(array).filter(function(value) {
21436           values.push(value);
21437           return isEven(value);
21438         })
21439         .tail()
21440         .value();
21441
21442         assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
21443         assert.deepEqual(values, array);
21444       }
21445       else {
21446         skipAssert(assert, 4);
21447       }
21448     });
21449
21450     QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
21451       assert.expect(4);
21452
21453       if (!isNpm) {
21454         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21455             iteratee = function() { pass = false; },
21456             pass = true,
21457             actual = _(array).slice(0, 1).tail().map(iteratee).value();
21458
21459         assert.ok(pass);
21460         assert.deepEqual(actual, []);
21461
21462         pass = true;
21463         actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
21464
21465         assert.ok(pass);
21466         assert.deepEqual(actual, []);
21467       }
21468       else {
21469         skipAssert(assert, 4);
21470       }
21471     });
21472   }());
21473
21474   /*--------------------------------------------------------------------------*/
21475
21476   QUnit.module('lodash.take');
21477
21478   (function() {
21479     var array = [1, 2, 3];
21480
21481     QUnit.test('should take the first two elements', function(assert) {
21482       assert.expect(1);
21483
21484       assert.deepEqual(_.take(array, 2), [1, 2]);
21485     });
21486
21487     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21488       assert.expect(1);
21489
21490       var expected = lodashStable.map(falsey, function(value) {
21491         return value === undefined ? [1] : [];
21492       });
21493
21494       var actual = lodashStable.map(falsey, function(n) {
21495         return _.take(array, n);
21496       });
21497
21498       assert.deepEqual(actual, expected);
21499     });
21500
21501     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21502       assert.expect(3);
21503
21504       lodashStable.each([0, -1, -Infinity], function(n) {
21505         assert.deepEqual(_.take(array, n), []);
21506       });
21507     });
21508
21509     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21510       assert.expect(4);
21511
21512       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21513         assert.deepEqual(_.take(array, n), array);
21514       });
21515     });
21516
21517     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21518       assert.expect(1);
21519
21520       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21521           actual = lodashStable.map(array, _.take);
21522
21523       assert.deepEqual(actual, [[1], [4], [7]]);
21524     });
21525
21526     QUnit.test('should work in a lazy sequence', function(assert) {
21527       assert.expect(6);
21528
21529       if (!isNpm) {
21530         var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
21531             predicate = function(value) { values.push(value); return isEven(value); },
21532             values = [],
21533             actual = _(array).take(2).take().value();
21534
21535         assert.deepEqual(actual, _.take(_.take(array, 2)));
21536
21537         actual = _(array).filter(predicate).take(2).take().value();
21538         assert.deepEqual(values, [1, 2]);
21539         assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
21540
21541         actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
21542         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
21543
21544         values = [];
21545
21546         actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
21547         assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
21548         assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
21549       }
21550       else {
21551         skipAssert(assert, 6);
21552       }
21553     });
21554   }());
21555
21556   /*--------------------------------------------------------------------------*/
21557
21558   QUnit.module('lodash.takeRight');
21559
21560   (function() {
21561     var array = [1, 2, 3];
21562
21563     QUnit.test('should take the last two elements', function(assert) {
21564       assert.expect(1);
21565
21566       assert.deepEqual(_.takeRight(array, 2), [2, 3]);
21567     });
21568
21569     QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21570       assert.expect(1);
21571
21572       var expected = lodashStable.map(falsey, function(value) {
21573         return value === undefined ? [3] : [];
21574       });
21575
21576       var actual = lodashStable.map(falsey, function(n) {
21577         return _.takeRight(array, n);
21578       });
21579
21580       assert.deepEqual(actual, expected);
21581     });
21582
21583     QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21584       assert.expect(3);
21585
21586       lodashStable.each([0, -1, -Infinity], function(n) {
21587         assert.deepEqual(_.takeRight(array, n), []);
21588       });
21589     });
21590
21591     QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21592       assert.expect(4);
21593
21594       lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21595         assert.deepEqual(_.takeRight(array, n), array);
21596       });
21597     });
21598
21599     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21600       assert.expect(1);
21601
21602       var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21603           actual = lodashStable.map(array, _.takeRight);
21604
21605       assert.deepEqual(actual, [[3], [6], [9]]);
21606     });
21607
21608     QUnit.test('should work in a lazy sequence', function(assert) {
21609       assert.expect(6);
21610
21611       if (!isNpm) {
21612         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21613             predicate = function(value) { values.push(value); return isEven(value); },
21614             values = [],
21615             actual = _(array).takeRight(2).takeRight().value();
21616
21617         assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
21618
21619         actual = _(array).filter(predicate).takeRight(2).takeRight().value();
21620         assert.deepEqual(values, array);
21621         assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
21622
21623         actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
21624         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
21625
21626         values = [];
21627
21628         actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
21629         assert.deepEqual(values, array);
21630         assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
21631       }
21632       else {
21633         skipAssert(assert, 6);
21634       }
21635     });
21636   }());
21637
21638   /*--------------------------------------------------------------------------*/
21639
21640   QUnit.module('lodash.takeRightWhile');
21641
21642   (function() {
21643     var array = [1, 2, 3, 4];
21644
21645     var objects = [
21646       { 'a': 0, 'b': 0 },
21647       { 'a': 1, 'b': 1 },
21648       { 'a': 2, 'b': 2 }
21649     ];
21650
21651     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21652       assert.expect(1);
21653
21654       var actual = _.takeRightWhile(array, function(n) {
21655         return n > 2;
21656       });
21657
21658       assert.deepEqual(actual, [3, 4]);
21659     });
21660
21661     QUnit.test('should provide correct `predicate` arguments', function(assert) {
21662       assert.expect(1);
21663
21664       var args;
21665
21666       _.takeRightWhile(array, function() {
21667         args = slice.call(arguments);
21668       });
21669
21670       assert.deepEqual(args, [4, 3, array]);
21671     });
21672
21673     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21674       assert.expect(1);
21675
21676       assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
21677     });
21678
21679     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21680       assert.expect(1);
21681
21682       assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
21683     });
21684
21685     QUnit.test('should work with `_.property` shorthands', function(assert) {
21686       assert.expect(1);
21687
21688       assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
21689     });
21690
21691     QUnit.test('should work in a lazy sequence', function(assert) {
21692       assert.expect(3);
21693
21694       if (!isNpm) {
21695         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21696             predicate = function(n) { return n > 2; },
21697             expected = _.takeRightWhile(array, predicate),
21698             wrapped = _(array).takeRightWhile(predicate);
21699
21700         assert.deepEqual(wrapped.value(), expected);
21701         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21702         assert.strictEqual(wrapped.last(), _.last(expected));
21703       }
21704       else {
21705         skipAssert(assert, 3);
21706       }
21707     });
21708
21709     QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
21710       assert.expect(5);
21711
21712       if (!isNpm) {
21713         var args,
21714             array = lodashStable.range(LARGE_ARRAY_SIZE + 1);
21715
21716         var expected = [
21717           square(LARGE_ARRAY_SIZE),
21718           LARGE_ARRAY_SIZE - 1,
21719           lodashStable.map(array.slice(1), square)
21720         ];
21721
21722         _(array).slice(1).takeRightWhile(function(value, index, array) {
21723           args = slice.call(arguments);
21724         }).value();
21725
21726         assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
21727
21728         _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
21729           args = slice.call(arguments);
21730         }).value();
21731
21732         assert.deepEqual(args, expected);
21733
21734         _(array).slice(1).map(square).takeRightWhile(function(value, index) {
21735           args = slice.call(arguments);
21736         }).value();
21737
21738         assert.deepEqual(args, expected);
21739
21740         _(array).slice(1).map(square).takeRightWhile(function(index) {
21741           args = slice.call(arguments);
21742         }).value();
21743
21744         assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
21745
21746         _(array).slice(1).map(square).takeRightWhile(function() {
21747           args = slice.call(arguments);
21748         }).value();
21749
21750         assert.deepEqual(args, expected);
21751       }
21752       else {
21753         skipAssert(assert, 5);
21754       }
21755     });
21756   }());
21757
21758   /*--------------------------------------------------------------------------*/
21759
21760   QUnit.module('lodash.takeWhile');
21761
21762   (function() {
21763     var array = [1, 2, 3, 4];
21764
21765     var objects = [
21766       { 'a': 2, 'b': 2 },
21767       { 'a': 1, 'b': 1 },
21768       { 'a': 0, 'b': 0 }
21769     ];
21770
21771     QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21772       assert.expect(1);
21773
21774       var actual = _.takeWhile(array, function(n) {
21775         return n < 3;
21776       });
21777
21778       assert.deepEqual(actual, [1, 2]);
21779     });
21780
21781     QUnit.test('should provide correct `predicate` arguments', function(assert) {
21782       assert.expect(1);
21783
21784       var args;
21785
21786       _.takeWhile(array, function() {
21787         args = slice.call(arguments);
21788       });
21789
21790       assert.deepEqual(args, [1, 0, array]);
21791     });
21792
21793     QUnit.test('should work with `_.matches` shorthands', function(assert) {
21794       assert.expect(1);
21795
21796       assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
21797     });
21798
21799     QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21800       assert.expect(1);
21801
21802       assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
21803     });
21804     QUnit.test('should work with `_.property` shorthands', function(assert) {
21805       assert.expect(1);
21806
21807       assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
21808     });
21809
21810     QUnit.test('should work in a lazy sequence', function(assert) {
21811       assert.expect(3);
21812
21813       if (!isNpm) {
21814         var array = lodashStable.range(LARGE_ARRAY_SIZE),
21815             predicate = function(n) { return n < 3; },
21816             expected = _.takeWhile(array, predicate),
21817             wrapped = _(array).takeWhile(predicate);
21818
21819         assert.deepEqual(wrapped.value(), expected);
21820         assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21821         assert.strictEqual(wrapped.last(), _.last(expected));
21822       }
21823       else {
21824         skipAssert(assert, 3);
21825       }
21826     });
21827
21828     QUnit.test('should work in a lazy sequence with `take`', function(assert) {
21829       assert.expect(1);
21830
21831       if (!isNpm) {
21832         var array = lodashStable.range(LARGE_ARRAY_SIZE);
21833
21834         var actual = _(array)
21835           .takeWhile(function(n) { return n < 4; })
21836           .take(2)
21837           .takeWhile(function(n) { return n == 0; })
21838           .value();
21839
21840         assert.deepEqual(actual, [0]);
21841       }
21842       else {
21843         skipAssert(assert);
21844       }
21845     });
21846
21847     QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
21848       assert.expect(5);
21849
21850       if (!isNpm) {
21851         var args,
21852             array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21853             expected = [1, 0, lodashStable.map(array.slice(1), square)];
21854
21855         _(array).slice(1).takeWhile(function(value, index, array) {
21856           args = slice.call(arguments);
21857         }).value();
21858
21859         assert.deepEqual(args, [1, 0, array.slice(1)]);
21860
21861         _(array).slice(1).map(square).takeWhile(function(value, index, array) {
21862           args = slice.call(arguments);
21863         }).value();
21864
21865         assert.deepEqual(args, expected);
21866
21867         _(array).slice(1).map(square).takeWhile(function(value, index) {
21868           args = slice.call(arguments);
21869         }).value();
21870
21871         assert.deepEqual(args, expected);
21872
21873         _(array).slice(1).map(square).takeWhile(function(value) {
21874           args = slice.call(arguments);
21875         }).value();
21876
21877         assert.deepEqual(args, [1]);
21878
21879         _(array).slice(1).map(square).takeWhile(function() {
21880           args = slice.call(arguments);
21881         }).value();
21882
21883         assert.deepEqual(args, expected);
21884       }
21885       else {
21886         skipAssert(assert, 5);
21887       }
21888     });
21889   }());
21890
21891   /*--------------------------------------------------------------------------*/
21892
21893   QUnit.module('lodash.tap');
21894
21895   (function() {
21896     QUnit.test('should intercept and return the given value', function(assert) {
21897       assert.expect(2);
21898
21899       if (!isNpm) {
21900         var intercepted,
21901             array = [1, 2, 3];
21902
21903         var actual = _.tap(array, function(value) {
21904           intercepted = value;
21905         });
21906
21907         assert.strictEqual(actual, array);
21908         assert.strictEqual(intercepted, array);
21909       }
21910       else {
21911         skipAssert(assert, 2);
21912       }
21913     });
21914
21915     QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
21916       assert.expect(2);
21917
21918       if (!isNpm) {
21919         var intercepted,
21920             array = [1, 2, 3];
21921
21922         var wrapped = _(array).tap(function(value) {
21923           intercepted = value;
21924           value.pop();
21925         });
21926
21927         assert.ok(wrapped instanceof _);
21928
21929         wrapped.value();
21930         assert.strictEqual(intercepted, array);
21931       }
21932       else {
21933         skipAssert(assert, 2);
21934       }
21935     });
21936   }());
21937
21938   /*--------------------------------------------------------------------------*/
21939
21940   QUnit.module('lodash.template');
21941
21942   (function() {
21943     QUnit.test('should escape values in "escape" delimiters', function(assert) {
21944       assert.expect(1);
21945
21946       var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
21947           expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;/</p>')),
21948           data = { 'value': '&<>"\'/' };
21949
21950       var actual = lodashStable.map(strings, function(string) {
21951         return _.template(string)(data);
21952       });
21953
21954       assert.deepEqual(actual, expected);
21955     });
21956
21957     QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
21958       assert.expect(1);
21959
21960       var compiled = _.template('<%= typeof __e %>');
21961       assert.strictEqual(compiled({}), 'undefined');
21962     });
21963
21964     QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
21965       assert.expect(1);
21966
21967       var compiled = _.template(
21968         '<ul><%\
21969         for (var key in collection) {\
21970           %><li><%= collection[key] %></li><%\
21971         } %></ul>'
21972       );
21973
21974       var data = { 'collection': { 'a': 'A', 'b': 'B' } },
21975           actual = compiled(data);
21976
21977       assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
21978     });
21979
21980     QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
21981       assert.expect(1);
21982
21983       var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
21984           data = { 'value': true };
21985
21986       assert.strictEqual(compiled(data), 'yap');
21987     });
21988
21989     QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
21990       assert.expect(1);
21991
21992       var compiled = _.template('<% var b = a; %><%= b.value %>'),
21993           data = { 'a': { 'value': 1 } };
21994
21995       assert.strictEqual(compiled(data), '1');
21996     });
21997
21998     QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
21999       assert.expect(1);
22000
22001       var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
22002           expected = lodashStable.map(strings, lodashStable.constant('ABC')),
22003           data = { 'a': 'A' };
22004
22005       var actual = lodashStable.map(strings, function(string) {
22006         return _.template(string)(data);
22007       });
22008
22009       assert.deepEqual(actual, expected);
22010     });
22011
22012     QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
22013       assert.expect(1);
22014
22015       var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
22016           data = { 'a': true };
22017
22018       assert.strictEqual(compiled(data), 'a="A"');
22019     });
22020
22021     QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
22022       assert.expect(1);
22023
22024       var compiled = _.template('<%= value ? value : "b" %>'),
22025           data = { 'value': 'a' };
22026
22027       assert.strictEqual(compiled(data), 'a');
22028     });
22029
22030     QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
22031       assert.expect(1);
22032
22033       var compiled = _.template('<%= typeof Math.abs %>');
22034
22035       try {
22036         var actual = compiled();
22037       } catch (e) {}
22038
22039       assert.strictEqual(actual, 'function');
22040     });
22041
22042     QUnit.test('should support complex "interpolate" delimiters', function(assert) {
22043       assert.expect(22);
22044
22045       lodashStable.forOwn({
22046         '<%= a + b %>': '3',
22047         '<%= b - a %>': '1',
22048         '<%= a = b %>': '2',
22049         '<%= !a %>': 'false',
22050         '<%= ~a %>': '-2',
22051         '<%= a * b %>': '2',
22052         '<%= a / b %>': '0.5',
22053         '<%= a % b %>': '1',
22054         '<%= a >> b %>': '0',
22055         '<%= a << b %>': '4',
22056         '<%= a & b %>': '0',
22057         '<%= a ^ b %>': '3',
22058         '<%= a | b %>': '3',
22059         '<%= {}.toString.call(0) %>': numberTag,
22060         '<%= a.toFixed(2) %>': '1.00',
22061         '<%= obj["a"] %>': '1',
22062         '<%= delete a %>': 'true',
22063         '<%= "a" in obj %>': 'true',
22064         '<%= obj instanceof Object %>': 'true',
22065         '<%= new Boolean %>': 'false',
22066         '<%= typeof a %>': 'number',
22067         '<%= void a %>': ''
22068       },
22069       function(value, key) {
22070         var compiled = _.template(key),
22071             data = { 'a': 1, 'b': 2 };
22072
22073         assert.strictEqual(compiled(data), value, key);
22074       });
22075     });
22076
22077     QUnit.test('should support ES6 template delimiters', function(assert) {
22078       assert.expect(2);
22079
22080       var data = { 'value': 2 };
22081       assert.strictEqual(_.template('1${value}3')(data), '123');
22082       assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
22083     });
22084
22085     QUnit.test('should support the "imports" option', function(assert) {
22086       assert.expect(1);
22087
22088       var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
22089       assert.strictEqual(compiled({}), '1');
22090     });
22091
22092     QUnit.test('should support the "variable" options', function(assert) {
22093       assert.expect(1);
22094
22095       var compiled = _.template(
22096         '<% _.each( data.a, function( value ) { %>' +
22097             '<%= value.valueOf() %>' +
22098         '<% }) %>', { 'variable': 'data' }
22099       );
22100
22101       var data = { 'a': [1, 2, 3] };
22102
22103       try {
22104         assert.strictEqual(compiled(data), '123');
22105       } catch (e) {
22106         assert.ok(false, e.message);
22107       }
22108     });
22109
22110     QUnit.test('should support custom delimiters', function(assert) {
22111       assert.expect(2);
22112
22113       lodashStable.times(2, function(index) {
22114         var settingsClone = lodashStable.clone(_.templateSettings);
22115
22116         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22117           'escape': /\{\{-([\s\S]+?)\}\}/g,
22118           'evaluate': /\{\{([\s\S]+?)\}\}/g,
22119           'interpolate': /\{\{=([\s\S]+?)\}\}/g
22120         });
22121
22122         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22123             compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
22124             data = { 'collection': ['a & A', 'b & B'] };
22125
22126         assert.strictEqual(compiled(data), expected);
22127         lodashStable.assign(_.templateSettings, settingsClone);
22128       });
22129     });
22130
22131     QUnit.test('should support custom delimiters containing special characters', function(assert) {
22132       assert.expect(2);
22133
22134       lodashStable.times(2, function(index) {
22135         var settingsClone = lodashStable.clone(_.templateSettings);
22136
22137         var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22138           'escape': /<\?-([\s\S]+?)\?>/g,
22139           'evaluate': /<\?([\s\S]+?)\?>/g,
22140           'interpolate': /<\?=([\s\S]+?)\?>/g
22141         });
22142
22143         var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22144             compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
22145             data = { 'collection': ['a & A', 'b & B'] };
22146
22147         assert.strictEqual(compiled(data), expected);
22148         lodashStable.assign(_.templateSettings, settingsClone);
22149       });
22150     });
22151
22152     QUnit.test('should use a `with` statement by default', function(assert) {
22153       assert.expect(1);
22154
22155       var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
22156           actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
22157
22158       assert.strictEqual(actual, '1b012');
22159     });
22160
22161     QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
22162       assert.expect(1);
22163
22164       var lodash = _.templateSettings.imports._,
22165           settingsClone = lodashStable.clone(lodash.templateSettings);
22166
22167       lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
22168         'interpolate': /\{\{=([\s\S]+?)\}\}/g
22169       });
22170
22171       var compiled = _.template('{{= a }}');
22172       assert.strictEqual(compiled({ 'a': 1 }), '1');
22173
22174       if (settingsClone) {
22175         lodashStable.assign(lodash.templateSettings, settingsClone);
22176       } else {
22177         delete lodash.templateSettings;
22178       }
22179     });
22180
22181     QUnit.test('should fallback to `_.templateSettings`', function(assert) {
22182       assert.expect(1);
22183
22184       var lodash = _.templateSettings.imports._,
22185           delimiter = _.templateSettings.interpolate;
22186
22187       _.templateSettings.imports._ = { 'escape': lodashStable.escape };
22188       _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
22189
22190       var compiled = _.template('{{= a }}');
22191       assert.strictEqual(compiled({ 'a': 1 }), '1');
22192
22193       _.templateSettings.imports._ = lodash;
22194       _.templateSettings.interpolate = delimiter;
22195     });
22196
22197     QUnit.test('should ignore `null` delimiters', function(assert) {
22198       assert.expect(3);
22199
22200       var delimiter = {
22201         'escape': /\{\{-([\s\S]+?)\}\}/g,
22202         'evaluate': /\{\{([\s\S]+?)\}\}/g,
22203         'interpolate': /\{\{=([\s\S]+?)\}\}/g
22204       };
22205
22206       lodashStable.forOwn({
22207         'escape': '{{- a }}',
22208         'evaluate': '{{ print(a) }}',
22209         'interpolate': '{{= a }}'
22210       },
22211       function(value, key) {
22212         var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
22213         settings[key] = delimiter[key];
22214
22215         var expected = '1 <%- a %> <% print(a) %> <%= a %>',
22216             compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
22217             data = { 'a': 1 };
22218
22219         assert.strictEqual(compiled(data), expected);
22220       });
22221     });
22222
22223     QUnit.test('should work without delimiters', function(assert) {
22224       assert.expect(1);
22225
22226       var expected = 'abc';
22227       assert.strictEqual(_.template(expected)({}), expected);
22228     });
22229
22230     QUnit.test('should work with `this` references', function(assert) {
22231       assert.expect(2);
22232
22233       var compiled = _.template('a<%= this.String("b") %>c');
22234       assert.strictEqual(compiled(), 'abc');
22235
22236       var object = { 'b': 'B' };
22237       object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
22238       assert.strictEqual(object.compiled(), 'ABC');
22239     });
22240
22241     QUnit.test('should work with backslashes', function(assert) {
22242       assert.expect(1);
22243
22244       var compiled = _.template('<%= a %> \\b'),
22245           data = { 'a': 'A' };
22246
22247       assert.strictEqual(compiled(data), 'A \\b');
22248     });
22249
22250     QUnit.test('should work with escaped characters in string literals', function(assert) {
22251       assert.expect(2);
22252
22253       var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
22254       assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
22255
22256       var data = { 'a': 'A' };
22257       compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
22258       assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
22259     });
22260
22261     QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
22262       assert.expect(1);
22263
22264       var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
22265       assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
22266     });
22267
22268     QUnit.test('should work with statements containing quotes', function(assert) {
22269       assert.expect(1);
22270
22271       var compiled = _.template("<%\
22272         if (a == 'A' || a == \"a\") {\
22273           %>'a',\"A\"<%\
22274         } %>"
22275       );
22276
22277       var data = { 'a': 'A' };
22278       assert.strictEqual(compiled(data), "'a',\"A\"");
22279     });
22280
22281     QUnit.test('should work with templates containing newlines and comments', function(assert) {
22282       assert.expect(1);
22283
22284       var compiled = _.template('<%\n\
22285         // A code comment.\n\
22286         if (value) { value += 3; }\n\
22287         %><p><%= value %></p>'
22288       );
22289
22290       assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
22291     });
22292
22293     QUnit.test('should tokenize delimiters', function(assert) {
22294       assert.expect(1);
22295
22296       var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
22297           data = { 'type': 1 };
22298
22299       assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
22300     });
22301
22302     QUnit.test('should evaluate delimiters once', function(assert) {
22303       assert.expect(1);
22304
22305       var actual = [],
22306           compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
22307           data = { 'func': function(value) { actual.push(value); } };
22308
22309       compiled(data);
22310       assert.deepEqual(actual, ['a', 'b', 'c']);
22311     });
22312
22313     QUnit.test('should match delimiters before escaping text', function(assert) {
22314       assert.expect(1);
22315
22316       var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
22317       assert.strictEqual(compiled(), '<<\n a \n>>');
22318     });
22319
22320     QUnit.test('should resolve nullish values to an empty string', function(assert) {
22321       assert.expect(3);
22322
22323       var compiled = _.template('<%= a %><%- a %>'),
22324           data = { 'a': null };
22325
22326       assert.strictEqual(compiled(data), '');
22327
22328       data = { 'a': undefined };
22329       assert.strictEqual(compiled(data), '');
22330
22331       data = { 'a': {} };
22332       compiled = _.template('<%= a.b %><%- a.b %>');
22333       assert.strictEqual(compiled(data), '');
22334     });
22335
22336     QUnit.test('should return an empty string for empty values', function(assert) {
22337       assert.expect(1);
22338
22339       var values = [, null, undefined, ''],
22340           expected = lodashStable.map(values, stubString),
22341           data = { 'a': 1 };
22342
22343       var actual = lodashStable.map(values, function(value, index) {
22344         var compiled = index ? _.template(value) : _.template();
22345         return compiled(data);
22346       });
22347
22348       assert.deepEqual(actual, expected);
22349     });
22350
22351     QUnit.test('should parse delimiters without newlines', function(assert) {
22352       assert.expect(1);
22353
22354       var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
22355           compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
22356           data = { 'value': true };
22357
22358       assert.strictEqual(compiled(data), expected);
22359     });
22360
22361     QUnit.test('should support recursive calls', function(assert) {
22362       assert.expect(1);
22363
22364       var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
22365           data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
22366
22367       assert.strictEqual(compiled(data), 'AB');
22368     });
22369
22370     QUnit.test('should coerce `text` to a string', function(assert) {
22371       assert.expect(1);
22372
22373       var object = { 'toString': lodashStable.constant('<%= a %>') },
22374           data = { 'a': 1 };
22375
22376       assert.strictEqual(_.template(object)(data), '1');
22377     });
22378
22379     QUnit.test('should not modify the `options` object', function(assert) {
22380       assert.expect(1);
22381
22382       var options = {};
22383       _.template('', options);
22384       assert.deepEqual(options, {});
22385     });
22386
22387     QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
22388       assert.expect(2);
22389
22390       var data = { 'a': 1 };
22391
22392       assert.notOk('a' in _.templateSettings);
22393       _.template('', {}, data);
22394       assert.notOk('a' in _.templateSettings);
22395
22396       delete _.templateSettings.a;
22397     });
22398
22399     QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
22400       assert.expect(2);
22401
22402       _.template('')(1);
22403       assert.ok(true, '`data` value');
22404
22405       _.template('', 1)(1);
22406       assert.ok(true, '`options` value');
22407     });
22408
22409     QUnit.test('should expose the source on compiled templates', function(assert) {
22410       assert.expect(1);
22411
22412       var compiled = _.template('x'),
22413           values = [String(compiled), compiled.source],
22414           expected = lodashStable.map(values, stubTrue);
22415
22416       var actual = lodashStable.map(values, function(value) {
22417         return lodashStable.includes(value, '__p');
22418       });
22419
22420       assert.deepEqual(actual, expected);
22421     });
22422
22423     QUnit.test('should expose the source on SyntaxErrors', function(assert) {
22424       assert.expect(1);
22425
22426       try {
22427         _.template('<% if x %>');
22428       } catch (e) {
22429         var source = e.source;
22430       }
22431       assert.ok(lodashStable.includes(source, '__p'));
22432     });
22433
22434     QUnit.test('should not include sourceURLs in the source', function(assert) {
22435       assert.expect(1);
22436
22437       var options = { 'sourceURL': '/a/b/c' },
22438           compiled = _.template('x', options),
22439           values = [compiled.source, undefined];
22440
22441       try {
22442         _.template('<% if x %>', options);
22443       } catch (e) {
22444         values[1] = e.source;
22445       }
22446       var expected = lodashStable.map(values, stubFalse);
22447
22448       var actual = lodashStable.map(values, function(value) {
22449         return lodashStable.includes(value, 'sourceURL');
22450       });
22451
22452       assert.deepEqual(actual, expected);
22453     });
22454
22455     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22456       assert.expect(1);
22457
22458       var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
22459           compiles = lodashStable.map(array, _.template),
22460           data = { 'a': 'one', 'b': '"two"', 'c': 'three' };
22461
22462       var actual = lodashStable.map(compiles, function(compiled) {
22463         return compiled(data);
22464       });
22465
22466       assert.deepEqual(actual, ['one', '&quot;two&quot;', 'three']);
22467     });
22468   }());
22469
22470   /*--------------------------------------------------------------------------*/
22471
22472   QUnit.module('lodash.truncate');
22473
22474   (function() {
22475     var string = 'hi-diddly-ho there, neighborino';
22476
22477     QUnit.test('should use a default `length` of `30`', function(assert) {
22478       assert.expect(1);
22479
22480       assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
22481     });
22482
22483     QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
22484       assert.expect(2);
22485
22486       assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
22487       assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
22488     });
22489
22490     QUnit.test('should truncate string the given length', function(assert) {
22491       assert.expect(1);
22492
22493       assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
22494     });
22495
22496     QUnit.test('should support a `omission` option', function(assert) {
22497       assert.expect(1);
22498
22499       assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
22500     });
22501
22502     QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
22503       assert.expect(2);
22504
22505       assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
22506       assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
22507     });
22508
22509     QUnit.test('should support a `length` option', function(assert) {
22510       assert.expect(1);
22511
22512       assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
22513     });
22514
22515     QUnit.test('should support a `separator` option', function(assert) {
22516       assert.expect(3);
22517
22518       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
22519       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
22520       assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
22521     });
22522
22523     QUnit.test('should treat negative `length` as `0`', function(assert) {
22524       assert.expect(2);
22525
22526       lodashStable.each([0, -2], function(length) {
22527         assert.strictEqual(_.truncate(string, { 'length': length }), '...');
22528       });
22529     });
22530
22531     QUnit.test('should coerce `length` to an integer', function(assert) {
22532       assert.expect(4);
22533
22534       lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
22535         var actual = index > 1 ? 'h...' : '...';
22536         assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
22537       });
22538     });
22539
22540     QUnit.test('should coerce `string` to a string', function(assert) {
22541       assert.expect(2);
22542
22543       assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
22544       assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
22545     });
22546
22547     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22548       assert.expect(1);
22549
22550       var actual = lodashStable.map([string, string, string], _.truncate),
22551           truncated = 'hi-diddly-ho there, neighbo...';
22552
22553       assert.deepEqual(actual, [truncated, truncated, truncated]);
22554     });
22555   }());
22556
22557   /*--------------------------------------------------------------------------*/
22558
22559   QUnit.module('lodash.throttle');
22560
22561   (function() {
22562     QUnit.test('should throttle a function', function(assert) {
22563       assert.expect(2);
22564
22565       var done = assert.async();
22566
22567       var callCount = 0,
22568           throttled = _.throttle(function() { callCount++; }, 32);
22569
22570       throttled();
22571       throttled();
22572       throttled();
22573
22574       var lastCount = callCount;
22575       assert.ok(callCount);
22576
22577       setTimeout(function() {
22578         assert.ok(callCount > lastCount);
22579         done();
22580       }, 64);
22581     });
22582
22583     QUnit.test('subsequent calls should return the result of the first call', function(assert) {
22584       assert.expect(5);
22585
22586       var done = assert.async();
22587
22588       var throttled = _.throttle(identity, 32),
22589           results = [throttled('a'), throttled('b')];
22590
22591       assert.deepEqual(results, ['a', 'a']);
22592
22593       setTimeout(function() {
22594         var results = [throttled('c'), throttled('d')];
22595         assert.notEqual(results[0], 'a');
22596         assert.notStrictEqual(results[0], undefined);
22597
22598         assert.notEqual(results[1], 'd');
22599         assert.notStrictEqual(results[1], undefined);
22600         done();
22601       }, 64);
22602     });
22603
22604     QUnit.test('should clear timeout when `func` is called', function(assert) {
22605       assert.expect(1);
22606
22607       var done = assert.async();
22608
22609       if (!isModularize) {
22610         var callCount = 0,
22611             dateCount = 0;
22612
22613         var lodash = _.runInContext({
22614           'Date': {
22615             'now': function() {
22616               return ++dateCount == 5 ? Infinity : +new Date;
22617             }
22618           }
22619         });
22620
22621         var throttled = lodash.throttle(function() { callCount++; }, 32);
22622
22623         throttled();
22624         throttled();
22625
22626         setTimeout(function() {
22627           assert.strictEqual(callCount, 2);
22628           done();
22629         }, 64);
22630       }
22631       else {
22632         skipAssert(assert);
22633         done();
22634       }
22635     });
22636
22637     QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
22638       assert.expect(2);
22639
22640       var done = assert.async();
22641
22642       var callCount = 0,
22643           throttled = _.throttle(function() { callCount++; }, 32);
22644
22645       throttled();
22646       assert.strictEqual(callCount, 1);
22647
22648       setTimeout(function() {
22649         assert.strictEqual(callCount, 1);
22650         done();
22651       }, 64);
22652     });
22653
22654     lodashStable.times(2, function(index) {
22655       QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
22656         assert.expect(1);
22657
22658         var done = assert.async();
22659
22660         var callCount = 0,
22661             limit = (argv || isPhantom) ? 1000 : 320,
22662             options = index ? { 'leading': false } : {},
22663             throttled = _.throttle(function() { callCount++; }, 32, options);
22664
22665         var start = +new Date;
22666         while ((new Date - start) < limit) {
22667           throttled();
22668         }
22669         var actual = callCount > 1;
22670         setTimeout(function() {
22671           assert.ok(actual);
22672           done();
22673         }, 1);
22674       });
22675     });
22676
22677     QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
22678       assert.expect(3);
22679
22680       var done = assert.async();
22681
22682       var callCount = 0;
22683
22684       var throttled = _.throttle(function() {
22685         callCount++;
22686       }, 128, { 'leading': false });
22687
22688       throttled();
22689
22690       setTimeout(function() {
22691         assert.strictEqual(callCount, 1);
22692         throttled();
22693       }, 192);
22694
22695       setTimeout(function() {
22696         assert.strictEqual(callCount, 1);
22697       }, 254);
22698
22699       setTimeout(function() {
22700         assert.strictEqual(callCount, 2);
22701         done();
22702       }, 384);
22703     });
22704
22705     QUnit.test('should apply default options', function(assert) {
22706       assert.expect(2);
22707
22708       var done = assert.async();
22709
22710       var callCount = 0,
22711           throttled = _.throttle(function() { callCount++; }, 32, {});
22712
22713       throttled();
22714       throttled();
22715       assert.strictEqual(callCount, 1);
22716
22717       setTimeout(function() {
22718         assert.strictEqual(callCount, 2);
22719         done();
22720       }, 128);
22721     });
22722
22723     QUnit.test('should support a `leading` option', function(assert) {
22724       assert.expect(2);
22725
22726       var withLeading = _.throttle(identity, 32, { 'leading': true });
22727       assert.strictEqual(withLeading('a'), 'a');
22728
22729       var withoutLeading = _.throttle(identity, 32, { 'leading': false });
22730       assert.strictEqual(withoutLeading('a'), undefined);
22731     });
22732
22733     QUnit.test('should support a `trailing` option', function(assert) {
22734       assert.expect(6);
22735
22736       var done = assert.async();
22737
22738       var withCount = 0,
22739           withoutCount = 0;
22740
22741       var withTrailing = _.throttle(function(value) {
22742         withCount++;
22743         return value;
22744       }, 64, { 'trailing': true });
22745
22746       var withoutTrailing = _.throttle(function(value) {
22747         withoutCount++;
22748         return value;
22749       }, 64, { 'trailing': false });
22750
22751       assert.strictEqual(withTrailing('a'), 'a');
22752       assert.strictEqual(withTrailing('b'), 'a');
22753
22754       assert.strictEqual(withoutTrailing('a'), 'a');
22755       assert.strictEqual(withoutTrailing('b'), 'a');
22756
22757       setTimeout(function() {
22758         assert.strictEqual(withCount, 2);
22759         assert.strictEqual(withoutCount, 1);
22760         done();
22761       }, 256);
22762     });
22763
22764     QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
22765       assert.expect(1);
22766
22767       var done = assert.async();
22768
22769       var callCount = 0;
22770
22771       var throttled = _.throttle(function() {
22772         callCount++;
22773       }, 64, { 'trailing': false });
22774
22775       throttled();
22776       throttled();
22777
22778       setTimeout(function() {
22779         throttled();
22780         throttled();
22781       }, 96);
22782
22783       setTimeout(function() {
22784         assert.ok(callCount > 1);
22785         done();
22786       }, 192);
22787     });
22788
22789     QUnit.test('should work with a system time of `0`', function(assert) {
22790       assert.expect(3);
22791
22792       var done = assert.async();
22793
22794       if (!isModularize) {
22795         var callCount = 0,
22796             dateCount = 0;
22797
22798         var lodash = _.runInContext({
22799           'Date': {
22800             'now': function() {
22801               return ++dateCount < 4 ? 0 : +new Date;
22802             }
22803           }
22804         });
22805
22806         var throttled = lodash.throttle(function(value) {
22807           callCount++;
22808           return value;
22809         }, 32);
22810
22811         var results = [throttled('a'), throttled('b'), throttled('c')];
22812         assert.deepEqual(results, ['a', 'a', 'a']);
22813         assert.strictEqual(callCount, 1);
22814
22815         setTimeout(function() {
22816           assert.strictEqual(callCount, 2);
22817           done();
22818         }, 64);
22819       }
22820       else {
22821         skipAssert(assert, 3);
22822         done();
22823       }
22824     });
22825   }());
22826
22827   /*--------------------------------------------------------------------------*/
22828
22829   QUnit.module('lodash.debounce and lodash.throttle');
22830
22831   lodashStable.each(['debounce', 'throttle'], function(methodName) {
22832     var func = _[methodName],
22833         isDebounce = methodName == 'debounce';
22834
22835     QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
22836       assert.expect(1);
22837
22838       func(noop, 32, 1);
22839       assert.ok(true);
22840     });
22841
22842     QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
22843       assert.expect(1);
22844
22845       var done = assert.async();
22846
22847       var callCount = 0,
22848           funced = func(function() { callCount++; });
22849
22850       funced();
22851
22852       setTimeout(function() {
22853         funced();
22854         assert.strictEqual(callCount, isDebounce ? 1 : 2);
22855         done();
22856       }, 32);
22857     });
22858
22859     QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
22860       assert.expect(1);
22861
22862       var done = assert.async();
22863
22864       var actual = [],
22865           object = { 'funced': func(function() { actual.push(this); }, 32) },
22866           expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
22867
22868       object.funced();
22869       if (!isDebounce) {
22870         object.funced();
22871       }
22872       setTimeout(function() {
22873         assert.deepEqual(actual, expected);
22874         done();
22875       }, 64);
22876     });
22877
22878     QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
22879       assert.expect(2);
22880
22881       var done = assert.async();
22882
22883       var actual = [],
22884           args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
22885           expected = args.slice(),
22886           queue = args.slice();
22887
22888       var funced = func(function() {
22889         var current = [this];
22890         push.apply(current, arguments);
22891         actual.push(current);
22892
22893         var next = queue.shift();
22894         if (next) {
22895           funced.call(next[0], next[1]);
22896         }
22897       }, 32);
22898
22899       var next = queue.shift();
22900       funced.call(next[0], next[1]);
22901       assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
22902
22903       setTimeout(function() {
22904         assert.deepEqual(actual, expected.slice(0, actual.length));
22905         done();
22906       }, 256);
22907     });
22908
22909     QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
22910       assert.expect(1);
22911
22912       var done = assert.async();
22913
22914       if (!isModularize) {
22915         var callCount = 0,
22916             dateCount = 0;
22917
22918         var lodash = _.runInContext({
22919           'Date': {
22920             'now': function() {
22921               return ++dateCount == 4
22922                 ? +new Date(2012, 3, 23, 23, 27, 18)
22923                 : +new Date;
22924             }
22925           }
22926         });
22927
22928         var funced = lodash[methodName](function() {
22929           callCount++;
22930         }, 32);
22931
22932         funced();
22933
22934         setTimeout(function() {
22935           funced();
22936           assert.strictEqual(callCount, isDebounce ? 1 : 2);
22937           done();
22938         }, 64);
22939       }
22940       else {
22941         skipAssert(assert);
22942         done();
22943       }
22944     });
22945
22946     QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
22947       assert.expect(1);
22948
22949       var done = assert.async();
22950
22951       var callCount = 0;
22952
22953       var funced = func(function() {
22954         callCount++;
22955       }, 32, { 'leading': false });
22956
22957       funced();
22958       funced.cancel();
22959
22960       setTimeout(function() {
22961         assert.strictEqual(callCount, 0);
22962         done();
22963       }, 64);
22964     });
22965
22966     QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
22967       assert.expect(3);
22968
22969       var done = assert.async();
22970
22971       var callCount = 0;
22972
22973       var funced = func(function() {
22974         return ++callCount;
22975       }, 32, { 'leading': true });
22976
22977       assert.strictEqual(funced(), 1);
22978       funced.cancel();
22979
22980       assert.strictEqual(funced(), 2);
22981       funced();
22982
22983       setTimeout(function() {
22984         assert.strictEqual(callCount, 3);
22985         done();
22986       }, 64);
22987     });
22988
22989     QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
22990       assert.expect(2);
22991
22992       var done = assert.async();
22993
22994       var callCount = 0;
22995
22996       var funced = func(function() {
22997         return ++callCount;
22998       }, 32, { 'leading': false });
22999
23000       funced();
23001       assert.strictEqual(funced.flush(), 1);
23002
23003       setTimeout(function() {
23004         assert.strictEqual(callCount, 1);
23005         done();
23006       }, 64);
23007     });
23008
23009     QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
23010       assert.expect(2);
23011
23012       var done = assert.async();
23013
23014       var callCount = 0,
23015           funced = func(function() { callCount++; }, 32);
23016
23017       funced.cancel();
23018       assert.strictEqual(funced.flush(), undefined);
23019
23020       setTimeout(function() {
23021         assert.strictEqual(callCount, 0);
23022         done();
23023       }, 64);
23024     });
23025   });
23026
23027   /*--------------------------------------------------------------------------*/
23028
23029   QUnit.module('lodash.times');
23030
23031   (function() {
23032     QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
23033       assert.expect(3);
23034
23035       lodashStable.each([-Infinity, NaN, Infinity], function(n) {
23036         assert.deepEqual(_.times(n), []);
23037       });
23038     });
23039
23040     QUnit.test('should coerce `n` to an integer', function(assert) {
23041       assert.expect(1);
23042
23043       var actual = _.times(2.6, _.identity);
23044       assert.deepEqual(actual, [0, 1]);
23045     });
23046
23047     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
23048       assert.expect(1);
23049
23050       var args;
23051
23052       _.times(1, function(assert) {
23053         args || (args = slice.call(arguments));
23054       });
23055
23056       assert.deepEqual(args, [0]);
23057     });
23058
23059     QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
23060       assert.expect(1);
23061
23062       var values = [, null, undefined],
23063           expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
23064
23065       var actual = lodashStable.map(values, function(value, index) {
23066         return index ? _.times(3, value) : _.times(3);
23067       });
23068
23069       assert.deepEqual(actual, expected);
23070     });
23071
23072     QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
23073       assert.expect(1);
23074
23075       assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
23076     });
23077
23078     QUnit.test('should return an empty array for falsey and negative `n` values', function(assert) {
23079       assert.expect(1);
23080
23081       var values = falsey.concat(-1, -Infinity),
23082           expected = lodashStable.map(values, stubArray);
23083
23084       var actual = lodashStable.map(values, function(value, index) {
23085         return index ? _.times(value) : _.times();
23086       });
23087
23088       assert.deepEqual(actual, expected);
23089     });
23090
23091     QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
23092       assert.expect(1);
23093
23094       if (!isNpm) {
23095         assert.deepEqual(_(3).times(), [0, 1, 2]);
23096       }
23097       else {
23098         skipAssert(assert);
23099       }
23100     });
23101
23102     QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
23103       assert.expect(1);
23104
23105       if (!isNpm) {
23106         assert.ok(_(3).chain().times() instanceof _);
23107       }
23108       else {
23109         skipAssert(assert);
23110       }
23111     });
23112   }());
23113
23114   /*--------------------------------------------------------------------------*/
23115
23116   QUnit.module('lodash.toArray');
23117
23118   (function() {
23119     QUnit.test('should convert objects to arrays', function(assert) {
23120       assert.expect(1);
23121
23122       assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
23123     });
23124
23125     QUnit.test('should convert iterables to arrays', function(assert) {
23126       assert.expect(1);
23127
23128       if (Symbol && Symbol.iterator) {
23129         var object = { '0': 'a', 'length': 1 };
23130         object[Symbol.iterator] = arrayProto[Symbol.iterator];
23131
23132         assert.deepEqual(_.toArray(object), ['a']);
23133       }
23134       else {
23135         skipAssert(assert);
23136       }
23137     });
23138
23139     QUnit.test('should convert maps to arrays', function(assert) {
23140       assert.expect(1);
23141
23142       if (Map) {
23143         var map = new Map;
23144         map.set('a', 1);
23145         map.set('b', 2);
23146         assert.deepEqual(_.toArray(map), [['a', 1], ['b', 2]]);
23147       }
23148       else {
23149         skipAssert(assert);
23150       }
23151     });
23152
23153     QUnit.test('should convert strings to arrays', function(assert) {
23154       assert.expect(3);
23155
23156       assert.deepEqual(_.toArray(''), []);
23157       assert.deepEqual(_.toArray('ab'), ['a', 'b']);
23158       assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
23159     });
23160
23161     QUnit.test('should work in a lazy sequence', function(assert) {
23162       assert.expect(2);
23163
23164       if (!isNpm) {
23165         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1);
23166
23167         var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
23168           return ['key' + index, index];
23169         }));
23170
23171         var actual = _(array).slice(1).map(String).toArray().value();
23172         assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
23173
23174         actual = _(object).toArray().slice(1).map(String).value();
23175         assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
23176       }
23177       else {
23178         skipAssert(assert, 2);
23179       }
23180     });
23181   }());
23182
23183   /*--------------------------------------------------------------------------*/
23184
23185   QUnit.module('lodash.toLower');
23186
23187   (function() {
23188     QUnit.test('should convert whole string to lower case', function(assert) {
23189       assert.expect(3);
23190
23191       assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
23192       assert.deepEqual(_.toLower('fooBar'), 'foobar');
23193       assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
23194     });
23195   }());
23196
23197   /*--------------------------------------------------------------------------*/
23198
23199   QUnit.module('lodash.toUpper');
23200
23201   (function() {
23202     QUnit.test('should convert whole string to upper case', function(assert) {
23203       assert.expect(3);
23204
23205       assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
23206       assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
23207       assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
23208     });
23209   }());
23210
23211   /*--------------------------------------------------------------------------*/
23212
23213   QUnit.module('lodash.slice and lodash.toArray');
23214
23215   lodashStable.each(['slice', 'toArray'], function(methodName) {
23216     var array = [1, 2, 3],
23217         func = _[methodName];
23218
23219     QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
23220       assert.expect(3);
23221
23222       var sparse = Array(3);
23223       sparse[1] = 2;
23224
23225       var actual = func(sparse);
23226
23227       assert.ok('0' in actual);
23228       assert.ok('2' in actual);
23229       assert.deepEqual(actual, sparse);
23230     });
23231
23232     QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
23233       assert.expect(2);
23234
23235       var object = { '0': 'a', 'length': 1 };
23236       assert.deepEqual(func(object), ['a']);
23237       assert.deepEqual(func(args), array);
23238     });
23239
23240     QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
23241       assert.expect(2);
23242
23243       var actual = func(array);
23244       assert.deepEqual(actual, array);
23245       assert.notStrictEqual(actual, array);
23246     });
23247
23248     QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
23249       assert.expect(1);
23250
23251       if (document) {
23252         try {
23253           var actual = func(document.getElementsByTagName('body'));
23254         } catch (e) {}
23255
23256         assert.deepEqual(actual, [body]);
23257       }
23258       else {
23259         skipAssert(assert);
23260       }
23261     });
23262   });
23263
23264   /*--------------------------------------------------------------------------*/
23265
23266   QUnit.module('toInteger methods');
23267
23268   lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
23269     var func = _[methodName],
23270         isSafe = methodName == 'toSafeInteger';
23271
23272     QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
23273       assert.expect(6);
23274
23275       assert.strictEqual(func(-5.6), -5);
23276       assert.strictEqual(func('5.6'), 5);
23277       assert.strictEqual(func(), 0);
23278       assert.strictEqual(func(NaN), 0);
23279
23280       var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
23281       assert.strictEqual(func(Infinity), expected);
23282       assert.strictEqual(func(-Infinity), -expected);
23283     });
23284
23285     QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
23286       assert.expect(1);
23287
23288       assert.strictEqual(1 / func(-0), -Infinity);
23289     });
23290   });
23291
23292   /*--------------------------------------------------------------------------*/
23293
23294   QUnit.module('lodash.toLength');
23295
23296   (function() {
23297     QUnit.test('should return a valid length', function(assert) {
23298       assert.expect(4);
23299
23300       assert.strictEqual(_.toLength(-1), 0);
23301       assert.strictEqual(_.toLength('1'), 1);
23302       assert.strictEqual(_.toLength(1.1), 1);
23303       assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
23304     });
23305
23306     QUnit.test('should return `value` if a valid length', function(assert) {
23307       assert.expect(3);
23308
23309       assert.strictEqual(_.toLength(0), 0);
23310       assert.strictEqual(_.toLength(3), 3);
23311       assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
23312     });
23313
23314     QUnit.test('should convert `-0` to `0`', function(assert) {
23315       assert.expect(1);
23316
23317       assert.strictEqual(1 / _.toLength(-0), Infinity);
23318     });
23319   }());
23320
23321   /*--------------------------------------------------------------------------*/
23322
23323   QUnit.module('number coercion methods');
23324
23325   lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
23326     var func = _[methodName];
23327
23328     QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
23329       assert.expect(2);
23330
23331       var values = [0, '0', -0, '-0'],
23332           expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
23333
23334       lodashStable.times(2, function(index) {
23335         var others = lodashStable.map(values, index ? Object : identity);
23336
23337         var actual = lodashStable.map(others, function(value) {
23338           var result = func(value);
23339           return [result, 1 / result];
23340         });
23341
23342         assert.deepEqual(actual, expected);
23343       });
23344     });
23345   });
23346
23347   lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
23348     var func = _[methodName],
23349         isToFinite = methodName == 'toFinite',
23350         isToLength = methodName == 'toLength',
23351         isToNumber = methodName == 'toNumber',
23352         isToSafeInteger = methodName == 'toSafeInteger';
23353
23354     function negative(string) {
23355       return '-' + string;
23356     }
23357
23358     function pad(string) {
23359       return whitespace + string + whitespace;
23360     }
23361
23362     function positive(string) {
23363       return '+' + string;
23364     }
23365
23366     QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
23367       assert.expect(1);
23368
23369       var values = [0, 1, NaN];
23370
23371       var expected = lodashStable.map(values, function(value) {
23372         return (!isToNumber && value !== value) ? 0 : value;
23373       });
23374
23375       var actual = lodashStable.map(values, func);
23376
23377       assert.deepEqual(actual, expected);
23378     });
23379
23380     QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
23381       assert.expect(1);
23382
23383       var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
23384
23385       var expected = lodashStable.map(values, function(value) {
23386         if (!isToNumber) {
23387           if (!isToFinite && value == 1.2) {
23388             value = 1;
23389           }
23390           else if (value == Infinity) {
23391             value = MAX_INTEGER;
23392           }
23393           else if (value !== value) {
23394             value = 0;
23395           }
23396           if (isToLength || isToSafeInteger) {
23397             value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23398           }
23399         }
23400         var neg = isToLength ? 0 : -value;
23401         return [value, value, neg, neg];
23402       });
23403
23404       var actual = lodashStable.map(values, function(value) {
23405         return [func(value), func(Object(value)), func(-value), func(Object(-value))];
23406       });
23407
23408       assert.deepEqual(actual, expected);
23409     });
23410
23411     QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
23412       assert.expect(1);
23413
23414       var transforms = [identity, pad, positive, negative];
23415
23416       var values = [
23417         '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
23418         '1e+308', '1e308', '1E+308', '1E308',
23419         '5e-324', '5E-324',
23420         'Infinity', 'NaN'
23421       ];
23422
23423       var expected = lodashStable.map(values, function(value) {
23424         var n = +value;
23425         if (!isToNumber) {
23426           if (!isToFinite && n == 1.234567890) {
23427             n = 1;
23428           }
23429           else if (n == Infinity) {
23430             n = MAX_INTEGER;
23431           }
23432           else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) {
23433             n = 0;
23434           }
23435           if (isToLength || isToSafeInteger) {
23436             n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23437           }
23438         }
23439         var neg = isToLength ? 0 : -n;
23440         return [n, n, n, n, n, n, neg, neg];
23441       });
23442
23443       var actual = lodashStable.map(values, function(value) {
23444         return lodashStable.flatMap(transforms, function(mod) {
23445           return [func(mod(value)), func(Object(mod(value)))];
23446         });
23447       });
23448
23449       assert.deepEqual(actual, expected);
23450     });
23451
23452     QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
23453       assert.expect(1);
23454
23455       var numbers = [42, 5349, 1715004],
23456           transforms = [identity, pad],
23457           values = ['0b101010', '0o12345', '0x1a2b3c'];
23458
23459       var expected = lodashStable.map(numbers, function(n) {
23460         return lodashStable.times(8, lodashStable.constant(n));
23461       });
23462
23463       var actual = lodashStable.map(values, function(value) {
23464         var upper = value.toUpperCase();
23465         return lodashStable.flatMap(transforms, function(mod) {
23466           return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
23467         });
23468       });
23469
23470       assert.deepEqual(actual, expected);
23471     });
23472
23473     QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23474       assert.expect(1);
23475
23476       var transforms = [identity, pad, positive, negative],
23477           values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
23478
23479       var expected = lodashStable.map(values, function(n) {
23480         return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
23481       });
23482
23483       var actual = lodashStable.map(values, function(value) {
23484         return lodashStable.flatMap(transforms, function(mod) {
23485           return [func(mod(value)), func(Object(mod(value)))];
23486         });
23487       });
23488
23489       assert.deepEqual(actual, expected);
23490     });
23491
23492     QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23493       assert.expect(1);
23494
23495       if (Symbol) {
23496         var object1 = Object(symbol),
23497             object2 = Object(symbol),
23498             values = [symbol, object1, object2],
23499             expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
23500
23501         object2.valueOf = undefined;
23502         var actual = lodashStable.map(values, func);
23503
23504         assert.deepEqual(actual, expected);
23505       }
23506       else {
23507         skipAssert(assert);
23508       }
23509     });
23510
23511     QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
23512       assert.expect(1);
23513
23514       var values = falsey.concat(whitespace);
23515
23516       var expected = lodashStable.map(values, function(value) {
23517         return (isToNumber && value !== whitespace) ? Number(value) : 0;
23518       });
23519
23520       var actual = lodashStable.map(values, function(value, index) {
23521         return index ? func(value) : func();
23522       });
23523
23524       assert.deepEqual(actual, expected);
23525     });
23526
23527     QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
23528       assert.expect(1);
23529
23530       var values = [
23531         {},
23532         [],
23533         [1],
23534         [1, 2],
23535         { 'valueOf': '1.1' },
23536         { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
23537         { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
23538         { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
23539         { 'valueOf': lodashStable.constant('-0x1a2b3c') },
23540         { 'toString': lodashStable.constant('-0x1a2b3c') },
23541         { 'valueOf': lodashStable.constant('0o12345') },
23542         { 'toString': lodashStable.constant('0o12345') },
23543         { 'valueOf': lodashStable.constant('0b101010') },
23544         { 'toString': lodashStable.constant('0b101010') }
23545       ];
23546
23547       var expected = [
23548         NaN,  0,   1,   NaN,
23549         NaN,  2.2, 1.1, 1.1,
23550         NaN,  NaN,
23551         5349, 5349,
23552         42,   42
23553       ];
23554
23555       if (isToFinite) {
23556         expected = [
23557           0,    0,    1,   0,
23558           0,    2.2,  1.1, 1.1,
23559           0,    0,
23560           5349, 5349,
23561           42,   42
23562         ];
23563       }
23564       else if (!isToNumber) {
23565         expected = [
23566           0,    0,    1, 0,
23567           0,    2,    1, 1,
23568           0,    0,
23569           5349, 5349,
23570           42,   42
23571         ];
23572       }
23573       var actual = lodashStable.map(values, func);
23574
23575       assert.deepEqual(actual, expected);
23576     });
23577   });
23578
23579   /*--------------------------------------------------------------------------*/
23580
23581   QUnit.module('lodash.toPairs');
23582
23583   (function() {
23584     QUnit.test('should be aliased', function(assert) {
23585       assert.expect(1);
23586
23587       assert.strictEqual(_.entries, _.toPairs);
23588     });
23589   }());
23590
23591   /*--------------------------------------------------------------------------*/
23592
23593   QUnit.module('lodash.toPairsIn');
23594
23595   (function() {
23596     QUnit.test('should be aliased', function(assert) {
23597       assert.expect(1);
23598
23599       assert.strictEqual(_.entriesIn, _.toPairsIn);
23600     });
23601   }());
23602
23603   /*--------------------------------------------------------------------------*/
23604
23605   QUnit.module('toPairs methods');
23606
23607   lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
23608     var func = _[methodName],
23609         isToPairs = methodName == 'toPairs';
23610
23611     QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
23612       assert.expect(1);
23613
23614       var object = { 'a': 1, 'b': 2 },
23615           actual = lodashStable.sortBy(func(object), 0);
23616
23617       assert.deepEqual(actual, [['a', 1], ['b', 2]]);
23618     });
23619
23620     QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
23621       assert.expect(1);
23622
23623       function Foo() {
23624         this.a = 1;
23625       }
23626       Foo.prototype.b = 2;
23627
23628       var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
23629           actual = lodashStable.sortBy(func(new Foo), 0);
23630
23631       assert.deepEqual(actual, expected);
23632     });
23633
23634     QUnit.test('`_.' + methodName + '` should convert objects with a `length` property', function(assert) {
23635       assert.expect(1);
23636
23637       var object = { '0': 'a', '1': 'b', 'length': 2 },
23638           actual = lodashStable.sortBy(func(object), 0);
23639
23640       assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
23641     });
23642
23643     QUnit.test('`_.' + methodName + '` should convert maps', function(assert) {
23644       assert.expect(1);
23645
23646       if (Map) {
23647         var map = new Map;
23648         map.set('a', 1);
23649         map.set('b', 2);
23650         assert.deepEqual(func(map), [['a', 1], ['b', 2]]);
23651       }
23652       else {
23653         skipAssert(assert);
23654       }
23655     });
23656
23657     QUnit.test('`_.' + methodName + '` should convert sets', function(assert) {
23658       assert.expect(1);
23659
23660       if (Set) {
23661         var set = new Set;
23662         set.add(1);
23663         set.add(2);
23664         assert.deepEqual(func(set), [[1, 1], [2, 2]]);
23665       }
23666       else {
23667         skipAssert(assert);
23668       }
23669     });
23670
23671     QUnit.test('`_.' + methodName + '` should convert strings', function(assert) {
23672       assert.expect(2);
23673
23674       lodashStable.each(['xo', Object('xo')], function(string) {
23675         var actual = lodashStable.sortBy(func(string), 0);
23676         assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
23677       });
23678     });
23679   });
23680
23681   /*--------------------------------------------------------------------------*/
23682
23683   QUnit.module('lodash.toPath');
23684
23685   (function() {
23686     QUnit.test('should convert a string to a path', function(assert) {
23687       assert.expect(2);
23688
23689       assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
23690       assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
23691     });
23692
23693     QUnit.test('should coerce array elements to strings', function(assert) {
23694       assert.expect(4);
23695
23696       var array = ['a', 'b', 'c'];
23697
23698       lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
23699         var actual = _.toPath(value);
23700         assert.deepEqual(actual, array);
23701         assert.notStrictEqual(actual, array);
23702       });
23703     });
23704
23705     QUnit.test('should return new path array', function(assert) {
23706       assert.expect(1);
23707
23708       assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
23709     });
23710
23711     QUnit.test('should not coerce symbols to strings', function(assert) {
23712       assert.expect(4);
23713
23714       if (Symbol) {
23715         var object = Object(symbol);
23716         lodashStable.each([symbol, object, [symbol], [object]], function(value) {
23717           var actual = _.toPath(value);
23718           assert.ok(lodashStable.isSymbol(actual[0]));
23719         });
23720       }
23721       else {
23722         skipAssert(assert, 4);
23723       }
23724     });
23725
23726     QUnit.test('should handle complex paths', function(assert) {
23727       assert.expect(1);
23728
23729       var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
23730       assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
23731     });
23732
23733     QUnit.test('should handle consecutive empty brackets and dots', function(assert) {
23734       assert.expect(12);
23735
23736       var expected = ['', 'a'];
23737       assert.deepEqual(_.toPath('.a'), expected);
23738       assert.deepEqual(_.toPath('[].a'), expected);
23739
23740       expected = ['', '', 'a'];
23741       assert.deepEqual(_.toPath('..a'), expected);
23742       assert.deepEqual(_.toPath('[][].a'), expected);
23743
23744       expected = ['a', '', 'b'];
23745       assert.deepEqual(_.toPath('a..b'), expected);
23746       assert.deepEqual(_.toPath('a[].b'), expected);
23747
23748       expected = ['a', '', '', 'b'];
23749       assert.deepEqual(_.toPath('a...b'), expected);
23750       assert.deepEqual(_.toPath('a[][].b'), expected);
23751
23752       expected = ['a', ''];
23753       assert.deepEqual(_.toPath('a.'), expected);
23754       assert.deepEqual(_.toPath('a[]'), expected);
23755
23756       expected = ['a', '', ''];
23757       assert.deepEqual(_.toPath('a..'), expected);
23758       assert.deepEqual(_.toPath('a[][]'), expected);
23759     });
23760   }());
23761
23762   /*--------------------------------------------------------------------------*/
23763
23764   QUnit.module('lodash.toPlainObject');
23765
23766   (function() {
23767     QUnit.test('should flatten inherited string keyed properties', function(assert) {
23768       assert.expect(1);
23769
23770       function Foo() {
23771         this.b = 2;
23772       }
23773       Foo.prototype.c = 3;
23774
23775       var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
23776       assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
23777     });
23778
23779     QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
23780       assert.expect(1);
23781
23782       var actual = _.toPlainObject(args),
23783           expected = { '0': 1, '1': 2, '2': 3 };
23784
23785       assert.deepEqual(actual, expected);
23786     });
23787
23788     QUnit.test('should convert arrays to plain objects', function(assert) {
23789       assert.expect(1);
23790
23791       var actual = _.toPlainObject(['a', 'b', 'c']),
23792           expected = { '0': 'a', '1': 'b', '2': 'c' };
23793
23794       assert.deepEqual(actual, expected);
23795     });
23796   }());
23797
23798   /*--------------------------------------------------------------------------*/
23799
23800   QUnit.module('lodash.toString');
23801
23802   (function() {
23803     QUnit.test('should treat nullish values as empty strings', function(assert) {
23804       assert.expect(1);
23805
23806       var values = [, null, undefined],
23807           expected = lodashStable.map(values, stubString);
23808
23809       var actual = lodashStable.map(values, function(value, index) {
23810         return index ? _.toString(value) : _.toString();
23811       });
23812
23813       assert.deepEqual(actual, expected);
23814     });
23815
23816     QUnit.test('should preserve the sign of `0`', function(assert) {
23817       assert.expect(1);
23818
23819       var values = [-0, Object(-0), 0, Object(0)],
23820           expected = ['-0', '-0', '0', '0'],
23821           actual = lodashStable.map(values, _.toString);
23822
23823       assert.deepEqual(actual, expected);
23824     });
23825
23826     QUnit.test('should preserve the sign of `0` in an array', function(assert) {
23827       assert.expect(1);
23828
23829       var values = [-0, Object(-0), 0, Object(0)];
23830       assert.deepEqual(_.toString(values), '-0,-0,0,0');
23831     });
23832
23833     QUnit.test('should not error on symbols', function(assert) {
23834       assert.expect(1);
23835
23836       if (Symbol) {
23837         try {
23838           assert.strictEqual(_.toString(symbol), 'Symbol(a)');
23839         } catch (e) {
23840           assert.ok(false, e.message);
23841         }
23842       }
23843       else {
23844         skipAssert(assert);
23845       }
23846     });
23847
23848     QUnit.test('should not error on an array of symbols', function(assert) {
23849       assert.expect(1);
23850
23851       if (Symbol) {
23852         try {
23853           assert.strictEqual(_.toString([symbol]), 'Symbol(a)');
23854         } catch (e) {
23855           assert.ok(false, e.message);
23856         }
23857       }
23858       else {
23859         skipAssert(assert);
23860       }
23861     });
23862
23863     QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
23864       assert.expect(1);
23865
23866       if (!isNpm) {
23867         var wrapped = _([1, 2, 3]);
23868         assert.strictEqual(wrapped.toString(), '1,2,3');
23869       }
23870       else {
23871         skipAssert(assert);
23872       }
23873     });
23874   }());
23875
23876   /*--------------------------------------------------------------------------*/
23877
23878   QUnit.module('lodash.transform');
23879
23880   (function() {
23881     function Foo() {
23882       this.a = 1;
23883       this.b = 2;
23884       this.c = 3;
23885     }
23886
23887     QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
23888       assert.expect(4);
23889
23890       var accumulators = [, null, undefined],
23891           object = new Foo,
23892           expected = lodashStable.map(accumulators, stubTrue);
23893
23894       var iteratee = function(result, value, key) {
23895         result[key] = square(value);
23896       };
23897
23898       var mapper = function(accumulator, index) {
23899         return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
23900       };
23901
23902       var results = lodashStable.map(accumulators, mapper);
23903
23904       var actual = lodashStable.map(results, function(result) {
23905         return result instanceof Foo;
23906       });
23907
23908       assert.deepEqual(actual, expected);
23909
23910       expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
23911       actual = lodashStable.map(results, lodashStable.toPlainObject);
23912
23913       assert.deepEqual(actual, expected);
23914
23915       object = { 'a': 1, 'b': 2, 'c': 3 };
23916       actual = lodashStable.map(accumulators, mapper);
23917
23918       assert.deepEqual(actual, expected);
23919
23920       object = [1, 2, 3];
23921       expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
23922       actual = lodashStable.map(accumulators, mapper);
23923
23924       assert.deepEqual(actual, expected);
23925     });
23926
23927     QUnit.test('should create regular arrays from typed arrays', function(assert) {
23928       assert.expect(1);
23929
23930       var expected = lodashStable.map(typedArrays, stubTrue);
23931
23932       var actual = lodashStable.map(typedArrays, function(type) {
23933         var Ctor = root[type],
23934             array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
23935
23936         return lodashStable.isArray(_.transform(array, noop));
23937       });
23938
23939       assert.deepEqual(actual, expected);
23940     });
23941
23942     QUnit.test('should support an `accumulator` value', function(assert) {
23943       assert.expect(6);
23944
23945       var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
23946           expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
23947
23948       var actual = lodashStable.map(values, function(value) {
23949         return _.transform(value, function(result, value) {
23950           result.push(square(value));
23951         }, []);
23952       });
23953
23954       assert.deepEqual(actual, expected);
23955
23956       var object = { 'a': 1, 'b': 4, 'c': 9 },
23957       expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
23958
23959       actual = lodashStable.map(values, function(value) {
23960         return _.transform(value, function(result, value, key) {
23961           result[key] = square(value);
23962         }, {});
23963       });
23964
23965       assert.deepEqual(actual, expected);
23966
23967       lodashStable.each([[], {}], function(accumulator) {
23968         var actual = lodashStable.map(values, function(value) {
23969           return _.transform(value, noop, accumulator);
23970         });
23971
23972         assert.ok(lodashStable.every(actual, function(result) {
23973           return result === accumulator;
23974         }));
23975
23976         assert.strictEqual(_.transform(null, null, accumulator), accumulator);
23977       });
23978     });
23979
23980     QUnit.test('should treat sparse arrays as dense', function(assert) {
23981       assert.expect(1);
23982
23983       var actual = _.transform(Array(1), function(result, value, index) {
23984         result[index] = String(value);
23985       });
23986
23987       assert.deepEqual(actual, ['undefined']);
23988     });
23989
23990     QUnit.test('should work without an `iteratee`', function(assert) {
23991       assert.expect(1);
23992
23993       assert.ok(_.transform(new Foo) instanceof Foo);
23994     });
23995
23996     QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
23997       assert.expect(2);
23998
23999       var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
24000           values = [false, true, 0, 1, NaN, '', 'a'],
24001           expected = lodashStable.map(values, stubObject);
24002
24003       var results = lodashStable.map(values, function(value) {
24004         return _.transform(value);
24005       });
24006
24007       assert.deepEqual(results, expected);
24008
24009       expected = lodashStable.map(values, stubFalse);
24010
24011       var actual = lodashStable.map(results, function(value, index) {
24012         return value instanceof Ctors[index];
24013       });
24014
24015       assert.deepEqual(actual, expected);
24016     });
24017
24018     QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
24019       assert.expect(1);
24020
24021       Foo.prototype.constructor = null;
24022       assert.notOk(_.transform(new Foo) instanceof Foo);
24023       Foo.prototype.constructor = Foo;
24024     });
24025
24026     QUnit.test('should create an empty object when given a falsey `object`', function(assert) {
24027       assert.expect(1);
24028
24029       var expected = lodashStable.map(falsey, stubObject);
24030
24031       var actual = lodashStable.map(falsey, function(object, index) {
24032         return index ? _.transform(object) : _.transform();
24033       });
24034
24035       assert.deepEqual(actual, expected);
24036     });
24037
24038     lodashStable.each({
24039       'array': [1, 2, 3],
24040       'object': { 'a': 1, 'b': 2, 'c': 3 }
24041     },
24042     function(object, key) {
24043       QUnit.test('should provide correct `iteratee` arguments when transforming an ' + key, function(assert) {
24044         assert.expect(2);
24045
24046         var args;
24047
24048         _.transform(object, function() {
24049           args || (args = slice.call(arguments));
24050         });
24051
24052         var first = args[0];
24053         if (key == 'array') {
24054           assert.ok(first !== object && lodashStable.isArray(first));
24055           assert.deepEqual(args, [first, 1, 0, object]);
24056         } else {
24057           assert.ok(first !== object && lodashStable.isPlainObject(first));
24058           assert.deepEqual(args, [first, 1, 'a', object]);
24059         }
24060       });
24061     });
24062
24063     QUnit.test('should create an object from the same realm as `object`', function(assert) {
24064       assert.expect(1);
24065
24066       var objects = lodashStable.filter(realm, function(value) {
24067         return lodashStable.isObject(value) && !lodashStable.isElement(value);
24068       });
24069
24070       var expected = lodashStable.map(objects, stubTrue);
24071
24072       var actual = lodashStable.map(objects, function(object) {
24073         var Ctor = object.constructor,
24074             result = _.transform(object);
24075
24076         if (result === object) {
24077           return false;
24078         }
24079         if (lodashStable.isTypedArray(object)) {
24080           return result instanceof Array;
24081         }
24082         return result instanceof Ctor || !(new Ctor instanceof Ctor);
24083       });
24084
24085       assert.deepEqual(actual, expected);
24086     });
24087   }());
24088
24089   /*--------------------------------------------------------------------------*/
24090
24091   QUnit.module('trim methods');
24092
24093   lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
24094     var func = _[methodName],
24095         parts = [];
24096
24097     if (index != 2) {
24098       parts.push('leading');
24099     }
24100     if (index != 1) {
24101       parts.push('trailing');
24102     }
24103     parts = parts.join(' and ');
24104
24105     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
24106       assert.expect(1);
24107
24108       var string = whitespace + 'a b c' + whitespace,
24109           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24110
24111       assert.strictEqual(func(string), expected);
24112     });
24113
24114     QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
24115       assert.expect(1);
24116
24117       var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
24118           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24119
24120       assert.strictEqual(func(object), expected);
24121     });
24122
24123     QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
24124       assert.expect(1);
24125
24126       var string = '-_-a-b-c-_-',
24127           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24128
24129       assert.strictEqual(func(string, '_-'), expected);
24130     });
24131
24132     QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
24133       assert.expect(1);
24134
24135       var object = { 'toString': lodashStable.constant('_-') },
24136           string = '-_-a-b-c-_-',
24137           expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24138
24139       assert.strictEqual(func(string, object), expected);
24140     });
24141
24142     QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
24143       assert.expect(6);
24144
24145       lodashStable.each([null, '_-'], function(chars) {
24146         assert.strictEqual(func(null, chars), '');
24147         assert.strictEqual(func(undefined, chars), '');
24148         assert.strictEqual(func('', chars), '');
24149       });
24150     });
24151
24152     QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
24153       assert.expect(2);
24154
24155       var string = whitespace + 'a b c' + whitespace,
24156           expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24157
24158       assert.strictEqual(func(string, undefined), expected);
24159       assert.strictEqual(func(string, ''), string);
24160     });
24161
24162     QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
24163       assert.expect(1);
24164
24165       var string = Object(whitespace + 'a b c' + whitespace),
24166           trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
24167           actual = lodashStable.map([string, string, string], func);
24168
24169       assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
24170     });
24171
24172     QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
24173       assert.expect(1);
24174
24175       if (!isNpm) {
24176         var string = whitespace + 'a b c' + whitespace,
24177             expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24178
24179         assert.strictEqual(_(string)[methodName](), expected);
24180       }
24181       else {
24182         skipAssert(assert);
24183       }
24184     });
24185
24186     QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
24187       assert.expect(1);
24188
24189       if (!isNpm) {
24190         var string = whitespace + 'a b c' + whitespace;
24191         assert.ok(_(string).chain()[methodName]() instanceof _);
24192       }
24193       else {
24194         skipAssert(assert);
24195       }
24196     });
24197   });
24198
24199   /*--------------------------------------------------------------------------*/
24200
24201   QUnit.module('uncommon symbols');
24202
24203   (function() {
24204     var flag = '\ud83c\uddfa\ud83c\uddf8',
24205         heart = '\u2764' + emojiVar,
24206         hearts = '\ud83d\udc95',
24207         comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
24208         hashKeycap = '#' + emojiVar + '\u20e3',
24209         leafs = '\ud83c\udf42',
24210         mic = '\ud83c\udf99',
24211         noMic = mic + '\u20e0',
24212         raisedHand = '\u270B' + emojiVar,
24213         rocket = '\ud83d\ude80',
24214         thumbsUp = '\ud83d\udc4d';
24215
24216     QUnit.test('should account for astral symbols', function(assert) {
24217       assert.expect(34);
24218
24219       var allHearts = _.repeat(hearts, 10),
24220           chars = hearts + comboGlyph,
24221           string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
24222           trimChars = comboGlyph + hearts,
24223           trimString = trimChars + string + trimChars;
24224
24225       assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
24226       assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
24227       assert.strictEqual(_.capitalize(rocket), rocket);
24228
24229       assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
24230       assert.strictEqual(_.padStart(string, 16), '   ' + string);
24231       assert.strictEqual(_.padEnd(string, 16), string + '   ');
24232
24233       assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
24234       assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
24235       assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
24236
24237       assert.strictEqual(_.size(string), 13);
24238       assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
24239       assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
24240       assert.deepEqual(_.split(string, undefined), [string]);
24241       assert.deepEqual(_.split(string, undefined, -1), [string]);
24242       assert.deepEqual(_.split(string, undefined, 0), []);
24243
24244       var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
24245
24246       assert.deepEqual(_.split(string, ''), expected);
24247       assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
24248       assert.deepEqual(_.toArray(string), expected);
24249
24250       assert.strictEqual(_.trim(trimString, chars), string);
24251       assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
24252       assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
24253
24254       assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
24255       assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
24256
24257       assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
24258       assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
24259       assert.deepEqual(_.toArray(noMic), [noMic]);
24260
24261       lodashStable.times(2, function(index) {
24262         var separator = index ? RegExp(hearts) : hearts,
24263             options = { 'length': 4, 'separator': separator },
24264             actual = _.truncate(string, options);
24265
24266         assert.strictEqual(actual, 'A...');
24267         assert.strictEqual(actual.length, 4);
24268
24269         actual = _.truncate(allHearts, options);
24270         assert.strictEqual(actual, hearts + '...');
24271         assert.strictEqual(actual.length, 5);
24272       });
24273     });
24274
24275     QUnit.test('should account for combining diacritical marks', function(assert) {
24276       assert.expect(1);
24277
24278       var values = lodashStable.map(comboMarks, function(mark) {
24279         return 'o' + mark;
24280       });
24281
24282       var expected = lodashStable.map(values, function(value) {
24283         return [1, [value], [value]];
24284       });
24285
24286       var actual = lodashStable.map(values, function(value) {
24287         return [_.size(value), _.toArray(value), _.words(value)];
24288       });
24289
24290       assert.deepEqual(actual, expected);
24291     });
24292
24293     QUnit.test('should account for fitzpatrick modifiers', function(assert) {
24294       assert.expect(1);
24295
24296       var values = lodashStable.map(fitzModifiers, function(modifier) {
24297         return thumbsUp + modifier;
24298       });
24299
24300       var expected = lodashStable.map(values, function(value) {
24301         return [1, [value], [value]];
24302       });
24303
24304       var actual = lodashStable.map(values, function(value) {
24305         return [_.size(value), _.toArray(value), _.words(value)];
24306       });
24307
24308       assert.deepEqual(actual, expected);
24309     });
24310
24311     QUnit.test('should account for regional symbols', function(assert) {
24312       assert.expect(6);
24313
24314       var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
24315           regionals = pair.join(' ');
24316
24317       assert.strictEqual(_.size(flag), 1);
24318       assert.strictEqual(_.size(regionals), 3);
24319
24320       assert.deepEqual(_.toArray(flag), [flag]);
24321       assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
24322
24323       assert.deepEqual(_.words(flag), [flag]);
24324       assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
24325     });
24326
24327     QUnit.test('should account for variation selectors', function(assert) {
24328       assert.expect(3);
24329
24330       assert.strictEqual(_.size(heart), 1);
24331       assert.deepEqual(_.toArray(heart), [heart]);
24332       assert.deepEqual(_.words(heart), [heart]);
24333     });
24334
24335     QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
24336       assert.expect(1);
24337
24338       var values = lodashStable.map(fitzModifiers, function(modifier) {
24339         return raisedHand + modifier;
24340       });
24341
24342       var expected = lodashStable.map(values, function(value) {
24343         return [1, [value], [value]];
24344       });
24345
24346       var actual = lodashStable.map(values, function(value) {
24347         return [_.size(value), _.toArray(value), _.words(value)];
24348       });
24349
24350       assert.deepEqual(actual, expected);
24351     });
24352
24353     QUnit.test('should match lone surrogates', function(assert) {
24354       assert.expect(3);
24355
24356       var pair = hearts.split(''),
24357           surrogates = pair[0] + ' ' + pair[1];
24358
24359       assert.strictEqual(_.size(surrogates), 3);
24360       assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
24361       assert.deepEqual(_.words(surrogates), []);
24362     });
24363
24364     QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
24365       assert.expect(1);
24366
24367       var string = fitzModifiers[0] + fitzModifiers[0];
24368       assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
24369     });
24370   }());
24371
24372   /*--------------------------------------------------------------------------*/
24373
24374   QUnit.module('lodash.unary');
24375
24376   (function() {
24377     function fn() {
24378       return slice.call(arguments);
24379     }
24380
24381     QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
24382       assert.expect(1);
24383
24384       var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
24385       assert.deepEqual(actual, [6, 8, 10]);
24386     });
24387
24388     QUnit.test('should not force a minimum argument count', function(assert) {
24389       assert.expect(1);
24390
24391       var capped = _.unary(fn);
24392       assert.deepEqual(capped(), []);
24393     });
24394
24395     QUnit.test('should use `this` binding of function', function(assert) {
24396       assert.expect(1);
24397
24398       var capped = _.unary(function(a, b) { return this; }),
24399           object = { 'capped': capped };
24400
24401       assert.strictEqual(object.capped(), object);
24402     });
24403   }());
24404
24405   /*--------------------------------------------------------------------------*/
24406
24407   QUnit.module('lodash.unescape');
24408
24409   (function() {
24410     var escaped = '&amp;&lt;&gt;&quot;&#39;/',
24411         unescaped = '&<>"\'/';
24412
24413     escaped += escaped;
24414     unescaped += unescaped;
24415
24416     QUnit.test('should unescape entities in order', function(assert) {
24417       assert.expect(1);
24418
24419       assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
24420     });
24421
24422     QUnit.test('should unescape the proper entities', function(assert) {
24423       assert.expect(1);
24424
24425       assert.strictEqual(_.unescape(escaped), unescaped);
24426     });
24427
24428     QUnit.test('should handle strings with nothing to unescape', function(assert) {
24429       assert.expect(1);
24430
24431       assert.strictEqual(_.unescape('abc'), 'abc');
24432     });
24433
24434     QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
24435       assert.expect(1);
24436
24437       assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
24438     });
24439
24440     lodashStable.each(['&#96;', '&#x2F;'], function(entity) {
24441       QUnit.test('should not unescape the "' + entity + '" entity', function(assert) {
24442         assert.expect(1);
24443
24444         assert.strictEqual(_.unescape(entity), entity);
24445       });
24446     });
24447   }());
24448
24449   /*--------------------------------------------------------------------------*/
24450
24451   QUnit.module('union methods');
24452
24453   lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
24454     var func = _[methodName];
24455
24456     QUnit.test('`_.' + methodName + '` should return the union of two arrays', function(assert) {
24457       assert.expect(1);
24458
24459       var actual = func([2], [1, 2]);
24460       assert.deepEqual(actual, [2, 1]);
24461     });
24462
24463     QUnit.test('`_.' + methodName + '` should return the union of multiple arrays', function(assert) {
24464       assert.expect(1);
24465
24466       var actual = func([2], [1, 2], [2, 3]);
24467       assert.deepEqual(actual, [2, 1, 3]);
24468     });
24469
24470     QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
24471       assert.expect(1);
24472
24473       var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
24474       assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
24475     });
24476
24477     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24478       assert.expect(3);
24479
24480       var array = [0];
24481       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24482       assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
24483       assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
24484     });
24485   });
24486
24487   /*--------------------------------------------------------------------------*/
24488
24489   QUnit.module('lodash.unionBy');
24490
24491   (function() {
24492     QUnit.test('should accept an `iteratee`', function(assert) {
24493       assert.expect(2);
24494
24495       var actual = _.unionBy([2.1], [1.2, 2.3], Math.floor);
24496       assert.deepEqual(actual, [2.1, 1.2]);
24497
24498       actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
24499       assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
24500     });
24501
24502     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
24503       assert.expect(1);
24504
24505       var args;
24506
24507       _.unionBy([2.1], [1.2, 2.3], function() {
24508         args || (args = slice.call(arguments));
24509       });
24510
24511       assert.deepEqual(args, [2.1]);
24512     });
24513
24514     QUnit.test('should output values from the first possible array', function(assert) {
24515       assert.expect(1);
24516
24517       var actual = _.unionBy([{ 'x': 1, 'y': 1 }], [{ 'x': 1, 'y': 2 }], 'x');
24518       assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]);
24519     });
24520   }());
24521
24522   /*--------------------------------------------------------------------------*/
24523
24524   QUnit.module('lodash.unionWith');
24525
24526   (function() {
24527     QUnit.test('should work with a `comparator`', function(assert) {
24528       assert.expect(1);
24529
24530       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
24531           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
24532           actual = _.unionWith(objects, others, lodashStable.isEqual);
24533
24534       assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
24535     });
24536
24537     QUnit.test('should output values from the first possible array', function(assert) {
24538       assert.expect(1);
24539
24540       var objects = [{ 'x': 1, 'y': 1 }],
24541           others = [{ 'x': 1, 'y': 2 }];
24542
24543       var actual = _.unionWith(objects, others, function(a, b) {
24544         return a.x == b.x;
24545       });
24546
24547       assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]);
24548     });
24549   }());
24550
24551   /*--------------------------------------------------------------------------*/
24552
24553   QUnit.module('uniq methods');
24554
24555   lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
24556     var func = _[methodName],
24557         isSorted = /^sorted/.test(methodName),
24558         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24559
24560     if (isSorted) {
24561       objects = _.sortBy(objects, 'a');
24562     }
24563     else {
24564       QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
24565         assert.expect(1);
24566
24567         var array = [2, 1, 2];
24568         assert.deepEqual(func(array), [2, 1]);
24569       });
24570     }
24571     QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
24572       assert.expect(1);
24573
24574       var array = [1, 2, 2];
24575       assert.deepEqual(func(array), [1, 2]);
24576     });
24577
24578     QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
24579       assert.expect(1);
24580
24581       assert.deepEqual(func(objects), objects);
24582     });
24583
24584     QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
24585       assert.expect(1);
24586
24587       var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
24588       assert.deepEqual(actual, ['0']);
24589     });
24590
24591     QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
24592       assert.expect(1);
24593
24594       assert.deepEqual(func([NaN, NaN]), [NaN]);
24595     });
24596
24597     QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
24598       assert.expect(1);
24599
24600       var largeArray = [],
24601           expected = [0, {}, 'a'],
24602           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24603
24604       lodashStable.each(expected, function(value) {
24605         lodashStable.times(count, function() {
24606           largeArray.push(value);
24607         });
24608       });
24609
24610       assert.deepEqual(func(largeArray), expected);
24611     });
24612
24613     QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
24614       assert.expect(1);
24615
24616       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24617         return isEven(index) ? -0 : 0;
24618       });
24619
24620       var actual = lodashStable.map(func(largeArray), lodashStable.toString);
24621       assert.deepEqual(actual, ['0']);
24622     });
24623
24624     QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
24625       assert.expect(1);
24626
24627       var largeArray = [],
24628           expected = [null, undefined, false, true, NaN],
24629           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24630
24631       lodashStable.each(expected, function(value) {
24632         lodashStable.times(count, function() {
24633           largeArray.push(value);
24634         });
24635       });
24636
24637       assert.deepEqual(func(largeArray), expected);
24638     });
24639
24640     QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
24641       assert.expect(1);
24642
24643       if (Symbol) {
24644         var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
24645         assert.deepEqual(func(largeArray), largeArray);
24646       }
24647       else {
24648         skipAssert(assert);
24649       }
24650     });
24651
24652     QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
24653       assert.expect(1);
24654
24655       // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
24656       if (Symbol) {
24657         var expected = [
24658           Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
24659           Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
24660           Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
24661         ];
24662
24663         var largeArray = [],
24664             count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24665
24666         expected = lodashStable.map(expected, function(symbol) {
24667           return symbol || {};
24668         });
24669
24670         lodashStable.each(expected, function(value) {
24671           lodashStable.times(count, function() {
24672             largeArray.push(value);
24673           });
24674         });
24675
24676         assert.deepEqual(func(largeArray), expected);
24677       }
24678       else {
24679         skipAssert(assert);
24680       }
24681     });
24682
24683     QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
24684       assert.expect(1);
24685
24686       var largeArray = [],
24687           expected = ['2', 2, Object('2'), Object(2)],
24688           count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24689
24690       lodashStable.each(expected, function(value) {
24691         lodashStable.times(count, function() {
24692           largeArray.push(value);
24693         });
24694       });
24695
24696       assert.deepEqual(func(largeArray), expected);
24697     });
24698   });
24699
24700   /*--------------------------------------------------------------------------*/
24701
24702   QUnit.module('lodash.uniq');
24703
24704   (function() {
24705     QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
24706       assert.expect(1);
24707
24708       var array = [[2, 1, 2], [1, 2, 1]],
24709           actual = lodashStable.map(array, lodashStable.uniq);
24710
24711       assert.deepEqual(actual, [[2, 1], [1, 2]]);
24712     });
24713   }());
24714
24715   /*--------------------------------------------------------------------------*/
24716
24717   QUnit.module('uniqBy methods');
24718
24719   lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
24720     var func = _[methodName],
24721         isSorted = methodName == 'sortedUniqBy',
24722         objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24723
24724     if (isSorted) {
24725       objects = _.sortBy(objects, 'a');
24726     }
24727     QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) {
24728       assert.expect(1);
24729
24730       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
24731
24732       var actual = func(objects, function(object) {
24733         return object.a;
24734       });
24735
24736       assert.deepEqual(actual, expected);
24737     });
24738
24739     QUnit.test('should work with large arrays', function(assert) {
24740       assert.expect(2);
24741
24742       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
24743         return [1, 2];
24744       });
24745
24746       var actual = func(largeArray, String);
24747       assert.strictEqual(actual[0], largeArray[0]);
24748       assert.deepEqual(actual, [[1, 2]]);
24749     });
24750
24751     QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) {
24752       assert.expect(1);
24753
24754       var args;
24755
24756       func(objects, function() {
24757         args || (args = slice.call(arguments));
24758       });
24759
24760       assert.deepEqual(args, [objects[0]]);
24761     });
24762
24763     QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
24764       assert.expect(2);
24765
24766       var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
24767           actual = func(objects, 'a');
24768
24769       assert.deepEqual(actual, expected);
24770
24771       var arrays = [[2], [3], [1], [2], [3], [1]];
24772       if (isSorted) {
24773         arrays = lodashStable.sortBy(arrays, 0);
24774       }
24775       expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
24776       actual = func(arrays, 0);
24777
24778       assert.deepEqual(actual, expected);
24779     });
24780
24781     lodashStable.each({
24782       'an array': [0, 'a'],
24783       'an object': { '0': 'a' },
24784       'a number': 0,
24785       'a string': '0'
24786     },
24787     function(iteratee, key) {
24788       QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
24789         assert.expect(1);
24790
24791         var actual = func([['a'], ['a'], ['b']], iteratee);
24792         assert.deepEqual(actual, [['a'], ['b']]);
24793       });
24794     });
24795   });
24796
24797   /*--------------------------------------------------------------------------*/
24798
24799   QUnit.module('lodash.uniqWith');
24800
24801   (function() {
24802     QUnit.test('should work with a `comparator`', function(assert) {
24803       assert.expect(1);
24804
24805       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }],
24806           actual = _.uniqWith(objects, lodashStable.isEqual);
24807
24808       assert.deepEqual(actual, [objects[0], objects[1]]);
24809     });
24810
24811     QUnit.test('should preserve the sign of `0`', function(assert) {
24812       assert.expect(1);
24813
24814       var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24815         return isEven(index) ? -0 : 0;
24816       });
24817
24818       var arrays = [[-0, 0], largeArray],
24819           expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
24820
24821       var actual = lodashStable.map(arrays, function(array) {
24822         return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
24823       });
24824
24825       assert.deepEqual(actual, expected);
24826     });
24827   }());
24828
24829   /*--------------------------------------------------------------------------*/
24830
24831   QUnit.module('lodash.uniqueId');
24832
24833   (function() {
24834     QUnit.test('should generate unique ids', function(assert) {
24835       assert.expect(1);
24836
24837       var actual = lodashStable.times(1000, function(assert) {
24838         return _.uniqueId();
24839       });
24840
24841       assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
24842     });
24843
24844     QUnit.test('should return a string value when not providing a `prefix`', function(assert) {
24845       assert.expect(1);
24846
24847       assert.strictEqual(typeof _.uniqueId(), 'string');
24848     });
24849
24850     QUnit.test('should coerce the prefix argument to a string', function(assert) {
24851       assert.expect(1);
24852
24853       var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
24854       assert.ok(/3\d+,2\d+,1\d+/.test(actual));
24855     });
24856   }());
24857
24858   /*--------------------------------------------------------------------------*/
24859
24860   QUnit.module('lodash.unset');
24861
24862   (function() {
24863     QUnit.test('should unset property values', function(assert) {
24864       assert.expect(4);
24865
24866       lodashStable.each(['a', ['a']], function(path) {
24867         var object = { 'a': 1, 'c': 2 };
24868         assert.strictEqual(_.unset(object, path), true);
24869         assert.deepEqual(object, { 'c': 2 });
24870       });
24871     });
24872
24873     QUnit.test('should preserve the sign of `0`', function(assert) {
24874       assert.expect(1);
24875
24876       var props = [-0, Object(-0), 0, Object(0)],
24877           expected = lodashStable.map(props, lodashStable.constant([true, false]));
24878
24879       var actual = lodashStable.map(props, function(key) {
24880         var object = { '-0': 'a', '0': 'b' };
24881         return [_.unset(object, key), lodashStable.toString(key) in object];
24882       });
24883
24884       assert.deepEqual(actual, expected);
24885     });
24886
24887     QUnit.test('should unset symbol keyed property values', function(assert) {
24888       assert.expect(2);
24889
24890       if (Symbol) {
24891         var object = {};
24892         object[symbol] = 1;
24893
24894         assert.strictEqual(_.unset(object, symbol), true);
24895         assert.notOk(symbol in object);
24896       }
24897       else {
24898         skipAssert(assert, 2);
24899       }
24900     });
24901
24902     QUnit.test('should unset deep property values', function(assert) {
24903       assert.expect(4);
24904
24905       lodashStable.each(['a.b', ['a', 'b']], function(path) {
24906         var object = { 'a': { 'b': null } };
24907         assert.strictEqual(_.unset(object, path), true);
24908         assert.deepEqual(object, { 'a': {} });
24909       });
24910     });
24911
24912     QUnit.test('should handle complex paths', function(assert) {
24913       assert.expect(4);
24914
24915       var paths = [
24916         'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
24917         ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
24918       ];
24919
24920       lodashStable.each(paths, function(path) {
24921         var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
24922         assert.strictEqual(_.unset(object, path), true);
24923         assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
24924       });
24925     });
24926
24927     QUnit.test('should return `true` for nonexistent paths', function(assert) {
24928       assert.expect(5);
24929
24930       var object = { 'a': { 'b': { 'c': null } } };
24931
24932       lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
24933         assert.strictEqual(_.unset(object, path), true);
24934       });
24935
24936       assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
24937     });
24938
24939     QUnit.test('should not error when `object` is nullish', function(assert) {
24940       assert.expect(1);
24941
24942       var values = [null, undefined],
24943           expected = [[true, true], [true, true]];
24944
24945       var actual = lodashStable.map(values, function(value) {
24946         try {
24947           return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
24948         } catch (e) {
24949           return e.message;
24950         }
24951       });
24952
24953       assert.deepEqual(actual, expected);
24954     });
24955
24956     QUnit.test('should follow `path` over non-plain objects', function(assert) {
24957       assert.expect(8);
24958
24959       var object = { 'a': '' },
24960           paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
24961
24962       lodashStable.each(paths, function(path) {
24963         numberProto.a = 1;
24964
24965         var actual = _.unset(0, path);
24966         assert.strictEqual(actual, true);
24967         assert.notOk('a' in numberProto);
24968
24969         delete numberProto.a;
24970       });
24971
24972       lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
24973         stringProto.replace.b = 1;
24974
24975         var actual = _.unset(object, path);
24976         assert.strictEqual(actual, true);
24977         assert.notOk('a' in stringProto.replace);
24978
24979         delete stringProto.replace.b;
24980       });
24981     });
24982
24983     QUnit.test('should return `false` for non-configurable properties', function(assert) {
24984       assert.expect(1);
24985
24986       var object = {};
24987
24988       if (!isStrict) {
24989         defineProperty(object, 'a', {
24990           'configurable': false,
24991           'enumerable': true,
24992           'writable': true,
24993           'value': 1,
24994         });
24995         assert.strictEqual(_.unset(object, 'a'), false);
24996       }
24997       else {
24998         skipAssert(assert);
24999       }
25000     });
25001   }());
25002
25003   /*--------------------------------------------------------------------------*/
25004
25005   QUnit.module('lodash.unzipWith');
25006
25007   (function() {
25008     QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
25009       assert.expect(1);
25010
25011       var array = [[1, 4], [2, 5], [3, 6]];
25012
25013       var actual = _.unzipWith(array, function(a, b, c) {
25014         return a + b + c;
25015       });
25016
25017       assert.deepEqual(actual, [6, 15]);
25018     });
25019
25020     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25021       assert.expect(1);
25022
25023       var args;
25024
25025       _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
25026         args || (args = slice.call(arguments));
25027       });
25028
25029       assert.deepEqual(args, [1, 2]);
25030     });
25031
25032     QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
25033       assert.expect(1);
25034
25035       var array = [[1, 3], [2, 4]],
25036           values = [, null, undefined],
25037           expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
25038
25039       var actual = lodashStable.map(values, function(value, index) {
25040         return index ? _.unzipWith(array, value) : _.unzipWith(array);
25041       });
25042
25043       assert.deepEqual(actual, expected);
25044     });
25045   }());
25046
25047   /*--------------------------------------------------------------------------*/
25048
25049   QUnit.module('lodash.updateWith');
25050
25051   (function() {
25052     QUnit.test('should work with a `customizer` callback', function(assert) {
25053       assert.expect(1);
25054
25055       var actual = _.updateWith({ '0': {} }, '[0][1][2]', stubThree, function(value) {
25056         return lodashStable.isObject(value) ? undefined : {};
25057       });
25058
25059       assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
25060     });
25061
25062     QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
25063       assert.expect(1);
25064
25065       var actual = _.updateWith({}, 'a[0].b.c', stubFour, noop);
25066       assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
25067     });
25068   }());
25069
25070   /*--------------------------------------------------------------------------*/
25071
25072   QUnit.module('update methods');
25073
25074   lodashStable.each(['update', 'updateWith'], function(methodName) {
25075     var func = _[methodName],
25076         oldValue = 1;
25077
25078     QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
25079       assert.expect(4);
25080
25081       var object = { 'a': [{ 'b': { 'c': oldValue } }] },
25082           expected = oldValue + 1;
25083
25084       lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
25085         func(object, path, function(n) {
25086           assert.strictEqual(n, oldValue);
25087           return ++n;
25088         });
25089
25090         assert.strictEqual(object.a[0].b.c, expected);
25091         object.a[0].b.c = oldValue;
25092       });
25093     });
25094   });
25095
25096   /*--------------------------------------------------------------------------*/
25097
25098   QUnit.module('lodash.upperCase');
25099
25100   (function() {
25101     QUnit.test('should uppercase as space-separated words', function(assert) {
25102       assert.expect(3);
25103
25104       assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
25105       assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
25106       assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
25107     });
25108   }());
25109
25110   /*--------------------------------------------------------------------------*/
25111
25112   QUnit.module('lodash.upperFirst');
25113
25114   (function() {
25115     QUnit.test('should uppercase only the first character', function(assert) {
25116       assert.expect(3);
25117
25118       assert.strictEqual(_.upperFirst('fred'), 'Fred');
25119       assert.strictEqual(_.upperFirst('Fred'), 'Fred');
25120       assert.strictEqual(_.upperFirst('FRED'), 'FRED');
25121     });
25122   }());
25123
25124   /*--------------------------------------------------------------------------*/
25125
25126   QUnit.module('values methods');
25127
25128   lodashStable.each(['values', 'valuesIn'], function(methodName) {
25129     var func = _[methodName],
25130         isValues = methodName == 'values';
25131
25132     QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
25133       assert.expect(1);
25134
25135       var object = { 'a': 1, 'b': 2 },
25136           actual = func(object).sort();
25137
25138       assert.deepEqual(actual, [1, 2]);
25139     });
25140
25141     QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
25142       assert.expect(1);
25143
25144       var object = { '0': 'a', '1': 'b', 'length': 2 },
25145           actual = func(object).sort();
25146
25147       assert.deepEqual(actual, [2, 'a', 'b']);
25148     });
25149
25150     QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
25151       assert.expect(1);
25152
25153       function Foo() {
25154         this.a = 1;
25155       }
25156       Foo.prototype.b = 2;
25157
25158       var expected = isValues ? [1] : [1, 2],
25159           actual = func(new Foo).sort();
25160
25161       assert.deepEqual(actual, expected);
25162     });
25163
25164     QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
25165       assert.expect(1);
25166
25167       var values = [args, strictArgs],
25168           expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
25169
25170       var actual = lodashStable.map(values, function(value) {
25171         return func(value).sort();
25172       });
25173
25174       assert.deepEqual(actual, expected);
25175     });
25176   });
25177
25178   /*--------------------------------------------------------------------------*/
25179
25180   QUnit.module('lodash.without');
25181
25182   (function() {
25183     QUnit.test('should return the difference of values', function(assert) {
25184       assert.expect(1);
25185
25186       var actual = _.without([2, 1, 2, 3], 1, 2);
25187       assert.deepEqual(actual, [3]);
25188     });
25189
25190     QUnit.test('should use strict equality to determine the values to reject', function(assert) {
25191       assert.expect(2);
25192
25193       var object1 = { 'a': 1 },
25194           object2 = { 'b': 2 },
25195           array = [object1, object2];
25196
25197       assert.deepEqual(_.without(array, { 'a': 1 }), array);
25198       assert.deepEqual(_.without(array, object1), [object2]);
25199     });
25200
25201     QUnit.test('should remove all occurrences of each value from an array', function(assert) {
25202       assert.expect(1);
25203
25204       var array = [1, 2, 3, 1, 2, 3];
25205       assert.deepEqual(_.without(array, 1, 2), [3, 3]);
25206     });
25207   }());
25208
25209   /*--------------------------------------------------------------------------*/
25210
25211   QUnit.module('lodash.words');
25212
25213   (function() {
25214     QUnit.test('should match words containing Latin Unicode letters', function(assert) {
25215       assert.expect(1);
25216
25217       var expected = lodashStable.map(burredLetters, function(letter) {
25218         return [letter];
25219       });
25220
25221       var actual = lodashStable.map(burredLetters, function(letter) {
25222         return _.words(letter);
25223       });
25224
25225       assert.deepEqual(actual, expected);
25226     });
25227
25228     QUnit.test('should support a `pattern`', function(assert) {
25229       assert.expect(2);
25230
25231       assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
25232       assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
25233     });
25234
25235     QUnit.test('should work with compound words', function(assert) {
25236       assert.expect(12);
25237
25238       assert.deepEqual(_.words('12ft'), ['12', 'ft']);
25239       assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
25240       assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
25241       assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
25242       assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
25243       assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
25244       assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
25245       assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
25246       assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
25247       assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
25248       assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
25249       assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
25250     });
25251
25252     QUnit.test('should work with compound words containing diacritical marks', function(assert) {
25253       assert.expect(3);
25254
25255       assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
25256       assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
25257       assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
25258     });
25259
25260     QUnit.test('should not treat contractions as separate words', function(assert) {
25261       assert.expect(4);
25262
25263       var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
25264
25265       lodashStable.each(["'", '\u2019'], function(apos) {
25266         lodashStable.times(2, function(index) {
25267           var actual = lodashStable.map(postfixes, function(postfix) {
25268             var string = 'a b' + apos + postfix +  ' c';
25269             return _.words(string[index ? 'toUpperCase' : 'toLowerCase']());
25270           });
25271
25272           var expected = lodashStable.map(postfixes, function(postfix) {
25273             var words = ['a', 'b' + apos + postfix, 'c'];
25274             return lodashStable.map(words, function(word) {
25275               return word[index ? 'toUpperCase' : 'toLowerCase']();
25276             });
25277           });
25278
25279           assert.deepEqual(actual, expected);
25280         });
25281       });
25282     });
25283
25284     QUnit.test('should not treat ordinal numbers as separate words', function(assert) {
25285       assert.expect(2);
25286
25287       var ordinals = ['1st', '2nd', '3rd', '4th'];
25288
25289       lodashStable.times(2, function(index) {
25290         var expected = lodashStable.map(ordinals, function(ordinal) {
25291           return [ordinal[index ? 'toUpperCase' : 'toLowerCase']()];
25292         });
25293
25294         var actual = lodashStable.map(expected, function(words) {
25295           return _.words(words[0]);
25296         });
25297
25298         assert.deepEqual(actual, expected);
25299       });
25300     });
25301
25302     QUnit.test('should not treat mathematical operators as words', function(assert) {
25303       assert.expect(1);
25304
25305       var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
25306           expected = lodashStable.map(operators, stubArray),
25307           actual = lodashStable.map(operators, _.words);
25308
25309       assert.deepEqual(actual, expected);
25310     });
25311
25312     QUnit.test('should not treat punctuation as words', function(assert) {
25313       assert.expect(1);
25314
25315       var marks = [
25316         '\u2012', '\u2013', '\u2014', '\u2015',
25317         '\u2024', '\u2025', '\u2026',
25318         '\u205d', '\u205e'
25319       ];
25320
25321       var expected = lodashStable.map(marks, stubArray),
25322           actual = lodashStable.map(marks, _.words);
25323
25324       assert.deepEqual(actual, expected);
25325     });
25326
25327     QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
25328       assert.expect(1);
25329
25330       var strings = lodashStable.map(['a', 'b', 'c'], Object),
25331           actual = lodashStable.map(strings, _.words);
25332
25333       assert.deepEqual(actual, [['a'], ['b'], ['c']]);
25334     });
25335   }());
25336
25337   /*--------------------------------------------------------------------------*/
25338
25339   QUnit.module('lodash.wrap');
25340
25341   (function() {
25342     QUnit.test('should create a wrapped function', function(assert) {
25343       assert.expect(1);
25344
25345       var p = _.wrap(lodashStable.escape, function(func, text) {
25346         return '<p>' + func(text) + '</p>';
25347       });
25348
25349       assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
25350     });
25351
25352     QUnit.test('should provide correct `wrapper` arguments', function(assert) {
25353       assert.expect(1);
25354
25355       var args;
25356
25357       var wrapped = _.wrap(noop, function() {
25358         args || (args = slice.call(arguments));
25359       });
25360
25361       wrapped(1, 2, 3);
25362       assert.deepEqual(args, [noop, 1, 2, 3]);
25363     });
25364
25365     QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
25366       assert.expect(1);
25367
25368       var values = [, null, undefined],
25369           expected = lodashStable.map(values, stubA);
25370
25371       var actual = lodashStable.map(values, function(value, index) {
25372         var wrapped = index ? _.wrap('a', value) : _.wrap('a');
25373         return wrapped('b', 'c');
25374       });
25375
25376       assert.deepEqual(actual, expected);
25377     });
25378
25379     QUnit.test('should use `this` binding of function', function(assert) {
25380       assert.expect(1);
25381
25382       var p = _.wrap(lodashStable.escape, function(func) {
25383         return '<p>' + func(this.text) + '</p>';
25384       });
25385
25386       var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
25387       assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
25388     });
25389   }());
25390
25391   /*--------------------------------------------------------------------------*/
25392
25393   QUnit.module('xor methods');
25394
25395   lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
25396     var func = _[methodName];
25397
25398     QUnit.test('`_.' + methodName + '` should return the symmetric difference of two arrays', function(assert) {
25399       assert.expect(1);
25400
25401       var actual = func([2, 1], [2, 3]);
25402       assert.deepEqual(actual, [1, 3]);
25403     });
25404
25405     QUnit.test('`_.' + methodName + '` should return the symmetric difference of multiple arrays', function(assert) {
25406       assert.expect(2);
25407
25408       var actual = func([2, 1], [2, 3], [3, 4]);
25409       assert.deepEqual(actual, [1, 4]);
25410
25411       actual = func([1, 2], [2, 1], [1, 2]);
25412       assert.deepEqual(actual, []);
25413     });
25414
25415     QUnit.test('`_.' + methodName + '` should return an empty array when comparing the same array', function(assert) {
25416       assert.expect(1);
25417
25418       var array = [1],
25419           actual = func(array, array, array);
25420
25421       assert.deepEqual(actual, []);
25422     });
25423
25424     QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
25425       assert.expect(2);
25426
25427       var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
25428       assert.deepEqual(actual, [1, 4]);
25429
25430       actual = func([1, 1]);
25431       assert.deepEqual(actual, [1]);
25432     });
25433
25434     QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
25435       assert.expect(1);
25436
25437       var array = [1];
25438       assert.notStrictEqual(func(array), array);
25439     });
25440
25441     QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
25442       assert.expect(1);
25443
25444       var array = [0];
25445       assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
25446     });
25447
25448     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25449       assert.expect(3);
25450
25451       var array = [1, 2];
25452       assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
25453       assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
25454       assert.deepEqual(func(array, null, args, null), [3]);
25455     });
25456
25457     QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
25458       assert.expect(1);
25459
25460       if (!isNpm) {
25461         var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
25462         assert.ok(wrapped instanceof _);
25463       }
25464       else {
25465         skipAssert(assert);
25466       }
25467     });
25468
25469     QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
25470       assert.expect(1);
25471
25472       if (!isNpm) {
25473         var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
25474             wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
25475
25476         var actual = lodashStable.map(['head', 'last'], function(methodName) {
25477           return wrapped[methodName]();
25478         });
25479
25480         assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
25481       }
25482       else {
25483         skipAssert(assert);
25484       }
25485     });
25486   });
25487
25488   /*--------------------------------------------------------------------------*/
25489
25490   QUnit.module('lodash.xorBy');
25491
25492   (function() {
25493     QUnit.test('should accept an `iteratee`', function(assert) {
25494       assert.expect(2);
25495
25496       var actual = _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
25497       assert.deepEqual(actual, [1.2, 3.4]);
25498
25499       actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
25500       assert.deepEqual(actual, [{ 'x': 2 }]);
25501     });
25502
25503     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25504       assert.expect(1);
25505
25506       var args;
25507
25508       _.xorBy([2.1, 1.2], [2.3, 3.4], function() {
25509         args || (args = slice.call(arguments));
25510       });
25511
25512       assert.deepEqual(args, [2.3]);
25513     });
25514   }());
25515
25516   /*--------------------------------------------------------------------------*/
25517
25518   QUnit.module('lodash.xorWith');
25519
25520   (function() {
25521     QUnit.test('should work with a `comparator`', function(assert) {
25522       assert.expect(1);
25523
25524       var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
25525           others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
25526           actual = _.xorWith(objects, others, lodashStable.isEqual);
25527
25528       assert.deepEqual(actual, [objects[1], others[0]]);
25529     });
25530   }());
25531
25532   /*--------------------------------------------------------------------------*/
25533
25534   QUnit.module('zipObject methods');
25535
25536   lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
25537     var func = _[methodName],
25538         object = { 'barney': 36, 'fred': 40 },
25539         isDeep = methodName == 'zipObjectDeep';
25540
25541     QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
25542       assert.expect(1);
25543
25544       var actual = func(['barney', 'fred'], [36, 40]);
25545       assert.deepEqual(actual, object);
25546     });
25547
25548     QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
25549       assert.expect(1);
25550
25551       assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
25552     });
25553
25554     QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
25555       assert.expect(1);
25556
25557       assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
25558     });
25559
25560     QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
25561       assert.expect(2);
25562
25563       lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
25564         var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
25565         assert.deepEqual(func([path], [1]), expected);
25566       });
25567     });
25568
25569     QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
25570       assert.expect(1);
25571
25572       if (!isNpm) {
25573         var values = lodashStable.range(LARGE_ARRAY_SIZE),
25574             props = lodashStable.map(values, function(value) { return 'key' + value; }),
25575             actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
25576
25577         assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
25578       }
25579       else {
25580         skipAssert(assert);
25581       }
25582     });
25583   });
25584
25585   /*--------------------------------------------------------------------------*/
25586
25587   QUnit.module('lodash.zipWith');
25588
25589   (function() {
25590     QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
25591       assert.expect(2);
25592
25593       var array1 = [1, 2, 3],
25594           array2 = [4, 5, 6],
25595           array3 = [7, 8, 9];
25596
25597       var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
25598         return a + b + c;
25599       });
25600
25601       assert.deepEqual(actual, [12, 15, 18]);
25602
25603       var actual = _.zipWith(array1, [], function(a, b) {
25604         return a + (b || 0);
25605       });
25606
25607       assert.deepEqual(actual, [1, 2, 3]);
25608     });
25609
25610     QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25611       assert.expect(1);
25612
25613       var args;
25614
25615       _.zipWith([1, 2], [3, 4], [5, 6], function() {
25616         args || (args = slice.call(arguments));
25617       });
25618
25619       assert.deepEqual(args, [1, 3, 5]);
25620     });
25621
25622     QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
25623       assert.expect(1);
25624
25625       var array1 = [1, 2],
25626           array2 = [3, 4],
25627           values = [, null, undefined],
25628           expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
25629
25630       var actual = lodashStable.map(values, function(value, index) {
25631         return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
25632       });
25633
25634       assert.deepEqual(actual, expected);
25635     });
25636   }());
25637
25638   /*--------------------------------------------------------------------------*/
25639
25640   QUnit.module('lodash.unzip and lodash.zip');
25641
25642   lodashStable.each(['unzip', 'zip'], function(methodName, index) {
25643     var func = _[methodName];
25644     func = lodashStable.bind(index ? func.apply : func.call, func, null);
25645
25646     var object = {
25647       'an empty array': [
25648         [],
25649         []
25650       ],
25651       '0-tuples': [
25652         [[], []],
25653         []
25654       ],
25655       '2-tuples': [
25656         [['barney', 'fred'], [36, 40]],
25657         [['barney', 36], ['fred', 40]]
25658       ],
25659       '3-tuples': [
25660         [['barney', 'fred'], [36, 40], [false, true]],
25661         [['barney', 36, false], ['fred', 40, true]]
25662       ]
25663     };
25664
25665     lodashStable.forOwn(object, function(pair, key) {
25666       QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
25667         assert.expect(2);
25668
25669         var actual = func(pair[0]);
25670         assert.deepEqual(actual, pair[1]);
25671         assert.deepEqual(func(actual), actual.length ? pair[0] : []);
25672       });
25673     });
25674
25675     QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
25676       assert.expect(4);
25677
25678       var pair = [
25679         [['barney', 36], ['fred', 40, false]],
25680         [['barney', 'fred'], [36, 40], [undefined, false]]
25681       ];
25682
25683       var actual = func(pair[0]);
25684       assert.ok('0' in actual[2]);
25685       assert.deepEqual(actual, pair[1]);
25686
25687       actual = func(actual);
25688       assert.ok('2' in actual[0]);
25689       assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
25690     });
25691
25692     QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
25693       assert.expect(1);
25694
25695       var expected = lodashStable.map(falsey, stubArray);
25696
25697       var actual = lodashStable.map(falsey, function(value) {
25698         return func([value, value, value]);
25699       });
25700
25701       assert.deepEqual(actual, expected);
25702     });
25703
25704     QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25705       assert.expect(1);
25706
25707       var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
25708       assert.deepEqual(func(array), [[1, 3], [2, 4]]);
25709     });
25710
25711     QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
25712       assert.expect(1);
25713
25714       var expected = [['barney', 'fred'], [36, 40]];
25715       assert.deepEqual(func(func(func(func(expected)))), expected);
25716     });
25717   });
25718
25719   /*--------------------------------------------------------------------------*/
25720
25721   QUnit.module('lodash(...).commit');
25722
25723   (function() {
25724     QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
25725       assert.expect(4);
25726
25727       if (!isNpm) {
25728         var array = [1],
25729             wrapped = _(array).push(2).push(3);
25730
25731         assert.deepEqual(array, [1]);
25732
25733         var otherWrapper = wrapped.commit();
25734         assert.ok(otherWrapper instanceof _);
25735         assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
25736         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25737       }
25738       else {
25739         skipAssert(assert, 4);
25740       }
25741     });
25742
25743     QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
25744       assert.expect(2);
25745
25746       if (!isNpm) {
25747         var wrapped = _([1]).chain().commit().head();
25748         assert.ok(wrapped instanceof _);
25749         assert.strictEqual(wrapped.value(), 1);
25750       }
25751       else {
25752         skipAssert(assert, 2);
25753       }
25754     });
25755   }());
25756
25757   /*--------------------------------------------------------------------------*/
25758
25759   QUnit.module('lodash(...).next');
25760
25761   lodashStable.each([false, true], function(implicit) {
25762     function chain(value) {
25763       return implicit ? _(value) : _.chain(value);
25764     }
25765
25766     var chainType = 'in an ' + (implicit ? 'implicit' : 'explict') + ' chain';
25767
25768     QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
25769       assert.expect(3);
25770
25771       if (!isNpm) {
25772         var wrapped = chain([1, 2]);
25773
25774         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
25775         assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
25776         assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
25777       }
25778       else {
25779         skipAssert(assert, 3);
25780       }
25781     });
25782
25783     QUnit.test('should act as an iterable ' + chainType, function(assert) {
25784       assert.expect(2);
25785
25786       if (!isNpm && Symbol && Symbol.iterator) {
25787         var array = [1, 2],
25788             wrapped = chain(array);
25789
25790         assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
25791         assert.deepEqual(lodashStable.toArray(wrapped), array);
25792       }
25793       else {
25794         skipAssert(assert, 2);
25795       }
25796     });
25797
25798     QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
25799       assert.expect(3);
25800
25801       if (!isNpm && Array.from) {
25802         var hearts = '\ud83d\udc95',
25803             values = [[1], { 'a': 1 }, hearts];
25804
25805         lodashStable.each(values, function(value) {
25806           var wrapped = chain(value);
25807           assert.deepEqual(Array.from(wrapped), _.toArray(value));
25808         });
25809       }
25810       else {
25811         skipAssert(assert, 3);
25812       }
25813     });
25814
25815     QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
25816       assert.expect(4);
25817
25818       if (!isNpm && Symbol && Symbol.iterator) {
25819         var array = [1, 2],
25820             wrapped = chain(array);
25821
25822         assert.deepEqual(lodashStable.toArray(wrapped), array);
25823         assert.deepEqual(lodashStable.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
25824
25825         var other = wrapped.filter();
25826         assert.deepEqual(lodashStable.toArray(other), array, 'reset for new chain segments');
25827         assert.deepEqual(lodashStable.toArray(wrapped), [], 'iterator is still exhausted');
25828       }
25829       else {
25830         skipAssert(assert, 4);
25831       }
25832     });
25833
25834     QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
25835       assert.expect(3);
25836
25837       if (!isNpm && Symbol && Symbol.iterator) {
25838         var array = lodashStable.range(LARGE_ARRAY_SIZE),
25839             predicate = function(value) { values.push(value); return isEven(value); },
25840             values = [],
25841             wrapped = chain(array);
25842
25843         assert.deepEqual(lodashStable.toArray(wrapped), array);
25844
25845         wrapped = wrapped.filter(predicate);
25846         assert.deepEqual(lodashStable.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
25847         assert.deepEqual(values, array, 'memoizes iterator values');
25848       }
25849       else {
25850         skipAssert(assert, 3);
25851       }
25852     });
25853   });
25854
25855   /*--------------------------------------------------------------------------*/
25856
25857   QUnit.module('lodash(...).plant');
25858
25859   (function() {
25860     QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
25861       assert.expect(2);
25862
25863       if (!isNpm) {
25864         var array1 = [5, null, 3, null, 1],
25865             array2 = [10, null, 8, null, 6],
25866             wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
25867             wrapped2 = wrapped1.plant(array2);
25868
25869         assert.deepEqual(wrapped2.value(), [36, 64]);
25870         assert.deepEqual(wrapped1.value(), [1, 9]);
25871       }
25872       else {
25873         skipAssert(assert, 2);
25874       }
25875     });
25876
25877     QUnit.test('should clone `chainAll` settings', function(assert) {
25878       assert.expect(1);
25879
25880       if (!isNpm) {
25881         var array1 = [2, 4],
25882             array2 = [6, 8],
25883             wrapped1 = _(array1).chain().map(square),
25884             wrapped2 = wrapped1.plant(array2);
25885
25886         assert.deepEqual(wrapped2.head().value(), 36);
25887       }
25888       else {
25889         skipAssert(assert);
25890       }
25891     });
25892
25893     QUnit.test('should reset iterator data on cloned sequences', function(assert) {
25894       assert.expect(3);
25895
25896       if (!isNpm && Symbol && Symbol.iterator) {
25897         var array1 = [2, 4],
25898             array2 = [6, 8],
25899             wrapped1 = _(array1).map(square);
25900
25901         assert.deepEqual(lodashStable.toArray(wrapped1), [4, 16]);
25902         assert.deepEqual(lodashStable.toArray(wrapped1), []);
25903
25904         var wrapped2 = wrapped1.plant(array2);
25905         assert.deepEqual(lodashStable.toArray(wrapped2), [36, 64]);
25906       }
25907       else {
25908         skipAssert(assert, 3);
25909       }
25910     });
25911   }());
25912
25913   /*--------------------------------------------------------------------------*/
25914
25915   QUnit.module('lodash(...).pop');
25916
25917   (function() {
25918     QUnit.test('should remove elements from the end of `array`', function(assert) {
25919       assert.expect(5);
25920
25921       if (!isNpm) {
25922         var array = [1, 2],
25923             wrapped = _(array);
25924
25925         assert.strictEqual(wrapped.pop(), 2);
25926         assert.deepEqual(wrapped.value(), [1]);
25927         assert.strictEqual(wrapped.pop(), 1);
25928
25929         var actual = wrapped.value();
25930         assert.strictEqual(actual, array);
25931         assert.deepEqual(actual, []);
25932       }
25933       else {
25934         skipAssert(assert, 5);
25935       }
25936     });
25937
25938     QUnit.test('should accept falsey arguments', function(assert) {
25939       assert.expect(1);
25940
25941       if (!isNpm) {
25942         var expected = lodashStable.map(falsey, stubTrue);
25943
25944         var actual = lodashStable.map(falsey, function(value, index) {
25945           try {
25946             var result = index ? _(value).pop() : _().pop();
25947             return result === undefined;
25948           } catch (e) {}
25949         });
25950
25951         assert.deepEqual(actual, expected);
25952       }
25953       else {
25954         skipAssert(assert);
25955       }
25956     });
25957   }());
25958
25959   /*--------------------------------------------------------------------------*/
25960
25961   QUnit.module('lodash(...).push');
25962
25963   (function() {
25964     QUnit.test('should append elements to `array`', function(assert) {
25965       assert.expect(2);
25966
25967       if (!isNpm) {
25968         var array = [1],
25969             wrapped = _(array).push(2, 3),
25970             actual = wrapped.value();
25971
25972         assert.strictEqual(actual, array);
25973         assert.deepEqual(actual, [1, 2, 3]);
25974       }
25975       else {
25976         skipAssert(assert, 2);
25977       }
25978     });
25979
25980     QUnit.test('should accept falsey arguments', function(assert) {
25981       assert.expect(1);
25982
25983       if (!isNpm) {
25984         var expected = lodashStable.map(falsey, stubTrue);
25985
25986         var actual = lodashStable.map(falsey, function(value, index) {
25987           try {
25988             var result = index ? _(value).push(1).value() : _().push(1).value();
25989             return lodashStable.eq(result, value);
25990           } catch (e) {}
25991         });
25992
25993         assert.deepEqual(actual, expected);
25994       }
25995       else {
25996         skipAssert(assert);
25997       }
25998     });
25999   }());
26000
26001   /*--------------------------------------------------------------------------*/
26002
26003   QUnit.module('lodash(...).shift');
26004
26005   (function() {
26006     QUnit.test('should remove elements from the front of `array`', function(assert) {
26007       assert.expect(5);
26008
26009       if (!isNpm) {
26010         var array = [1, 2],
26011             wrapped = _(array);
26012
26013         assert.strictEqual(wrapped.shift(), 1);
26014         assert.deepEqual(wrapped.value(), [2]);
26015         assert.strictEqual(wrapped.shift(), 2);
26016
26017         var actual = wrapped.value();
26018         assert.strictEqual(actual, array);
26019         assert.deepEqual(actual, []);
26020       }
26021       else {
26022         skipAssert(assert, 5);
26023       }
26024     });
26025
26026     QUnit.test('should accept falsey arguments', function(assert) {
26027       assert.expect(1);
26028
26029       if (!isNpm) {
26030         var expected = lodashStable.map(falsey, stubTrue);
26031
26032         var actual = lodashStable.map(falsey, function(value, index) {
26033           try {
26034             var result = index ? _(value).shift() : _().shift();
26035             return result === undefined;
26036           } catch (e) {}
26037         });
26038
26039         assert.deepEqual(actual, expected);
26040       }
26041       else {
26042         skipAssert(assert);
26043       }
26044     });
26045   }());
26046
26047   /*--------------------------------------------------------------------------*/
26048
26049   QUnit.module('lodash(...).sort');
26050
26051   (function() {
26052     QUnit.test('should return the wrapped sorted `array`', function(assert) {
26053       assert.expect(2);
26054
26055       if (!isNpm) {
26056         var array = [3, 1, 2],
26057             wrapped = _(array).sort(),
26058             actual = wrapped.value();
26059
26060         assert.strictEqual(actual, array);
26061         assert.deepEqual(actual, [1, 2, 3]);
26062       }
26063       else {
26064         skipAssert(assert, 2);
26065       }
26066     });
26067
26068     QUnit.test('should accept falsey arguments', function(assert) {
26069       assert.expect(1);
26070
26071       if (!isNpm) {
26072         var expected = lodashStable.map(falsey, stubTrue);
26073
26074         var actual = lodashStable.map(falsey, function(value, index) {
26075           try {
26076             var result = index ? _(value).sort().value() : _().sort().value();
26077             return lodashStable.eq(result, value);
26078           } catch (e) {}
26079         });
26080
26081         assert.deepEqual(actual, expected);
26082       }
26083       else {
26084         skipAssert(assert);
26085       }
26086     });
26087   }());
26088
26089   /*--------------------------------------------------------------------------*/
26090
26091   QUnit.module('lodash(...).splice');
26092
26093   (function() {
26094     QUnit.test('should support removing and inserting elements', function(assert) {
26095       assert.expect(5);
26096
26097       if (!isNpm) {
26098         var array = [1, 2],
26099             wrapped = _(array);
26100
26101         assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
26102         assert.deepEqual(wrapped.value(), [1, 3]);
26103         assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
26104
26105         var actual = wrapped.value();
26106         assert.strictEqual(actual, array);
26107         assert.deepEqual(actual, []);
26108       }
26109       else {
26110         skipAssert(assert, 5);
26111       }
26112     });
26113
26114     QUnit.test('should accept falsey arguments', function(assert) {
26115       assert.expect(1);
26116
26117       if (!isNpm) {
26118         var expected = lodashStable.map(falsey, stubTrue);
26119
26120         var actual = lodashStable.map(falsey, function(value, index) {
26121           try {
26122             var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
26123             return lodashStable.isEqual(result, []);
26124           } catch (e) {}
26125         });
26126
26127         assert.deepEqual(actual, expected);
26128       }
26129       else {
26130         skipAssert(assert);
26131       }
26132     });
26133   }());
26134
26135   /*--------------------------------------------------------------------------*/
26136
26137   QUnit.module('lodash(...).unshift');
26138
26139   (function() {
26140     QUnit.test('should prepend elements to `array`', function(assert) {
26141       assert.expect(2);
26142
26143       if (!isNpm) {
26144         var array = [3],
26145             wrapped = _(array).unshift(1, 2),
26146             actual = wrapped.value();
26147
26148         assert.strictEqual(actual, array);
26149         assert.deepEqual(actual, [1, 2, 3]);
26150       }
26151       else {
26152         skipAssert(assert, 2);
26153       }
26154     });
26155
26156     QUnit.test('should accept falsey arguments', function(assert) {
26157       assert.expect(1);
26158
26159       if (!isNpm) {
26160         var expected = lodashStable.map(falsey, stubTrue);
26161
26162         var actual = lodashStable.map(falsey, function(value, index) {
26163           try {
26164             var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
26165             return lodashStable.eq(result, value);
26166           } catch (e) {}
26167         });
26168
26169         assert.deepEqual(actual, expected);
26170       }
26171       else {
26172         skipAssert(assert);
26173       }
26174     });
26175   }());
26176
26177   /*--------------------------------------------------------------------------*/
26178
26179   QUnit.module('lodash(...).value');
26180
26181   (function() {
26182     QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
26183       assert.expect(4);
26184
26185       if (!isNpm) {
26186         var array = [1],
26187             wrapped = _(array).push(2).push(3);
26188
26189         assert.deepEqual(array, [1]);
26190         assert.deepEqual(wrapped.value(), [1, 2, 3]);
26191         assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
26192         assert.deepEqual(array, [1, 2, 3, 2, 3]);
26193       }
26194       else {
26195         skipAssert(assert, 4);
26196       }
26197     });
26198
26199     QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
26200       assert.expect(1);
26201
26202       if (!isNpm) {
26203         var wrapped = _(123);
26204         assert.strictEqual(Number(wrapped), 123);
26205       }
26206       else {
26207         skipAssert(assert);
26208       }
26209     });
26210
26211     QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
26212       assert.expect(1);
26213
26214       if (!isNpm && JSON) {
26215         var wrapped = _([1, 2, 3]);
26216         assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
26217       }
26218       else {
26219         skipAssert(assert);
26220       }
26221     });
26222
26223     QUnit.test('should be aliased', function(assert) {
26224       assert.expect(2);
26225
26226       if (!isNpm) {
26227         var expected = _.prototype.value;
26228         assert.strictEqual(_.prototype.toJSON, expected);
26229         assert.strictEqual(_.prototype.valueOf, expected);
26230       }
26231       else {
26232         skipAssert(assert, 2);
26233       }
26234     });
26235   }());
26236
26237   /*--------------------------------------------------------------------------*/
26238
26239   QUnit.module('lodash(...) methods that return the wrapped modified array');
26240
26241   (function() {
26242     var funcs = [
26243       'push',
26244       'reverse',
26245       'sort',
26246       'unshift'
26247     ];
26248
26249     lodashStable.each(funcs, function(methodName) {
26250       QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
26251         assert.expect(2);
26252
26253         if (!isNpm) {
26254           var array = [1, 2, 3],
26255               wrapped = _(array),
26256               actual = wrapped[methodName]();
26257
26258           assert.ok(actual instanceof _);
26259           assert.notStrictEqual(actual, wrapped);
26260         }
26261         else {
26262           skipAssert(assert, 2);
26263         }
26264       });
26265     });
26266   }());
26267
26268   /*--------------------------------------------------------------------------*/
26269
26270   QUnit.module('lodash(...) methods that return new wrapped values');
26271
26272   (function() {
26273     var funcs = [
26274       'castArray',
26275       'concat',
26276       'difference',
26277       'differenceBy',
26278       'differenceWith',
26279       'intersection',
26280       'intersectionBy',
26281       'intersectionWith',
26282       'pull',
26283       'pullAll',
26284       'pullAt',
26285       'sampleSize',
26286       'shuffle',
26287       'slice',
26288       'splice',
26289       'split',
26290       'toArray',
26291       'union',
26292       'unionBy',
26293       'unionWith',
26294       'uniq',
26295       'uniqBy',
26296       'uniqWith',
26297       'words',
26298       'xor',
26299       'xorBy',
26300       'xorWith'
26301     ];
26302
26303     lodashStable.each(funcs, function(methodName) {
26304       QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
26305         assert.expect(2);
26306
26307         if (!isNpm) {
26308           var value = methodName == 'split' ? 'abc' : [1, 2, 3],
26309               wrapped = _(value),
26310               actual = wrapped[methodName]();
26311
26312           assert.ok(actual instanceof _);
26313           assert.notStrictEqual(actual, wrapped);
26314         }
26315         else {
26316           skipAssert(assert, 2);
26317         }
26318       });
26319     });
26320   }());
26321
26322   /*--------------------------------------------------------------------------*/
26323
26324   QUnit.module('lodash(...) methods that return unwrapped values');
26325
26326   (function() {
26327     var funcs = [
26328       'add',
26329       'camelCase',
26330       'capitalize',
26331       'ceil',
26332       'clone',
26333       'deburr',
26334       'defaultTo',
26335       'divide',
26336       'endsWith',
26337       'escape',
26338       'escapeRegExp',
26339       'every',
26340       'find',
26341       'floor',
26342       'has',
26343       'hasIn',
26344       'head',
26345       'includes',
26346       'isArguments',
26347       'isArray',
26348       'isArrayBuffer',
26349       'isArrayLike',
26350       'isBoolean',
26351       'isBuffer',
26352       'isDate',
26353       'isElement',
26354       'isEmpty',
26355       'isEqual',
26356       'isError',
26357       'isFinite',
26358       'isFunction',
26359       'isInteger',
26360       'isMap',
26361       'isNaN',
26362       'isNative',
26363       'isNil',
26364       'isNull',
26365       'isNumber',
26366       'isObject',
26367       'isObjectLike',
26368       'isPlainObject',
26369       'isRegExp',
26370       'isSafeInteger',
26371       'isSet',
26372       'isString',
26373       'isUndefined',
26374       'isWeakMap',
26375       'isWeakSet',
26376       'join',
26377       'kebabCase',
26378       'last',
26379       'lowerCase',
26380       'lowerFirst',
26381       'max',
26382       'maxBy',
26383       'min',
26384       'minBy',
26385       'multiply',
26386       'nth',
26387       'pad',
26388       'padEnd',
26389       'padStart',
26390       'parseInt',
26391       'pop',
26392       'random',
26393       'reduce',
26394       'reduceRight',
26395       'repeat',
26396       'replace',
26397       'round',
26398       'sample',
26399       'shift',
26400       'size',
26401       'snakeCase',
26402       'some',
26403       'startCase',
26404       'startsWith',
26405       'subtract',
26406       'sum',
26407       'toFinite',
26408       'toInteger',
26409       'toLower',
26410       'toNumber',
26411       'toSafeInteger',
26412       'toString',
26413       'toUpper',
26414       'trim',
26415       'trimEnd',
26416       'trimStart',
26417       'truncate',
26418       'unescape',
26419       'upperCase',
26420       'upperFirst'
26421     ];
26422
26423     lodashStable.each(funcs, function(methodName) {
26424       QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
26425         assert.expect(1);
26426
26427         if (!isNpm) {
26428           var actual = _()[methodName]();
26429           assert.notOk(actual instanceof _);
26430         }
26431         else {
26432           skipAssert(assert);
26433         }
26434       });
26435
26436       QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
26437         assert.expect(1);
26438
26439         if (!isNpm) {
26440           var actual = _().chain()[methodName]();
26441           assert.ok(actual instanceof _);
26442         }
26443         else {
26444           skipAssert(assert);
26445         }
26446       });
26447     });
26448   }());
26449
26450   /*--------------------------------------------------------------------------*/
26451
26452   QUnit.module('"Arrays" category methods');
26453
26454   (function() {
26455     var args = toArgs([1, null, [3], null, 5]),
26456         sortedArgs = toArgs([1, [3], 5, null, null]),
26457         array = [1, 2, 3, 4, 5, 6];
26458
26459     QUnit.test('should work with `arguments` objects', function(assert) {
26460       assert.expect(30);
26461
26462       function message(methodName) {
26463         return '`_.' + methodName + '` should work with `arguments` objects';
26464       }
26465
26466       assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
26467       assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
26468
26469       assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
26470       assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
26471
26472       assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
26473       assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
26474       assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
26475       assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
26476       assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
26477       assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
26478       assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
26479       assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
26480       assert.deepEqual(_.head(args), 1, message('head'));
26481       assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
26482       assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
26483       assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
26484       assert.deepEqual(_.last(args), 5, message('last'));
26485       assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
26486       assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
26487       assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
26488       assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
26489       assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
26490       assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
26491       assert.deepEqual(_.take(args, 2), [1, null], message('take'));
26492       assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
26493       assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
26494       assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
26495       assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
26496       assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
26497       assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
26498     });
26499
26500     QUnit.test('should accept falsey primary arguments', function(assert) {
26501       assert.expect(4);
26502
26503       function message(methodName) {
26504         return '`_.' + methodName + '` should accept falsey primary arguments';
26505       }
26506
26507       assert.deepEqual(_.difference(null, array), [], message('difference'));
26508       assert.deepEqual(_.intersection(null, array), [], message('intersection'));
26509       assert.deepEqual(_.union(null, array), array, message('union'));
26510       assert.deepEqual(_.xor(null, array), array, message('xor'));
26511     });
26512
26513     QUnit.test('should accept falsey secondary arguments', function(assert) {
26514       assert.expect(3);
26515
26516       function message(methodName) {
26517         return '`_.' + methodName + '` should accept falsey secondary arguments';
26518       }
26519
26520       assert.deepEqual(_.difference(array, null), array, message('difference'));
26521       assert.deepEqual(_.intersection(array, null), [], message('intersection'));
26522       assert.deepEqual(_.union(array, null), array, message('union'));
26523     });
26524   }());
26525
26526   /*--------------------------------------------------------------------------*/
26527
26528   QUnit.module('"Strings" category methods');
26529
26530   (function() {
26531     var stringMethods = [
26532       'camelCase',
26533       'capitalize',
26534       'escape',
26535       'kebabCase',
26536       'lowerCase',
26537       'lowerFirst',
26538       'pad',
26539       'padEnd',
26540       'padStart',
26541       'repeat',
26542       'snakeCase',
26543       'toLower',
26544       'toUpper',
26545       'trim',
26546       'trimEnd',
26547       'trimStart',
26548       'truncate',
26549       'unescape',
26550       'upperCase',
26551       'upperFirst'
26552     ];
26553
26554     lodashStable.each(stringMethods, function(methodName) {
26555       var func = _[methodName];
26556
26557       QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
26558         assert.expect(1);
26559
26560         var values = [, null, undefined, ''],
26561             expected = lodashStable.map(values, stubString);
26562
26563         var actual = lodashStable.map(values, function(value, index) {
26564           return index ? func(value) : func();
26565         });
26566
26567         assert.deepEqual(actual, expected);
26568       });
26569     });
26570   }());
26571
26572   /*--------------------------------------------------------------------------*/
26573
26574   QUnit.module('lodash methods');
26575
26576   (function() {
26577     var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
26578       return lodashStable.startsWith(methodName, '_');
26579     });
26580
26581     var checkFuncs = [
26582       'after',
26583       'ary',
26584       'before',
26585       'bind',
26586       'curry',
26587       'curryRight',
26588       'debounce',
26589       'defer',
26590       'delay',
26591       'flip',
26592       'flow',
26593       'flowRight',
26594       'memoize',
26595       'negate',
26596       'once',
26597       'partial',
26598       'partialRight',
26599       'rearg',
26600       'rest',
26601       'spread',
26602       'throttle',
26603       'unary'
26604     ];
26605
26606     var noBinding = [
26607       'flip',
26608       'memoize',
26609       'negate',
26610       'once',
26611       'overArgs',
26612       'partial',
26613       'partialRight',
26614       'rearg',
26615       'rest',
26616       'spread'
26617     ];
26618
26619     var rejectFalsey = [
26620       'tap',
26621       'thru'
26622     ].concat(checkFuncs);
26623
26624     var returnArrays = [
26625       'at',
26626       'chunk',
26627       'compact',
26628       'difference',
26629       'drop',
26630       'filter',
26631       'flatten',
26632       'functions',
26633       'initial',
26634       'intersection',
26635       'invokeMap',
26636       'keys',
26637       'map',
26638       'orderBy',
26639       'pull',
26640       'pullAll',
26641       'pullAt',
26642       'range',
26643       'rangeRight',
26644       'reject',
26645       'remove',
26646       'shuffle',
26647       'sortBy',
26648       'tail',
26649       'take',
26650       'times',
26651       'toArray',
26652       'toPairs',
26653       'toPairsIn',
26654       'union',
26655       'uniq',
26656       'values',
26657       'without',
26658       'xor',
26659       'zip'
26660     ];
26661
26662     var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
26663
26664     QUnit.test('should accept falsey arguments', function(assert) {
26665       assert.expect(316);
26666
26667       var arrays = lodashStable.map(falsey, stubArray);
26668
26669       lodashStable.each(acceptFalsey, function(methodName) {
26670         var expected = arrays,
26671             func = _[methodName];
26672
26673         var actual = lodashStable.map(falsey, function(value, index) {
26674           return index ? func(value) : func();
26675         });
26676
26677         if (methodName == 'noConflict') {
26678           root._ = oldDash;
26679         }
26680         else if (methodName == 'pull' || methodName == 'pullAll') {
26681           expected = falsey;
26682         }
26683         if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
26684           assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
26685         }
26686         assert.ok(true, '`_.' + methodName + '` accepts falsey arguments');
26687       });
26688
26689       // Skip tests for missing methods of modularized builds.
26690       lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
26691         if (!_[methodName]) {
26692           skipAssert(assert);
26693         }
26694       });
26695     });
26696
26697     QUnit.test('should return an array', function(assert) {
26698       assert.expect(70);
26699
26700       var array = [1, 2, 3];
26701
26702       lodashStable.each(returnArrays, function(methodName) {
26703         var actual,
26704             func = _[methodName];
26705
26706         switch (methodName) {
26707           case 'invokeMap':
26708             actual = func(array, 'toFixed');
26709             break;
26710           case 'sample':
26711             actual = func(array, 1);
26712             break;
26713           default:
26714             actual = func(array);
26715         }
26716         assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
26717
26718         var isPull = methodName == 'pull' || methodName == 'pullAll';
26719         assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
26720       });
26721     });
26722
26723     QUnit.test('should throw an error for falsey arguments', function(assert) {
26724       assert.expect(24);
26725
26726       lodashStable.each(rejectFalsey, function(methodName) {
26727         var expected = lodashStable.map(falsey, stubTrue),
26728             func = _[methodName];
26729
26730         var actual = lodashStable.map(falsey, function(value, index) {
26731           var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
26732
26733           try {
26734             index ? func(value) : func();
26735           } catch (e) {
26736             pass = !pass && (e instanceof TypeError) &&
26737               (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
26738           }
26739           return pass;
26740         });
26741
26742         assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
26743       });
26744     });
26745
26746     QUnit.test('should use `this` binding of function', function(assert) {
26747       assert.expect(30);
26748
26749       lodashStable.each(noBinding, function(methodName) {
26750         var fn = function() { return this.a; },
26751             func = _[methodName],
26752             isNegate = methodName == 'negate',
26753             object = { 'a': 1 },
26754             expected = isNegate ? false : 1;
26755
26756         var wrapper = func(_.bind(fn, object));
26757         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
26758
26759         wrapper = _.bind(func(fn), object);
26760         assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
26761
26762         object.wrapper = func(fn);
26763         assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
26764       });
26765     });
26766
26767     QUnit.test('should not contain minified method names (test production builds)', function(assert) {
26768       assert.expect(1);
26769
26770       var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
26771       assert.ok(lodashStable.every(_.functions(_), function(methodName) {
26772         return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
26773       }));
26774     });
26775   }());
26776
26777   /*--------------------------------------------------------------------------*/
26778
26779   QUnit.config.asyncRetries = 10;
26780   QUnit.config.hidepassed = true;
26781
26782   if (!document) {
26783     QUnit.config.noglobals = true;
26784     QUnit.load();
26785     QUnit.start();
26786   }
26787 }.call(this));