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 || lodashStable.memoize).Cache;
350    var result = {
351      'Hash': new MapCache().__data__.hash.constructor,
352      'MapCache': MapCache
353    };
354    (_.isMatchWith || lodashStable.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    QUnit.test('should not indirectly merge `Object` properties', function(assert) {
4717      assert.expect(1);
4718
4719      _.defaultsDeep({}, { 'constructor': { 'a': 1 } });
4720
4721      var actual = 'a' in Object;
4722      delete Object.a;
4723
4724      assert.notOk(actual);
4725    });
4726  }());
4727
4728  /*--------------------------------------------------------------------------*/
4729
4730  QUnit.module('lodash.defaultTo');
4731
4732  (function() {
4733    QUnit.test('should return a default value if `value` is `NaN` or nullish', function(assert) {
4734      assert.expect(1);
4735
4736      var expected = lodashStable.map(falsey, function(value) {
4737        return (value == null || value !== value) ? 1 : value;
4738      });
4739
4740      var actual = lodashStable.map(falsey, function(value) {
4741        return _.defaultTo(value, 1);
4742      });
4743
4744      assert.deepEqual(actual, expected);
4745    });
4746  }());
4747
4748  /*--------------------------------------------------------------------------*/
4749
4750  QUnit.module('lodash.defer');
4751
4752  (function() {
4753    QUnit.test('should defer `func` execution', function(assert) {
4754      assert.expect(1);
4755
4756      var done = assert.async();
4757
4758      var pass = false;
4759      _.defer(function() { pass = true; });
4760
4761      setTimeout(function() {
4762        assert.ok(pass);
4763        done();
4764      }, 32);
4765    });
4766
4767    QUnit.test('should provide additional arguments to `func`', function(assert) {
4768      assert.expect(1);
4769
4770      var done = assert.async();
4771
4772      var args;
4773
4774      _.defer(function() {
4775        args = slice.call(arguments);
4776      }, 1, 2);
4777
4778      setTimeout(function() {
4779        assert.deepEqual(args, [1, 2]);
4780        done();
4781      }, 32);
4782    });
4783
4784    QUnit.test('should be cancelable', function(assert) {
4785      assert.expect(1);
4786
4787      var done = assert.async();
4788
4789      var pass = true,
4790          timerId = _.defer(function() { pass = false; });
4791
4792      clearTimeout(timerId);
4793
4794      setTimeout(function() {
4795        assert.ok(pass);
4796        done();
4797      }, 32);
4798    });
4799  }());
4800
4801  /*--------------------------------------------------------------------------*/
4802
4803  QUnit.module('lodash.delay');
4804
4805  (function() {
4806    QUnit.test('should delay `func` execution', function(assert) {
4807      assert.expect(2);
4808
4809      var done = assert.async();
4810
4811      var pass = false;
4812      _.delay(function() { pass = true; }, 32);
4813
4814      setTimeout(function() {
4815        assert.notOk(pass);
4816      }, 1);
4817
4818      setTimeout(function() {
4819        assert.ok(pass);
4820        done();
4821      }, 64);
4822    });
4823
4824    QUnit.test('should provide additional arguments to `func`', function(assert) {
4825      assert.expect(1);
4826
4827      var done = assert.async();
4828
4829      var args;
4830
4831      _.delay(function() {
4832        args = slice.call(arguments);
4833      }, 32, 1, 2);
4834
4835      setTimeout(function() {
4836        assert.deepEqual(args, [1, 2]);
4837        done();
4838      }, 64);
4839    });
4840
4841    QUnit.test('should use a default `wait` of `0`', function(assert) {
4842      assert.expect(2);
4843
4844      var done = assert.async();
4845
4846      var pass = false;
4847      _.delay(function() { pass = true; });
4848
4849      assert.notOk(pass);
4850
4851      setTimeout(function() {
4852        assert.ok(pass);
4853        done();
4854      }, 0);
4855    });
4856
4857    QUnit.test('should be cancelable', function(assert) {
4858      assert.expect(1);
4859
4860      var done = assert.async();
4861
4862      var pass = true,
4863          timerId = _.delay(function() { pass = false; }, 32);
4864
4865      clearTimeout(timerId);
4866
4867      setTimeout(function() {
4868        assert.ok(pass);
4869        done();
4870      }, 64);
4871    });
4872
4873    QUnit.test('should work with mocked `setTimeout`', function(assert) {
4874      assert.expect(1);
4875
4876      if (!isPhantom) {
4877        var pass = false,
4878            setTimeout = root.setTimeout;
4879
4880        setProperty(root, 'setTimeout', function(func) { func(); });
4881        _.delay(function() { pass = true; }, 32);
4882        setProperty(root, 'setTimeout', setTimeout);
4883
4884        assert.ok(pass);
4885      }
4886      else {
4887        skipAssert(assert);
4888      }
4889    });
4890  }());
4891
4892  /*--------------------------------------------------------------------------*/
4893
4894  QUnit.module('difference methods');
4895
4896  lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4897    var func = _[methodName];
4898
4899    QUnit.test('`_.' + methodName + '` should return the difference of two arrays', function(assert) {
4900      assert.expect(1);
4901
4902      var actual = func([2, 1], [2, 3]);
4903      assert.deepEqual(actual, [1]);
4904    });
4905
4906    QUnit.test('`_.' + methodName + '` should return the difference of multiple arrays', function(assert) {
4907      assert.expect(1);
4908
4909      var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
4910      assert.deepEqual(actual, [1]);
4911    });
4912
4913    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
4914      assert.expect(2);
4915
4916      var array = [-0, 0];
4917
4918      var actual = lodashStable.map(array, function(value) {
4919        return func(array, [value]);
4920      });
4921
4922      assert.deepEqual(actual, [[], []]);
4923
4924      actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
4925      assert.deepEqual(actual, ['0']);
4926    });
4927
4928    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4929      assert.expect(1);
4930
4931      assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4932    });
4933
4934    QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4935      assert.expect(1);
4936
4937      var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4938          array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4939          a = {},
4940          b = {},
4941          c = {};
4942
4943      array1.push(a, b, c);
4944      array2.push(b, c, a);
4945
4946      assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4947    });
4948
4949    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
4950      assert.expect(2);
4951
4952      var array = [-0, 0];
4953
4954      var actual = lodashStable.map(array, function(value) {
4955        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
4956        return func(array, largeArray);
4957      });
4958
4959      assert.deepEqual(actual, [[], []]);
4960
4961      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne);
4962      actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
4963      assert.deepEqual(actual, ['0']);
4964    });
4965
4966    QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4967      assert.expect(1);
4968
4969      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
4970      assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4971    });
4972
4973    QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4974      assert.expect(1);
4975
4976      var object1 = {},
4977          object2 = {},
4978          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4979
4980      assert.deepEqual(func([object1, object2], largeArray), [object2]);
4981    });
4982
4983    QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4984      assert.expect(3);
4985
4986      var array = [1, null, 3];
4987
4988      assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4989      assert.deepEqual(func(null, array, 1), []);
4990      assert.deepEqual(func(array, args, null), [null]);
4991    });
4992  });
4993
4994  /*--------------------------------------------------------------------------*/
4995
4996  QUnit.module('lodash.differenceBy');
4997
4998  (function() {
4999    QUnit.test('should accept an `iteratee`', function(assert) {
5000      assert.expect(2);
5001
5002      var actual = _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
5003      assert.deepEqual(actual, [1.2]);
5004
5005      actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5006      assert.deepEqual(actual, [{ 'x': 2 }]);
5007    });
5008
5009    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
5010      assert.expect(1);
5011
5012      var args;
5013
5014      _.differenceBy([2.1, 1.2], [2.3, 3.4], function() {
5015        args || (args = slice.call(arguments));
5016      });
5017
5018      assert.deepEqual(args, [2.3]);
5019    });
5020  }());
5021
5022  /*--------------------------------------------------------------------------*/
5023
5024  QUnit.module('lodash.differenceWith');
5025
5026  (function() {
5027    QUnit.test('should work with a `comparator`', function(assert) {
5028      assert.expect(1);
5029
5030      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
5031          actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
5032
5033      assert.deepEqual(actual, [objects[1]]);
5034    });
5035
5036    QUnit.test('should preserve the sign of `0`', function(assert) {
5037      assert.expect(1);
5038
5039      var array = [-0, 1],
5040          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne),
5041          others = [[1], largeArray],
5042          expected = lodashStable.map(others, lodashStable.constant(['-0']));
5043
5044      var actual = lodashStable.map(others, function(other) {
5045        return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
5046      });
5047
5048      assert.deepEqual(actual, expected);
5049    });
5050  }());
5051
5052  /*--------------------------------------------------------------------------*/
5053
5054  QUnit.module('lodash.divide');
5055
5056  (function() {
5057    QUnit.test('should divide two numbers', function(assert) {
5058      assert.expect(3);
5059
5060      assert.strictEqual(_.divide(6, 4), 1.5);
5061      assert.strictEqual(_.divide(-6, 4), -1.5);
5062      assert.strictEqual(_.divide(-6, -4), 1.5);
5063    });
5064
5065    QUnit.test('should coerce arguments to numbers', function(assert) {
5066      assert.expect(2);
5067
5068      assert.strictEqual(_.divide('6', '4'), 1.5);
5069      assert.deepEqual(_.divide('x', 'y'), NaN);
5070    });
5071  }());
5072
5073  /*--------------------------------------------------------------------------*/
5074
5075  QUnit.module('lodash.drop');
5076
5077  (function() {
5078    var array = [1, 2, 3];
5079
5080    QUnit.test('should drop the first two elements', function(assert) {
5081      assert.expect(1);
5082
5083      assert.deepEqual(_.drop(array, 2), [3]);
5084    });
5085
5086    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
5087      assert.expect(1);
5088
5089      var expected = lodashStable.map(falsey, function(value) {
5090        return value === undefined ? [2, 3] : array;
5091      });
5092
5093      var actual = lodashStable.map(falsey, function(n) {
5094        return _.drop(array, n);
5095      });
5096
5097      assert.deepEqual(actual, expected);
5098    });
5099
5100    QUnit.test('should return all elements when `n` < `1`', function(assert) {
5101      assert.expect(3);
5102
5103      lodashStable.each([0, -1, -Infinity], function(n) {
5104        assert.deepEqual(_.drop(array, n), array);
5105      });
5106    });
5107
5108    QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
5109      assert.expect(4);
5110
5111      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5112        assert.deepEqual(_.drop(array, n), []);
5113      });
5114    });
5115
5116    QUnit.test('should coerce `n` to an integer', function(assert) {
5117      assert.expect(1);
5118
5119      assert.deepEqual(_.drop(array, 1.6), [2, 3]);
5120    });
5121
5122    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5123      assert.expect(1);
5124
5125      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5126          actual = lodashStable.map(array, _.drop);
5127
5128      assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
5129    });
5130
5131    QUnit.test('should work in a lazy sequence', function(assert) {
5132      assert.expect(6);
5133
5134      if (!isNpm) {
5135        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5136            predicate = function(value) { values.push(value); return isEven(value); },
5137            values = [],
5138            actual = _(array).drop(2).drop().value();
5139
5140        assert.deepEqual(actual, array.slice(3));
5141
5142        actual = _(array).filter(predicate).drop(2).drop().value();
5143        assert.deepEqual(values, array);
5144        assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
5145
5146        actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
5147        assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
5148
5149        values = [];
5150
5151        actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
5152        assert.deepEqual(values, array.slice(1));
5153        assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
5154      }
5155      else {
5156        skipAssert(assert, 6);
5157      }
5158    });
5159  }());
5160
5161  /*--------------------------------------------------------------------------*/
5162
5163  QUnit.module('lodash.dropRight');
5164
5165  (function() {
5166    var array = [1, 2, 3];
5167
5168    QUnit.test('should drop the last two elements', function(assert) {
5169      assert.expect(1);
5170
5171      assert.deepEqual(_.dropRight(array, 2), [1]);
5172    });
5173
5174    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
5175      assert.expect(1);
5176
5177      var expected = lodashStable.map(falsey, function(value) {
5178        return value === undefined ? [1, 2] : array;
5179      });
5180
5181      var actual = lodashStable.map(falsey, function(n) {
5182        return _.dropRight(array, n);
5183      });
5184
5185      assert.deepEqual(actual, expected);
5186    });
5187
5188    QUnit.test('should return all elements when `n` < `1`', function(assert) {
5189      assert.expect(3);
5190
5191      lodashStable.each([0, -1, -Infinity], function(n) {
5192        assert.deepEqual(_.dropRight(array, n), array);
5193      });
5194    });
5195
5196    QUnit.test('should return an empty array when `n` >= `length`', function(assert) {
5197      assert.expect(4);
5198
5199      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5200        assert.deepEqual(_.dropRight(array, n), []);
5201      });
5202    });
5203
5204    QUnit.test('should coerce `n` to an integer', function(assert) {
5205      assert.expect(1);
5206
5207      assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
5208    });
5209
5210    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5211      assert.expect(1);
5212
5213      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5214          actual = lodashStable.map(array, _.dropRight);
5215
5216      assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
5217    });
5218
5219    QUnit.test('should work in a lazy sequence', function(assert) {
5220      assert.expect(6);
5221
5222      if (!isNpm) {
5223        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5224            predicate = function(value) { values.push(value); return isEven(value); },
5225            values = [],
5226            actual = _(array).dropRight(2).dropRight().value();
5227
5228        assert.deepEqual(actual, array.slice(0, -3));
5229
5230        actual = _(array).filter(predicate).dropRight(2).dropRight().value();
5231        assert.deepEqual(values, array);
5232        assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
5233
5234        actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
5235        assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
5236
5237        values = [];
5238
5239        actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
5240        assert.deepEqual(values, array.slice(0, -1));
5241        assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
5242      }
5243      else {
5244        skipAssert(assert, 6);
5245      }
5246    });
5247  }());
5248
5249  /*--------------------------------------------------------------------------*/
5250
5251  QUnit.module('lodash.dropRightWhile');
5252
5253  (function() {
5254    var array = [1, 2, 3, 4];
5255
5256    var objects = [
5257      { 'a': 0, 'b': 0 },
5258      { 'a': 1, 'b': 1 },
5259      { 'a': 2, 'b': 2 }
5260    ];
5261
5262    QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5263      assert.expect(1);
5264
5265      var actual = _.dropRightWhile(array, function(n) {
5266        return n > 2;
5267      });
5268
5269      assert.deepEqual(actual, [1, 2]);
5270    });
5271
5272    QUnit.test('should provide correct `predicate` arguments', function(assert) {
5273      assert.expect(1);
5274
5275      var args;
5276
5277      _.dropRightWhile(array, function() {
5278        args = slice.call(arguments);
5279      });
5280
5281      assert.deepEqual(args, [4, 3, array]);
5282    });
5283
5284    QUnit.test('should work with `_.matches` shorthands', function(assert) {
5285      assert.expect(1);
5286
5287      assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
5288    });
5289
5290    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5291      assert.expect(1);
5292
5293      assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
5294    });
5295
5296    QUnit.test('should work with `_.property` shorthands', function(assert) {
5297      assert.expect(1);
5298
5299      assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
5300    });
5301
5302    QUnit.test('should return a wrapped value when chaining', function(assert) {
5303      assert.expect(2);
5304
5305      if (!isNpm) {
5306        var wrapped = _(array).dropRightWhile(function(n) {
5307          return n > 2;
5308        });
5309
5310        assert.ok(wrapped instanceof _);
5311        assert.deepEqual(wrapped.value(), [1, 2]);
5312      }
5313      else {
5314        skipAssert(assert, 2);
5315      }
5316    });
5317  }());
5318
5319  /*--------------------------------------------------------------------------*/
5320
5321  QUnit.module('lodash.dropWhile');
5322
5323  (function() {
5324    var array = [1, 2, 3, 4];
5325
5326    var objects = [
5327      { 'a': 2, 'b': 2 },
5328      { 'a': 1, 'b': 1 },
5329      { 'a': 0, 'b': 0 }
5330    ];
5331
5332    QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5333      assert.expect(1);
5334
5335      var actual = _.dropWhile(array, function(n) {
5336        return n < 3;
5337      });
5338
5339      assert.deepEqual(actual, [3, 4]);
5340    });
5341
5342    QUnit.test('should provide correct `predicate` arguments', function(assert) {
5343      assert.expect(1);
5344
5345      var args;
5346
5347      _.dropWhile(array, function() {
5348        args = slice.call(arguments);
5349      });
5350
5351      assert.deepEqual(args, [1, 0, array]);
5352    });
5353
5354    QUnit.test('should work with `_.matches` shorthands', function(assert) {
5355      assert.expect(1);
5356
5357      assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
5358    });
5359
5360    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5361      assert.expect(1);
5362
5363      assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
5364    });
5365
5366    QUnit.test('should work with `_.property` shorthands', function(assert) {
5367      assert.expect(1);
5368
5369      assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
5370    });
5371
5372    QUnit.test('should work in a lazy sequence', function(assert) {
5373      assert.expect(3);
5374
5375      if (!isNpm) {
5376        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
5377            predicate = function(n) { return n < 3; },
5378            expected = _.dropWhile(array, predicate),
5379            wrapped = _(array).dropWhile(predicate);
5380
5381        assert.deepEqual(wrapped.value(), expected);
5382        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
5383        assert.strictEqual(wrapped.last(), _.last(expected));
5384      }
5385      else {
5386        skipAssert(assert, 3);
5387      }
5388    });
5389
5390    QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
5391      assert.expect(1);
5392
5393      if (!isNpm) {
5394        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
5395
5396        var actual = _(array)
5397          .dropWhile(function(n) { return n == 1; })
5398          .drop()
5399          .dropWhile(function(n) { return n == 3; })
5400          .value();
5401
5402        assert.deepEqual(actual, array.slice(3));
5403      }
5404      else {
5405        skipAssert(assert);
5406      }
5407    });
5408  }());
5409
5410  /*--------------------------------------------------------------------------*/
5411
5412  QUnit.module('lodash.endsWith');
5413
5414  (function() {
5415    var string = 'abc';
5416
5417    QUnit.test('should return `true` if a string ends with `target`', function(assert) {
5418      assert.expect(1);
5419
5420      assert.strictEqual(_.endsWith(string, 'c'), true);
5421    });
5422
5423    QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
5424      assert.expect(1);
5425
5426      assert.strictEqual(_.endsWith(string, 'b'), false);
5427    });
5428
5429    QUnit.test('should work with a `position`', function(assert) {
5430      assert.expect(1);
5431
5432      assert.strictEqual(_.endsWith(string, 'b', 2), true);
5433    });
5434
5435    QUnit.test('should work with `position` >= `length`', function(assert) {
5436      assert.expect(4);
5437
5438      lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5439        assert.strictEqual(_.endsWith(string, 'c', position), true);
5440      });
5441    });
5442
5443    QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5444      assert.expect(1);
5445
5446      var expected = lodashStable.map(falsey, stubTrue);
5447
5448      var actual = lodashStable.map(falsey, function(position) {
5449        return _.endsWith(string, position === undefined ? 'c' : '', position);
5450      });
5451
5452      assert.deepEqual(actual, expected);
5453    });
5454
5455    QUnit.test('should treat a negative `position` as `0`', function(assert) {
5456      assert.expect(6);
5457
5458      lodashStable.each([-1, -3, -Infinity], function(position) {
5459        assert.ok(lodashStable.every(string, function(chr) {
5460          return !_.endsWith(string, chr, position);
5461        }));
5462        assert.strictEqual(_.endsWith(string, '', position), true);
5463      });
5464    });
5465
5466    QUnit.test('should coerce `position` to an integer', function(assert) {
5467      assert.expect(1);
5468
5469      assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5470    });
5471  }());
5472
5473  /*--------------------------------------------------------------------------*/
5474
5475  QUnit.module('lodash.eq');
5476
5477  (function() {
5478    QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5479      assert.expect(11);
5480
5481      assert.strictEqual(_.eq(), true);
5482      assert.strictEqual(_.eq(undefined), true);
5483      assert.strictEqual(_.eq(0, -0), true);
5484      assert.strictEqual(_.eq(NaN, NaN), true);
5485      assert.strictEqual(_.eq(1, 1), true);
5486
5487      assert.strictEqual(_.eq(null, undefined), false);
5488      assert.strictEqual(_.eq(1, Object(1)), false);
5489      assert.strictEqual(_.eq(1, '1'), false);
5490      assert.strictEqual(_.eq(1, '1'), false);
5491
5492      var object = { 'a': 1 };
5493      assert.strictEqual(_.eq(object, object), true);
5494      assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5495    });
5496  }());
5497
5498  /*--------------------------------------------------------------------------*/
5499
5500  QUnit.module('lodash.escape');
5501
5502  (function() {
5503    var escaped = '&amp;&lt;&gt;&quot;&#39;/',
5504        unescaped = '&<>"\'/';
5505
5506    escaped += escaped;
5507    unescaped += unescaped;
5508
5509    QUnit.test('should escape values', function(assert) {
5510      assert.expect(1);
5511
5512      assert.strictEqual(_.escape(unescaped), escaped);
5513    });
5514
5515    QUnit.test('should handle strings with nothing to escape', function(assert) {
5516      assert.expect(1);
5517
5518      assert.strictEqual(_.escape('abc'), 'abc');
5519    });
5520
5521    QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5522      assert.expect(1);
5523
5524      assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5525    });
5526
5527    lodashStable.each(['`', '/'], function(chr) {
5528      QUnit.test('should not escape the "' + chr + '" character', function(assert) {
5529        assert.expect(1);
5530
5531        assert.strictEqual(_.escape(chr), chr);
5532      });
5533    });
5534  }());
5535
5536  /*--------------------------------------------------------------------------*/
5537
5538  QUnit.module('lodash.escapeRegExp');
5539
5540  (function() {
5541    var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5542        unescaped = '^$.*+?()[]{}|\\';
5543
5544    QUnit.test('should escape values', function(assert) {
5545      assert.expect(1);
5546
5547      assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5548    });
5549
5550    QUnit.test('should handle strings with nothing to escape', function(assert) {
5551      assert.expect(1);
5552
5553      assert.strictEqual(_.escapeRegExp('abc'), 'abc');
5554    });
5555
5556    QUnit.test('should return an empty string for empty values', function(assert) {
5557      assert.expect(1);
5558
5559      var values = [, null, undefined, ''],
5560          expected = lodashStable.map(values, stubString);
5561
5562      var actual = lodashStable.map(values, function(value, index) {
5563        return index ? _.escapeRegExp(value) : _.escapeRegExp();
5564      });
5565
5566      assert.deepEqual(actual, expected);
5567    });
5568  }());
5569
5570  /*--------------------------------------------------------------------------*/
5571
5572  QUnit.module('lodash.every');
5573
5574  (function() {
5575    QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5576      assert.expect(1);
5577
5578      assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5579    });
5580
5581    QUnit.test('should return `true` for empty collections', function(assert) {
5582      assert.expect(1);
5583
5584      var expected = lodashStable.map(empties, stubTrue);
5585
5586      var actual = lodashStable.map(empties, function(value) {
5587        try {
5588          return _.every(value, identity);
5589        } catch (e) {}
5590      });
5591
5592      assert.deepEqual(actual, expected);
5593    });
5594
5595    QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5596      assert.expect(2);
5597
5598      var count = 0;
5599
5600      assert.strictEqual(_.every([true, null, true], function(value) {
5601        count++;
5602        return value;
5603      }), false);
5604
5605      assert.strictEqual(count, 2);
5606    });
5607
5608    QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5609      assert.expect(1);
5610
5611      assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5612    });
5613
5614    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5615      assert.expect(2);
5616
5617      var values = [, null, undefined],
5618          expected = lodashStable.map(values, stubFalse);
5619
5620      var actual = lodashStable.map(values, function(value, index) {
5621        var array = [0];
5622        return index ? _.every(array, value) : _.every(array);
5623      });
5624
5625      assert.deepEqual(actual, expected);
5626
5627      expected = lodashStable.map(values, stubTrue);
5628      actual = lodashStable.map(values, function(value, index) {
5629        var array = [1];
5630        return index ? _.every(array, value) : _.every(array);
5631      });
5632
5633      assert.deepEqual(actual, expected);
5634    });
5635
5636    QUnit.test('should work with `_.property` shorthands', function(assert) {
5637      assert.expect(2);
5638
5639      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5640      assert.strictEqual(_.every(objects, 'a'), false);
5641      assert.strictEqual(_.every(objects, 'b'), true);
5642    });
5643
5644    QUnit.test('should work with `_.matches` shorthands', function(assert) {
5645      assert.expect(2);
5646
5647      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5648      assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5649      assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5650    });
5651
5652    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5653      assert.expect(1);
5654
5655      var actual = lodashStable.map([[1]], _.every);
5656      assert.deepEqual(actual, [true]);
5657    });
5658  }());
5659
5660  /*--------------------------------------------------------------------------*/
5661
5662  QUnit.module('strict mode checks');
5663
5664  lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults', 'defaultsDeep', 'merge'], function(methodName) {
5665    var func = _[methodName],
5666        isBindAll = methodName == 'bindAll';
5667
5668    QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5669      assert.expect(1);
5670
5671      var object = freeze({ 'a': undefined, 'b': function() {} }),
5672          pass = !isStrict;
5673
5674      try {
5675        func(object, isBindAll ? 'b' : { 'a': 1 });
5676      } catch (e) {
5677        pass = !pass;
5678      }
5679      assert.ok(pass);
5680    });
5681  });
5682
5683  /*--------------------------------------------------------------------------*/
5684
5685  QUnit.module('lodash.fill');
5686
5687  (function() {
5688    QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
5689      assert.expect(1);
5690
5691      var array = [1, 2, 3];
5692      assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5693    });
5694
5695    QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5696      assert.expect(2);
5697
5698      var array = [1, 2, 3],
5699          actual = _.fill(array);
5700
5701      assert.deepEqual(actual, Array(3));
5702      assert.ok(lodashStable.every(actual, function(value, index) {
5703        return index in actual;
5704      }));
5705    });
5706
5707    QUnit.test('should work with a positive `start`', function(assert) {
5708      assert.expect(1);
5709
5710      var array = [1, 2, 3];
5711      assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5712    });
5713
5714    QUnit.test('should work with a `start` >= `length`', function(assert) {
5715      assert.expect(4);
5716
5717      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5718        var array = [1, 2, 3];
5719        assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5720      });
5721    });
5722
5723    QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5724      assert.expect(1);
5725
5726      var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5727
5728      var actual = lodashStable.map(falsey, function(start) {
5729        var array = [1, 2, 3];
5730        return _.fill(array, 'a', start);
5731      });
5732
5733      assert.deepEqual(actual, expected);
5734    });
5735
5736    QUnit.test('should work with a negative `start`', function(assert) {
5737      assert.expect(1);
5738
5739      var array = [1, 2, 3];
5740      assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5741    });
5742
5743    QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
5744      assert.expect(3);
5745
5746      lodashStable.each([-3, -4, -Infinity], function(start) {
5747        var array = [1, 2, 3];
5748        assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5749      });
5750    });
5751
5752    QUnit.test('should work with `start` >= `end`', function(assert) {
5753      assert.expect(2);
5754
5755      lodashStable.each([2, 3], function(start) {
5756        var array = [1, 2, 3];
5757        assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5758      });
5759    });
5760
5761    QUnit.test('should work with a positive `end`', function(assert) {
5762      assert.expect(1);
5763
5764      var array = [1, 2, 3];
5765      assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5766    });
5767
5768    QUnit.test('should work with a `end` >= `length`', function(assert) {
5769      assert.expect(4);
5770
5771      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5772        var array = [1, 2, 3];
5773        assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5774      });
5775    });
5776
5777    QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5778      assert.expect(1);
5779
5780      var expected = lodashStable.map(falsey, function(value) {
5781        return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5782      });
5783
5784      var actual = lodashStable.map(falsey, function(end) {
5785        var array = [1, 2, 3];
5786        return _.fill(array, 'a', 0, end);
5787      });
5788
5789      assert.deepEqual(actual, expected);
5790    });
5791
5792    QUnit.test('should work with a negative `end`', function(assert) {
5793      assert.expect(1);
5794
5795      var array = [1, 2, 3];
5796      assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5797    });
5798
5799    QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
5800      assert.expect(3);
5801
5802      lodashStable.each([-3, -4, -Infinity], function(end) {
5803        var array = [1, 2, 3];
5804        assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5805      });
5806    });
5807
5808    QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5809      assert.expect(1);
5810
5811      var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5812
5813      var actual = lodashStable.map(positions, function(pos) {
5814        var array = [1, 2, 3];
5815        return _.fill.apply(_, [array, 'a'].concat(pos));
5816      });
5817
5818      assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5819    });
5820
5821    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5822      assert.expect(1);
5823
5824      var array = [[1, 2], [3, 4]],
5825          actual = lodashStable.map(array, _.fill);
5826
5827      assert.deepEqual(actual, [[0, 0], [1, 1]]);
5828    });
5829
5830    QUnit.test('should return a wrapped value when chaining', function(assert) {
5831      assert.expect(3);
5832
5833      if (!isNpm) {
5834        var array = [1, 2, 3],
5835            wrapped = _(array).fill('a'),
5836            actual = wrapped.value();
5837
5838        assert.ok(wrapped instanceof _);
5839        assert.strictEqual(actual, array);
5840        assert.deepEqual(actual, ['a', 'a', 'a']);
5841      }
5842      else {
5843        skipAssert(assert, 3);
5844      }
5845    });
5846  }());
5847
5848  /*--------------------------------------------------------------------------*/
5849
5850  QUnit.module('lodash.filter');
5851
5852  (function() {
5853    var array = [1, 2, 3];
5854
5855    QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5856      assert.expect(1);
5857
5858      assert.deepEqual(_.filter(array, isEven), [2]);
5859    });
5860  }());
5861
5862  /*--------------------------------------------------------------------------*/
5863
5864  lodashStable.each(['find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', 'findLastKey'], function(methodName) {
5865    QUnit.module('lodash.' + methodName);
5866
5867    var array = [1, 2, 3, 4],
5868        func = _[methodName];
5869
5870    var objects = [
5871      { 'a': 0, 'b': 0 },
5872      { 'a': 1, 'b': 1 },
5873      { 'a': 2, 'b': 2 }
5874    ];
5875
5876    var expected = ({
5877      'find': [objects[1], undefined, objects[2]],
5878      'findIndex': [1, -1, 2],
5879      'findKey': ['1', undefined, '2'],
5880      'findLast': [objects[2], undefined, objects[2]],
5881      'findLastIndex': [2, -1, 2],
5882      'findLastKey': ['2', undefined, '2']
5883    })[methodName];
5884
5885    QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
5886      assert.expect(1);
5887
5888      assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5889    });
5890
5891    QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
5892      assert.expect(1);
5893
5894      assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5895    });
5896
5897    QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
5898      assert.expect(1);
5899
5900      assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5901    });
5902
5903    QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
5904      assert.expect(1);
5905
5906      assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5907    });
5908
5909    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5910      assert.expect(1);
5911
5912      assert.strictEqual(func(objects, 'b'), expected[0]);
5913    });
5914
5915    QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
5916      assert.expect(1);
5917
5918      var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5919          expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5920
5921      var actual = lodashStable.map(emptyValues, function(value) {
5922        try {
5923          return func(value, { 'a': 3 });
5924        } catch (e) {}
5925      });
5926
5927      assert.deepEqual(actual, expecting);
5928    });
5929
5930    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5931      assert.expect(1);
5932
5933      var expected = ({
5934        'find': 1,
5935        'findIndex': 0,
5936        'findKey': '0',
5937        'findLast': 4,
5938        'findLastIndex': 3,
5939        'findLastKey': '3'
5940      })[methodName];
5941
5942      if (!isNpm) {
5943        assert.strictEqual(_(array)[methodName](), expected);
5944      }
5945      else {
5946        skipAssert(assert);
5947      }
5948    });
5949
5950    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5951      assert.expect(1);
5952
5953      if (!isNpm) {
5954        assert.ok(_(array).chain()[methodName]() instanceof _);
5955      }
5956      else {
5957        skipAssert(assert);
5958      }
5959    });
5960
5961    QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
5962      assert.expect(1);
5963
5964      if (!isNpm) {
5965        var wrapped = _(array).chain()[methodName]();
5966        assert.strictEqual(wrapped.__wrapped__, array);
5967      }
5968      else {
5969        skipAssert(assert);
5970      }
5971    });
5972
5973    QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
5974      assert.expect(2);
5975
5976      if (!isNpm) {
5977        var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5978            smallArray = array;
5979
5980        lodashStable.times(2, function(index) {
5981          var array = index ? largeArray : smallArray,
5982              wrapped = _(array).filter(isEven);
5983
5984          assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5985        });
5986      }
5987      else {
5988        skipAssert(assert, 2);
5989      }
5990    });
5991  });
5992
5993  _.each(['find', 'findIndex', 'findLast', 'findLastIndex'], function(methodName) {
5994    var func = _[methodName];
5995
5996    QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for arrays', function(assert) {
5997      assert.expect(1);
5998
5999      var args,
6000          array = ['a'];
6001
6002      func(array, function() {
6003        args || (args = slice.call(arguments));
6004      });
6005
6006      assert.deepEqual(args, ['a', 0, array]);
6007    });
6008  });
6009
6010  _.each(['find', 'findKey', 'findLast', 'findLastKey'], function(methodName) {
6011    var func = _[methodName];
6012
6013    QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
6014      assert.expect(1);
6015
6016      var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
6017        return n < 3;
6018      });
6019
6020      var expected = ({
6021        'find': 1,
6022        'findKey': 'a',
6023        'findLast': 2,
6024        'findLastKey': 'b'
6025      })[methodName];
6026
6027      assert.strictEqual(actual, expected);
6028    });
6029
6030    QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for objects', function(assert) {
6031      assert.expect(1);
6032
6033      var args,
6034          object = { 'a': 1 };
6035
6036      func(object, function() {
6037        args || (args = slice.call(arguments));
6038      });
6039
6040      assert.deepEqual(args, [1, 'a', object]);
6041    });
6042  });
6043
6044  /*--------------------------------------------------------------------------*/
6045
6046  QUnit.module('lodash.find and lodash.findLast');
6047
6048  lodashStable.each(['find', 'findLast'], function(methodName) {
6049    var isFind = methodName == 'find';
6050
6051    QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6052      assert.expect(3);
6053
6054      if (!isNpm) {
6055        var findCount = 0,
6056            mapCount = 0,
6057            array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
6058            iteratee = function(value) { mapCount++; return square(value); },
6059            predicate = function(value) { findCount++; return isEven(value); },
6060            actual = _(array).map(iteratee)[methodName](predicate);
6061
6062        assert.strictEqual(findCount, isFind ? 2 : 1);
6063        assert.strictEqual(mapCount, isFind ? 2 : 1);
6064        assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
6065      }
6066      else {
6067        skipAssert(assert, 3);
6068      }
6069    });
6070  });
6071
6072  /*--------------------------------------------------------------------------*/
6073
6074  QUnit.module('lodash.find and lodash.includes');
6075
6076  lodashStable.each(['includes', 'find'], function(methodName) {
6077    var func = _[methodName],
6078        isIncludes = methodName == 'includes',
6079        resolve = methodName == 'find' ? lodashStable.curry(lodashStable.eq) : identity;
6080
6081    lodashStable.each({
6082      'an `arguments` object': args,
6083      'an array': [1, 2, 3]
6084    },
6085    function(collection, key) {
6086      var values = lodashStable.toArray(collection);
6087
6088      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6089        assert.expect(1);
6090
6091        var expected = [
6092          isIncludes || values[2],
6093          isIncludes ? false : undefined
6094        ];
6095
6096        var actual = [
6097          func(collection, resolve(values[2]), 2),
6098          func(collection, resolve(values[1]), 2)
6099        ];
6100
6101        assert.deepEqual(actual, expected);
6102      });
6103
6104      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6105        assert.expect(1);
6106
6107        var indexes = [4, 6, Math.pow(2, 32), Infinity];
6108
6109        var expected = lodashStable.map(indexes, function() {
6110          var result = isIncludes ? false : undefined;
6111          return [result, result, result];
6112        });
6113
6114        var actual = lodashStable.map(indexes, function(fromIndex) {
6115          return [
6116            func(collection, resolve(1), fromIndex),
6117            func(collection, resolve(undefined), fromIndex),
6118            func(collection, resolve(''), fromIndex)
6119          ];
6120        });
6121
6122        assert.deepEqual(actual, expected);
6123      });
6124
6125      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
6126        assert.expect(1);
6127
6128        var expected = lodashStable.map(falsey, lodashStable.constant(isIncludes || values[0]));
6129
6130        var actual = lodashStable.map(falsey, function(fromIndex) {
6131          return func(collection, resolve(values[0]), fromIndex);
6132        });
6133
6134        assert.deepEqual(actual, expected);
6135      });
6136
6137      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6138        assert.expect(1);
6139
6140        var expected = [
6141          isIncludes || values[0],
6142          isIncludes || values[0],
6143          isIncludes ? false : undefined
6144        ];
6145
6146        var actual = [
6147          func(collection, resolve(values[0]), 0.1),
6148          func(collection, resolve(values[0]), NaN),
6149          func(collection, resolve(values[0]), '1')
6150        ];
6151
6152        assert.deepEqual(actual, expected);
6153      });
6154
6155      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6156        assert.expect(1);
6157
6158        var expected = [
6159          isIncludes || values[2],
6160          isIncludes ? false : undefined
6161        ];
6162
6163        var actual = [
6164          func(collection, resolve(values[2]), -1),
6165          func(collection, resolve(values[1]), -1)
6166        ];
6167
6168        assert.deepEqual(actual, expected);
6169      });
6170
6171      QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6172        assert.expect(1);
6173
6174        var indexes = [-4, -6, -Infinity],
6175            expected = lodashStable.map(indexes, lodashStable.constant(isIncludes || values[0]));
6176
6177        var actual = lodashStable.map(indexes, function(fromIndex) {
6178          return func(collection, resolve(values[0]), fromIndex);
6179        });
6180
6181        assert.deepEqual(actual, expected);
6182      });
6183    });
6184  });
6185
6186  /*--------------------------------------------------------------------------*/
6187
6188  QUnit.module('lodash.findIndex and lodash.indexOf');
6189
6190  lodashStable.each(['findIndex', 'indexOf'], function(methodName) {
6191    var array = [1, 2, 3, 1, 2, 3],
6192        func = _[methodName],
6193        resolve = methodName == 'findIndex' ? lodashStable.curry(lodashStable.eq) : identity;
6194
6195    QUnit.test('`_.' + methodName + '` should return the index of the first matched value', function(assert) {
6196      assert.expect(1);
6197
6198      assert.strictEqual(func(array, resolve(3)), 2);
6199    });
6200
6201    QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
6202      assert.expect(1);
6203
6204      assert.strictEqual(func(array, resolve(1), 2), 3);
6205    });
6206
6207    QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
6208      assert.expect(1);
6209
6210      var values = [6, 8, Math.pow(2, 32), Infinity],
6211          expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
6212
6213      var actual = lodashStable.map(values, function(fromIndex) {
6214        return [
6215          func(array, resolve(undefined), fromIndex),
6216          func(array, resolve(1), fromIndex),
6217          func(array, resolve(''), fromIndex)
6218        ];
6219      });
6220
6221      assert.deepEqual(actual, expected);
6222    });
6223
6224    QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
6225      assert.expect(1);
6226
6227      assert.strictEqual(func(array, resolve(2), -3), 4);
6228    });
6229
6230    QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
6231      assert.expect(1);
6232
6233      var values = [-6, -8, -Infinity],
6234          expected = lodashStable.map(values, stubZero);
6235
6236      var actual = lodashStable.map(values, function(fromIndex) {
6237        return func(array, resolve(1), fromIndex);
6238      });
6239
6240      assert.deepEqual(actual, expected);
6241    });
6242
6243    QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values as `0`', function(assert) {
6244      assert.expect(1);
6245
6246      var expected = lodashStable.map(falsey, stubZero);
6247
6248      var actual = lodashStable.map(falsey, function(fromIndex) {
6249        return func(array, resolve(1), fromIndex);
6250      });
6251
6252      assert.deepEqual(actual, expected);
6253    });
6254
6255    QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
6256      assert.expect(1);
6257
6258      assert.strictEqual(func(array, resolve(2), 1.2), 1);
6259    });
6260  });
6261
6262  /*--------------------------------------------------------------------------*/
6263
6264  QUnit.module('lodash.findLast');
6265
6266  (function() {
6267    var resolve = lodashStable.curry(lodashStable.eq);
6268
6269    lodashStable.each({
6270      'an `arguments` object': args,
6271      'an array': [1, 2, 3]
6272    },
6273    function(collection, key) {
6274      var values = lodashStable.toArray(collection);
6275
6276      QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
6277        assert.expect(1);
6278
6279        var expected = [
6280          values[1],
6281          undefined
6282        ];
6283
6284        var actual = [
6285          _.findLast(collection, resolve(values[1]), 1),
6286          _.findLast(collection, resolve(values[2]), 1)
6287        ];
6288
6289        assert.deepEqual(actual, expected);
6290      });
6291
6292      QUnit.test('should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) {
6293        assert.expect(1);
6294
6295        var indexes = [4, 6, Math.pow(2, 32), Infinity];
6296
6297        var expected = lodashStable.map(indexes, lodashStable.constant([values[0], undefined, undefined]));
6298
6299        var actual = lodashStable.map(indexes, function(fromIndex) {
6300          return [
6301            _.findLast(collection, resolve(1), fromIndex),
6302            _.findLast(collection, resolve(undefined), fromIndex),
6303            _.findLast(collection, resolve(''), fromIndex)
6304          ];
6305        });
6306
6307        assert.deepEqual(actual, expected);
6308      });
6309
6310      QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values correctly', function(assert) {
6311        assert.expect(1);
6312
6313        var expected = lodashStable.map(falsey, function(value) {
6314          return value === undefined ? values[3] : undefined;
6315        });
6316
6317        var actual = lodashStable.map(falsey, function(fromIndex) {
6318          return _.findLast(collection, resolve(values[3]), fromIndex);
6319        });
6320
6321        assert.deepEqual(actual, expected);
6322      });
6323
6324      QUnit.test('should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) {
6325        assert.expect(1);
6326
6327        var expected = [
6328          values[0],
6329          values[0],
6330          undefined
6331        ];
6332
6333        var actual = [
6334          _.findLast(collection, resolve(values[0]), 0.1),
6335          _.findLast(collection, resolve(values[0]), NaN),
6336          _.findLast(collection, resolve(values[2]), '1')
6337        ];
6338
6339        assert.deepEqual(actual, expected);
6340      });
6341
6342      QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
6343        assert.expect(1);
6344
6345        var expected = [
6346          values[1],
6347          undefined
6348        ];
6349
6350        var actual = [
6351          _.findLast(collection, resolve(values[1]), -2),
6352          _.findLast(collection, resolve(values[2]), -2)
6353        ];
6354
6355        assert.deepEqual(actual, expected);
6356      });
6357
6358      QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) {
6359        assert.expect(1);
6360
6361        var indexes = [-4, -6, -Infinity],
6362            expected = lodashStable.map(indexes, lodashStable.constant(values[0]));
6363
6364        var actual = lodashStable.map(indexes, function(fromIndex) {
6365          return _.findLast(collection, resolve(values[0]), fromIndex);
6366        });
6367
6368        assert.deepEqual(actual, expected);
6369      });
6370    });
6371  }());
6372
6373  /*--------------------------------------------------------------------------*/
6374
6375  QUnit.module('lodash.flip');
6376
6377  (function() {
6378    function fn() {
6379      return slice.call(arguments);
6380    }
6381
6382    QUnit.test('should flip arguments provided to `func`', function(assert) {
6383      assert.expect(1);
6384
6385      var flipped = _.flip(fn);
6386      assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
6387    });
6388  }());
6389
6390  /*--------------------------------------------------------------------------*/
6391
6392  QUnit.module('lodash.flatMapDepth');
6393
6394  (function() {
6395    var array = [1, [2, [3, [4]], 5]];
6396
6397    QUnit.test('should use a default `depth` of `1`', function(assert) {
6398      assert.expect(1);
6399
6400      assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
6401    });
6402
6403    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
6404      assert.expect(1);
6405
6406      var values = [, null, undefined],
6407          expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
6408
6409      var actual = lodashStable.map(values, function(value, index) {
6410        return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
6411      });
6412
6413      assert.deepEqual(actual, expected);
6414    });
6415
6416    QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6417      assert.expect(2);
6418
6419      lodashStable.each([-1, 0], function(depth) {
6420        assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
6421      });
6422    });
6423
6424    QUnit.test('should coerce `depth` to an integer', function(assert) {
6425      assert.expect(1);
6426
6427      assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
6428    });
6429  }());
6430
6431  /*--------------------------------------------------------------------------*/
6432
6433  QUnit.module('flatMap methods');
6434
6435  lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
6436    var func = _[methodName],
6437        array = [1, 2, 3, 4];
6438
6439    function duplicate(n) {
6440      return [n, n];
6441    }
6442
6443    QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
6444      assert.expect(1);
6445
6446      var actual = func(array, duplicate),
6447          expected = lodashStable.flatten(lodashStable.map(array, duplicate));
6448
6449      assert.deepEqual(actual, expected);
6450    });
6451
6452    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
6453      assert.expect(1);
6454
6455      var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
6456      assert.deepEqual(func(objects, 'a'), array);
6457    });
6458
6459    QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
6460      assert.expect(1);
6461
6462      function Foo() {
6463        this.a = [1, 2];
6464      }
6465      Foo.prototype.b = [3, 4];
6466
6467      var actual = func(new Foo, identity);
6468      assert.deepEqual(actual, [1, 2]);
6469    });
6470
6471    QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
6472      assert.expect(2);
6473
6474      var array = [[1, 2], [3, 4]],
6475          object = { 'a': [1, 2], 'b': [3, 4] },
6476          values = [, null, undefined],
6477          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
6478
6479      lodashStable.each([array, object], function(collection) {
6480        var actual = lodashStable.map(values, function(value, index) {
6481          return index ? func(collection, value) : func(collection);
6482        });
6483
6484        assert.deepEqual(actual, expected);
6485      });
6486    });
6487
6488    QUnit.test('`_.' + methodName + '` should accept a falsey `collection`', function(assert) {
6489      assert.expect(1);
6490
6491      var expected = lodashStable.map(falsey, stubArray);
6492
6493      var actual = lodashStable.map(falsey, function(collection, index) {
6494        try {
6495          return index ? func(collection) : func();
6496        } catch (e) {}
6497      });
6498
6499      assert.deepEqual(actual, expected);
6500    });
6501
6502    QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
6503      assert.expect(1);
6504
6505      assert.deepEqual(func(1), []);
6506    });
6507
6508    QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
6509      assert.expect(1);
6510
6511      var object = { 'length': [1, 2] };
6512      assert.deepEqual(func(object, identity), [1, 2]);
6513    });
6514  });
6515
6516  /*--------------------------------------------------------------------------*/
6517
6518  QUnit.module('lodash.flattenDepth');
6519
6520  (function() {
6521    var array = [1, [2, [3, [4]], 5]];
6522
6523    QUnit.test('should use a default `depth` of `1`', function(assert) {
6524      assert.expect(1);
6525
6526      assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
6527    });
6528
6529    QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6530      assert.expect(2);
6531
6532      lodashStable.each([-1, 0], function(depth) {
6533        assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
6534      });
6535    });
6536
6537    QUnit.test('should coerce `depth` to an integer', function(assert) {
6538      assert.expect(1);
6539
6540      assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
6541    });
6542  }());
6543
6544  /*--------------------------------------------------------------------------*/
6545
6546  QUnit.module('flatten methods');
6547
6548  (function() {
6549    var array = [1, [2, [3, [4]], 5]],
6550        methodNames = ['flatten', 'flattenDeep', 'flattenDepth'];
6551
6552    QUnit.test('should flatten `arguments` objects', function(assert) {
6553      assert.expect(3);
6554
6555      var array = [args, [args]];
6556
6557      assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
6558      assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
6559      assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
6560    });
6561
6562    QUnit.test('should treat sparse arrays as dense', function(assert) {
6563      assert.expect(6);
6564
6565      var array = [[1, 2, 3], Array(3)],
6566          expected = [1, 2, 3];
6567
6568      expected.push(undefined, undefined, undefined);
6569
6570      lodashStable.each(methodNames, function(methodName) {
6571        var actual = _[methodName](array);
6572        assert.deepEqual(actual, expected);
6573        assert.ok('4' in actual);
6574      });
6575    });
6576
6577    QUnit.test('should flatten objects with a truthy `Symbol.isConcatSpreadable` value', function(assert) {
6578      assert.expect(1);
6579
6580      if (Symbol && Symbol.isConcatSpreadable) {
6581        var object = { '0': 'a', 'length': 1 },
6582            array = [object],
6583            expected = lodashStable.map(methodNames, lodashStable.constant(['a']));
6584
6585        object[Symbol.isConcatSpreadable] = true;
6586
6587        var actual = lodashStable.map(methodNames, function(methodName) {
6588          return _[methodName](array);
6589        });
6590
6591        assert.deepEqual(actual, expected);
6592      }
6593      else {
6594        skipAssert(assert);
6595      }
6596    });
6597
6598    QUnit.test('should work with extremely large arrays', function(assert) {
6599      assert.expect(3);
6600
6601      lodashStable.times(3, function(index) {
6602        var expected = Array(5e5);
6603        try {
6604          var func = _.flatten;
6605          if (index == 1) {
6606            func = _.flattenDeep;
6607          } else if (index == 2) {
6608            func = _.flattenDepth;
6609          }
6610          assert.deepEqual(func([expected]), expected);
6611        } catch (e) {
6612          assert.ok(false, e.message);
6613        }
6614      });
6615    });
6616
6617    QUnit.test('should work with empty arrays', function(assert) {
6618      assert.expect(3);
6619
6620      var array = [[], [[]], [[], [[[]]]]];
6621
6622      assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
6623      assert.deepEqual(_.flattenDeep(array), []);
6624      assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
6625    });
6626
6627    QUnit.test('should support flattening of nested arrays', function(assert) {
6628      assert.expect(3);
6629
6630      assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
6631      assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
6632      assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
6633    });
6634
6635    QUnit.test('should return an empty array for non array-like objects', function(assert) {
6636      assert.expect(3);
6637
6638      var expected = [],
6639          nonArray = { '0': 'a' };
6640
6641      assert.deepEqual(_.flatten(nonArray), expected);
6642      assert.deepEqual(_.flattenDeep(nonArray), expected);
6643      assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
6644    });
6645
6646    QUnit.test('should return a wrapped value when chaining', function(assert) {
6647      assert.expect(6);
6648
6649      if (!isNpm) {
6650        var wrapped = _(array),
6651            actual = wrapped.flatten();
6652
6653        assert.ok(actual instanceof _);
6654        assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
6655
6656        actual = wrapped.flattenDeep();
6657
6658        assert.ok(actual instanceof _);
6659        assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
6660
6661        actual = wrapped.flattenDepth(2);
6662
6663        assert.ok(actual instanceof _);
6664        assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
6665      }
6666      else {
6667        skipAssert(assert, 6);
6668      }
6669    });
6670  }());
6671
6672  /*--------------------------------------------------------------------------*/
6673
6674  QUnit.module('flow methods');
6675
6676  lodashStable.each(['flow', 'flowRight'], function(methodName) {
6677    var func = _[methodName],
6678        isFlow = methodName == 'flow';
6679
6680    QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
6681      assert.expect(1);
6682
6683      var fixed = function(n) { return n.toFixed(1); },
6684          combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
6685
6686      assert.strictEqual(combined(1, 2), '9.0');
6687    });
6688
6689    QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
6690      assert.expect(1);
6691
6692      assert.notStrictEqual(func(noop), noop);
6693    });
6694
6695    QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
6696      assert.expect(6);
6697
6698      _.times(2, function(index) {
6699        try {
6700          var combined = index ? func([]) : func();
6701          assert.strictEqual(combined('a'), 'a');
6702        } catch (e) {
6703          assert.ok(false, e.message);
6704        }
6705        assert.strictEqual(combined.length, 0);
6706        assert.notStrictEqual(combined, identity);
6707      });
6708    });
6709
6710    QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
6711      assert.expect(1);
6712
6713      var curried = _.curry(identity);
6714
6715      var combined = isFlow
6716        ? func(_.head, curried)
6717        : func(curried, _.head);
6718
6719      assert.strictEqual(combined([1]), 1);
6720    });
6721
6722    QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6723      assert.expect(6);
6724
6725      var filterCount,
6726          mapCount,
6727          array = lodashStable.range(LARGE_ARRAY_SIZE),
6728          iteratee = function(value) { mapCount++; return square(value); },
6729          predicate = function(value) { filterCount++; return isEven(value); };
6730
6731      lodashStable.times(2, function(index) {
6732        var filter1 = _.filter,
6733            filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
6734            filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
6735
6736        var map1 = _.map,
6737            map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
6738            map3 = (_.map = index ? map2 : map1, map2(iteratee));
6739
6740        var take1 = _.take,
6741            take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
6742            take3 = (_.take = index ? take2 : take1, take2(2));
6743
6744        var combined = isFlow
6745          ? func(map3, filter3, _.compact, take3)
6746          : func(take3, _.compact, filter3, map3);
6747
6748        filterCount = mapCount = 0;
6749        assert.deepEqual(combined(array), [4, 16]);
6750
6751        if (!isNpm && WeakMap && WeakMap.name) {
6752          assert.strictEqual(filterCount, 5, 'filterCount');
6753          assert.strictEqual(mapCount, 5, 'mapCount');
6754        }
6755        else {
6756          skipAssert(assert, 2);
6757        }
6758        _.filter = filter1;
6759        _.map = map1;
6760        _.take = take1;
6761      });
6762    });
6763
6764    QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
6765      assert.expect(1);
6766
6767      var curried = _.curry(_.ary(_.map, 2), 2),
6768          getProp = curried(curried.placeholder, 'a'),
6769          objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
6770
6771      var combined = isFlow
6772        ? func(getProp, _.uniq)
6773        : func(_.uniq, getProp);
6774
6775      assert.deepEqual(combined(objects), [1, 2]);
6776    });
6777
6778    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6779      assert.expect(1);
6780
6781      if (!isNpm) {
6782        var wrapped = _(noop)[methodName]();
6783        assert.ok(wrapped instanceof _);
6784      }
6785      else {
6786        skipAssert(assert);
6787      }
6788    });
6789  });
6790
6791  /*--------------------------------------------------------------------------*/
6792
6793  QUnit.module('lodash.forEach');
6794
6795  (function() {
6796    QUnit.test('should be aliased', function(assert) {
6797      assert.expect(1);
6798
6799      assert.strictEqual(_.each, _.forEach);
6800    });
6801  }());
6802
6803  /*--------------------------------------------------------------------------*/
6804
6805  QUnit.module('lodash.forEachRight');
6806
6807  (function() {
6808    QUnit.test('should be aliased', function(assert) {
6809      assert.expect(1);
6810
6811      assert.strictEqual(_.eachRight, _.forEachRight);
6812    });
6813  }());
6814
6815  /*--------------------------------------------------------------------------*/
6816
6817  QUnit.module('forIn methods');
6818
6819  lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6820    var func = _[methodName];
6821
6822    QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
6823      assert.expect(1);
6824
6825      function Foo() {
6826        this.a = 1;
6827      }
6828      Foo.prototype.b = 2;
6829
6830      var keys = [];
6831      func(new Foo, function(value, key) { keys.push(key); });
6832      assert.deepEqual(keys.sort(), ['a', 'b']);
6833    });
6834  });
6835
6836  /*--------------------------------------------------------------------------*/
6837
6838  QUnit.module('forOwn methods');
6839
6840  lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6841    var func = _[methodName];
6842
6843    QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
6844      assert.expect(1);
6845
6846      var object = { '0': 'zero', '1': 'one', 'length': 2 },
6847          props = [];
6848
6849      func(object, function(value, prop) { props.push(prop); });
6850      assert.deepEqual(props.sort(), ['0', '1', 'length']);
6851    });
6852  });
6853
6854  /*--------------------------------------------------------------------------*/
6855
6856  QUnit.module('iteration methods');
6857
6858  (function() {
6859    var methods = [
6860      '_baseEach',
6861      'countBy',
6862      'every',
6863      'filter',
6864      'find',
6865      'findIndex',
6866      'findKey',
6867      'findLast',
6868      'findLastIndex',
6869      'findLastKey',
6870      'forEach',
6871      'forEachRight',
6872      'forIn',
6873      'forInRight',
6874      'forOwn',
6875      'forOwnRight',
6876      'groupBy',
6877      'keyBy',
6878      'map',
6879      'mapKeys',
6880      'mapValues',
6881      'maxBy',
6882      'minBy',
6883      'omitBy',
6884      'partition',
6885      'pickBy',
6886      'reject',
6887      'some'
6888    ];
6889
6890    var arrayMethods = [
6891      'findIndex',
6892      'findLastIndex',
6893      'maxBy',
6894      'minBy'
6895    ];
6896
6897    var collectionMethods = [
6898      '_baseEach',
6899      'countBy',
6900      'every',
6901      'filter',
6902      'find',
6903      'findLast',
6904      'forEach',
6905      'forEachRight',
6906      'groupBy',
6907      'keyBy',
6908      'map',
6909      'partition',
6910      'reduce',
6911      'reduceRight',
6912      'reject',
6913      'some'
6914    ];
6915
6916    var forInMethods = [
6917      'forIn',
6918      'forInRight',
6919      'omitBy',
6920      'pickBy'
6921    ];
6922
6923    var iterationMethods = [
6924      '_baseEach',
6925      'forEach',
6926      'forEachRight',
6927      'forIn',
6928      'forInRight',
6929      'forOwn',
6930      'forOwnRight'
6931    ];
6932
6933    var objectMethods = [
6934      'findKey',
6935      'findLastKey',
6936      'forIn',
6937      'forInRight',
6938      'forOwn',
6939      'forOwnRight',
6940      'mapKeys',
6941      'mapValues',
6942      'omitBy',
6943      'pickBy'
6944    ];
6945
6946    var rightMethods = [
6947      'findLast',
6948      'findLastIndex',
6949      'findLastKey',
6950      'forEachRight',
6951      'forInRight',
6952      'forOwnRight'
6953    ];
6954
6955    var unwrappedMethods = [
6956      'each',
6957      'eachRight',
6958      'every',
6959      'find',
6960      'findIndex',
6961      'findKey',
6962      'findLast',
6963      'findLastIndex',
6964      'findLastKey',
6965      'forEach',
6966      'forEachRight',
6967      'forIn',
6968      'forInRight',
6969      'forOwn',
6970      'forOwnRight',
6971      'max',
6972      'maxBy',
6973      'min',
6974      'minBy',
6975      'some'
6976    ];
6977
6978    lodashStable.each(methods, function(methodName) {
6979      var array = [1, 2, 3],
6980          func = _[methodName],
6981          isBy = /(^partition|By)$/.test(methodName),
6982          isFind = /^find/.test(methodName),
6983          isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6984          isSome = methodName == 'some';
6985
6986      QUnit.test('`_.' + methodName + '` should provide correct iteratee arguments', function(assert) {
6987        assert.expect(1);
6988
6989        if (func) {
6990          var args,
6991              expected = [1, 0, array];
6992
6993          func(array, function() {
6994            args || (args = slice.call(arguments));
6995          });
6996
6997          if (lodashStable.includes(rightMethods, methodName)) {
6998            expected[0] = 3;
6999            expected[1] = 2;
7000          }
7001          if (lodashStable.includes(objectMethods, methodName)) {
7002            expected[1] += '';
7003          }
7004          if (isBy) {
7005            expected.length = isOmitPick ? 2 : 1;
7006          }
7007          assert.deepEqual(args, expected);
7008        }
7009        else {
7010          skipAssert(assert);
7011        }
7012      });
7013
7014      QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
7015        assert.expect(1);
7016
7017        if (func) {
7018          var array = [1];
7019          array[2] = 3;
7020
7021          var expected = lodashStable.includes(objectMethods, methodName)
7022            ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
7023            : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
7024
7025          if (isBy) {
7026            expected = lodashStable.map(expected, function(args) {
7027              return args.slice(0, isOmitPick ? 2 : 1);
7028            });
7029          }
7030          else if (lodashStable.includes(objectMethods, methodName)) {
7031            expected = lodashStable.map(expected, function(args) {
7032              args[1] += '';
7033              return args;
7034            });
7035          }
7036          if (lodashStable.includes(rightMethods, methodName)) {
7037            expected.reverse();
7038          }
7039          var argsList = [];
7040          func(array, function() {
7041            argsList.push(slice.call(arguments));
7042            return !(isFind || isSome);
7043          });
7044
7045          assert.deepEqual(argsList, expected);
7046        }
7047        else {
7048          skipAssert(assert);
7049        }
7050      });
7051    });
7052
7053    lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
7054      var array = [1, 2, 3],
7055          func = _[methodName],
7056          isEvery = methodName == 'every';
7057
7058      array.a = 1;
7059
7060      QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
7061        assert.expect(1);
7062
7063        if (func) {
7064          var keys = [];
7065          func(array, function(value, key) {
7066            keys.push(key);
7067            return isEvery;
7068          });
7069
7070          assert.notOk(lodashStable.includes(keys, 'a'));
7071        }
7072        else {
7073          skipAssert(assert);
7074        }
7075      });
7076    });
7077
7078    lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
7079      var array = [1, 2, 3],
7080          isBaseEach = methodName == '_baseEach';
7081
7082      QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
7083        assert.expect(1);
7084
7085        if (!(isBaseEach || isNpm)) {
7086          var wrapped = _(array)[methodName](noop);
7087          assert.ok(wrapped instanceof _);
7088        }
7089        else {
7090          skipAssert(assert);
7091        }
7092      });
7093    });
7094
7095    lodashStable.each(unwrappedMethods, function(methodName) {
7096      var array = [1, 2, 3];
7097
7098      QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
7099        assert.expect(1);
7100
7101        if (!isNpm) {
7102          var actual = _(array)[methodName](noop);
7103          assert.notOk(actual instanceof _);
7104        }
7105        else {
7106          skipAssert(assert);
7107        }
7108      });
7109
7110      QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
7111        assert.expect(2);
7112
7113        if (!isNpm) {
7114          var wrapped = _(array).chain(),
7115              actual = wrapped[methodName](noop);
7116
7117          assert.ok(actual instanceof _);
7118          assert.notStrictEqual(actual, wrapped);
7119        }
7120        else {
7121          skipAssert(assert, 2);
7122        }
7123      });
7124    });
7125
7126    lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
7127      var func = _[methodName];
7128
7129      QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
7130        assert.expect(1);
7131
7132        function Foo() {
7133          this.a = 1;
7134        }
7135        Foo.prototype.b = 2;
7136
7137        if (func) {
7138          var values = [];
7139          func(new Foo, function(value) { values.push(value); });
7140          assert.deepEqual(values, [1]);
7141        }
7142        else {
7143          skipAssert(assert);
7144        }
7145      });
7146    });
7147
7148    lodashStable.each(iterationMethods, function(methodName) {
7149      var array = [1, 2, 3],
7150          func = _[methodName];
7151
7152      QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
7153        assert.expect(1);
7154
7155        if (func) {
7156          assert.strictEqual(func(array, Boolean), array);
7157        }
7158        else {
7159          skipAssert(assert);
7160        }
7161      });
7162    });
7163
7164    lodashStable.each(collectionMethods, function(methodName) {
7165      var func = _[methodName];
7166
7167      QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
7168        assert.expect(3);
7169
7170        if (func) {
7171          var isIteratedAsObject = function(object) {
7172            var result = false;
7173            func(object, function() { result = true; }, 0);
7174            return result;
7175          };
7176
7177          var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
7178              expected = lodashStable.map(values, stubTrue);
7179
7180          var actual = lodashStable.map(values, function(length) {
7181            return isIteratedAsObject({ 'length': length });
7182          });
7183
7184          var Foo = function(a) {};
7185          Foo.a = 1;
7186
7187          assert.deepEqual(actual, expected);
7188          assert.ok(isIteratedAsObject(Foo));
7189          assert.notOk(isIteratedAsObject({ 'length': 0 }));
7190        }
7191        else {
7192          skipAssert(assert, 3);
7193        }
7194      });
7195    });
7196
7197    lodashStable.each(methods, function(methodName) {
7198      var func = _[methodName],
7199          isFind = /^find/.test(methodName),
7200          isSome = methodName == 'some',
7201          isReduce = /^reduce/.test(methodName);
7202
7203      QUnit.test('`_.' + methodName + '` should ignore changes to `length`', function(assert) {
7204        assert.expect(1);
7205
7206        if (func) {
7207          var count = 0,
7208              array = [1];
7209
7210          func(array, function() {
7211            if (++count == 1) {
7212              array.push(2);
7213            }
7214            return !(isFind || isSome);
7215          }, isReduce ? array : null);
7216
7217          assert.strictEqual(count, 1);
7218        }
7219        else {
7220          skipAssert(assert);
7221        }
7222      });
7223    });
7224
7225    lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
7226      var func = _[methodName],
7227          isFind = /^find/.test(methodName),
7228          isSome = methodName == 'some',
7229          isReduce = /^reduce/.test(methodName);
7230
7231      QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
7232        assert.expect(1);
7233
7234        if (func) {
7235          var count = 0,
7236              object = { 'a': 1 };
7237
7238          func(object, function() {
7239            if (++count == 1) {
7240              object.b = 2;
7241            }
7242            return !(isFind || isSome);
7243          }, isReduce ? object : null);
7244
7245          assert.strictEqual(count, 1);
7246        }
7247        else {
7248          skipAssert(assert);
7249        }
7250      });
7251    });
7252  }());
7253
7254  /*--------------------------------------------------------------------------*/
7255
7256  QUnit.module('object assignments');
7257
7258  lodashStable.each(['assign', 'assignIn', 'defaults', 'defaultsDeep', 'merge'], function(methodName) {
7259    var func = _[methodName],
7260        isAssign = methodName == 'assign',
7261        isDefaults = /^defaults/.test(methodName);
7262
7263    QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
7264      assert.expect(1);
7265
7266      var expected = lodashStable.map(primitives, function(value) {
7267        var object = Object(value);
7268        object.a = 1;
7269        return object;
7270      });
7271
7272      var actual = lodashStable.map(primitives, function(value) {
7273        return func(value, { 'a': 1 });
7274      });
7275
7276      assert.deepEqual(actual, expected);
7277    });
7278
7279    QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
7280      assert.expect(1);
7281
7282      function Foo() {
7283        this.a = 1;
7284      }
7285      Foo.prototype.b = 2;
7286
7287      var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
7288      assert.deepEqual(func({}, new Foo), expected);
7289    });
7290
7291    QUnit.test('`_.' + methodName + '` should not skip a trailing function source', function(assert) {
7292      assert.expect(1);
7293
7294      function fn() {}
7295      fn.b = 2;
7296
7297      assert.deepEqual(func({}, { 'a': 1 }, fn), { 'a': 1, 'b': 2 });
7298    });
7299
7300    QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
7301      assert.expect(1);
7302
7303      try {
7304        assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
7305      } catch (e) {
7306        assert.ok(false, e.message);
7307      }
7308    });
7309
7310    QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
7311      assert.expect(2);
7312
7313      var source = { 'a': 1 },
7314          values = [null, undefined],
7315          expected = lodashStable.map(values, stubTrue);
7316
7317      var actual = lodashStable.map(values, function(value) {
7318        var object = func(value, source);
7319        return object !== source && lodashStable.isEqual(object, source);
7320      });
7321
7322      assert.deepEqual(actual, expected);
7323
7324      actual = lodashStable.map(values, function(value) {
7325        return lodashStable.isEqual(func(value), {});
7326      });
7327
7328      assert.deepEqual(actual, expected);
7329    });
7330
7331    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
7332      assert.expect(2);
7333
7334      var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
7335          expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
7336
7337      function fn() {};
7338      fn.a = array[0];
7339      fn.b = array[1];
7340      fn.c = array[2];
7341
7342      assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
7343      assert.deepEqual(lodashStable.reduce(fn, func, { 'a': 0 }), expected);
7344    });
7345
7346    QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
7347      assert.expect(1);
7348
7349      if (!isNpm) {
7350        var wrapped = _({ 'a': 1 }),
7351            actual = wrapped[methodName]({ 'b': 2 });
7352
7353        assert.notStrictEqual(actual, wrapped);
7354      }
7355      else {
7356        skipAssert(assert);
7357      }
7358    });
7359  });
7360
7361  lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
7362    var func = _[methodName];
7363
7364    QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
7365      assert.expect(1);
7366
7367      function Foo() {}
7368      Foo.prototype.a = 1;
7369
7370      var actual = func(new Foo, { 'b': 2 });
7371      assert.notOk(_.has(actual, 'a'));
7372    });
7373  });
7374
7375  lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'defaultsDeep', 'merge', 'mergeWith'], function(methodName) {
7376    var func = _[methodName];
7377
7378    QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
7379      assert.expect(4);
7380
7381      lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
7382        var object = {},
7383            pass = true;
7384
7385        defineProperty(object, 'a', {
7386          'configurable': true,
7387          'enumerable': true,
7388          'get': lodashStable.constant(value),
7389          'set': function() { pass = false; }
7390        });
7391
7392        func(object, { 'a': value });
7393        assert.ok(pass);
7394      });
7395    });
7396  });
7397
7398  lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
7399    var func = _[methodName],
7400        isMergeWith = methodName == 'mergeWith';
7401
7402    QUnit.test('`_.' + methodName + '` should provide correct `customizer` arguments', function(assert) {
7403      assert.expect(3);
7404
7405      var args,
7406          object = { 'a': 1 },
7407          source = { 'a': 2 },
7408          expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
7409
7410      func(object, source, function() {
7411        args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7412      });
7413
7414      assert.deepEqual(args, expected, 'primitive values');
7415
7416      var argsList = [],
7417          objectValue = [1, 2],
7418          sourceValue = { 'b': 2 };
7419
7420      object = { 'a': objectValue };
7421      source = { 'a': sourceValue };
7422      expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
7423
7424      if (isMergeWith) {
7425        expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
7426      }
7427      func(object, source, function() {
7428        argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7429      });
7430
7431      assert.deepEqual(argsList, expected, 'object values');
7432
7433      args = undefined;
7434      object = { 'a': 1 };
7435      source = { 'b': 2 };
7436      expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
7437
7438      func(object, source, function() {
7439        args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
7440      });
7441
7442      assert.deepEqual(args, expected, 'undefined properties');
7443    });
7444
7445    QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
7446      assert.expect(2);
7447
7448      function callback() {}
7449      callback.b = 2;
7450
7451      var actual = func({ 'a': 1 }, callback);
7452      assert.deepEqual(actual, { 'a': 1, 'b': 2 });
7453
7454      actual = func({ 'a': 1 }, callback, { 'c': 3 });
7455      assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
7456    });
7457  });
7458
7459  /*--------------------------------------------------------------------------*/
7460
7461  QUnit.module('exit early');
7462
7463  lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
7464    var func = _[methodName];
7465
7466    QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
7467      assert.expect(1);
7468
7469      if (func) {
7470        var array = [1, 2, 3],
7471            values = [];
7472
7473        func(array, function(value, other) {
7474          values.push(lodashStable.isArray(value) ? other : value);
7475          return false;
7476        });
7477
7478        assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
7479      }
7480      else {
7481        skipAssert(assert);
7482      }
7483    });
7484
7485    QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
7486      assert.expect(1);
7487
7488      if (func) {
7489        var object = { 'a': 1, 'b': 2, 'c': 3 },
7490            values = [];
7491
7492        func(object, function(value, other) {
7493          values.push(lodashStable.isArray(value) ? other : value);
7494          return false;
7495        });
7496
7497        assert.strictEqual(values.length, 1);
7498      }
7499      else {
7500        skipAssert(assert);
7501      }
7502    });
7503  });
7504
7505  /*--------------------------------------------------------------------------*/
7506
7507  QUnit.module('`__proto__` property bugs');
7508
7509  (function() {
7510    QUnit.test('should work with the "__proto__" key in internal data objects', function(assert) {
7511      assert.expect(4);
7512
7513      var stringLiteral = '__proto__',
7514          stringObject = Object(stringLiteral),
7515          expected = [stringLiteral, stringObject];
7516
7517      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
7518        return isEven(count) ? stringLiteral : stringObject;
7519      });
7520
7521      assert.deepEqual(_.difference(largeArray, largeArray), []);
7522      assert.deepEqual(_.intersection(largeArray, largeArray), expected);
7523      assert.deepEqual(_.uniq(largeArray), expected);
7524      assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
7525    });
7526
7527    QUnit.test('should treat "__proto__" as a regular key in assignments', function(assert) {
7528      assert.expect(2);
7529
7530      var methods = [
7531        'assign',
7532        'assignIn',
7533        'defaults',
7534        'defaultsDeep',
7535        'merge'
7536      ];
7537
7538      var source = create(null);
7539      source.__proto__ = [];
7540
7541      var expected = lodashStable.map(methods, stubFalse);
7542
7543      var actual = lodashStable.map(methods, function(methodName) {
7544        var result = _[methodName]({}, source);
7545        return result instanceof Array;
7546      });
7547
7548      assert.deepEqual(actual, expected);
7549
7550      actual = _.groupBy([{ 'a': '__proto__' }], 'a');
7551      assert.notOk(actual instanceof Array);
7552    });
7553
7554    QUnit.test('should not merge "__proto__" properties', function(assert) {
7555      assert.expect(1);
7556
7557      if (JSON) {
7558        _.merge({}, JSON.parse('{"__proto__":{"a":1}}'));
7559
7560        var actual = 'a' in objectProto;
7561        delete objectProto.a;
7562
7563        assert.notOk(actual);
7564      } else {
7565        skipAssert(assert);
7566      }
7567    });
7568
7569    QUnit.test('should not indirectly merge builtin prototype properties', function(assert) {
7570      assert.expect(2);
7571
7572      _.merge({}, { 'toString': { 'constructor': { 'prototype': { 'a': 1 } } } });
7573
7574      var actual = 'a' in funcProto;
7575      delete funcProto.a;
7576
7577      assert.notOk(actual);
7578
7579      _.merge({}, { 'constructor': { 'prototype': { 'a': 1 } } });
7580
7581      actual = 'a' in objectProto;
7582      delete objectProto.a;
7583
7584      assert.notOk(actual);
7585    });
7586
7587    QUnit.test('should not indirectly merge `Object` properties', function(assert) {
7588      assert.expect(1);
7589
7590      _.merge({}, { 'constructor': { 'a': 1 } });
7591
7592      var actual = 'a' in Object;
7593      delete Object.a;
7594
7595      assert.notOk(actual);
7596    });
7597  }());
7598
7599  /*--------------------------------------------------------------------------*/
7600
7601  QUnit.module('lodash.fromPairs');
7602
7603  (function() {
7604    QUnit.test('should accept a two dimensional array', function(assert) {
7605      assert.expect(1);
7606
7607      var array = [['a', 1], ['b', 2]],
7608          object = { 'a': 1, 'b': 2 },
7609          actual = _.fromPairs(array);
7610
7611      assert.deepEqual(actual, object);
7612    });
7613
7614    QUnit.test('should accept a falsey `array`', function(assert) {
7615      assert.expect(1);
7616
7617      var expected = lodashStable.map(falsey, stubObject);
7618
7619      var actual = lodashStable.map(falsey, function(array, index) {
7620        try {
7621          return index ? _.fromPairs(array) : _.fromPairs();
7622        } catch (e) {}
7623      });
7624
7625      assert.deepEqual(actual, expected);
7626    });
7627
7628    QUnit.test('should not support deep paths', function(assert) {
7629      assert.expect(1);
7630
7631      var actual = _.fromPairs([['a.b', 1]]);
7632      assert.deepEqual(actual, { 'a.b': 1 });
7633    });
7634
7635    QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
7636      assert.expect(1);
7637
7638      var object = { 'a.b': 1 };
7639      assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
7640    });
7641
7642    QUnit.test('should work in a lazy sequence', function(assert) {
7643      assert.expect(1);
7644
7645      if (!isNpm) {
7646        var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7647          return ['key' + index, index];
7648        });
7649
7650        var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
7651
7652        assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
7653      }
7654      else {
7655        skipAssert(assert);
7656      }
7657    });
7658  }());
7659
7660  /*--------------------------------------------------------------------------*/
7661
7662  QUnit.module('lodash.functions');
7663
7664  (function() {
7665    QUnit.test('should return the function names of an object', function(assert) {
7666      assert.expect(1);
7667
7668      var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
7669          actual = _.functions(object).sort();
7670
7671      assert.deepEqual(actual, ['b', 'd']);
7672    });
7673
7674    QUnit.test('should not include inherited functions', function(assert) {
7675      assert.expect(1);
7676
7677      function Foo() {
7678        this.a = identity;
7679        this.b = 'b';
7680      }
7681      Foo.prototype.c = noop;
7682
7683      assert.deepEqual(_.functions(new Foo), ['a']);
7684    });
7685  }());
7686
7687  /*--------------------------------------------------------------------------*/
7688
7689  QUnit.module('lodash.groupBy');
7690
7691  (function() {
7692    var array = [6.1, 4.2, 6.3];
7693
7694    QUnit.test('should transform keys by `iteratee`', function(assert) {
7695      assert.expect(1);
7696
7697      var actual = _.groupBy(array, Math.floor);
7698      assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7699    });
7700
7701    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7702      assert.expect(1);
7703
7704      var array = [6, 4, 6],
7705          values = [, null, undefined],
7706          expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
7707
7708      var actual = lodashStable.map(values, function(value, index) {
7709        return index ? _.groupBy(array, value) : _.groupBy(array);
7710      });
7711
7712      assert.deepEqual(actual, expected);
7713    });
7714
7715    QUnit.test('should work with `_.property` shorthands', function(assert) {
7716      assert.expect(1);
7717
7718      var actual = _.groupBy(['one', 'two', 'three'], 'length');
7719      assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
7720    });
7721
7722    QUnit.test('should only add values to own, not inherited, properties', function(assert) {
7723      assert.expect(2);
7724
7725      var actual = _.groupBy(array, function(n) {
7726        return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
7727      });
7728
7729      assert.deepEqual(actual.constructor, [4.2]);
7730      assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
7731    });
7732
7733    QUnit.test('should work with a number for `iteratee`', function(assert) {
7734      assert.expect(2);
7735
7736      var array = [
7737        [1, 'a'],
7738        [2, 'a'],
7739        [2, 'b']
7740      ];
7741
7742      assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
7743      assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
7744    });
7745
7746    QUnit.test('should work with an object for `collection`', function(assert) {
7747      assert.expect(1);
7748
7749      var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
7750      assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7751    });
7752
7753    QUnit.test('should work in a lazy sequence', function(assert) {
7754      assert.expect(1);
7755
7756      if (!isNpm) {
7757        var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
7758          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
7759          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
7760        );
7761
7762        var iteratee = function(value) { value.push(value[0]); return value; },
7763            predicate = function(value) { return isEven(value[0]); },
7764            actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
7765
7766        assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
7767      }
7768      else {
7769        skipAssert(assert);
7770      }
7771    });
7772  }());
7773
7774  /*--------------------------------------------------------------------------*/
7775
7776  QUnit.module('lodash.gt');
7777
7778  (function() {
7779    QUnit.test('should return `true` if `value` > `other`', function(assert) {
7780      assert.expect(2);
7781
7782      assert.strictEqual(_.gt(3, 1), true);
7783      assert.strictEqual(_.gt('def', 'abc'), true);
7784    });
7785
7786    QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
7787      assert.expect(4);
7788
7789      assert.strictEqual(_.gt(1, 3), false);
7790      assert.strictEqual(_.gt(3, 3), false);
7791      assert.strictEqual(_.gt('abc', 'def'), false);
7792      assert.strictEqual(_.gt('def', 'def'), false);
7793    });
7794  }());
7795
7796  /*--------------------------------------------------------------------------*/
7797
7798  QUnit.module('lodash.gte');
7799
7800  (function() {
7801    QUnit.test('should return `true` if `value` >= `other`', function(assert) {
7802      assert.expect(4);
7803
7804      assert.strictEqual(_.gte(3, 1), true);
7805      assert.strictEqual(_.gte(3, 3), true);
7806      assert.strictEqual(_.gte('def', 'abc'), true);
7807      assert.strictEqual(_.gte('def', 'def'), true);
7808    });
7809
7810    QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
7811      assert.expect(2);
7812
7813      assert.strictEqual(_.gte(1, 3), false);
7814      assert.strictEqual(_.gte('abc', 'def'), false);
7815    });
7816  }());
7817
7818  /*--------------------------------------------------------------------------*/
7819
7820  QUnit.module('has methods');
7821
7822  lodashStable.each(['has', 'hasIn'], function(methodName) {
7823    var func = _[methodName],
7824        isHas = methodName == 'has',
7825        sparseArgs = toArgs([1]),
7826        sparseArray = Array(1),
7827        sparseString = Object('a');
7828
7829    delete sparseArgs[0];
7830    delete sparseString[0];
7831
7832    QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
7833      assert.expect(2);
7834
7835      var object = { 'a': 1 };
7836
7837      lodashStable.each(['a', ['a']], function(path) {
7838        assert.strictEqual(func(object, path), true);
7839      });
7840    });
7841
7842    QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of `object`', function(assert) {
7843      assert.expect(1);
7844
7845      var object = { 'hasOwnProperty': null, 'a': 1 };
7846      assert.strictEqual(func(object, 'a'), true);
7847    });
7848
7849    QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
7850      assert.expect(4);
7851
7852      var object = { 'a': { 'b': 2 } };
7853
7854      lodashStable.each(['a.b', ['a', 'b']], function(path) {
7855        assert.strictEqual(func(object, path), true);
7856      });
7857
7858      lodashStable.each(['a.a', ['a', 'a']], function(path) {
7859        assert.strictEqual(func(object, path), false);
7860      });
7861    });
7862
7863    QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
7864      assert.expect(2);
7865
7866      function fn() {}
7867      fn.toString = lodashStable.constant('fn');
7868
7869      var object = { 'null': 1 , 'undefined': 2, 'fn': 3, '[object Object]': 4 },
7870          paths = [null, undefined, fn, {}],
7871          expected = lodashStable.map(paths, stubTrue);
7872
7873      lodashStable.times(2, function(index) {
7874        var actual = lodashStable.map(paths, function(path) {
7875          return func(object, index ? [path] : path);
7876        });
7877
7878        assert.deepEqual(actual, expected);
7879      });
7880    });
7881
7882    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7883      assert.expect(1);
7884
7885      assert.strictEqual(func(args, 1), true);
7886    });
7887
7888    QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
7889      assert.expect(2);
7890
7891      var array = [1, 2, 3];
7892
7893      lodashStable.each([1, [1]], function(path) {
7894        assert.strictEqual(func(array, path), true);
7895      });
7896    });
7897
7898    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
7899      assert.expect(1);
7900
7901      var object = { '-0': 'a', '0': 'b' },
7902          props = [-0, Object(-0), 0, Object(0)],
7903          expected = lodashStable.map(props, stubTrue);
7904
7905      var actual = lodashStable.map(props, function(key) {
7906        return func(object, key);
7907      });
7908
7909      assert.deepEqual(actual, expected);
7910    });
7911
7912    QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
7913      assert.expect(2);
7914
7915      function Foo() {}
7916
7917      if (Symbol) {
7918        Foo.prototype[symbol] = 1;
7919
7920        var symbol2 = Symbol('b');
7921        defineProperty(Foo.prototype, symbol2, {
7922          'configurable': true,
7923          'enumerable': false,
7924          'writable': true,
7925          'value': 2
7926        });
7927
7928        var object = isHas ? Foo.prototype : new Foo;
7929        assert.strictEqual(func(object, symbol), true);
7930        assert.strictEqual(func(object, symbol2), true);
7931      }
7932      else {
7933        skipAssert(assert, 2);
7934      }
7935    });
7936
7937    QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7938      assert.expect(2);
7939
7940      var object = { 'a.b': 1 };
7941
7942      lodashStable.each(['a.b', ['a.b']], function(path) {
7943        assert.strictEqual(func(object, path), true);
7944      });
7945    });
7946
7947    QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values', function(assert) {
7948      assert.expect(1);
7949
7950      var values = [sparseArgs, sparseArray, sparseString],
7951          expected = lodashStable.map(values, stubTrue);
7952
7953      var actual = lodashStable.map(values, function(value) {
7954        return func(value, 0);
7955      });
7956
7957      assert.deepEqual(actual, expected);
7958    });
7959
7960    QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values with deep paths', function(assert) {
7961      assert.expect(1);
7962
7963      var values = [sparseArgs, sparseArray, sparseString],
7964          expected = lodashStable.map(values, lodashStable.constant([true, true]));
7965
7966      var actual = lodashStable.map(values, function(value) {
7967        return lodashStable.map(['a[0]', ['a', '0']], function(path) {
7968          return func({ 'a': value }, path);
7969        });
7970      });
7971
7972      assert.deepEqual(actual, expected);
7973    });
7974
7975    QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7976      assert.expect(2);
7977
7978      function Foo() {}
7979      Foo.prototype.a = 1;
7980
7981      lodashStable.each(['a', ['a']], function(path) {
7982        assert.strictEqual(func(new Foo, path), !isHas);
7983      });
7984    });
7985
7986    QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
7987      assert.expect(2);
7988
7989      function Foo() {}
7990      Foo.prototype.a = { 'b': 1 };
7991
7992      lodashStable.each(['a.b', ['a', 'b']], function(path) {
7993        assert.strictEqual(func(new Foo, path), !isHas);
7994      });
7995    });
7996
7997    QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7998      assert.expect(2);
7999
8000      var values = [null, undefined],
8001          expected = lodashStable.map(values, stubFalse);
8002
8003      lodashStable.each(['constructor', ['constructor']], function(path) {
8004        var actual = lodashStable.map(values, function(value) {
8005          return func(value, path);
8006        });
8007
8008        assert.deepEqual(actual, expected);
8009      });
8010    });
8011
8012    QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
8013      assert.expect(2);
8014
8015      var values = [null, undefined],
8016          expected = lodashStable.map(values, stubFalse);
8017
8018      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
8019        var actual = lodashStable.map(values, function(value) {
8020          return func(value, path);
8021        });
8022
8023        assert.deepEqual(actual, expected);
8024      });
8025    });
8026
8027    QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
8028      assert.expect(2);
8029
8030      var values = [, null, undefined],
8031          expected = lodashStable.map(values, stubFalse);
8032
8033      lodashStable.each(['a.b', ['a', 'b']], function(path) {
8034        var actual = lodashStable.map(values, function(value, index) {
8035          var object = index ? { 'a': value } : {};
8036          return func(object, path);
8037        });
8038
8039        assert.deepEqual(actual, expected);
8040      });
8041    });
8042
8043    QUnit.test('`_.' + methodName + '` should return `false` over sparse values of deep paths', function(assert) {
8044      assert.expect(1);
8045
8046      var values = [sparseArgs, sparseArray, sparseString],
8047          expected = lodashStable.map(values, lodashStable.constant([false, false]));
8048
8049      var actual = lodashStable.map(values, function(value) {
8050        return lodashStable.map(['a[0].b', ['a', '0', 'b']], function(path) {
8051          return func({ 'a': value }, path);
8052        });
8053      });
8054
8055      assert.deepEqual(actual, expected);
8056    });
8057  });
8058
8059  /*--------------------------------------------------------------------------*/
8060
8061  QUnit.module('lodash.head');
8062
8063  (function() {
8064    var array = [1, 2, 3, 4];
8065
8066    QUnit.test('should return the first element', function(assert) {
8067      assert.expect(1);
8068
8069      assert.strictEqual(_.head(array), 1);
8070    });
8071
8072    QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
8073      assert.expect(1);
8074
8075      arrayProto[0] = 1;
8076      assert.strictEqual(_.head([]), undefined);
8077      arrayProto.length = 0;
8078    });
8079
8080    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
8081      assert.expect(1);
8082
8083      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
8084          actual = lodashStable.map(array, _.head);
8085
8086      assert.deepEqual(actual, [1, 4, 7]);
8087    });
8088
8089    QUnit.test('should be aliased', function(assert) {
8090      assert.expect(1);
8091
8092      assert.strictEqual(_.first, _.head);
8093    });
8094
8095    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8096      assert.expect(2);
8097
8098      if (!isNpm) {
8099        var wrapped = _(array);
8100        assert.strictEqual(wrapped.head(), 1);
8101        assert.strictEqual(wrapped.first(), 1);
8102      }
8103      else {
8104        skipAssert(assert, 2);
8105      }
8106    });
8107
8108    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8109      assert.expect(2);
8110
8111      if (!isNpm) {
8112        var wrapped = _(array).chain();
8113        assert.ok(wrapped.head() instanceof _);
8114        assert.ok(wrapped.first() instanceof _);
8115      }
8116      else {
8117        skipAssert(assert, 2);
8118      }
8119    });
8120
8121    QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
8122      assert.expect(2);
8123
8124      if (!isNpm) {
8125        var wrapped = _(array).chain();
8126        assert.strictEqual(wrapped.head().__wrapped__, array);
8127        assert.strictEqual(wrapped.first().__wrapped__, array);
8128      }
8129      else {
8130        skipAssert(assert, 2);
8131      }
8132    });
8133
8134    QUnit.test('should work in a lazy sequence', function(assert) {
8135      assert.expect(4);
8136
8137      if (!isNpm) {
8138        var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
8139            smallArray = array;
8140
8141        lodashStable.each(['head', 'first'], function(methodName) {
8142          lodashStable.times(2, function(index) {
8143            var array = index ? largeArray : smallArray,
8144                actual = _(array).filter(isEven)[methodName]();
8145
8146            assert.strictEqual(actual, _[methodName](_.filter(array, isEven)));
8147          });
8148        });
8149      }
8150      else {
8151        skipAssert(assert, 4);
8152      }
8153    });
8154  }());
8155
8156  /*--------------------------------------------------------------------------*/
8157
8158  QUnit.module('lodash.identity');
8159
8160  (function() {
8161    QUnit.test('should return the first argument given', function(assert) {
8162      assert.expect(1);
8163
8164      var object = { 'name': 'fred' };
8165      assert.strictEqual(_.identity(object), object);
8166    });
8167  }());
8168
8169  /*--------------------------------------------------------------------------*/
8170
8171  QUnit.module('lodash.includes');
8172
8173  (function() {
8174    lodashStable.each({
8175      'an `arguments` object': arguments,
8176      'an array': [1, 2, 3, 4],
8177      'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
8178      'a string': '1234'
8179    },
8180    function(collection, key) {
8181      QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
8182        assert.expect(1);
8183
8184        assert.strictEqual(_.includes(collection, 3), true);
8185      });
8186
8187      QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
8188        assert.expect(1);
8189
8190        assert.strictEqual(_.includes(collection, 5), false);
8191      });
8192
8193      QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
8194        assert.expect(1);
8195
8196        assert.strictEqual(_.includes(collection, 2, 1.2), true);
8197      });
8198
8199      QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
8200        assert.expect(1);
8201
8202        if (!isNpm) {
8203          assert.strictEqual(_(collection).includes(3), true);
8204        }
8205        else {
8206          skipAssert(assert);
8207        }
8208      });
8209
8210      QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
8211        assert.expect(1);
8212
8213        if (!isNpm) {
8214          assert.ok(_(collection).chain().includes(3) instanceof _);
8215        }
8216        else {
8217          skipAssert(assert);
8218        }
8219      });
8220    });
8221
8222    lodashStable.each({
8223      'literal': 'abc',
8224      'object': Object('abc')
8225    },
8226    function(collection, key) {
8227      QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
8228        assert.expect(2);
8229
8230        assert.strictEqual(_.includes(collection, 'bc'), true);
8231        assert.strictEqual(_.includes(collection, 'd'), false);
8232      });
8233    });
8234
8235    QUnit.test('should return `false` for empty collections', function(assert) {
8236      assert.expect(1);
8237
8238      var expected = lodashStable.map(empties, stubFalse);
8239
8240      var actual = lodashStable.map(empties, function(value) {
8241        try {
8242          return _.includes(value);
8243        } catch (e) {}
8244      });
8245
8246      assert.deepEqual(actual, expected);
8247    });
8248
8249    QUnit.test('should work with a string and a `fromIndex` >= `length`', function(assert) {
8250      assert.expect(1);
8251
8252      var string = '1234',
8253          length = string.length,
8254          indexes = [4, 6, Math.pow(2, 32), Infinity];
8255
8256      var expected = lodashStable.map(indexes, function(index) {
8257        return [false, false, index == length];
8258      });
8259
8260      var actual = lodashStable.map(indexes, function(fromIndex) {
8261        return [
8262          _.includes(string, 1, fromIndex),
8263          _.includes(string, undefined, fromIndex),
8264          _.includes(string, '', fromIndex)
8265        ];
8266      });
8267
8268      assert.deepEqual(actual, expected);
8269    });
8270
8271    QUnit.test('should match `NaN`', function(assert) {
8272      assert.expect(1);
8273
8274      assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
8275    });
8276
8277    QUnit.test('should match `-0` as `0`', function(assert) {
8278      assert.expect(2);
8279
8280      assert.strictEqual(_.includes([-0], 0), true);
8281      assert.strictEqual(_.includes([0], -0), true);
8282    });
8283
8284    QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
8285      assert.expect(1);
8286
8287      var array = [2, 3, 1],
8288          values = [1, 2, 3];
8289
8290      assert.ok(lodashStable.every(values, lodashStable.partial(_.includes, array)));
8291    });
8292  }(1, 2, 3, 4));
8293
8294  /*--------------------------------------------------------------------------*/
8295
8296  QUnit.module('lodash.initial');
8297
8298  (function() {
8299    var array = [1, 2, 3];
8300
8301    QUnit.test('should accept a falsey `array`', function(assert) {
8302      assert.expect(1);
8303
8304      var expected = lodashStable.map(falsey, stubArray);
8305
8306      var actual = lodashStable.map(falsey, function(array, index) {
8307        try {
8308          return index ? _.initial(array) : _.initial();
8309        } catch (e) {}
8310      });
8311
8312      assert.deepEqual(actual, expected);
8313    });
8314
8315    QUnit.test('should exclude last element', function(assert) {
8316      assert.expect(1);
8317
8318      assert.deepEqual(_.initial(array), [1, 2]);
8319    });
8320
8321    QUnit.test('should return an empty when querying empty arrays', function(assert) {
8322      assert.expect(1);
8323
8324      assert.deepEqual(_.initial([]), []);
8325    });
8326
8327    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
8328      assert.expect(1);
8329
8330      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
8331          actual = lodashStable.map(array, _.initial);
8332
8333      assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
8334    });
8335
8336    QUnit.test('should work in a lazy sequence', function(assert) {
8337      assert.expect(4);
8338
8339      if (!isNpm) {
8340        var array = lodashStable.range(LARGE_ARRAY_SIZE),
8341            values = [];
8342
8343        var actual = _(array).initial().filter(function(value) {
8344          values.push(value);
8345          return false;
8346        })
8347        .value();
8348
8349        assert.deepEqual(actual, []);
8350        assert.deepEqual(values, _.initial(array));
8351
8352        values = [];
8353
8354        actual = _(array).filter(function(value) {
8355          values.push(value);
8356          return isEven(value);
8357        })
8358        .initial()
8359        .value();
8360
8361        assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
8362        assert.deepEqual(values, array);
8363      }
8364      else {
8365        skipAssert(assert, 4);
8366      }
8367    });
8368  }());
8369
8370  /*--------------------------------------------------------------------------*/
8371
8372  QUnit.module('lodash.inRange');
8373
8374  (function() {
8375    QUnit.test('should work with an `end`', function(assert) {
8376      assert.expect(3);
8377
8378      assert.strictEqual(_.inRange(3, 5), true);
8379      assert.strictEqual(_.inRange(5, 5), false);
8380      assert.strictEqual(_.inRange(6, 5), false);
8381    });
8382
8383    QUnit.test('should work with a `start` and `end`', function(assert) {
8384      assert.expect(4);
8385
8386      assert.strictEqual(_.inRange(1, 1, 5), true);
8387      assert.strictEqual(_.inRange(3, 1, 5), true);
8388      assert.strictEqual(_.inRange(0, 1, 5), false);
8389      assert.strictEqual(_.inRange(5, 1, 5), false);
8390    });
8391
8392    QUnit.test('should treat falsey `start` as `0`', function(assert) {
8393      assert.expect(13);
8394
8395      lodashStable.each(falsey, function(value, index) {
8396        if (index) {
8397          assert.strictEqual(_.inRange(0, value), false);
8398          assert.strictEqual(_.inRange(0, value, 1), true);
8399        } else {
8400          assert.strictEqual(_.inRange(0), false);
8401        }
8402      });
8403    });
8404
8405    QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
8406      assert.expect(2);
8407
8408      assert.strictEqual(_.inRange(2, 5, 1), true);
8409      assert.strictEqual(_.inRange(-3, -2, -6), true);
8410    });
8411
8412    QUnit.test('should work with a floating point `n` value', function(assert) {
8413      assert.expect(4);
8414
8415      assert.strictEqual(_.inRange(0.5, 5), true);
8416      assert.strictEqual(_.inRange(1.2, 1, 5), true);
8417      assert.strictEqual(_.inRange(5.2, 5), false);
8418      assert.strictEqual(_.inRange(0.5, 1, 5), false);
8419    });
8420
8421    QUnit.test('should coerce arguments to finite numbers', function(assert) {
8422      assert.expect(1);
8423
8424      var actual = [
8425        _.inRange(0, '1'),
8426        _.inRange(0, '0', 1),
8427        _.inRange(0, 0, '1'),
8428        _.inRange(0, NaN, 1),
8429        _.inRange(-1, -1, NaN)
8430      ];
8431
8432      assert.deepEqual(actual, lodashStable.map(actual, stubTrue));
8433    });
8434  }());
8435
8436  /*--------------------------------------------------------------------------*/
8437
8438  QUnit.module('intersection methods');
8439
8440  lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
8441    var func = _[methodName];
8442
8443    QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
8444      assert.expect(1);
8445
8446      var actual = func([2, 1], [2, 3]);
8447      assert.deepEqual(actual, [2]);
8448    });
8449
8450    QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
8451      assert.expect(1);
8452
8453      var actual = func([2, 1, 2, 3], [3, 4], [3, 2]);
8454      assert.deepEqual(actual, [3]);
8455    });
8456
8457    QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
8458      assert.expect(1);
8459
8460      var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
8461      assert.deepEqual(actual, [1, 2]);
8462    });
8463
8464    QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
8465      assert.expect(1);
8466
8467      var actual = func([1, 1, 3, 2, 2]);
8468      assert.deepEqual(actual, [1, 3, 2]);
8469    });
8470
8471    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
8472      assert.expect(2);
8473
8474      var array = [0, 1, null, 3],
8475          expected = [1, 3];
8476
8477      assert.deepEqual(func(array, args), expected);
8478      assert.deepEqual(func(args, array), expected);
8479    });
8480
8481    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
8482      assert.expect(1);
8483
8484      var values = [-0, 0],
8485          expected = lodashStable.map(values, lodashStable.constant(['0']));
8486
8487      var actual = lodashStable.map(values, function(value) {
8488        return lodashStable.map(func(values, [value]), lodashStable.toString);
8489      });
8490
8491      assert.deepEqual(actual, expected);
8492    });
8493
8494    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
8495      assert.expect(1);
8496
8497      var actual = func([1, NaN, 3], [NaN, 5, NaN]);
8498      assert.deepEqual(actual, [NaN]);
8499    });
8500
8501    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
8502      assert.expect(1);
8503
8504      var values = [-0, 0],
8505          expected = lodashStable.map(values, lodashStable.constant(['0']));
8506
8507      var actual = lodashStable.map(values, function(value) {
8508        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
8509        return lodashStable.map(func(values, largeArray), lodashStable.toString);
8510      });
8511
8512      assert.deepEqual(actual, expected);
8513    });
8514
8515    QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
8516      assert.expect(1);
8517
8518      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN);
8519      assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
8520    });
8521
8522    QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
8523      assert.expect(2);
8524
8525      var object = {},
8526          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
8527
8528      assert.deepEqual(func([object], largeArray), [object]);
8529      assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
8530    });
8531
8532    QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
8533      assert.expect(3);
8534
8535      var array = [0, 1, null, 3];
8536      assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
8537      assert.deepEqual(func(null, array, null, [2, 3]), []);
8538      assert.deepEqual(func(array, null, args, null), []);
8539    });
8540
8541    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
8542      assert.expect(2);
8543
8544      if (!isNpm) {
8545        var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
8546        assert.ok(wrapped instanceof _);
8547        assert.deepEqual(wrapped.value(), [1, 2]);
8548      }
8549      else {
8550        skipAssert(assert, 2);
8551      }
8552    });
8553  });
8554
8555  /*--------------------------------------------------------------------------*/
8556
8557  QUnit.module('lodash.intersectionBy');
8558
8559  (function() {
8560    QUnit.test('should accept an `iteratee`', function(assert) {
8561      assert.expect(2);
8562
8563      var actual = _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8564      assert.deepEqual(actual, [2.1]);
8565
8566      actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8567      assert.deepEqual(actual, [{ 'x': 1 }]);
8568    });
8569
8570    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
8571      assert.expect(1);
8572
8573      var args;
8574
8575      _.intersectionBy([2.1, 1.2], [2.3, 3.4], function() {
8576        args || (args = slice.call(arguments));
8577      });
8578
8579      assert.deepEqual(args, [2.3]);
8580    });
8581  }());
8582
8583  /*--------------------------------------------------------------------------*/
8584
8585  QUnit.module('lodash.intersectionWith');
8586
8587  (function() {
8588    QUnit.test('should work with a `comparator`', function(assert) {
8589      assert.expect(1);
8590
8591      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
8592          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
8593          actual = _.intersectionWith(objects, others, lodashStable.isEqual);
8594
8595      assert.deepEqual(actual, [objects[0]]);
8596    });
8597
8598    QUnit.test('should preserve the sign of `0`', function(assert) {
8599      assert.expect(1);
8600
8601      var array = [-0],
8602          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubZero),
8603          others = [[0], largeArray],
8604          expected = lodashStable.map(others, lodashStable.constant(['-0']));
8605
8606      var actual = lodashStable.map(others, function(other) {
8607        return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
8608      });
8609
8610      assert.deepEqual(actual, expected);
8611    });
8612  }());
8613
8614  /*--------------------------------------------------------------------------*/
8615
8616  QUnit.module('lodash.invert');
8617
8618  (function() {
8619    QUnit.test('should invert an object', function(assert) {
8620      assert.expect(2);
8621
8622      var object = { 'a': 1, 'b': 2 },
8623          actual = _.invert(object);
8624
8625      assert.deepEqual(actual, { '1': 'a', '2': 'b' });
8626      assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
8627    });
8628
8629    QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
8630      assert.expect(1);
8631
8632      var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
8633      assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
8634    });
8635
8636    QUnit.test('should work with an object that has a `length` property', function(assert) {
8637      assert.expect(1);
8638
8639      var object = { '0': 'a', '1': 'b', 'length': 2 };
8640      assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
8641    });
8642
8643    QUnit.test('should return a wrapped value when chaining', function(assert) {
8644      assert.expect(2);
8645
8646      if (!isNpm) {
8647        var object = { 'a': 1, 'b': 2 },
8648            wrapped = _(object).invert();
8649
8650        assert.ok(wrapped instanceof _);
8651        assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
8652      }
8653      else {
8654        skipAssert(assert, 2);
8655      }
8656    });
8657  }());
8658
8659  /*--------------------------------------------------------------------------*/
8660
8661  QUnit.module('lodash.invertBy');
8662
8663  (function() {
8664    var object = { 'a': 1, 'b': 2, 'c': 1 };
8665
8666    QUnit.test('should transform keys by `iteratee`', function(assert) {
8667      assert.expect(1);
8668
8669      var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
8670
8671      var actual = _.invertBy(object, function(value) {
8672        return 'group' + value;
8673      });
8674
8675      assert.deepEqual(actual, expected);
8676    });
8677
8678    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
8679      assert.expect(1);
8680
8681      var values = [, null, undefined],
8682          expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
8683
8684      var actual = lodashStable.map(values, function(value, index) {
8685        return index ? _.invertBy(object, value) : _.invertBy(object);
8686      });
8687
8688      assert.deepEqual(actual, expected);
8689    });
8690
8691    QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
8692      assert.expect(1);
8693
8694      var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
8695          expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
8696
8697      assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
8698    });
8699
8700    QUnit.test('should return a wrapped value when chaining', function(assert) {
8701      assert.expect(2);
8702
8703      if (!isNpm) {
8704        var wrapped = _(object).invertBy();
8705
8706        assert.ok(wrapped instanceof _);
8707        assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
8708      }
8709      else {
8710        skipAssert(assert, 2);
8711      }
8712    });
8713  }());
8714
8715  /*--------------------------------------------------------------------------*/
8716
8717  QUnit.module('lodash.invoke');
8718
8719  (function() {
8720    QUnit.test('should invoke a method on `object`', function(assert) {
8721      assert.expect(1);
8722
8723      var object = { 'a': lodashStable.constant('A') },
8724          actual = _.invoke(object, 'a');
8725
8726      assert.strictEqual(actual, 'A');
8727    });
8728
8729    QUnit.test('should support invoking with arguments', function(assert) {
8730      assert.expect(1);
8731
8732      var object = { 'a': function(a, b) { return [a, b]; } },
8733          actual = _.invoke(object, 'a', 1, 2);
8734
8735      assert.deepEqual(actual, [1, 2]);
8736    });
8737
8738    QUnit.test('should not error on nullish elements', function(assert) {
8739      assert.expect(1);
8740
8741      var values = [null, undefined],
8742          expected = lodashStable.map(values, noop);
8743
8744      var actual = lodashStable.map(values, function(value) {
8745        try {
8746          return _.invoke(value, 'a.b', 1, 2);
8747        } catch (e) {}
8748      });
8749
8750      assert.deepEqual(actual, expected);
8751    });
8752
8753    QUnit.test('should preserve the sign of `0`', function(assert) {
8754      assert.expect(1);
8755
8756      var object = { '-0': stubA, '0': stubB },
8757          props = [-0, Object(-0), 0, Object(0)];
8758
8759      var actual = lodashStable.map(props, function(key) {
8760        return _.invoke(object, key);
8761      });
8762
8763      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
8764    });
8765
8766    QUnit.test('should support deep paths', function(assert) {
8767      assert.expect(2);
8768
8769      var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
8770
8771      lodashStable.each(['a.b', ['a', 'b']], function(path) {
8772        var actual = _.invoke(object, path, 1, 2);
8773        assert.deepEqual(actual, [1, 2]);
8774      });
8775    });
8776
8777    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8778      assert.expect(2);
8779
8780      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8781
8782      lodashStable.each(['a.b', ['a', 'b']], function(path) {
8783        assert.deepEqual(_.invoke(object, path), 1);
8784      });
8785    });
8786
8787    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8788      assert.expect(1);
8789
8790      if (!isNpm) {
8791        var object = { 'a': stubOne };
8792        assert.strictEqual(_(object).invoke('a'), 1);
8793      }
8794      else {
8795        skipAssert(assert);
8796      }
8797    });
8798
8799    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8800      assert.expect(1);
8801
8802      if (!isNpm) {
8803        var object = { 'a': stubOne };
8804        assert.ok(_(object).chain().invoke('a') instanceof _);
8805      }
8806      else {
8807        skipAssert(assert);
8808      }
8809    });
8810  }());
8811
8812  /*--------------------------------------------------------------------------*/
8813
8814  QUnit.module('lodash.invokeMap');
8815
8816  (function() {
8817    QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
8818      assert.expect(1);
8819
8820      var array = ['a', 'b', 'c'],
8821          actual = _.invokeMap(array, 'toUpperCase');
8822
8823      assert.deepEqual(actual, ['A', 'B', 'C']);
8824    });
8825
8826    QUnit.test('should support invoking with arguments', function(assert) {
8827      assert.expect(1);
8828
8829      var array = [function() { return slice.call(arguments); }],
8830          actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
8831
8832      assert.deepEqual(actual, [['a', 'b', 'c']]);
8833    });
8834
8835    QUnit.test('should work with a function for `methodName`', function(assert) {
8836      assert.expect(1);
8837
8838      var array = ['a', 'b', 'c'];
8839
8840      var actual = _.invokeMap(array, function(left, right) {
8841        return left + this.toUpperCase() + right;
8842      }, '(', ')');
8843
8844      assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
8845    });
8846
8847    QUnit.test('should work with an object for `collection`', function(assert) {
8848      assert.expect(1);
8849
8850      var object = { 'a': 1, 'b': 2, 'c': 3 },
8851          actual = _.invokeMap(object, 'toFixed', 1);
8852
8853      assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
8854    });
8855
8856    QUnit.test('should treat number values for `collection` as empty', function(assert) {
8857      assert.expect(1);
8858
8859      assert.deepEqual(_.invokeMap(1), []);
8860    });
8861
8862    QUnit.test('should not error on nullish elements', function(assert) {
8863      assert.expect(1);
8864
8865      var array = ['a', null, undefined, 'd'];
8866
8867      try {
8868        var actual = _.invokeMap(array, 'toUpperCase');
8869      } catch (e) {}
8870
8871      assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
8872    });
8873
8874    QUnit.test('should not error on elements with missing properties', function(assert) {
8875      assert.expect(1);
8876
8877      var objects = lodashStable.map([null, undefined, stubOne], function(value) {
8878        return { 'a': value };
8879      });
8880
8881      var expected = lodashStable.map(objects, function(object) {
8882        return object.a ? object.a() : undefined;
8883      });
8884
8885      try {
8886        var actual = _.invokeMap(objects, 'a');
8887      } catch (e) {}
8888
8889      assert.deepEqual(actual, expected);
8890    });
8891
8892    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8893      assert.expect(2);
8894
8895      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8896
8897      lodashStable.each(['a.b', ['a', 'b']], function(path) {
8898        assert.deepEqual(_.invokeMap([object], path), [1]);
8899      });
8900    });
8901
8902    QUnit.test('should return a wrapped value when chaining', function(assert) {
8903      assert.expect(4);
8904
8905      if (!isNpm) {
8906        var array = ['a', 'b', 'c'],
8907            wrapped = _(array),
8908            actual = wrapped.invokeMap('toUpperCase');
8909
8910        assert.ok(actual instanceof _);
8911        assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8912
8913        actual = wrapped.invokeMap(function(left, right) {
8914          return left + this.toUpperCase() + right;
8915        }, '(', ')');
8916
8917        assert.ok(actual instanceof _);
8918        assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8919      }
8920      else {
8921        skipAssert(assert, 4);
8922      }
8923    });
8924
8925    QUnit.test('should support shortcut fusion', function(assert) {
8926      assert.expect(2);
8927
8928      if (!isNpm) {
8929        var count = 0,
8930            method = function() { count++; return this.index; };
8931
8932        var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8933          return { 'index': index, 'method': method };
8934        });
8935
8936        var actual = _(array).invokeMap('method').take(1).value();
8937
8938        assert.strictEqual(count, 1);
8939        assert.deepEqual(actual, [0]);
8940      }
8941      else {
8942        skipAssert(assert, 2);
8943      }
8944    });
8945  }());
8946
8947  /*--------------------------------------------------------------------------*/
8948
8949  QUnit.module('lodash.isArguments');
8950
8951  (function() {
8952    QUnit.test('should return `true` for `arguments` objects', function(assert) {
8953      assert.expect(2);
8954
8955      assert.strictEqual(_.isArguments(args), true);
8956      assert.strictEqual(_.isArguments(strictArgs), true);
8957    });
8958
8959    QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8960      assert.expect(12);
8961
8962      var expected = lodashStable.map(falsey, stubFalse);
8963
8964      var actual = lodashStable.map(falsey, function(value, index) {
8965        return index ? _.isArguments(value) : _.isArguments();
8966      });
8967
8968      assert.deepEqual(actual, expected);
8969
8970      assert.strictEqual(_.isArguments([1, 2, 3]), false);
8971      assert.strictEqual(_.isArguments(true), false);
8972      assert.strictEqual(_.isArguments(new Date), false);
8973      assert.strictEqual(_.isArguments(new Error), false);
8974      assert.strictEqual(_.isArguments(_), false);
8975      assert.strictEqual(_.isArguments(slice), false);
8976      assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8977      assert.strictEqual(_.isArguments(1), false);
8978      assert.strictEqual(_.isArguments(/x/), false);
8979      assert.strictEqual(_.isArguments('a'), false);
8980      assert.strictEqual(_.isArguments(symbol), false);
8981    });
8982
8983    QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8984      assert.expect(1);
8985
8986      if (realm.arguments) {
8987        assert.strictEqual(_.isArguments(realm.arguments), true);
8988      }
8989      else {
8990        skipAssert(assert);
8991      }
8992    });
8993  }());
8994
8995  /*--------------------------------------------------------------------------*/
8996
8997  QUnit.module('lodash.isArray');
8998
8999  (function() {
9000    QUnit.test('should return `true` for arrays', function(assert) {
9001      assert.expect(1);
9002
9003      assert.strictEqual(_.isArray([1, 2, 3]), true);
9004    });
9005
9006    QUnit.test('should return `false` for non-arrays', function(assert) {
9007      assert.expect(12);
9008
9009      var expected = lodashStable.map(falsey, stubFalse);
9010
9011      var actual = lodashStable.map(falsey, function(value, index) {
9012        return index ? _.isArray(value) : _.isArray();
9013      });
9014
9015      assert.deepEqual(actual, expected);
9016
9017      assert.strictEqual(_.isArray(args), false);
9018      assert.strictEqual(_.isArray(true), false);
9019      assert.strictEqual(_.isArray(new Date), false);
9020      assert.strictEqual(_.isArray(new Error), false);
9021      assert.strictEqual(_.isArray(_), false);
9022      assert.strictEqual(_.isArray(slice), false);
9023      assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
9024      assert.strictEqual(_.isArray(1), false);
9025      assert.strictEqual(_.isArray(/x/), false);
9026      assert.strictEqual(_.isArray('a'), false);
9027      assert.strictEqual(_.isArray(symbol), false);
9028    });
9029
9030    QUnit.test('should work with an array from another realm', function(assert) {
9031      assert.expect(1);
9032
9033      if (realm.array) {
9034        assert.strictEqual(_.isArray(realm.array), true);
9035      }
9036      else {
9037        skipAssert(assert);
9038      }
9039    });
9040  }());
9041
9042  /*--------------------------------------------------------------------------*/
9043
9044  QUnit.module('lodash.isArrayBuffer');
9045
9046  (function() {
9047    QUnit.test('should return `true` for array buffers', function(assert) {
9048      assert.expect(1);
9049
9050      if (ArrayBuffer) {
9051        assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
9052      }
9053      else {
9054        skipAssert(assert);
9055      }
9056    });
9057
9058    QUnit.test('should return `false` for non array buffers', function(assert) {
9059      assert.expect(13);
9060
9061      var expected = lodashStable.map(falsey, stubFalse);
9062
9063      var actual = lodashStable.map(falsey, function(value, index) {
9064        return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
9065      });
9066
9067      assert.deepEqual(actual, expected);
9068
9069      assert.strictEqual(_.isArrayBuffer(args), false);
9070      assert.strictEqual(_.isArrayBuffer([1]), false);
9071      assert.strictEqual(_.isArrayBuffer(true), false);
9072      assert.strictEqual(_.isArrayBuffer(new Date), false);
9073      assert.strictEqual(_.isArrayBuffer(new Error), false);
9074      assert.strictEqual(_.isArrayBuffer(_), false);
9075      assert.strictEqual(_.isArrayBuffer(slice), false);
9076      assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
9077      assert.strictEqual(_.isArrayBuffer(1), false);
9078      assert.strictEqual(_.isArrayBuffer(/x/), false);
9079      assert.strictEqual(_.isArrayBuffer('a'), false);
9080      assert.strictEqual(_.isArrayBuffer(symbol), false);
9081    });
9082
9083    QUnit.test('should work with array buffers from another realm', function(assert) {
9084      assert.expect(1);
9085
9086      if (realm.arrayBuffer) {
9087        assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
9088      }
9089      else {
9090        skipAssert(assert);
9091      }
9092    });
9093  }());
9094
9095  /*--------------------------------------------------------------------------*/
9096
9097  QUnit.module('lodash.isArrayLike');
9098
9099  (function() {
9100    QUnit.test('should return `true` for array-like values', function(assert) {
9101      assert.expect(1);
9102
9103      var values = [args, [1, 2, 3], { '0': 'a', 'length': 1 }, 'a'],
9104          expected = lodashStable.map(values, stubTrue),
9105          actual = lodashStable.map(values, _.isArrayLike);
9106
9107      assert.deepEqual(actual, expected);
9108    });
9109
9110    QUnit.test('should return `false` for non-arrays', function(assert) {
9111      assert.expect(12);
9112
9113      var expected = lodashStable.map(falsey, function(value) {
9114        return value === '';
9115      });
9116
9117      var actual = lodashStable.map(falsey, function(value, index) {
9118        return index ? _.isArrayLike(value) : _.isArrayLike();
9119      });
9120
9121      assert.deepEqual(actual, expected);
9122
9123      assert.strictEqual(_.isArrayLike(true), false);
9124      assert.strictEqual(_.isArrayLike(new Date), false);
9125      assert.strictEqual(_.isArrayLike(new Error), false);
9126      assert.strictEqual(_.isArrayLike(_), false);
9127      assert.strictEqual(_.isArrayLike(asyncFunc), false);
9128      assert.strictEqual(_.isArrayLike(genFunc), false);
9129      assert.strictEqual(_.isArrayLike(slice), false);
9130      assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
9131      assert.strictEqual(_.isArrayLike(1), false);
9132      assert.strictEqual(_.isArrayLike(/x/), false);
9133      assert.strictEqual(_.isArrayLike(symbol), false);
9134    });
9135
9136    QUnit.test('should work with an array from another realm', function(assert) {
9137      assert.expect(1);
9138
9139      if (realm.object) {
9140        var values = [realm.arguments, realm.array, realm.string],
9141            expected = lodashStable.map(values, stubTrue),
9142            actual = lodashStable.map(values, _.isArrayLike);
9143
9144        assert.deepEqual(actual, expected);
9145      }
9146      else {
9147        skipAssert(assert);
9148      }
9149    });
9150  }());
9151
9152  /*--------------------------------------------------------------------------*/
9153
9154  QUnit.module('lodash.isBoolean');
9155
9156  (function() {
9157    QUnit.test('should return `true` for booleans', function(assert) {
9158      assert.expect(4);
9159
9160      assert.strictEqual(_.isBoolean(true), true);
9161      assert.strictEqual(_.isBoolean(false), true);
9162      assert.strictEqual(_.isBoolean(Object(true)), true);
9163      assert.strictEqual(_.isBoolean(Object(false)), true);
9164    });
9165
9166    QUnit.test('should return `false` for non-booleans', function(assert) {
9167      assert.expect(12);
9168
9169      var expected = lodashStable.map(falsey, function(value) {
9170        return value === false;
9171      });
9172
9173      var actual = lodashStable.map(falsey, function(value, index) {
9174        return index ? _.isBoolean(value) : _.isBoolean();
9175      });
9176
9177      assert.deepEqual(actual, expected);
9178
9179      assert.strictEqual(_.isBoolean(args), false);
9180      assert.strictEqual(_.isBoolean([1, 2, 3]), false);
9181      assert.strictEqual(_.isBoolean(new Date), false);
9182      assert.strictEqual(_.isBoolean(new Error), false);
9183      assert.strictEqual(_.isBoolean(_), false);
9184      assert.strictEqual(_.isBoolean(slice), false);
9185      assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
9186      assert.strictEqual(_.isBoolean(1), false);
9187      assert.strictEqual(_.isBoolean(/x/), false);
9188      assert.strictEqual(_.isBoolean('a'), false);
9189      assert.strictEqual(_.isBoolean(symbol), false);
9190    });
9191
9192    QUnit.test('should work with a boolean from another realm', function(assert) {
9193      assert.expect(1);
9194
9195      if (realm.boolean) {
9196        assert.strictEqual(_.isBoolean(realm.boolean), true);
9197      }
9198      else {
9199        skipAssert(assert);
9200      }
9201    });
9202  }());
9203
9204  /*--------------------------------------------------------------------------*/
9205
9206  QUnit.module('lodash.isBuffer');
9207
9208  (function() {
9209    QUnit.test('should return `true` for buffers', function(assert) {
9210      assert.expect(1);
9211
9212      if (Buffer) {
9213        assert.strictEqual(_.isBuffer(new Buffer(2)), true);
9214      }
9215      else {
9216        skipAssert(assert);
9217      }
9218    });
9219
9220    QUnit.test('should return `false` for non-buffers', function(assert) {
9221      assert.expect(13);
9222
9223      var expected = lodashStable.map(falsey, stubFalse);
9224
9225      var actual = lodashStable.map(falsey, function(value, index) {
9226        return index ? _.isBuffer(value) : _.isBuffer();
9227      });
9228
9229      assert.deepEqual(actual, expected);
9230
9231      assert.strictEqual(_.isBuffer(args), false);
9232      assert.strictEqual(_.isBuffer([1]), false);
9233      assert.strictEqual(_.isBuffer(true), false);
9234      assert.strictEqual(_.isBuffer(new Date), false);
9235      assert.strictEqual(_.isBuffer(new Error), false);
9236      assert.strictEqual(_.isBuffer(_), false);
9237      assert.strictEqual(_.isBuffer(slice), false);
9238      assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
9239      assert.strictEqual(_.isBuffer(1), false);
9240      assert.strictEqual(_.isBuffer(/x/), false);
9241      assert.strictEqual(_.isBuffer('a'), false);
9242      assert.strictEqual(_.isBuffer(symbol), false);
9243    });
9244
9245    QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
9246      assert.expect(1);
9247
9248      if (!isStrict && Buffer && lodashBizarro) {
9249        assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
9250      }
9251      else {
9252        skipAssert(assert);
9253      }
9254    });
9255  }());
9256
9257  /*--------------------------------------------------------------------------*/
9258
9259  QUnit.module('lodash.isDate');
9260
9261  (function() {
9262    QUnit.test('should return `true` for dates', function(assert) {
9263      assert.expect(1);
9264
9265      assert.strictEqual(_.isDate(new Date), true);
9266    });
9267
9268    QUnit.test('should return `false` for non-dates', function(assert) {
9269      assert.expect(12);
9270
9271      var expected = lodashStable.map(falsey, stubFalse);
9272
9273      var actual = lodashStable.map(falsey, function(value, index) {
9274        return index ? _.isDate(value) : _.isDate();
9275      });
9276
9277      assert.deepEqual(actual, expected);
9278
9279      assert.strictEqual(_.isDate(args), false);
9280      assert.strictEqual(_.isDate([1, 2, 3]), false);
9281      assert.strictEqual(_.isDate(true), false);
9282      assert.strictEqual(_.isDate(new Error), false);
9283      assert.strictEqual(_.isDate(_), false);
9284      assert.strictEqual(_.isDate(slice), false);
9285      assert.strictEqual(_.isDate({ 'a': 1 }), false);
9286      assert.strictEqual(_.isDate(1), false);
9287      assert.strictEqual(_.isDate(/x/), false);
9288      assert.strictEqual(_.isDate('a'), false);
9289      assert.strictEqual(_.isDate(symbol), false);
9290    });
9291
9292    QUnit.test('should work with a date object from another realm', function(assert) {
9293      assert.expect(1);
9294
9295      if (realm.date) {
9296        assert.strictEqual(_.isDate(realm.date), true);
9297      }
9298      else {
9299        skipAssert(assert);
9300      }
9301    });
9302  }());
9303
9304  /*--------------------------------------------------------------------------*/
9305
9306  QUnit.module('lodash.isElement');
9307
9308  (function() {
9309    QUnit.test('should return `true` for elements', function(assert) {
9310      assert.expect(1);
9311
9312      if (document) {
9313        assert.strictEqual(_.isElement(body), true);
9314      }
9315      else {
9316        skipAssert(assert);
9317      }
9318    });
9319
9320    QUnit.test('should return `true` for non-plain objects', function(assert) {
9321      assert.expect(1);
9322
9323      function Foo() {
9324        this.nodeType = 1;
9325      }
9326
9327      assert.strictEqual(_.isElement(new Foo), true);
9328    });
9329
9330    QUnit.test('should return `false` for non DOM elements', function(assert) {
9331      assert.expect(13);
9332
9333      var expected = lodashStable.map(falsey, stubFalse);
9334
9335      var actual = lodashStable.map(falsey, function(value, index) {
9336        return index ? _.isElement(value) : _.isElement();
9337      });
9338
9339      assert.deepEqual(actual, expected);
9340
9341      assert.strictEqual(_.isElement(args), false);
9342      assert.strictEqual(_.isElement([1, 2, 3]), false);
9343      assert.strictEqual(_.isElement(true), false);
9344      assert.strictEqual(_.isElement(new Date), false);
9345      assert.strictEqual(_.isElement(new Error), false);
9346      assert.strictEqual(_.isElement(_), false);
9347      assert.strictEqual(_.isElement(slice), false);
9348      assert.strictEqual(_.isElement({ 'a': 1 }), false);
9349      assert.strictEqual(_.isElement(1), false);
9350      assert.strictEqual(_.isElement(/x/), false);
9351      assert.strictEqual(_.isElement('a'), false);
9352      assert.strictEqual(_.isElement(symbol), false);
9353    });
9354
9355    QUnit.test('should return `false` for plain objects', function(assert) {
9356      assert.expect(6);
9357
9358      assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
9359      assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
9360      assert.strictEqual(_.isElement({ 'nodeType': true }), false);
9361      assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
9362      assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
9363      assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
9364    });
9365
9366    QUnit.test('should work with a DOM element from another realm', function(assert) {
9367      assert.expect(1);
9368
9369      if (realm.element) {
9370        assert.strictEqual(_.isElement(realm.element), true);
9371      }
9372      else {
9373        skipAssert(assert);
9374      }
9375    });
9376  }());
9377
9378  /*--------------------------------------------------------------------------*/
9379
9380  QUnit.module('lodash.isEmpty');
9381
9382  (function() {
9383    QUnit.test('should return `true` for empty values', function(assert) {
9384      assert.expect(10);
9385
9386      var expected = lodashStable.map(empties, stubTrue),
9387          actual = lodashStable.map(empties, _.isEmpty);
9388
9389      assert.deepEqual(actual, expected);
9390
9391      assert.strictEqual(_.isEmpty(true), true);
9392      assert.strictEqual(_.isEmpty(slice), true);
9393      assert.strictEqual(_.isEmpty(1), true);
9394      assert.strictEqual(_.isEmpty(NaN), true);
9395      assert.strictEqual(_.isEmpty(/x/), true);
9396      assert.strictEqual(_.isEmpty(symbol), true);
9397      assert.strictEqual(_.isEmpty(), true);
9398
9399      if (Buffer) {
9400        assert.strictEqual(_.isEmpty(new Buffer(0)), true);
9401        assert.strictEqual(_.isEmpty(new Buffer(1)), false);
9402      }
9403      else {
9404        skipAssert(assert, 2);
9405      }
9406    });
9407
9408    QUnit.test('should return `false` for non-empty values', function(assert) {
9409      assert.expect(3);
9410
9411      assert.strictEqual(_.isEmpty([0]), false);
9412      assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
9413      assert.strictEqual(_.isEmpty('a'), false);
9414    });
9415
9416    QUnit.test('should work with an object that has a `length` property', function(assert) {
9417      assert.expect(1);
9418
9419      assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
9420    });
9421
9422    QUnit.test('should work with `arguments` objects', function(assert) {
9423      assert.expect(1);
9424
9425      assert.strictEqual(_.isEmpty(args), false);
9426    });
9427
9428    QUnit.test('should work with prototytpe objects', function(assert) {
9429      assert.expect(2);
9430
9431      function Foo() {}
9432      Foo.prototype = { 'constructor': Foo };
9433
9434      assert.strictEqual(_.isEmpty(Foo.prototype), true);
9435
9436      Foo.prototype.a = 1;
9437      assert.strictEqual(_.isEmpty(Foo.prototype), false);
9438    });
9439
9440    QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
9441      assert.expect(1);
9442
9443      function Foo(elements) {
9444        push.apply(this, elements);
9445      }
9446      Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
9447
9448      assert.strictEqual(_.isEmpty(new Foo([])), true);
9449    });
9450
9451    QUnit.test('should work with maps', function(assert) {
9452      assert.expect(4);
9453
9454      if (Map) {
9455        lodashStable.each([new Map, realm.map], function(map) {
9456          assert.strictEqual(_.isEmpty(map), true);
9457          map.set('a', 1);
9458          assert.strictEqual(_.isEmpty(map), false);
9459          map.clear();
9460        });
9461      }
9462      else {
9463        skipAssert(assert, 4);
9464      }
9465    });
9466
9467    QUnit.test('should work with sets', function(assert) {
9468      assert.expect(4);
9469
9470      if (Set) {
9471        lodashStable.each([new Set, realm.set], function(set) {
9472          assert.strictEqual(_.isEmpty(set), true);
9473          set.add(1);
9474          assert.strictEqual(_.isEmpty(set), false);
9475          set.clear();
9476        });
9477      }
9478      else {
9479        skipAssert(assert, 4);
9480      }
9481    });
9482
9483    QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
9484      assert.expect(1);
9485
9486      function Foo() {}
9487      Foo.prototype.length = -1;
9488
9489      assert.strictEqual(_.isEmpty(new Foo), true);
9490    });
9491
9492    QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
9493      assert.expect(1);
9494
9495      function Foo() {}
9496      Foo.prototype.length = MAX_SAFE_INTEGER + 1;
9497
9498      assert.strictEqual(_.isEmpty(new Foo), true);
9499    });
9500
9501    QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
9502      assert.expect(1);
9503
9504      assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
9505    });
9506
9507    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9508      assert.expect(1);
9509
9510      if (!isNpm) {
9511        assert.strictEqual(_({}).isEmpty(), true);
9512      }
9513      else {
9514        skipAssert(assert);
9515      }
9516    });
9517
9518    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9519      assert.expect(1);
9520
9521      if (!isNpm) {
9522        assert.ok(_({}).chain().isEmpty() instanceof _);
9523      }
9524      else {
9525        skipAssert(assert);
9526      }
9527    });
9528  }());
9529
9530  /*--------------------------------------------------------------------------*/
9531
9532  QUnit.module('lodash.isEqual');
9533
9534  (function() {
9535    var symbol1 = Symbol ? Symbol('a') : true,
9536        symbol2 = Symbol ? Symbol('b') : false;
9537
9538    QUnit.test('should compare primitives', function(assert) {
9539      assert.expect(1);
9540
9541      var pairs = [
9542        [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
9543        [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
9544        [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
9545        ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
9546        [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
9547        [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
9548        [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
9549        [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
9550        [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
9551      ];
9552
9553      var expected = lodashStable.map(pairs, function(pair) {
9554        return pair[2];
9555      });
9556
9557      var actual = lodashStable.map(pairs, function(pair) {
9558        return _.isEqual(pair[0], pair[1]);
9559      });
9560
9561      assert.deepEqual(actual, expected);
9562    });
9563
9564    QUnit.test('should compare arrays', function(assert) {
9565      assert.expect(6);
9566
9567      var array1 = [true, null, 1, 'a', undefined],
9568          array2 = [true, null, 1, 'a', undefined];
9569
9570      assert.strictEqual(_.isEqual(array1, array2), true);
9571
9572      array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9573      array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9574
9575      assert.strictEqual(_.isEqual(array1, array2), true);
9576
9577      array1 = [1];
9578      array1[2] = 3;
9579
9580      array2 = [1];
9581      array2[1] = undefined;
9582      array2[2] = 3;
9583
9584      assert.strictEqual(_.isEqual(array1, array2), true);
9585
9586      array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
9587      array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
9588
9589      assert.strictEqual(_.isEqual(array1, array2), true);
9590
9591      array1 = [1, 2, 3];
9592      array2 = [3, 2, 1];
9593
9594      assert.strictEqual(_.isEqual(array1, array2), false);
9595
9596      array1 = [1, 2];
9597      array2 = [1, 2, 3];
9598
9599      assert.strictEqual(_.isEqual(array1, array2), false);
9600    });
9601
9602    QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
9603      assert.expect(3);
9604
9605      var array1 = [1, 2, 3],
9606          array2 = [1, 2, 3];
9607
9608      array1.every = array1.filter = array1.forEach =
9609      array1.indexOf = array1.lastIndexOf = array1.map =
9610      array1.some = array1.reduce = array1.reduceRight = null;
9611
9612      array2.concat = array2.join = array2.pop =
9613      array2.reverse = array2.shift = array2.slice =
9614      array2.sort = array2.splice = array2.unshift = null;
9615
9616      assert.strictEqual(_.isEqual(array1, array2), true);
9617
9618      array1 = [1, 2, 3];
9619      array1.a = 1;
9620
9621      array2 = [1, 2, 3];
9622      array2.b = 1;
9623
9624      assert.strictEqual(_.isEqual(array1, array2), true);
9625
9626      array1 = /c/.exec('abcde');
9627      array2 = ['c'];
9628
9629      assert.strictEqual(_.isEqual(array1, array2), true);
9630    });
9631
9632    QUnit.test('should compare sparse arrays', function(assert) {
9633      assert.expect(3);
9634
9635      var array = Array(1);
9636
9637      assert.strictEqual(_.isEqual(array, Array(1)), true);
9638      assert.strictEqual(_.isEqual(array, [undefined]), true);
9639      assert.strictEqual(_.isEqual(array, Array(2)), false);
9640    });
9641
9642    QUnit.test('should compare plain objects', function(assert) {
9643      assert.expect(5);
9644
9645      var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
9646          object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
9647
9648      assert.strictEqual(_.isEqual(object1, object2), true);
9649
9650      object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9651      object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9652
9653      assert.strictEqual(_.isEqual(object1, object2), true);
9654
9655      object1 = { 'a': 1, 'b': 2, 'c': 3 };
9656      object2 = { 'a': 3, 'b': 2, 'c': 1 };
9657
9658      assert.strictEqual(_.isEqual(object1, object2), false);
9659
9660      object1 = { 'a': 1, 'b': 2, 'c': 3 };
9661      object2 = { 'd': 1, 'e': 2, 'f': 3 };
9662
9663      assert.strictEqual(_.isEqual(object1, object2), false);
9664
9665      object1 = { 'a': 1, 'b': 2 };
9666      object2 = { 'a': 1, 'b': 2, 'c': 3 };
9667
9668      assert.strictEqual(_.isEqual(object1, object2), false);
9669    });
9670
9671    QUnit.test('should compare objects regardless of key order', function(assert) {
9672      assert.expect(1);
9673
9674      var object1 = { 'a': 1, 'b': 2, 'c': 3 },
9675          object2 = { 'c': 3, 'a': 1, 'b': 2 };
9676
9677      assert.strictEqual(_.isEqual(object1, object2), true);
9678    });
9679
9680    QUnit.test('should compare nested objects', function(assert) {
9681      assert.expect(1);
9682
9683      var object1 = {
9684        'a': [1, 2, 3],
9685        'b': true,
9686        'c': Object(1),
9687        'd': 'a',
9688        'e': {
9689          'f': ['a', Object('b'), 'c'],
9690          'g': Object(false),
9691          'h': new Date(2012, 4, 23),
9692          'i': noop,
9693          'j': 'a'
9694        }
9695      };
9696
9697      var object2 = {
9698        'a': [1, Object(2), 3],
9699        'b': Object(true),
9700        'c': 1,
9701        'd': Object('a'),
9702        'e': {
9703          'f': ['a', 'b', 'c'],
9704          'g': false,
9705          'h': new Date(2012, 4, 23),
9706          'i': noop,
9707          'j': 'a'
9708        }
9709      };
9710
9711      assert.strictEqual(_.isEqual(object1, object2), true);
9712    });
9713
9714    QUnit.test('should compare object instances', function(assert) {
9715      assert.expect(4);
9716
9717      function Foo() {
9718        this.a = 1;
9719      }
9720      Foo.prototype.a = 1;
9721
9722      function Bar() {
9723        this.a = 1;
9724      }
9725      Bar.prototype.a = 2;
9726
9727      assert.strictEqual(_.isEqual(new Foo, new Foo), true);
9728      assert.strictEqual(_.isEqual(new Foo, new Bar), false);
9729      assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
9730      assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
9731    });
9732
9733    QUnit.test('should compare objects with constructor properties', function(assert) {
9734      assert.expect(5);
9735
9736      assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
9737      assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
9738      assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
9739      assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
9740      assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
9741    });
9742
9743    QUnit.test('should compare arrays with circular references', function(assert) {
9744      assert.expect(4);
9745
9746      var array1 = [],
9747          array2 = [];
9748
9749      array1.push(array1);
9750      array2.push(array2);
9751
9752      assert.strictEqual(_.isEqual(array1, array2), true);
9753
9754      array1.push('b');
9755      array2.push('b');
9756
9757      assert.strictEqual(_.isEqual(array1, array2), true);
9758
9759      array1.push('c');
9760      array2.push('d');
9761
9762      assert.strictEqual(_.isEqual(array1, array2), false);
9763
9764      array1 = ['a', 'b', 'c'];
9765      array1[1] = array1;
9766      array2 = ['a', ['a', 'b', 'c'], 'c'];
9767
9768      assert.strictEqual(_.isEqual(array1, array2), false);
9769    });
9770
9771    QUnit.test('should have transitive equivalence for circular references of arrays', function(assert) {
9772      assert.expect(3);
9773
9774      var array1 = [],
9775          array2 = [array1],
9776          array3 = [array2];
9777
9778      array1[0] = array1;
9779
9780      assert.strictEqual(_.isEqual(array1, array2), true);
9781      assert.strictEqual(_.isEqual(array2, array3), true);
9782      assert.strictEqual(_.isEqual(array1, array3), true);
9783    });
9784
9785    QUnit.test('should compare objects with circular references', function(assert) {
9786      assert.expect(4);
9787
9788      var object1 = {},
9789          object2 = {};
9790
9791      object1.a = object1;
9792      object2.a = object2;
9793
9794      assert.strictEqual(_.isEqual(object1, object2), true);
9795
9796      object1.b = 0;
9797      object2.b = Object(0);
9798
9799      assert.strictEqual(_.isEqual(object1, object2), true);
9800
9801      object1.c = Object(1);
9802      object2.c = Object(2);
9803
9804      assert.strictEqual(_.isEqual(object1, object2), false);
9805
9806      object1 = { 'a': 1, 'b': 2, 'c': 3 };
9807      object1.b = object1;
9808      object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
9809
9810      assert.strictEqual(_.isEqual(object1, object2), false);
9811    });
9812
9813    QUnit.test('should have transitive equivalence for circular references of objects', function(assert) {
9814      assert.expect(3);
9815
9816      var object1 = {},
9817          object2 = { 'a': object1 },
9818          object3 = { 'a': object2 };
9819
9820      object1.a = object1;
9821
9822      assert.strictEqual(_.isEqual(object1, object2), true);
9823      assert.strictEqual(_.isEqual(object2, object3), true);
9824      assert.strictEqual(_.isEqual(object1, object3), true);
9825    });
9826
9827    QUnit.test('should compare objects with multiple circular references', function(assert) {
9828      assert.expect(3);
9829
9830      var array1 = [{}],
9831          array2 = [{}];
9832
9833      (array1[0].a = array1).push(array1);
9834      (array2[0].a = array2).push(array2);
9835
9836      assert.strictEqual(_.isEqual(array1, array2), true);
9837
9838      array1[0].b = 0;
9839      array2[0].b = Object(0);
9840
9841      assert.strictEqual(_.isEqual(array1, array2), true);
9842
9843      array1[0].c = Object(1);
9844      array2[0].c = Object(2);
9845
9846      assert.strictEqual(_.isEqual(array1, array2), false);
9847    });
9848
9849    QUnit.test('should compare objects with complex circular references', function(assert) {
9850      assert.expect(1);
9851
9852      var object1 = {
9853        'foo': { 'b': { 'c': { 'd': {} } } },
9854        'bar': { 'a': 2 }
9855      };
9856
9857      var object2 = {
9858        'foo': { 'b': { 'c': { 'd': {} } } },
9859        'bar': { 'a': 2 }
9860      };
9861
9862      object1.foo.b.c.d = object1;
9863      object1.bar.b = object1.foo.b;
9864
9865      object2.foo.b.c.d = object2;
9866      object2.bar.b = object2.foo.b;
9867
9868      assert.strictEqual(_.isEqual(object1, object2), true);
9869    });
9870
9871    QUnit.test('should compare objects with shared property values', function(assert) {
9872      assert.expect(1);
9873
9874      var object1 = {
9875        'a': [1, 2]
9876      };
9877
9878      var object2 = {
9879        'a': [1, 2],
9880        'b': [1, 2]
9881      };
9882
9883      object1.b = object1.a;
9884
9885      assert.strictEqual(_.isEqual(object1, object2), true);
9886    });
9887
9888    QUnit.test('should treat objects created by `Object.create(null)` like plain objects', function(assert) {
9889      assert.expect(2);
9890
9891      function Foo() {
9892        this.a = 1;
9893      }
9894      Foo.prototype.constructor = null;
9895
9896      var object1 = create(null);
9897      object1.a = 1;
9898
9899      var object2 = { 'a': 1 };
9900
9901      assert.strictEqual(_.isEqual(object1, object2), true);
9902      assert.strictEqual(_.isEqual(new Foo, object2), false);
9903    });
9904
9905    QUnit.test('should avoid common type coercions', function(assert) {
9906      assert.expect(9);
9907
9908      assert.strictEqual(_.isEqual(true, Object(false)), false);
9909      assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
9910      assert.strictEqual(_.isEqual(false, Object('')), false);
9911      assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
9912      assert.strictEqual(_.isEqual(0, ''), false);
9913      assert.strictEqual(_.isEqual(1, true), false);
9914      assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
9915      assert.strictEqual(_.isEqual('36', 36), false);
9916      assert.strictEqual(_.isEqual(36, '36'), false);
9917    });
9918
9919    QUnit.test('should compare `arguments` objects', function(assert) {
9920      assert.expect(2);
9921
9922      var args1 = (function() { return arguments; }()),
9923          args2 = (function() { return arguments; }()),
9924          args3 = (function() { return arguments; }(1, 2));
9925
9926      assert.strictEqual(_.isEqual(args1, args2), true);
9927      assert.strictEqual(_.isEqual(args1, args3), false);
9928    });
9929
9930    QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
9931      assert.expect(4);
9932
9933      var object = { '0': 1, '1': 2, '2': 3 };
9934
9935      function Foo() {}
9936      Foo.prototype = object;
9937
9938      assert.strictEqual(_.isEqual(args, object), true);
9939      assert.strictEqual(_.isEqual(object, args), true);
9940      assert.strictEqual(_.isEqual(args, new Foo), false);
9941      assert.strictEqual(_.isEqual(new Foo, args), false);
9942    });
9943
9944    QUnit.test('should compare array buffers', function(assert) {
9945      assert.expect(2);
9946
9947      if (ArrayBuffer) {
9948        var buffer = new Int8Array([-1]).buffer;
9949
9950        assert.strictEqual(_.isEqual(buffer, new Uint8Array([255]).buffer), true);
9951        assert.strictEqual(_.isEqual(buffer, new ArrayBuffer(1)), false);
9952      }
9953      else {
9954        skipAssert(assert, 2);
9955      }
9956    });
9957
9958    QUnit.test('should compare array views', function(assert) {
9959      assert.expect(2);
9960
9961      lodashStable.times(2, function(index) {
9962        var ns = index ? realm : root;
9963
9964        var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
9965          var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
9966              CtorA = ns[type] || function(n) { this.n = n; },
9967              CtorB = ns[otherType] || function(n) { this.n = n; },
9968              bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
9969              bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
9970              bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
9971
9972          return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
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
9985    QUnit.test('should compare buffers', function(assert) {
9986      assert.expect(3);
9987
9988      if (Buffer) {
9989        var buffer = new Buffer([1]);
9990
9991        assert.strictEqual(_.isEqual(buffer, new Buffer([1])), true);
9992        assert.strictEqual(_.isEqual(buffer, new Buffer([2])), false);
9993        assert.strictEqual(_.isEqual(buffer, new Uint8Array([1])), false);
9994      }
9995      else {
9996        skipAssert(assert, 3);
9997      }
9998    });
9999
10000    QUnit.test('should compare date objects', function(assert) {
10001      assert.expect(4);
10002
10003      var date = new Date(2012, 4, 23);
10004
10005      assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
10006      assert.strictEqual(_.isEqual(new Date('a'), new Date('b')), true);
10007      assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
10008      assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
10009    });
10010
10011    QUnit.test('should compare error objects', function(assert) {
10012      assert.expect(1);
10013
10014      var pairs = lodashStable.map([
10015        'Error',
10016        'EvalError',
10017        'RangeError',
10018        'ReferenceError',
10019        'SyntaxError',
10020        'TypeError',
10021        'URIError'
10022      ], function(type, index, errorTypes) {
10023        var otherType = errorTypes[++index % errorTypes.length],
10024            CtorA = root[type],
10025            CtorB = root[otherType];
10026
10027        return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
10028      });
10029
10030      var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
10031
10032      var actual = lodashStable.map(pairs, function(pair) {
10033        return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
10034      });
10035
10036      assert.deepEqual(actual, expected);
10037    });
10038
10039    QUnit.test('should compare functions', function(assert) {
10040      assert.expect(2);
10041
10042      function a() { return 1 + 2; }
10043      function b() { return 1 + 2; }
10044
10045      assert.strictEqual(_.isEqual(a, a), true);
10046      assert.strictEqual(_.isEqual(a, b), false);
10047    });
10048
10049    QUnit.test('should compare maps', function(assert) {
10050      assert.expect(8);
10051
10052      if (Map) {
10053        lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
10054          var map1 = maps[0],
10055              map2 = maps[1];
10056
10057          map1.set('a', 1);
10058          map2.set('b', 2);
10059          assert.strictEqual(_.isEqual(map1, map2), false);
10060
10061          map1.set('b', 2);
10062          map2.set('a', 1);
10063          assert.strictEqual(_.isEqual(map1, map2), true);
10064
10065          map1.delete('a');
10066          map1.set('a', 1);
10067          assert.strictEqual(_.isEqual(map1, map2), true);
10068
10069          map2.delete('a');
10070          assert.strictEqual(_.isEqual(map1, map2), false);
10071
10072          map1.clear();
10073          map2.clear();
10074        });
10075      }
10076      else {
10077        skipAssert(assert, 8);
10078      }
10079    });
10080
10081    QUnit.test('should compare maps with circular references', function(assert) {
10082      assert.expect(2);
10083
10084      if (Map) {
10085        var map1 = new Map,
10086            map2 = new Map;
10087
10088        map1.set('a', map1);
10089        map2.set('a', map2);
10090        assert.strictEqual(_.isEqual(map1, map2), true);
10091
10092        map1.set('b', 1);
10093        map2.set('b', 2);
10094        assert.strictEqual(_.isEqual(map1, map2), false);
10095      }
10096      else {
10097        skipAssert(assert, 2);
10098      }
10099    });
10100
10101    QUnit.test('should compare promises by reference', function(assert) {
10102      assert.expect(4);
10103
10104      if (promise) {
10105        lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
10106          var promise1 = promises[0],
10107              promise2 = promises[1];
10108
10109          assert.strictEqual(_.isEqual(promise1, promise2), false);
10110          assert.strictEqual(_.isEqual(promise1, promise1), true);
10111        });
10112      }
10113      else {
10114        skipAssert(assert, 4);
10115      }
10116    });
10117
10118    QUnit.test('should compare regexes', function(assert) {
10119      assert.expect(5);
10120
10121      assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
10122      assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
10123      assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
10124      assert.strictEqual(_.isEqual(/x/, /y/), false);
10125      assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
10126    });
10127
10128    QUnit.test('should compare sets', function(assert) {
10129      assert.expect(8);
10130
10131      if (Set) {
10132        lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
10133          var set1 = sets[0],
10134              set2 = sets[1];
10135
10136          set1.add(1);
10137          set2.add(2);
10138          assert.strictEqual(_.isEqual(set1, set2), false);
10139
10140          set1.add(2);
10141          set2.add(1);
10142          assert.strictEqual(_.isEqual(set1, set2), true);
10143
10144          set1.delete(1);
10145          set1.add(1);
10146          assert.strictEqual(_.isEqual(set1, set2), true);
10147
10148          set2.delete(1);
10149          assert.strictEqual(_.isEqual(set1, set2), false);
10150
10151          set1.clear();
10152          set2.clear();
10153        });
10154      }
10155      else {
10156        skipAssert(assert, 8);
10157      }
10158    });
10159
10160    QUnit.test('should compare sets with circular references', function(assert) {
10161      assert.expect(2);
10162
10163      if (Set) {
10164        var set1 = new Set,
10165            set2 = new Set;
10166
10167        set1.add(set1);
10168        set2.add(set2);
10169        assert.strictEqual(_.isEqual(set1, set2), true);
10170
10171        set1.add(1);
10172        set2.add(2);
10173        assert.strictEqual(_.isEqual(set1, set2), false);
10174      }
10175      else {
10176        skipAssert(assert, 2);
10177      }
10178    });
10179
10180    QUnit.test('should compare symbol properties', function(assert) {
10181      assert.expect(3);
10182
10183      if (Symbol) {
10184        var object1 = { 'a': 1 },
10185            object2 = { 'a': 1 };
10186
10187        object1[symbol1] = { 'a': { 'b': 2 } };
10188        object2[symbol1] = { 'a': { 'b': 2 } };
10189
10190        defineProperty(object2, symbol2, {
10191          'configurable': true,
10192          'enumerable': false,
10193          'writable': true,
10194          'value': 2
10195        });
10196
10197        assert.strictEqual(_.isEqual(object1, object2), true);
10198
10199        object2[symbol1] = { 'a': 1 };
10200        assert.strictEqual(_.isEqual(object1, object2), false);
10201
10202        delete object2[symbol1];
10203        object2[Symbol('a')] = { 'a': { 'b': 2 } };
10204        assert.strictEqual(_.isEqual(object1, object2), false);
10205      }
10206      else {
10207        skipAssert(assert, 3);
10208      }
10209    });
10210
10211    QUnit.test('should compare wrapped values', function(assert) {
10212      assert.expect(32);
10213
10214      var stamp = +new Date;
10215
10216      var values = [
10217        [[1, 2], [1, 2], [1, 2, 3]],
10218        [true, true, false],
10219        [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
10220        [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
10221        [1, 1, 2],
10222        [NaN, NaN, Infinity],
10223        [/x/, /x/, /x/i],
10224        ['a', 'a', 'A']
10225      ];
10226
10227      lodashStable.each(values, function(vals) {
10228        if (!isNpm) {
10229          var wrapped1 = _(vals[0]),
10230              wrapped2 = _(vals[1]),
10231              actual = wrapped1.isEqual(wrapped2);
10232
10233          assert.strictEqual(actual, true);
10234          assert.strictEqual(_.isEqual(_(actual), _(true)), true);
10235
10236          wrapped1 = _(vals[0]);
10237          wrapped2 = _(vals[2]);
10238
10239          actual = wrapped1.isEqual(wrapped2);
10240          assert.strictEqual(actual, false);
10241          assert.strictEqual(_.isEqual(_(actual), _(false)), true);
10242        }
10243        else {
10244          skipAssert(assert, 4);
10245        }
10246      });
10247    });
10248
10249    QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
10250      assert.expect(4);
10251
10252      if (!isNpm) {
10253        var object1 = _({ 'a': 1, 'b': 2 }),
10254            object2 = { 'a': 1, 'b': 2 };
10255
10256        assert.strictEqual(object1.isEqual(object2), true);
10257        assert.strictEqual(_.isEqual(object1, object2), true);
10258
10259        object1 = _({ 'a': 1, 'b': 2 });
10260        object2 = { 'a': 1, 'b': 1 };
10261
10262        assert.strictEqual(object1.isEqual(object2), false);
10263        assert.strictEqual(_.isEqual(object1, object2), false);
10264      }
10265      else {
10266        skipAssert(assert, 4);
10267      }
10268    });
10269
10270    QUnit.test('should work as an iteratee for `_.every`', function(assert) {
10271      assert.expect(1);
10272
10273      var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
10274      assert.ok(actual);
10275    });
10276
10277    QUnit.test('should not error on DOM elements', function(assert) {
10278      assert.expect(1);
10279
10280      if (document) {
10281        var element1 = document.createElement('div'),
10282            element2 = element1.cloneNode(true);
10283
10284        try {
10285          assert.strictEqual(_.isEqual(element1, element2), false);
10286        } catch (e) {
10287          assert.ok(false, e.message);
10288        }
10289      }
10290      else {
10291        skipAssert(assert);
10292      }
10293    });
10294
10295    QUnit.test('should return `true` for like-objects from different documents', function(assert) {
10296      assert.expect(4);
10297
10298      if (realm.object) {
10299        assert.strictEqual(_.isEqual([1], realm.array), true);
10300        assert.strictEqual(_.isEqual([2], realm.array), false);
10301        assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
10302        assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
10303      }
10304      else {
10305        skipAssert(assert, 4);
10306      }
10307    });
10308
10309    QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
10310      assert.expect(1);
10311
10312      var primitive,
10313          object = { 'toString': function() { return primitive; } },
10314          values = [true, null, 1, 'a', undefined],
10315          expected = lodashStable.map(values, stubFalse);
10316
10317      var actual = lodashStable.map(values, function(value) {
10318        primitive = value;
10319        return _.isEqual(object, value);
10320      });
10321
10322      assert.deepEqual(actual, expected);
10323    });
10324
10325    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
10326      assert.expect(1);
10327
10328      if (!isNpm) {
10329        assert.strictEqual(_('a').isEqual('a'), true);
10330      }
10331      else {
10332        skipAssert(assert);
10333      }
10334    });
10335
10336    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
10337      assert.expect(1);
10338
10339      if (!isNpm) {
10340        assert.ok(_('a').chain().isEqual('a') instanceof _);
10341      }
10342      else {
10343        skipAssert(assert);
10344      }
10345    });
10346  }());
10347
10348  /*--------------------------------------------------------------------------*/
10349
10350  QUnit.module('lodash.isEqualWith');
10351
10352  (function() {
10353    QUnit.test('should provide correct `customizer` arguments', function(assert) {
10354      assert.expect(1);
10355
10356      var argsList = [],
10357          object1 = { 'a': [1, 2], 'b': null },
10358          object2 = { 'a': [1, 2], 'b': null };
10359
10360      object1.b = object2;
10361      object2.b = object1;
10362
10363      var expected = [
10364        [object1, object2],
10365        [object1.a, object2.a, 'a', object1, object2],
10366        [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10367        [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10368        [object1.b, object2.b, 'b', object1.b, object2.b]
10369      ];
10370
10371      _.isEqualWith(object1, object2, function(assert) {
10372        var length = arguments.length,
10373            args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10374
10375        argsList.push(args);
10376      });
10377
10378      assert.deepEqual(argsList, expected);
10379    });
10380
10381    QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10382      assert.expect(3);
10383
10384      assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
10385      assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
10386      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
10387    });
10388
10389    QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10390      assert.expect(3);
10391
10392      var customizer = function(value) {
10393        return _.isString(value) || undefined;
10394      };
10395
10396      assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
10397      assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
10398      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10399    });
10400
10401    QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10402      assert.expect(3);
10403
10404      var customizer = function(value) {
10405        return _.isString(value) ? false : undefined;
10406      };
10407
10408      assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
10409      assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
10410      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10411    });
10412
10413    QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10414      assert.expect(2);
10415
10416      var actual = _.isEqualWith('a', 'b', stubC);
10417      assert.strictEqual(actual, true);
10418
10419      var values = _.without(falsey, undefined),
10420          expected = lodashStable.map(values, stubFalse);
10421
10422      actual = [];
10423      lodashStable.each(values, function(value) {
10424        actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
10425      });
10426
10427      assert.deepEqual(actual, expected);
10428    });
10429
10430    QUnit.test('should ensure `customizer` is a function', function(assert) {
10431      assert.expect(1);
10432
10433      var array = [1, 2, 3],
10434          eq = _.partial(_.isEqualWith, array),
10435          actual = lodashStable.map([array, [1, 0, 3]], eq);
10436
10437      assert.deepEqual(actual, [true, false]);
10438    });
10439
10440    QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10441      assert.expect(2);
10442
10443      var value = { 'a': { 'b': 2 } };
10444
10445      if (Map) {
10446        var map1 = new Map;
10447        map1.set('a', value);
10448
10449        var map2 = new Map;
10450        map2.set('a', value);
10451      }
10452      if (Set) {
10453        var set1 = new Set;
10454        set1.add(value);
10455
10456        var set2 = new Set;
10457        set2.add(value);
10458      }
10459      lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10460        if (pair[0]) {
10461          var argsList = [],
10462              array = lodashStable.toArray(pair[0]);
10463
10464          var expected = [
10465            [pair[0], pair[1]],
10466            [array[0], array[0], 0, array, array],
10467            [array[0][0], array[0][0], 0, array[0], array[0]],
10468            [array[0][1], array[0][1], 1, array[0], array[0]]
10469          ];
10470
10471          if (index) {
10472            expected.length = 2;
10473          }
10474          _.isEqualWith(pair[0], pair[1], function() {
10475            var length = arguments.length,
10476                args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
10477
10478            argsList.push(args);
10479          });
10480
10481          assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10482        }
10483        else {
10484          skipAssert(assert);
10485        }
10486      });
10487    });
10488  }());
10489
10490  /*--------------------------------------------------------------------------*/
10491
10492  QUnit.module('lodash.isError');
10493
10494  (function() {
10495    QUnit.test('should return `true` for error objects', function(assert) {
10496      assert.expect(1);
10497
10498      var expected = lodashStable.map(errors, stubTrue);
10499
10500      var actual = lodashStable.map(errors, function(error) {
10501        return _.isError(error) === true;
10502      });
10503
10504      assert.deepEqual(actual, expected);
10505    });
10506
10507    QUnit.test('should return `true` for subclassed values', function(assert) {
10508      assert.expect(1);
10509
10510      assert.strictEqual(_.isError(new CustomError('x')), true);
10511    });
10512
10513    QUnit.test('should return `false` for non error objects', function(assert) {
10514      assert.expect(12);
10515
10516      var expected = lodashStable.map(falsey, stubFalse);
10517
10518      var actual = lodashStable.map(falsey, function(value, index) {
10519        return index ? _.isError(value) : _.isError();
10520      });
10521
10522      assert.deepEqual(actual, expected);
10523
10524      assert.strictEqual(_.isError(args), false);
10525      assert.strictEqual(_.isError([1, 2, 3]), false);
10526      assert.strictEqual(_.isError(true), false);
10527      assert.strictEqual(_.isError(new Date), false);
10528      assert.strictEqual(_.isError(_), false);
10529      assert.strictEqual(_.isError(slice), false);
10530      assert.strictEqual(_.isError({ 'a': 1 }), false);
10531      assert.strictEqual(_.isError(1), false);
10532      assert.strictEqual(_.isError(/x/), false);
10533      assert.strictEqual(_.isError('a'), false);
10534      assert.strictEqual(_.isError(symbol), false);
10535    });
10536
10537    QUnit.test('should return `false` for plain objects', function(assert) {
10538      assert.expect(1);
10539
10540      assert.strictEqual(_.isError({ 'name': 'Error', 'message': '' }), false);
10541    });
10542
10543    QUnit.test('should work with an error object from another realm', function(assert) {
10544      assert.expect(1);
10545
10546      if (realm.errors) {
10547        var expected = lodashStable.map(realm.errors, stubTrue);
10548
10549        var actual = lodashStable.map(realm.errors, function(error) {
10550          return _.isError(error) === true;
10551        });
10552
10553        assert.deepEqual(actual, expected);
10554      }
10555      else {
10556        skipAssert(assert);
10557      }
10558    });
10559  }());
10560
10561  /*--------------------------------------------------------------------------*/
10562
10563  QUnit.module('lodash.isFinite');
10564
10565  (function() {
10566    QUnit.test('should return `true` for finite values', function(assert) {
10567      assert.expect(1);
10568
10569      var values = [0, 1, 3.14, -1],
10570          expected = lodashStable.map(values, stubTrue),
10571          actual = lodashStable.map(values, _.isFinite);
10572
10573      assert.deepEqual(actual, expected);
10574    });
10575
10576    QUnit.test('should return `false` for non-finite values', function(assert) {
10577      assert.expect(1);
10578
10579      var values = [NaN, Infinity, -Infinity, Object(1)],
10580          expected = lodashStable.map(values, stubFalse),
10581          actual = lodashStable.map(values, _.isFinite);
10582
10583      assert.deepEqual(actual, expected);
10584    });
10585
10586    QUnit.test('should return `false` for non-numeric values', function(assert) {
10587      assert.expect(10);
10588
10589      var values = [undefined, [], true, '', ' ', '2px'],
10590          expected = lodashStable.map(values, stubFalse),
10591          actual = lodashStable.map(values, _.isFinite);
10592
10593      assert.deepEqual(actual, expected);
10594
10595      assert.strictEqual(_.isFinite(args), false);
10596      assert.strictEqual(_.isFinite([1, 2, 3]), false);
10597      assert.strictEqual(_.isFinite(true), false);
10598      assert.strictEqual(_.isFinite(new Date), false);
10599      assert.strictEqual(_.isFinite(new Error), false);
10600      assert.strictEqual(_.isFinite({ 'a': 1 }), false);
10601      assert.strictEqual(_.isFinite(/x/), false);
10602      assert.strictEqual(_.isFinite('a'), false);
10603      assert.strictEqual(_.isFinite(symbol), false);
10604    });
10605
10606    QUnit.test('should return `false` for numeric string values', function(assert) {
10607      assert.expect(1);
10608
10609      var values = ['2', '0', '08'],
10610          expected = lodashStable.map(values, stubFalse),
10611          actual = lodashStable.map(values, _.isFinite);
10612
10613      assert.deepEqual(actual, expected);
10614    });
10615  }());
10616
10617  /*--------------------------------------------------------------------------*/
10618
10619  QUnit.module('lodash.isFunction');
10620
10621  (function() {
10622    QUnit.test('should return `true` for functions', function(assert) {
10623      assert.expect(2);
10624
10625      assert.strictEqual(_.isFunction(_), true);
10626      assert.strictEqual(_.isFunction(slice), true);
10627    });
10628
10629    QUnit.test('should return `true` for async functions', function(assert) {
10630      assert.expect(1);
10631
10632      assert.strictEqual(_.isFunction(asyncFunc), typeof asyncFunc == 'function');
10633    });
10634
10635    QUnit.test('should return `true` for generator functions', function(assert) {
10636      assert.expect(1);
10637
10638      assert.strictEqual(_.isFunction(genFunc), typeof genFunc == 'function');
10639    });
10640
10641    QUnit.test('should return `true` for the `Proxy` constructor', function(assert) {
10642      assert.expect(1);
10643
10644      if (Proxy) {
10645        assert.strictEqual(_.isFunction(Proxy), true);
10646      }
10647      else {
10648        skipAssert(assert);
10649      }
10650    });
10651
10652    QUnit.test('should return `true` for array view constructors', function(assert) {
10653      assert.expect(1);
10654
10655      var expected = lodashStable.map(arrayViews, function(type) {
10656        return objToString.call(root[type]) == funcTag;
10657      });
10658
10659      var actual = lodashStable.map(arrayViews, function(type) {
10660        return _.isFunction(root[type]);
10661      });
10662
10663      assert.deepEqual(actual, expected);
10664    });
10665
10666    QUnit.test('should return `false` for non-functions', function(assert) {
10667      assert.expect(12);
10668
10669      var expected = lodashStable.map(falsey, stubFalse);
10670
10671      var actual = lodashStable.map(falsey, function(value, index) {
10672        return index ? _.isFunction(value) : _.isFunction();
10673      });
10674
10675      assert.deepEqual(actual, expected);
10676
10677      assert.strictEqual(_.isFunction(args), false);
10678      assert.strictEqual(_.isFunction([1, 2, 3]), false);
10679      assert.strictEqual(_.isFunction(true), false);
10680      assert.strictEqual(_.isFunction(new Date), false);
10681      assert.strictEqual(_.isFunction(new Error), false);
10682      assert.strictEqual(_.isFunction({ 'a': 1 }), false);
10683      assert.strictEqual(_.isFunction(1), false);
10684      assert.strictEqual(_.isFunction(/x/), false);
10685      assert.strictEqual(_.isFunction('a'), false);
10686      assert.strictEqual(_.isFunction(symbol), false);
10687
10688      if (document) {
10689        assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
10690      }
10691      else {
10692        skipAssert(assert);
10693      }
10694    });
10695
10696    QUnit.test('should work with a function from another realm', function(assert) {
10697      assert.expect(1);
10698
10699      if (realm.function) {
10700        assert.strictEqual(_.isFunction(realm.function), true);
10701      }
10702      else {
10703        skipAssert(assert);
10704      }
10705    });
10706  }());
10707
10708  /*--------------------------------------------------------------------------*/
10709
10710  QUnit.module('isInteger methods');
10711
10712  lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
10713    var func = _[methodName],
10714        isSafe = methodName == 'isSafeInteger';
10715
10716    QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
10717      assert.expect(2);
10718
10719      var values = [-1, 0, 1],
10720          expected = lodashStable.map(values, stubTrue);
10721
10722      var actual = lodashStable.map(values, function(value) {
10723        return func(value);
10724      });
10725
10726      assert.deepEqual(actual, expected);
10727      assert.strictEqual(func(MAX_INTEGER), !isSafe);
10728    });
10729
10730    QUnit.test('should return `false` for non-integer number values', function(assert) {
10731      assert.expect(1);
10732
10733      var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
10734          expected = lodashStable.map(values, stubFalse);
10735
10736      var actual = lodashStable.map(values, function(value) {
10737        return func(value);
10738      });
10739
10740      assert.deepEqual(actual, expected);
10741    });
10742
10743    QUnit.test('should return `false` for non-numeric values', function(assert) {
10744      assert.expect(10);
10745
10746      var expected = lodashStable.map(falsey, function(value) {
10747        return value === 0;
10748      });
10749
10750      var actual = lodashStable.map(falsey, function(value, index) {
10751        return index ? func(value) : func();
10752      });
10753
10754      assert.deepEqual(actual, expected);
10755
10756      assert.strictEqual(func(args), false);
10757      assert.strictEqual(func([1, 2, 3]), false);
10758      assert.strictEqual(func(true), false);
10759      assert.strictEqual(func(new Date), false);
10760      assert.strictEqual(func(new Error), false);
10761      assert.strictEqual(func({ 'a': 1 }), false);
10762      assert.strictEqual(func(/x/), false);
10763      assert.strictEqual(func('a'), false);
10764      assert.strictEqual(func(symbol), false);
10765    });
10766  });
10767
10768  /*--------------------------------------------------------------------------*/
10769
10770  QUnit.module('lodash.isLength');
10771
10772  (function() {
10773    QUnit.test('should return `true` for lengths', function(assert) {
10774      assert.expect(1);
10775
10776      var values = [0, 3, MAX_SAFE_INTEGER],
10777          expected = lodashStable.map(values, stubTrue),
10778          actual = lodashStable.map(values, _.isLength);
10779
10780      assert.deepEqual(actual, expected);
10781    });
10782
10783    QUnit.test('should return `false` for non-lengths', function(assert) {
10784      assert.expect(1);
10785
10786      var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
10787          expected = lodashStable.map(values, stubFalse),
10788          actual = lodashStable.map(values, _.isLength);
10789
10790      assert.deepEqual(actual, expected);
10791    });
10792  }());
10793
10794  /*--------------------------------------------------------------------------*/
10795
10796  QUnit.module('lodash.isMap');
10797
10798  (function() {
10799    QUnit.test('should return `true` for maps', function(assert) {
10800      assert.expect(1);
10801
10802      if (Map) {
10803        assert.strictEqual(_.isMap(map), true);
10804      }
10805      else {
10806        skipAssert(assert);
10807      }
10808    });
10809
10810    QUnit.test('should return `false` for non-maps', function(assert) {
10811      assert.expect(14);
10812
10813      var expected = lodashStable.map(falsey, stubFalse);
10814
10815      var actual = lodashStable.map(falsey, function(value, index) {
10816        return index ? _.isMap(value) : _.isMap();
10817      });
10818
10819      assert.deepEqual(actual, expected);
10820
10821      assert.strictEqual(_.isMap(args), false);
10822      assert.strictEqual(_.isMap([1, 2, 3]), false);
10823      assert.strictEqual(_.isMap(true), false);
10824      assert.strictEqual(_.isMap(new Date), false);
10825      assert.strictEqual(_.isMap(new Error), false);
10826      assert.strictEqual(_.isMap(_), false);
10827      assert.strictEqual(_.isMap(slice), false);
10828      assert.strictEqual(_.isMap({ 'a': 1 }), false);
10829      assert.strictEqual(_.isMap(1), false);
10830      assert.strictEqual(_.isMap(/x/), false);
10831      assert.strictEqual(_.isMap('a'), false);
10832      assert.strictEqual(_.isMap(symbol), false);
10833      assert.strictEqual(_.isMap(weakMap), false);
10834    });
10835
10836    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
10837      assert.expect(1);
10838
10839      var values = [false, true],
10840          expected = lodashStable.map(values, stubFalse);
10841
10842      var actual = lodashStable.map(values, function(value) {
10843        return _.isMap({ 'constructor': value });
10844      });
10845
10846      assert.deepEqual(actual, expected);
10847    });
10848
10849    QUnit.test('should work with maps from another realm', function(assert) {
10850      assert.expect(1);
10851
10852      if (realm.map) {
10853        assert.strictEqual(_.isMap(realm.map), true);
10854      }
10855      else {
10856        skipAssert(assert);
10857      }
10858    });
10859  }());
10860
10861  /*--------------------------------------------------------------------------*/
10862
10863  QUnit.module('lodash.isMatchWith');
10864
10865  (function() {
10866    QUnit.test('should provide correct `customizer` arguments', function(assert) {
10867      assert.expect(1);
10868
10869      var argsList = [],
10870          object1 = { 'a': [1, 2], 'b': null },
10871          object2 = { 'a': [1, 2], 'b': null };
10872
10873      object1.b = object2;
10874      object2.b = object1;
10875
10876      var expected = [
10877        [object1.a, object2.a, 'a', object1, object2],
10878        [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10879        [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10880        [object1.b, object2.b, 'b', object1, object2],
10881        [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10882        [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10883        [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10884        [object1.b.b, object2.b.b, 'b', object1.b, object2.b]
10885      ];
10886
10887      _.isMatchWith(object1, object2, function(assert) {
10888        argsList.push(slice.call(arguments, 0, -1));
10889      });
10890
10891      assert.deepEqual(argsList, expected);
10892    });
10893
10894    QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) {
10895      assert.expect(1);
10896
10897      assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10898    });
10899
10900    QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) {
10901      assert.expect(2);
10902
10903      var customizer = function(value) {
10904        return _.isString(value) || undefined;
10905      };
10906
10907      assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10908      assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10909    });
10910
10911    QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) {
10912      assert.expect(2);
10913
10914      var customizer = function(value) {
10915        return _.isString(value) ? false : undefined;
10916      };
10917
10918      assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10919      assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10920    });
10921
10922    QUnit.test('should return a boolean value even when `customizer` does not', function(assert) {
10923      assert.expect(2);
10924
10925      var object = { 'a': 1 },
10926          actual = _.isMatchWith(object, { 'a': 1 }, stubA);
10927
10928      assert.strictEqual(actual, true);
10929
10930      var expected = lodashStable.map(falsey, stubFalse);
10931
10932      actual = [];
10933      lodashStable.each(falsey, function(value) {
10934        actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
10935      });
10936
10937      assert.deepEqual(actual, expected);
10938    });
10939
10940    QUnit.test('should provide `stack` to `customizer`', function(assert) {
10941      assert.expect(1);
10942
10943      var actual;
10944
10945      _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() {
10946        actual = _.last(arguments);
10947      });
10948
10949      assert.ok(isNpm
10950        ? actual.constructor.name == 'Stack'
10951        : actual instanceof mapCaches.Stack
10952      );
10953    });
10954
10955    QUnit.test('should ensure `customizer` is a function', function(assert) {
10956      assert.expect(1);
10957
10958      var object = { 'a': 1 },
10959          matches = _.partial(_.isMatchWith, object),
10960          actual = lodashStable.map([object, { 'a': 2 }], matches);
10961
10962      assert.deepEqual(actual, [true, false]);
10963    });
10964
10965    QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10966      assert.expect(2);
10967
10968      var value = { 'a': { 'b': 2 } };
10969
10970      if (Map) {
10971        var map1 = new Map;
10972        map1.set('a', value);
10973
10974        var map2 = new Map;
10975        map2.set('a', value);
10976      }
10977      if (Set) {
10978        var set1 = new Set;
10979        set1.add(value);
10980
10981        var set2 = new Set;
10982        set2.add(value);
10983      }
10984      lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10985        if (pair[0]) {
10986          var argsList = [],
10987              array = lodashStable.toArray(pair[0]),
10988              object1 = { 'a': pair[0] },
10989              object2 = { 'a': pair[1] };
10990
10991          var expected = [
10992            [pair[0], pair[1], 'a', object1, object2],
10993            [array[0], array[0], 0, array, array],
10994            [array[0][0], array[0][0], 0, array[0], array[0]],
10995            [array[0][1], array[0][1], 1, array[0], array[0]]
10996          ];
10997
10998          if (index) {
10999            expected.length = 2;
11000          }
11001          _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
11002            argsList.push(slice.call(arguments, 0, -1));
11003          });
11004
11005          assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
11006        }
11007        else {
11008          skipAssert(assert);
11009        }
11010      });
11011    });
11012  }());
11013
11014  /*--------------------------------------------------------------------------*/
11015
11016  QUnit.module('lodash.isNaN');
11017
11018  (function() {
11019    QUnit.test('should return `true` for NaNs', function(assert) {
11020      assert.expect(2);
11021
11022      assert.strictEqual(_.isNaN(NaN), true);
11023      assert.strictEqual(_.isNaN(Object(NaN)), true);
11024    });
11025
11026    QUnit.test('should return `false` for non-NaNs', function(assert) {
11027      assert.expect(14);
11028
11029      var expected = lodashStable.map(falsey, function(value) {
11030        return value !== value;
11031      });
11032
11033      var actual = lodashStable.map(falsey, function(value, index) {
11034        return index ? _.isNaN(value) : _.isNaN();
11035      });
11036
11037      assert.deepEqual(actual, expected);
11038
11039      assert.strictEqual(_.isNaN(args), false);
11040      assert.strictEqual(_.isNaN([1, 2, 3]), false);
11041      assert.strictEqual(_.isNaN(true), false);
11042      assert.strictEqual(_.isNaN(new Date), false);
11043      assert.strictEqual(_.isNaN(new Error), false);
11044      assert.strictEqual(_.isNaN(_), false);
11045      assert.strictEqual(_.isNaN(slice), false);
11046      assert.strictEqual(_.isNaN({ 'a': 1 }), false);
11047      assert.strictEqual(_.isNaN(1), false);
11048      assert.strictEqual(_.isNaN(Object(1)), false);
11049      assert.strictEqual(_.isNaN(/x/), false);
11050      assert.strictEqual(_.isNaN('a'), false);
11051      assert.strictEqual(_.isNaN(symbol), false);
11052    });
11053
11054    QUnit.test('should work with `NaN` from another realm', function(assert) {
11055      assert.expect(1);
11056
11057      if (realm.object) {
11058        assert.strictEqual(_.isNaN(realm.nan), true);
11059      }
11060      else {
11061        skipAssert(assert);
11062      }
11063    });
11064  }());
11065
11066  /*--------------------------------------------------------------------------*/
11067
11068  QUnit.module('lodash.isNative');
11069
11070  (function() {
11071    QUnit.test('should return `true` for native methods', function(assert) {
11072      assert.expect(1);
11073
11074      var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
11075          expected = lodashStable.map(values, Boolean),
11076          actual = lodashStable.map(values, _.isNative);
11077
11078      assert.deepEqual(actual, expected);
11079    });
11080
11081    QUnit.test('should return `false` for non-native methods', function(assert) {
11082      assert.expect(12);
11083
11084      var expected = lodashStable.map(falsey, stubFalse);
11085
11086      var actual = lodashStable.map(falsey, function(value, index) {
11087        return index ? _.isNative(value) : _.isNative();
11088      });
11089
11090      assert.deepEqual(actual, expected);
11091
11092      assert.strictEqual(_.isNative(args), false);
11093      assert.strictEqual(_.isNative([1, 2, 3]), false);
11094      assert.strictEqual(_.isNative(true), false);
11095      assert.strictEqual(_.isNative(new Date), false);
11096      assert.strictEqual(_.isNative(new Error), false);
11097      assert.strictEqual(_.isNative(_), false);
11098      assert.strictEqual(_.isNative({ 'a': 1 }), false);
11099      assert.strictEqual(_.isNative(1), false);
11100      assert.strictEqual(_.isNative(/x/), false);
11101      assert.strictEqual(_.isNative('a'), false);
11102      assert.strictEqual(_.isNative(symbol), false);
11103    });
11104
11105    QUnit.test('should work with native functions from another realm', function(assert) {
11106      assert.expect(2);
11107
11108      if (realm.element) {
11109        assert.strictEqual(_.isNative(realm.element.cloneNode), true);
11110      }
11111      else {
11112        skipAssert(assert);
11113      }
11114      if (realm.object) {
11115        assert.strictEqual(_.isNative(realm.object.valueOf), true);
11116      }
11117      else {
11118        skipAssert(assert);
11119      }
11120    });
11121
11122    QUnit.test('should throw an error if core-js is detected', function(assert) {
11123      assert.expect(1);
11124
11125      if (!isModularize) {
11126        var lodash = _.runInContext({
11127          '__core-js_shared__': {}
11128        });
11129
11130        assert.raises(function() { lodash.isNative(noop); });
11131      }
11132      else {
11133        skipAssert(assert);
11134      }
11135    });
11136
11137    QUnit.test('should detect methods masquerading as native (test in Node.js)', function(assert) {
11138      assert.expect(2);
11139
11140      if (!amd && _._baseEach) {
11141        var path = require('path'),
11142            basePath = path.dirname(filePath),
11143            uid = 'e0gvgyrad1jor',
11144            coreKey = '__core-js_shared__',
11145            fakeSrcKey = 'Symbol(src)_1.' + uid;
11146
11147        root[coreKey] = { 'keys': { 'IE_PROTO': 'Symbol(IE_PROTO)_3.' + uid } };
11148        emptyObject(require.cache);
11149
11150        var baseIsNative = interopRequire(path.join(basePath, '_baseIsNative'));
11151        assert.strictEqual(baseIsNative(slice), true);
11152
11153        slice[fakeSrcKey] = slice + '';
11154        assert.strictEqual(baseIsNative(slice), false);
11155
11156        delete slice[fakeSrcKey];
11157        delete root[coreKey];
11158      }
11159      else {
11160        skipAssert(assert, 2);
11161      }
11162    });
11163  }());
11164
11165  /*--------------------------------------------------------------------------*/
11166
11167  QUnit.module('lodash.isNil');
11168
11169  (function() {
11170    QUnit.test('should return `true` for nullish values', function(assert) {
11171      assert.expect(3);
11172
11173      assert.strictEqual(_.isNil(null), true);
11174      assert.strictEqual(_.isNil(), true);
11175      assert.strictEqual(_.isNil(undefined), true);
11176    });
11177
11178    QUnit.test('should return `false` for non-nullish values', function(assert) {
11179      assert.expect(13);
11180
11181      var expected = lodashStable.map(falsey, function(value) {
11182        return value == null;
11183      });
11184
11185      var actual = lodashStable.map(falsey, function(value, index) {
11186        return index ? _.isNil(value) : _.isNil();
11187      });
11188
11189      assert.deepEqual(actual, expected);
11190
11191      assert.strictEqual(_.isNil(args), false);
11192      assert.strictEqual(_.isNil([1, 2, 3]), false);
11193      assert.strictEqual(_.isNil(true), false);
11194      assert.strictEqual(_.isNil(new Date), false);
11195      assert.strictEqual(_.isNil(new Error), false);
11196      assert.strictEqual(_.isNil(_), false);
11197      assert.strictEqual(_.isNil(slice), false);
11198      assert.strictEqual(_.isNil({ 'a': 1 }), false);
11199      assert.strictEqual(_.isNil(1), false);
11200      assert.strictEqual(_.isNil(/x/), false);
11201      assert.strictEqual(_.isNil('a'), false);
11202
11203      if (Symbol) {
11204        assert.strictEqual(_.isNil(symbol), false);
11205      }
11206      else {
11207        skipAssert(assert);
11208      }
11209    });
11210
11211    QUnit.test('should work with nils from another realm', function(assert) {
11212      assert.expect(2);
11213
11214      if (realm.object) {
11215        assert.strictEqual(_.isNil(realm.null), true);
11216        assert.strictEqual(_.isNil(realm.undefined), true);
11217      }
11218      else {
11219        skipAssert(assert, 2);
11220      }
11221    });
11222  }());
11223
11224  /*--------------------------------------------------------------------------*/
11225
11226  QUnit.module('lodash.isNull');
11227
11228  (function() {
11229    QUnit.test('should return `true` for `null` values', function(assert) {
11230      assert.expect(1);
11231
11232      assert.strictEqual(_.isNull(null), true);
11233    });
11234
11235    QUnit.test('should return `false` for non `null` values', function(assert) {
11236      assert.expect(13);
11237
11238      var expected = lodashStable.map(falsey, function(value) {
11239        return value === null;
11240      });
11241
11242      var actual = lodashStable.map(falsey, function(value, index) {
11243        return index ? _.isNull(value) : _.isNull();
11244      });
11245
11246      assert.deepEqual(actual, expected);
11247
11248      assert.strictEqual(_.isNull(args), false);
11249      assert.strictEqual(_.isNull([1, 2, 3]), false);
11250      assert.strictEqual(_.isNull(true), false);
11251      assert.strictEqual(_.isNull(new Date), false);
11252      assert.strictEqual(_.isNull(new Error), false);
11253      assert.strictEqual(_.isNull(_), false);
11254      assert.strictEqual(_.isNull(slice), false);
11255      assert.strictEqual(_.isNull({ 'a': 1 }), false);
11256      assert.strictEqual(_.isNull(1), false);
11257      assert.strictEqual(_.isNull(/x/), false);
11258      assert.strictEqual(_.isNull('a'), false);
11259      assert.strictEqual(_.isNull(symbol), false);
11260    });
11261
11262    QUnit.test('should work with nulls from another realm', function(assert) {
11263      assert.expect(1);
11264
11265      if (realm.object) {
11266        assert.strictEqual(_.isNull(realm.null), true);
11267      }
11268      else {
11269        skipAssert(assert);
11270      }
11271    });
11272  }());
11273
11274  /*--------------------------------------------------------------------------*/
11275
11276  QUnit.module('lodash.isNumber');
11277
11278  (function() {
11279    QUnit.test('should return `true` for numbers', function(assert) {
11280      assert.expect(3);
11281
11282      assert.strictEqual(_.isNumber(0), true);
11283      assert.strictEqual(_.isNumber(Object(0)), true);
11284      assert.strictEqual(_.isNumber(NaN), true);
11285    });
11286
11287    QUnit.test('should return `false` for non-numbers', function(assert) {
11288      assert.expect(12);
11289
11290      var expected = lodashStable.map(falsey, function(value) {
11291        return typeof value == 'number';
11292      });
11293
11294      var actual = lodashStable.map(falsey, function(value, index) {
11295        return index ? _.isNumber(value) : _.isNumber();
11296      });
11297
11298      assert.deepEqual(actual, expected);
11299
11300      assert.strictEqual(_.isNumber(args), false);
11301      assert.strictEqual(_.isNumber([1, 2, 3]), false);
11302      assert.strictEqual(_.isNumber(true), false);
11303      assert.strictEqual(_.isNumber(new Date), false);
11304      assert.strictEqual(_.isNumber(new Error), false);
11305      assert.strictEqual(_.isNumber(_), false);
11306      assert.strictEqual(_.isNumber(slice), false);
11307      assert.strictEqual(_.isNumber({ 'a': 1 }), false);
11308      assert.strictEqual(_.isNumber(/x/), false);
11309      assert.strictEqual(_.isNumber('a'), false);
11310      assert.strictEqual(_.isNumber(symbol), false);
11311    });
11312
11313    QUnit.test('should work with numbers from another realm', function(assert) {
11314      assert.expect(1);
11315
11316      if (realm.number) {
11317        assert.strictEqual(_.isNumber(realm.number), true);
11318      }
11319      else {
11320        skipAssert(assert);
11321      }
11322    });
11323  }());
11324
11325  /*--------------------------------------------------------------------------*/
11326
11327  QUnit.module('lodash.isObject');
11328
11329  (function() {
11330    QUnit.test('should return `true` for objects', function(assert) {
11331      assert.expect(13);
11332
11333      assert.strictEqual(_.isObject(args), true);
11334      assert.strictEqual(_.isObject([1, 2, 3]), true);
11335      assert.strictEqual(_.isObject(Object(false)), true);
11336      assert.strictEqual(_.isObject(new Date), true);
11337      assert.strictEqual(_.isObject(new Error), true);
11338      assert.strictEqual(_.isObject(_), true);
11339      assert.strictEqual(_.isObject(slice), true);
11340      assert.strictEqual(_.isObject({ 'a': 1 }), true);
11341      assert.strictEqual(_.isObject(Object(0)), true);
11342      assert.strictEqual(_.isObject(/x/), true);
11343      assert.strictEqual(_.isObject(Object('a')), true);
11344
11345      if (document) {
11346        assert.strictEqual(_.isObject(body), true);
11347      }
11348      else {
11349        skipAssert(assert);
11350      }
11351      if (Symbol) {
11352        assert.strictEqual(_.isObject(Object(symbol)), true);
11353      }
11354      else {
11355        skipAssert(assert);
11356      }
11357    });
11358
11359    QUnit.test('should return `false` for non-objects', function(assert) {
11360      assert.expect(1);
11361
11362      var values = falsey.concat(true, 1, 'a', symbol),
11363          expected = lodashStable.map(values, stubFalse);
11364
11365      var actual = lodashStable.map(values, function(value, index) {
11366        return index ? _.isObject(value) : _.isObject();
11367      });
11368
11369      assert.deepEqual(actual, expected);
11370    });
11371
11372    QUnit.test('should work with objects from another realm', function(assert) {
11373      assert.expect(8);
11374
11375      if (realm.element) {
11376        assert.strictEqual(_.isObject(realm.element), true);
11377      }
11378      else {
11379        skipAssert(assert);
11380      }
11381      if (realm.object) {
11382        assert.strictEqual(_.isObject(realm.boolean), true);
11383        assert.strictEqual(_.isObject(realm.date), true);
11384        assert.strictEqual(_.isObject(realm.function), true);
11385        assert.strictEqual(_.isObject(realm.number), true);
11386        assert.strictEqual(_.isObject(realm.object), true);
11387        assert.strictEqual(_.isObject(realm.regexp), true);
11388        assert.strictEqual(_.isObject(realm.string), true);
11389      }
11390      else {
11391        skipAssert(assert, 7);
11392      }
11393    });
11394  }());
11395
11396  /*--------------------------------------------------------------------------*/
11397
11398  QUnit.module('lodash.isObjectLike');
11399
11400  (function() {
11401    QUnit.test('should return `true` for objects', function(assert) {
11402      assert.expect(9);
11403
11404      assert.strictEqual(_.isObjectLike(args), true);
11405      assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
11406      assert.strictEqual(_.isObjectLike(Object(false)), true);
11407      assert.strictEqual(_.isObjectLike(new Date), true);
11408      assert.strictEqual(_.isObjectLike(new Error), true);
11409      assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
11410      assert.strictEqual(_.isObjectLike(Object(0)), true);
11411      assert.strictEqual(_.isObjectLike(/x/), true);
11412      assert.strictEqual(_.isObjectLike(Object('a')), true);
11413    });
11414
11415    QUnit.test('should return `false` for non-objects', function(assert) {
11416      assert.expect(1);
11417
11418      var values = falsey.concat(true, _, slice, 1, 'a', symbol),
11419          expected = lodashStable.map(values, stubFalse);
11420
11421      var actual = lodashStable.map(values, function(value, index) {
11422        return index ? _.isObjectLike(value) : _.isObjectLike();
11423      });
11424
11425      assert.deepEqual(actual, expected);
11426    });
11427
11428    QUnit.test('should work with objects from another realm', function(assert) {
11429      assert.expect(6);
11430
11431      if (realm.object) {
11432        assert.strictEqual(_.isObjectLike(realm.boolean), true);
11433        assert.strictEqual(_.isObjectLike(realm.date), true);
11434        assert.strictEqual(_.isObjectLike(realm.number), true);
11435        assert.strictEqual(_.isObjectLike(realm.object), true);
11436        assert.strictEqual(_.isObjectLike(realm.regexp), true);
11437        assert.strictEqual(_.isObjectLike(realm.string), true);
11438      }
11439      else {
11440        skipAssert(assert, 6);
11441      }
11442    });
11443  }());
11444
11445  /*--------------------------------------------------------------------------*/
11446
11447  QUnit.module('lodash.isPlainObject');
11448
11449  (function() {
11450    var element = document && document.createElement('div');
11451
11452    QUnit.test('should detect plain objects', function(assert) {
11453      assert.expect(5);
11454
11455      function Foo(a) {
11456        this.a = 1;
11457      }
11458
11459      assert.strictEqual(_.isPlainObject({}), true);
11460      assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
11461      assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
11462      assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
11463      assert.strictEqual(_.isPlainObject(new Foo(1)), false);
11464    });
11465
11466    QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
11467      assert.expect(2);
11468
11469      var object = create(null);
11470      assert.strictEqual(_.isPlainObject(object), true);
11471
11472      object.constructor = objectProto.constructor;
11473      assert.strictEqual(_.isPlainObject(object), true);
11474    });
11475
11476    QUnit.test('should return `true` for objects with a `valueOf` property', function(assert) {
11477      assert.expect(1);
11478
11479      assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
11480    });
11481
11482    QUnit.test('should return `true` for objects with a writable `Symbol.toStringTag` property', function(assert) {
11483      assert.expect(1);
11484
11485      if (Symbol && Symbol.toStringTag) {
11486        var object = {};
11487        object[Symbol.toStringTag] = 'X';
11488
11489        assert.deepEqual(_.isPlainObject(object), true);
11490      }
11491      else {
11492        skipAssert(assert);
11493      }
11494    });
11495
11496    QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
11497      assert.expect(1);
11498
11499      var object = create({ 'a': 1 });
11500      assert.strictEqual(_.isPlainObject(object), false);
11501    });
11502
11503    QUnit.test('should return `false` for DOM elements', function(assert) {
11504      assert.expect(1);
11505
11506      if (element) {
11507        assert.strictEqual(_.isPlainObject(element), false);
11508      } else {
11509        skipAssert(assert);
11510      }
11511    });
11512
11513    QUnit.test('should return `false` for non-Object objects', function(assert) {
11514      assert.expect(3);
11515
11516      assert.strictEqual(_.isPlainObject(arguments), false);
11517      assert.strictEqual(_.isPlainObject(Error), false);
11518      assert.strictEqual(_.isPlainObject(Math), false);
11519    });
11520
11521    QUnit.test('should return `false` for non-objects', function(assert) {
11522      assert.expect(4);
11523
11524      var expected = lodashStable.map(falsey, stubFalse);
11525
11526      var actual = lodashStable.map(falsey, function(value, index) {
11527        return index ? _.isPlainObject(value) : _.isPlainObject();
11528      });
11529
11530      assert.deepEqual(actual, expected);
11531
11532      assert.strictEqual(_.isPlainObject(true), false);
11533      assert.strictEqual(_.isPlainObject('a'), false);
11534      assert.strictEqual(_.isPlainObject(symbol), false);
11535    });
11536
11537    QUnit.test('should return `false` for objects with a read-only `Symbol.toStringTag` property', function(assert) {
11538      assert.expect(1);
11539
11540      if (Symbol && Symbol.toStringTag) {
11541        var object = {};
11542        defineProperty(object, Symbol.toStringTag, {
11543          'configurable': true,
11544          'enumerable': false,
11545          'writable': false,
11546          'value': 'X'
11547        });
11548
11549        assert.deepEqual(_.isPlainObject(object), false);
11550      }
11551      else {
11552        skipAssert(assert);
11553      }
11554    });
11555
11556    QUnit.test('should not mutate `value`', function(assert) {
11557      assert.expect(2);
11558
11559      if (Symbol && Symbol.toStringTag) {
11560        var proto = {};
11561        proto[Symbol.toStringTag] = undefined;
11562        var object = create(proto);
11563
11564        assert.strictEqual(_.isPlainObject(object), false);
11565        assert.notOk(lodashStable.has(object, Symbol.toStringTag));
11566      }
11567      else {
11568        skipAssert(assert, 2);
11569      }
11570    });
11571
11572    QUnit.test('should work with objects from another realm', function(assert) {
11573      assert.expect(1);
11574
11575      if (realm.object) {
11576        assert.strictEqual(_.isPlainObject(realm.object), true);
11577      }
11578      else {
11579        skipAssert(assert);
11580      }
11581    });
11582  }());
11583
11584  /*--------------------------------------------------------------------------*/
11585
11586  QUnit.module('lodash.isRegExp');
11587
11588  (function() {
11589    QUnit.test('should return `true` for regexes', function(assert) {
11590      assert.expect(2);
11591
11592      assert.strictEqual(_.isRegExp(/x/), true);
11593      assert.strictEqual(_.isRegExp(RegExp('x')), true);
11594    });
11595
11596    QUnit.test('should return `false` for non-regexes', function(assert) {
11597      assert.expect(12);
11598
11599      var expected = lodashStable.map(falsey, stubFalse);
11600
11601      var actual = lodashStable.map(falsey, function(value, index) {
11602        return index ? _.isRegExp(value) : _.isRegExp();
11603      });
11604
11605      assert.deepEqual(actual, expected);
11606
11607      assert.strictEqual(_.isRegExp(args), false);
11608      assert.strictEqual(_.isRegExp([1, 2, 3]), false);
11609      assert.strictEqual(_.isRegExp(true), false);
11610      assert.strictEqual(_.isRegExp(new Date), false);
11611      assert.strictEqual(_.isRegExp(new Error), false);
11612      assert.strictEqual(_.isRegExp(_), false);
11613      assert.strictEqual(_.isRegExp(slice), false);
11614      assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
11615      assert.strictEqual(_.isRegExp(1), false);
11616      assert.strictEqual(_.isRegExp('a'), false);
11617      assert.strictEqual(_.isRegExp(symbol), false);
11618    });
11619
11620    QUnit.test('should work with regexes from another realm', function(assert) {
11621      assert.expect(1);
11622
11623      if (realm.regexp) {
11624        assert.strictEqual(_.isRegExp(realm.regexp), true);
11625      }
11626      else {
11627        skipAssert(assert);
11628      }
11629    });
11630  }());
11631
11632  /*--------------------------------------------------------------------------*/
11633
11634  QUnit.module('lodash.isSet');
11635
11636  (function() {
11637    QUnit.test('should return `true` for sets', function(assert) {
11638      assert.expect(1);
11639
11640      if (Set) {
11641        assert.strictEqual(_.isSet(set), true);
11642      }
11643      else {
11644        skipAssert(assert);
11645      }
11646    });
11647
11648    QUnit.test('should return `false` for non-sets', function(assert) {
11649      assert.expect(14);
11650
11651      var expected = lodashStable.map(falsey, stubFalse);
11652
11653      var actual = lodashStable.map(falsey, function(value, index) {
11654        return index ? _.isSet(value) : _.isSet();
11655      });
11656
11657      assert.deepEqual(actual, expected);
11658
11659      assert.strictEqual(_.isSet(args), false);
11660      assert.strictEqual(_.isSet([1, 2, 3]), false);
11661      assert.strictEqual(_.isSet(true), false);
11662      assert.strictEqual(_.isSet(new Date), false);
11663      assert.strictEqual(_.isSet(new Error), false);
11664      assert.strictEqual(_.isSet(_), false);
11665      assert.strictEqual(_.isSet(slice), false);
11666      assert.strictEqual(_.isSet({ 'a': 1 }), false);
11667      assert.strictEqual(_.isSet(1), false);
11668      assert.strictEqual(_.isSet(/x/), false);
11669      assert.strictEqual(_.isSet('a'), false);
11670      assert.strictEqual(_.isSet(symbol), false);
11671      assert.strictEqual(_.isSet(weakSet), false);
11672    });
11673
11674    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11675      assert.expect(1);
11676
11677      var values = [false, true],
11678          expected = lodashStable.map(values, stubFalse);
11679
11680      var actual = lodashStable.map(values, function(value) {
11681        return _.isSet({ 'constructor': value });
11682      });
11683
11684      assert.deepEqual(actual, expected);
11685    });
11686
11687    QUnit.test('should work with weak sets from another realm', function(assert) {
11688      assert.expect(1);
11689
11690      if (realm.set) {
11691        assert.strictEqual(_.isSet(realm.set), true);
11692      }
11693      else {
11694        skipAssert(assert);
11695      }
11696    });
11697  }());
11698
11699  /*--------------------------------------------------------------------------*/
11700
11701  QUnit.module('lodash.isString');
11702
11703  (function() {
11704    QUnit.test('should return `true` for strings', function(assert) {
11705      assert.expect(2);
11706
11707      assert.strictEqual(_.isString('a'), true);
11708      assert.strictEqual(_.isString(Object('a')), true);
11709    });
11710
11711    QUnit.test('should return `false` for non-strings', function(assert) {
11712      assert.expect(12);
11713
11714      var expected = lodashStable.map(falsey, function(value) {
11715        return value === '';
11716      });
11717
11718      var actual = lodashStable.map(falsey, function(value, index) {
11719        return index ? _.isString(value) : _.isString();
11720      });
11721
11722      assert.deepEqual(actual, expected);
11723
11724      assert.strictEqual(_.isString(args), false);
11725      assert.strictEqual(_.isString([1, 2, 3]), false);
11726      assert.strictEqual(_.isString(true), false);
11727      assert.strictEqual(_.isString(new Date), false);
11728      assert.strictEqual(_.isString(new Error), false);
11729      assert.strictEqual(_.isString(_), false);
11730      assert.strictEqual(_.isString(slice), false);
11731      assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
11732      assert.strictEqual(_.isString(1), false);
11733      assert.strictEqual(_.isString(/x/), false);
11734      assert.strictEqual(_.isString(symbol), false);
11735    });
11736
11737    QUnit.test('should work with strings from another realm', function(assert) {
11738      assert.expect(1);
11739
11740      if (realm.string) {
11741        assert.strictEqual(_.isString(realm.string), true);
11742      }
11743      else {
11744        skipAssert(assert);
11745      }
11746    });
11747  }());
11748
11749  /*--------------------------------------------------------------------------*/
11750
11751  QUnit.module('lodash.isSymbol');
11752
11753  (function() {
11754    QUnit.test('should return `true` for symbols', function(assert) {
11755      assert.expect(2);
11756
11757      if (Symbol) {
11758        assert.strictEqual(_.isSymbol(symbol), true);
11759        assert.strictEqual(_.isSymbol(Object(symbol)), true);
11760      }
11761      else {
11762        skipAssert(assert, 2);
11763      }
11764    });
11765
11766    QUnit.test('should return `false` for non-symbols', function(assert) {
11767      assert.expect(12);
11768
11769      var expected = lodashStable.map(falsey, stubFalse);
11770
11771      var actual = lodashStable.map(falsey, function(value, index) {
11772        return index ? _.isSymbol(value) : _.isSymbol();
11773      });
11774
11775      assert.deepEqual(actual, expected);
11776
11777      assert.strictEqual(_.isSymbol(args), false);
11778      assert.strictEqual(_.isSymbol([1, 2, 3]), false);
11779      assert.strictEqual(_.isSymbol(true), false);
11780      assert.strictEqual(_.isSymbol(new Date), false);
11781      assert.strictEqual(_.isSymbol(new Error), false);
11782      assert.strictEqual(_.isSymbol(_), false);
11783      assert.strictEqual(_.isSymbol(slice), false);
11784      assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
11785      assert.strictEqual(_.isSymbol(1), false);
11786      assert.strictEqual(_.isSymbol(/x/), false);
11787      assert.strictEqual(_.isSymbol('a'), false);
11788    });
11789
11790    QUnit.test('should work with symbols from another realm', function(assert) {
11791      assert.expect(1);
11792
11793      if (Symbol && realm.symbol) {
11794        assert.strictEqual(_.isSymbol(realm.symbol), true);
11795      }
11796      else {
11797        skipAssert(assert);
11798      }
11799    });
11800  }());
11801
11802  /*--------------------------------------------------------------------------*/
11803
11804  QUnit.module('lodash.isTypedArray');
11805
11806  (function() {
11807    QUnit.test('should return `true` for typed arrays', function(assert) {
11808      assert.expect(1);
11809
11810      var expected = lodashStable.map(typedArrays, function(type) {
11811        return type in root;
11812      });
11813
11814      var actual = lodashStable.map(typedArrays, function(type) {
11815        var Ctor = root[type];
11816        return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11817      });
11818
11819      assert.deepEqual(actual, expected);
11820    });
11821
11822    QUnit.test('should return `false` for non typed arrays', function(assert) {
11823      assert.expect(13);
11824
11825      var expected = lodashStable.map(falsey, stubFalse);
11826
11827      var actual = lodashStable.map(falsey, function(value, index) {
11828        return index ? _.isTypedArray(value) : _.isTypedArray();
11829      });
11830
11831      assert.deepEqual(actual, expected);
11832
11833      assert.strictEqual(_.isTypedArray(args), false);
11834      assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11835      assert.strictEqual(_.isTypedArray(true), false);
11836      assert.strictEqual(_.isTypedArray(new Date), false);
11837      assert.strictEqual(_.isTypedArray(new Error), false);
11838      assert.strictEqual(_.isTypedArray(_), false);
11839      assert.strictEqual(_.isTypedArray(slice), false);
11840      assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11841      assert.strictEqual(_.isTypedArray(1), false);
11842      assert.strictEqual(_.isTypedArray(/x/), false);
11843      assert.strictEqual(_.isTypedArray('a'), false);
11844      assert.strictEqual(_.isTypedArray(symbol), false);
11845    });
11846
11847    QUnit.test('should work with typed arrays from another realm', function(assert) {
11848      assert.expect(1);
11849
11850      if (realm.object) {
11851        var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11852
11853        var expected = lodashStable.map(props, function(key) {
11854          return realm[key] !== undefined;
11855        });
11856
11857        var actual = lodashStable.map(props, function(key) {
11858          var value = realm[key];
11859          return value ? _.isTypedArray(value) : false;
11860        });
11861
11862        assert.deepEqual(actual, expected);
11863      }
11864      else {
11865        skipAssert(assert);
11866      }
11867    });
11868  }());
11869
11870  /*--------------------------------------------------------------------------*/
11871
11872  QUnit.module('lodash.isUndefined');
11873
11874  (function() {
11875    QUnit.test('should return `true` for `undefined` values', function(assert) {
11876      assert.expect(2);
11877
11878      assert.strictEqual(_.isUndefined(), true);
11879      assert.strictEqual(_.isUndefined(undefined), true);
11880    });
11881
11882    QUnit.test('should return `false` for non `undefined` values', function(assert) {
11883      assert.expect(13);
11884
11885      var expected = lodashStable.map(falsey, function(value) {
11886        return value === undefined;
11887      });
11888
11889      var actual = lodashStable.map(falsey, function(value, index) {
11890        return index ? _.isUndefined(value) : _.isUndefined();
11891      });
11892
11893      assert.deepEqual(actual, expected);
11894
11895      assert.strictEqual(_.isUndefined(args), false);
11896      assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11897      assert.strictEqual(_.isUndefined(true), false);
11898      assert.strictEqual(_.isUndefined(new Date), false);
11899      assert.strictEqual(_.isUndefined(new Error), false);
11900      assert.strictEqual(_.isUndefined(_), false);
11901      assert.strictEqual(_.isUndefined(slice), false);
11902      assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11903      assert.strictEqual(_.isUndefined(1), false);
11904      assert.strictEqual(_.isUndefined(/x/), false);
11905      assert.strictEqual(_.isUndefined('a'), false);
11906
11907      if (Symbol) {
11908        assert.strictEqual(_.isUndefined(symbol), false);
11909      }
11910      else {
11911        skipAssert(assert);
11912      }
11913    });
11914
11915    QUnit.test('should work with `undefined` from another realm', function(assert) {
11916      assert.expect(1);
11917
11918      if (realm.object) {
11919        assert.strictEqual(_.isUndefined(realm.undefined), true);
11920      }
11921      else {
11922        skipAssert(assert);
11923      }
11924    });
11925  }());
11926
11927  /*--------------------------------------------------------------------------*/
11928
11929  QUnit.module('lodash.isWeakMap');
11930
11931  (function() {
11932    QUnit.test('should return `true` for weak maps', function(assert) {
11933      assert.expect(1);
11934
11935      if (WeakMap) {
11936        assert.strictEqual(_.isWeakMap(weakMap), true);
11937      }
11938      else {
11939        skipAssert(assert);
11940      }
11941    });
11942
11943    QUnit.test('should return `false` for non weak maps', function(assert) {
11944      assert.expect(14);
11945
11946      var expected = lodashStable.map(falsey, stubFalse);
11947
11948      var actual = lodashStable.map(falsey, function(value, index) {
11949        return index ? _.isWeakMap(value) : _.isWeakMap();
11950      });
11951
11952      assert.deepEqual(actual, expected);
11953
11954      assert.strictEqual(_.isWeakMap(args), false);
11955      assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
11956      assert.strictEqual(_.isWeakMap(true), false);
11957      assert.strictEqual(_.isWeakMap(new Date), false);
11958      assert.strictEqual(_.isWeakMap(new Error), false);
11959      assert.strictEqual(_.isWeakMap(_), false);
11960      assert.strictEqual(_.isWeakMap(slice), false);
11961      assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
11962      assert.strictEqual(_.isWeakMap(map), false);
11963      assert.strictEqual(_.isWeakMap(1), false);
11964      assert.strictEqual(_.isWeakMap(/x/), false);
11965      assert.strictEqual(_.isWeakMap('a'), false);
11966      assert.strictEqual(_.isWeakMap(symbol), false);
11967    });
11968
11969    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11970      assert.expect(1);
11971
11972      var values = [false, true],
11973          expected = lodashStable.map(values, stubFalse);
11974
11975      var actual = lodashStable.map(values, function(value) {
11976        return _.isWeakMap({ 'constructor': value });
11977      });
11978
11979      assert.deepEqual(actual, expected);
11980    });
11981
11982    QUnit.test('should work with weak maps from another realm', function(assert) {
11983      assert.expect(1);
11984
11985      if (realm.weakMap) {
11986        assert.strictEqual(_.isWeakMap(realm.weakMap), true);
11987      }
11988      else {
11989        skipAssert(assert);
11990      }
11991    });
11992  }());
11993
11994  /*--------------------------------------------------------------------------*/
11995
11996  QUnit.module('lodash.isWeakSet');
11997
11998  (function() {
11999    QUnit.test('should return `true` for weak sets', function(assert) {
12000      assert.expect(1);
12001
12002      if (WeakSet) {
12003        assert.strictEqual(_.isWeakSet(weakSet), true);
12004      }
12005      else {
12006        skipAssert(assert);
12007      }
12008    });
12009
12010    QUnit.test('should return `false` for non weak sets', function(assert) {
12011      assert.expect(14);
12012
12013      var expected = lodashStable.map(falsey, stubFalse);
12014
12015      var actual = lodashStable.map(falsey, function(value, index) {
12016        return index ? _.isWeakSet(value) : _.isWeakSet();
12017      });
12018
12019      assert.deepEqual(actual, expected);
12020
12021      assert.strictEqual(_.isWeakSet(args), false);
12022      assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
12023      assert.strictEqual(_.isWeakSet(true), false);
12024      assert.strictEqual(_.isWeakSet(new Date), false);
12025      assert.strictEqual(_.isWeakSet(new Error), false);
12026      assert.strictEqual(_.isWeakSet(_), false);
12027      assert.strictEqual(_.isWeakSet(slice), false);
12028      assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
12029      assert.strictEqual(_.isWeakSet(1), false);
12030      assert.strictEqual(_.isWeakSet(/x/), false);
12031      assert.strictEqual(_.isWeakSet('a'), false);
12032      assert.strictEqual(_.isWeakSet(set), false);
12033      assert.strictEqual(_.isWeakSet(symbol), false);
12034    });
12035
12036    QUnit.test('should work with weak sets from another realm', function(assert) {
12037      assert.expect(1);
12038
12039      if (realm.weakSet) {
12040        assert.strictEqual(_.isWeakSet(realm.weakSet), true);
12041      }
12042      else {
12043        skipAssert(assert);
12044      }
12045    });
12046  }());
12047
12048  /*--------------------------------------------------------------------------*/
12049
12050  QUnit.module('isType checks');
12051
12052  (function() {
12053    QUnit.test('should return `false` for subclassed values', function(assert) {
12054      assert.expect(7);
12055
12056      var funcs = [
12057        'isArray', 'isBoolean', 'isDate', 'isFunction',
12058        'isNumber', 'isRegExp', 'isString'
12059      ];
12060
12061      lodashStable.each(funcs, function(methodName) {
12062        function Foo() {}
12063        Foo.prototype = root[methodName.slice(2)].prototype;
12064
12065        var object = new Foo;
12066        if (objToString.call(object) == objectTag) {
12067          assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
12068        }
12069        else {
12070          skipAssert(assert);
12071        }
12072      });
12073    });
12074
12075    QUnit.test('should not error on host objects (test in IE)', function(assert) {
12076      assert.expect(26);
12077
12078      var funcs = [
12079        'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
12080        'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
12081        'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
12082        'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
12083        'isUndefined', 'isWeakMap', 'isWeakSet'
12084      ];
12085
12086      lodashStable.each(funcs, function(methodName) {
12087        if (xml) {
12088          _[methodName](xml);
12089          assert.ok(true, '`_.' + methodName + '` should not error');
12090        }
12091        else {
12092          skipAssert(assert);
12093        }
12094      });
12095    });
12096  }());
12097
12098  /*--------------------------------------------------------------------------*/
12099
12100  QUnit.module('lodash.iteratee');
12101
12102  (function() {
12103    QUnit.test('should provide arguments to `func`', function(assert) {
12104      assert.expect(1);
12105
12106      var fn = function() { return slice.call(arguments); },
12107          iteratee = _.iteratee(fn),
12108          actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
12109
12110      assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
12111    });
12112
12113    QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
12114      assert.expect(1);
12115
12116      var object = {},
12117          values = [, null, undefined],
12118          expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
12119
12120      var actual = lodashStable.map(values, function(value, index) {
12121        var identity = index ? _.iteratee(value) : _.iteratee();
12122        return [!isNpm && identity, identity(object)];
12123      });
12124
12125      assert.deepEqual(actual, expected);
12126    });
12127
12128    QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
12129      assert.expect(2);
12130
12131      var matches = _.iteratee({ 'a': 1, 'b': 2 });
12132      assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
12133      assert.strictEqual(matches({ 'b': 2 }), false);
12134    });
12135
12136    QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
12137      assert.expect(9);
12138
12139      var sources = [
12140        { 'a': { 'b': 2, 'c': 3 } },
12141        { 'a': 1, 'b': 2 },
12142        { 'a': 1 }
12143      ];
12144
12145      lodashStable.each(sources, function(source, index) {
12146        var object = lodashStable.cloneDeep(source),
12147            matches = _.iteratee(source);
12148
12149        assert.strictEqual(matches(object), true);
12150
12151        if (index) {
12152          source.a = 2;
12153          source.b = 1;
12154          source.c = 3;
12155        } else {
12156          source.a.b = 1;
12157          source.a.c = 2;
12158          source.a.d = 3;
12159        }
12160        assert.strictEqual(matches(object), true);
12161        assert.strictEqual(matches(source), false);
12162      });
12163    });
12164
12165    QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
12166      assert.expect(3);
12167
12168      var array = ['a', undefined],
12169          matches = _.iteratee([0, 'a']);
12170
12171      assert.strictEqual(matches(array), true);
12172
12173      matches = _.iteratee(['0', 'a']);
12174      assert.strictEqual(matches(array), true);
12175
12176      matches = _.iteratee([1, undefined]);
12177      assert.strictEqual(matches(array), true);
12178    });
12179
12180    QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
12181      assert.expect(1);
12182
12183      var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
12184          matches = _.iteratee(['a.b', { 'c': 1 }]);
12185
12186      assert.strictEqual(matches(object), true);
12187    });
12188
12189    QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
12190      assert.expect(9);
12191
12192      var sources = [
12193        { 'a': { 'b': 2, 'c': 3 } },
12194        { 'a': 1, 'b': 2 },
12195        { 'a': 1 }
12196      ];
12197
12198      lodashStable.each(sources, function(source, index) {
12199        var object = { 'a': lodashStable.cloneDeep(source) },
12200            matches = _.iteratee(['a', source]);
12201
12202        assert.strictEqual(matches(object), true);
12203
12204        if (index) {
12205          source.a = 2;
12206          source.b = 1;
12207          source.c = 3;
12208        } else {
12209          source.a.b = 1;
12210          source.a.c = 2;
12211          source.a.d = 3;
12212        }
12213        assert.strictEqual(matches(object), true);
12214        assert.strictEqual(matches({ 'a': source }), false);
12215      });
12216    });
12217
12218    QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
12219      assert.expect(2);
12220
12221      var array = ['a'],
12222          prop = _.iteratee(0);
12223
12224      assert.strictEqual(prop(array), 'a');
12225
12226      prop = _.iteratee('0');
12227      assert.strictEqual(prop(array), 'a');
12228    });
12229
12230    QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
12231      assert.expect(1);
12232
12233      var object = { 'a': { 'b': 2 } },
12234          prop = _.iteratee('a.b');
12235
12236      assert.strictEqual(prop(object), 2);
12237    });
12238
12239    QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
12240      assert.expect(2);
12241
12242      var fn = function() {
12243        var result = [this.a];
12244        push.apply(result, arguments);
12245        return result;
12246      };
12247
12248      var expected = [1, 2, 3],
12249          object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
12250
12251      assert.deepEqual(object.iteratee(3), expected);
12252
12253      object.iteratee = _.iteratee(_.partialRight(fn, 3));
12254      assert.deepEqual(object.iteratee(2), expected);
12255    });
12256
12257    QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
12258      assert.expect(1);
12259
12260      var iteratee = _.iteratee;
12261      delete _.iteratee;
12262
12263      assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
12264
12265      _.iteratee = iteratee;
12266    });
12267
12268    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12269      assert.expect(1);
12270
12271      var fn = function() { return this instanceof Number; },
12272          array = [fn, fn, fn],
12273          iteratees = lodashStable.map(array, _.iteratee),
12274          expected = lodashStable.map(array, stubFalse);
12275
12276      var actual = lodashStable.map(iteratees, function(iteratee) {
12277        return iteratee();
12278      });
12279
12280      assert.deepEqual(actual, expected);
12281    });
12282  }());
12283
12284  /*--------------------------------------------------------------------------*/
12285
12286  QUnit.module('custom `_.iteratee` methods');
12287
12288  (function() {
12289    var array = ['one', 'two', 'three'],
12290        getPropA = _.partial(_.property, 'a'),
12291        getPropB = _.partial(_.property, 'b'),
12292        getLength = _.partial(_.property, 'length'),
12293        iteratee = _.iteratee;
12294
12295    var getSum = function() {
12296      return function(result, object) {
12297        return result + object.a;
12298      };
12299    };
12300
12301    var objects = [
12302      { 'a': 0, 'b': 0 },
12303      { 'a': 1, 'b': 0 },
12304      { 'a': 1, 'b': 1 }
12305    ];
12306
12307    QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
12308      assert.expect(1);
12309
12310      if (!isModularize) {
12311        _.iteratee = getLength;
12312        assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
12313        _.iteratee = iteratee;
12314      }
12315      else {
12316        skipAssert(assert);
12317      }
12318    });
12319
12320    QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
12321      assert.expect(1);
12322
12323      if (!isModularize) {
12324        _.iteratee = getPropA;
12325        assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
12326        _.iteratee = iteratee;
12327      }
12328      else {
12329        skipAssert(assert);
12330      }
12331    });
12332
12333    QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
12334      assert.expect(1);
12335
12336      if (!isModularize) {
12337        _.iteratee = getPropB;
12338        assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
12339        _.iteratee = iteratee;
12340      }
12341      else {
12342        skipAssert(assert);
12343      }
12344    });
12345
12346    QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
12347      assert.expect(1);
12348
12349      if (!isModularize) {
12350        _.iteratee = getPropB;
12351        assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
12352        _.iteratee = iteratee;
12353      }
12354      else {
12355        skipAssert(assert);
12356      }
12357    });
12358
12359    QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
12360      assert.expect(1);
12361
12362      if (!isModularize) {
12363        _.iteratee = getPropA;
12364        assert.strictEqual(_.every(objects.slice(1)), true);
12365        _.iteratee = iteratee;
12366      }
12367      else {
12368        skipAssert(assert);
12369      }
12370    });
12371
12372    QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
12373      assert.expect(1);
12374
12375      if (!isModularize) {
12376        var objects = [{ 'a': 0 }, { 'a': 1 }];
12377
12378        _.iteratee = getPropA;
12379        assert.deepEqual(_.filter(objects), [objects[1]]);
12380        _.iteratee = iteratee;
12381      }
12382      else {
12383        skipAssert(assert);
12384      }
12385    });
12386
12387    QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
12388      assert.expect(1);
12389
12390      if (!isModularize) {
12391        _.iteratee = getPropA;
12392        assert.strictEqual(_.find(objects), objects[1]);
12393        _.iteratee = iteratee;
12394      }
12395      else {
12396        skipAssert(assert);
12397      }
12398    });
12399
12400    QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
12401      assert.expect(1);
12402
12403      if (!isModularize) {
12404        _.iteratee = getPropA;
12405        assert.strictEqual(_.findIndex(objects), 1);
12406        _.iteratee = iteratee;
12407      }
12408      else {
12409        skipAssert(assert);
12410      }
12411    });
12412
12413    QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
12414      assert.expect(1);
12415
12416      if (!isModularize) {
12417        _.iteratee = getPropA;
12418        assert.strictEqual(_.findLast(objects), objects[2]);
12419        _.iteratee = iteratee;
12420      }
12421      else {
12422        skipAssert(assert);
12423      }
12424    });
12425
12426    QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
12427      assert.expect(1);
12428
12429      if (!isModularize) {
12430        _.iteratee = getPropA;
12431        assert.strictEqual(_.findLastIndex(objects), 2);
12432        _.iteratee = iteratee;
12433      }
12434      else {
12435        skipAssert(assert);
12436      }
12437    });
12438
12439    QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
12440      assert.expect(1);
12441
12442      if (!isModularize) {
12443        _.iteratee = getPropB;
12444        assert.strictEqual(_.findKey(objects), '2');
12445        _.iteratee = iteratee;
12446      }
12447      else {
12448        skipAssert(assert);
12449      }
12450    });
12451
12452    QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
12453      assert.expect(1);
12454
12455      if (!isModularize) {
12456        _.iteratee = getPropB;
12457        assert.strictEqual(_.findLastKey(objects), '2');
12458        _.iteratee = iteratee;
12459      }
12460      else {
12461        skipAssert(assert);
12462      }
12463    });
12464
12465    QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
12466      assert.expect(1);
12467
12468      if (!isModularize) {
12469        _.iteratee = getLength;
12470        assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
12471        _.iteratee = iteratee;
12472      }
12473      else {
12474        skipAssert(assert);
12475      }
12476    });
12477
12478    QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
12479      assert.expect(1);
12480
12481      if (!isModularize) {
12482        _.iteratee = getPropA;
12483        assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
12484        _.iteratee = iteratee;
12485      }
12486      else {
12487        skipAssert(assert);
12488      }
12489    });
12490
12491    QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
12492      assert.expect(1);
12493
12494      if (!isModularize) {
12495        _.iteratee = getLength;
12496        assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
12497        _.iteratee = iteratee;
12498      }
12499      else {
12500        skipAssert(assert);
12501      }
12502    });
12503
12504    QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
12505      assert.expect(1);
12506
12507      if (!isModularize) {
12508        _.iteratee = getPropA;
12509        assert.deepEqual(_.map(objects), [0, 1, 1]);
12510        _.iteratee = iteratee;
12511      }
12512      else {
12513        skipAssert(assert);
12514      }
12515    });
12516
12517    QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
12518      assert.expect(1);
12519
12520      if (!isModularize) {
12521        _.iteratee = getPropB;
12522        assert.deepEqual(_.mapKeys({ 'a': { 'b': 2 } }), { '2':  { 'b': 2 } });
12523        _.iteratee = iteratee;
12524      }
12525      else {
12526        skipAssert(assert);
12527      }
12528    });
12529
12530    QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
12531      assert.expect(1);
12532
12533      if (!isModularize) {
12534        _.iteratee = getPropB;
12535        assert.deepEqual(_.mapValues({ 'a': { 'b': 2 } }), { 'a': 2 });
12536        _.iteratee = iteratee;
12537      }
12538      else {
12539        skipAssert(assert);
12540      }
12541    });
12542
12543    QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
12544      assert.expect(1);
12545
12546      if (!isModularize) {
12547        _.iteratee = getPropB;
12548        assert.deepEqual(_.maxBy(objects), objects[2]);
12549        _.iteratee = iteratee;
12550      }
12551      else {
12552        skipAssert(assert);
12553      }
12554    });
12555
12556    QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
12557      assert.expect(1);
12558
12559      if (!isModularize) {
12560        _.iteratee = getPropA;
12561        assert.strictEqual(_.meanBy(objects), 2 / 3);
12562        _.iteratee = iteratee;
12563      }
12564      else {
12565        skipAssert(assert);
12566      }
12567    });
12568
12569    QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
12570      assert.expect(1);
12571
12572      if (!isModularize) {
12573        _.iteratee = getPropB;
12574        assert.deepEqual(_.minBy(objects), objects[0]);
12575        _.iteratee = iteratee;
12576      }
12577      else {
12578        skipAssert(assert);
12579      }
12580    });
12581
12582    QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
12583      assert.expect(1);
12584
12585      if (!isModularize) {
12586        var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
12587
12588        _.iteratee = getPropA;
12589        assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
12590        _.iteratee = iteratee;
12591      }
12592      else {
12593        skipAssert(assert);
12594      }
12595    });
12596
12597    QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
12598      assert.expect(1);
12599
12600      if (!isModularize) {
12601        _.iteratee = getPropA;
12602        assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
12603        _.iteratee = iteratee;
12604      }
12605      else {
12606        skipAssert(assert);
12607      }
12608    });
12609
12610    QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
12611      assert.expect(1);
12612
12613      if (!isModularize) {
12614        _.iteratee = getSum;
12615        assert.strictEqual(_.reduce(objects, undefined, 0), 2);
12616        _.iteratee = iteratee;
12617      }
12618      else {
12619        skipAssert(assert);
12620      }
12621    });
12622
12623    QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
12624      assert.expect(1);
12625
12626      if (!isModularize) {
12627        _.iteratee = getSum;
12628        assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
12629        _.iteratee = iteratee;
12630      }
12631      else {
12632        skipAssert(assert);
12633      }
12634    });
12635
12636    QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
12637      assert.expect(1);
12638
12639      if (!isModularize) {
12640        var objects = [{ 'a': 0 }, { 'a': 1 }];
12641
12642        _.iteratee = getPropA;
12643        assert.deepEqual(_.reject(objects), [objects[0]]);
12644        _.iteratee = iteratee;
12645      }
12646      else {
12647        skipAssert(assert);
12648      }
12649    });
12650
12651    QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
12652      assert.expect(1);
12653
12654      if (!isModularize) {
12655        var objects = [{ 'a': 0 }, { 'a': 1 }];
12656
12657        _.iteratee = getPropA;
12658        _.remove(objects);
12659        assert.deepEqual(objects, [{ 'a': 0 }]);
12660        _.iteratee = iteratee;
12661      }
12662      else {
12663        skipAssert(assert);
12664      }
12665    });
12666
12667    QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
12668      assert.expect(1);
12669
12670      if (!isModularize) {
12671        _.iteratee = getPropB;
12672        assert.strictEqual(_.some(objects), true);
12673        _.iteratee = iteratee;
12674      }
12675      else {
12676        skipAssert(assert);
12677      }
12678    });
12679
12680    QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
12681      assert.expect(1);
12682
12683      if (!isModularize) {
12684        _.iteratee = getPropA;
12685        assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
12686        _.iteratee = iteratee;
12687      }
12688      else {
12689        skipAssert(assert);
12690      }
12691    });
12692
12693    QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
12694      assert.expect(1);
12695
12696      if (!isModularize) {
12697        var objects = [{ 'a': 30 }, { 'a': 50 }];
12698
12699        _.iteratee = getPropA;
12700        assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
12701        _.iteratee = iteratee;
12702      }
12703      else {
12704        skipAssert(assert);
12705      }
12706    });
12707
12708    QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
12709      assert.expect(1);
12710
12711      if (!isModularize) {
12712        var objects = [{ 'a': 30 }, { 'a': 50 }];
12713
12714        _.iteratee = getPropA;
12715        assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
12716        _.iteratee = iteratee;
12717      }
12718      else {
12719        skipAssert(assert);
12720      }
12721    });
12722
12723    QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
12724      assert.expect(1);
12725
12726      if (!isModularize) {
12727        _.iteratee = getPropB;
12728        assert.strictEqual(_.sumBy(objects), 1);
12729        _.iteratee = iteratee;
12730      }
12731      else {
12732        skipAssert(assert);
12733      }
12734    });
12735
12736    QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
12737      assert.expect(1);
12738
12739      if (!isModularize) {
12740        _.iteratee = getPropB;
12741        assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
12742        _.iteratee = iteratee;
12743      }
12744      else {
12745        skipAssert(assert);
12746      }
12747    });
12748
12749    QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
12750      assert.expect(1);
12751
12752      if (!isModularize) {
12753        _.iteratee = getPropB;
12754        assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
12755        _.iteratee = iteratee;
12756      }
12757      else {
12758        skipAssert(assert);
12759      }
12760    });
12761
12762    QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
12763      assert.expect(1);
12764
12765      if (!isModularize) {
12766        _.iteratee = function() {
12767          return function(result, object) {
12768            result.sum += object.a;
12769          };
12770        };
12771
12772        assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
12773        _.iteratee = iteratee;
12774      }
12775      else {
12776        skipAssert(assert);
12777      }
12778    });
12779
12780    QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
12781      assert.expect(1);
12782
12783      if (!isModularize) {
12784        _.iteratee = getPropB;
12785        assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
12786        _.iteratee = iteratee;
12787      }
12788      else {
12789        skipAssert(assert);
12790      }
12791    });
12792
12793    QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
12794      assert.expect(1);
12795
12796      if (!isModularize) {
12797        _.iteratee = getPropB;
12798        assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
12799        _.iteratee = iteratee;
12800      }
12801      else {
12802        skipAssert(assert);
12803      }
12804    });
12805
12806    QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
12807      assert.expect(1);
12808
12809      if (!isModularize) {
12810        _.iteratee = getPropA;
12811        assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
12812        _.iteratee = iteratee;
12813      }
12814      else {
12815        skipAssert(assert);
12816      }
12817    });
12818  }());
12819
12820  /*--------------------------------------------------------------------------*/
12821
12822  QUnit.module('lodash.join');
12823
12824  (function() {
12825    var array = ['a', 'b', 'c'];
12826
12827    QUnit.test('should return join all array elements into a string', function(assert) {
12828      assert.expect(1);
12829
12830      assert.strictEqual(_.join(array, '~'), 'a~b~c');
12831    });
12832
12833    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12834      assert.expect(2);
12835
12836      if (!isNpm) {
12837        var wrapped = _(array);
12838        assert.strictEqual(wrapped.join('~'), 'a~b~c');
12839        assert.strictEqual(wrapped.value(), array);
12840      }
12841      else {
12842        skipAssert(assert, 2);
12843      }
12844    });
12845
12846    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12847      assert.expect(1);
12848
12849      if (!isNpm) {
12850        assert.ok(_(array).chain().join('~') instanceof _);
12851      }
12852      else {
12853        skipAssert(assert);
12854      }
12855    });
12856  }());
12857
12858  /*--------------------------------------------------------------------------*/
12859
12860  QUnit.module('lodash.keyBy');
12861
12862  (function() {
12863    var array = [
12864      { 'dir': 'left', 'code': 97 },
12865      { 'dir': 'right', 'code': 100 }
12866    ];
12867
12868    QUnit.test('should transform keys by `iteratee`', function(assert) {
12869      assert.expect(1);
12870
12871      var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12872
12873      var actual = _.keyBy(array, function(object) {
12874        return String.fromCharCode(object.code);
12875      });
12876
12877      assert.deepEqual(actual, expected);
12878    });
12879
12880    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12881      assert.expect(1);
12882
12883      var array = [4, 6, 6],
12884          values = [, null, undefined],
12885          expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12886
12887      var actual = lodashStable.map(values, function(value, index) {
12888        return index ? _.keyBy(array, value) : _.keyBy(array);
12889      });
12890
12891      assert.deepEqual(actual, expected);
12892    });
12893
12894    QUnit.test('should work with `_.property` shorthands', function(assert) {
12895      assert.expect(1);
12896
12897      var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
12898          actual = _.keyBy(array, 'dir');
12899
12900      assert.deepEqual(actual, expected);
12901    });
12902
12903    QUnit.test('should only add values to own, not inherited, properties', function(assert) {
12904      assert.expect(2);
12905
12906      var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
12907        return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
12908      });
12909
12910      assert.deepEqual(actual.constructor, 4.2);
12911      assert.deepEqual(actual.hasOwnProperty, 6.3);
12912    });
12913
12914    QUnit.test('should work with a number for `iteratee`', function(assert) {
12915      assert.expect(2);
12916
12917      var array = [
12918        [1, 'a'],
12919        [2, 'a'],
12920        [2, 'b']
12921      ];
12922
12923      assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
12924      assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
12925    });
12926
12927    QUnit.test('should work with an object for `collection`', function(assert) {
12928      assert.expect(1);
12929
12930      var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
12931      assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
12932    });
12933
12934    QUnit.test('should work in a lazy sequence', function(assert) {
12935      assert.expect(1);
12936
12937      if (!isNpm) {
12938        var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
12939          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
12940          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
12941        );
12942
12943        var actual = _(array).keyBy().map(square).filter(isEven).take().value();
12944
12945        assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
12946      }
12947      else {
12948        skipAssert(assert);
12949      }
12950    });
12951  }());
12952
12953  /*--------------------------------------------------------------------------*/
12954
12955  QUnit.module('keys methods');
12956
12957  lodashStable.each(['keys', 'keysIn'], function(methodName) {
12958    var func = _[methodName],
12959        isKeys = methodName == 'keys';
12960
12961    QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
12962      assert.expect(1);
12963
12964      var actual = func({ 'a': 1, 'b': 1 }).sort();
12965
12966      assert.deepEqual(actual, ['a', 'b']);
12967    });
12968
12969    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
12970      assert.expect(1);
12971
12972      function Foo() {
12973        this.a = 1;
12974      }
12975      Foo.prototype.b = 2;
12976
12977      var expected = isKeys ? ['a'] : ['a', 'b'],
12978          actual = func(new Foo).sort();
12979
12980      assert.deepEqual(actual, expected);
12981    });
12982
12983    QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
12984      assert.expect(1);
12985
12986      var array = [1];
12987      array[2] = 3;
12988
12989      var actual = func(array).sort();
12990
12991      assert.deepEqual(actual, ['0', '1', '2']);
12992    });
12993
12994    QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
12995      assert.expect(1);
12996
12997      var array = [1];
12998      array.a = 1;
12999
13000      var actual = func(array).sort();
13001
13002      assert.deepEqual(actual, ['0', 'a']);
13003    });
13004
13005    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
13006      assert.expect(1);
13007
13008      arrayProto.a = 1;
13009
13010      var expected = isKeys ? ['0'] : ['0', 'a'],
13011          actual = func([1]).sort();
13012
13013      assert.deepEqual(actual, expected);
13014
13015      delete arrayProto.a;
13016    });
13017
13018    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
13019      assert.expect(1);
13020
13021      var values = [args, strictArgs],
13022          expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
13023
13024      var actual = lodashStable.map(values, function(value) {
13025        return func(value).sort();
13026      });
13027
13028      assert.deepEqual(actual, expected);
13029    });
13030
13031    QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
13032      assert.expect(1);
13033
13034      var values = [args, strictArgs],
13035          expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
13036
13037      var actual = lodashStable.map(values, function(value) {
13038        value.a = 1;
13039        var result = func(value).sort();
13040        delete value.a;
13041        return result;
13042      });
13043
13044      assert.deepEqual(actual, expected);
13045    });
13046
13047    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
13048      assert.expect(1);
13049
13050      var values = [args, strictArgs],
13051          expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
13052
13053      var actual = lodashStable.map(values, function(value) {
13054        objectProto.a = 1;
13055        var result = func(value).sort();
13056        delete objectProto.a;
13057        return result;
13058      });
13059
13060      assert.deepEqual(actual, expected);
13061    });
13062
13063    QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
13064      assert.expect(1);
13065
13066      var actual = func(Object('abc')).sort();
13067
13068      assert.deepEqual(actual, ['0', '1', '2']);
13069    });
13070
13071    QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
13072      assert.expect(1);
13073
13074      var object = Object('a');
13075      object.a = 1;
13076
13077      var actual = func(object).sort();
13078
13079      assert.deepEqual(actual, ['0', 'a']);
13080    });
13081
13082    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
13083      assert.expect(1);
13084
13085      stringProto.a = 1;
13086
13087      var expected = isKeys ? ['0'] : ['0', 'a'],
13088          actual = func(Object('a')).sort();
13089
13090      assert.deepEqual(actual, expected);
13091
13092      delete stringProto.a;
13093    });
13094
13095    QUnit.test('`_.' + methodName + '` should work with array-like objects', function(assert) {
13096      assert.expect(1);
13097
13098      var object = { '0': 'a', 'length': 1 },
13099          actual = func(object).sort();
13100
13101      assert.deepEqual(actual, ['0', 'length']);
13102    });
13103
13104    QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
13105      assert.expect(2);
13106
13107      var expected = lodashStable.map(primitives, function(value) {
13108        return typeof value == 'string' ? ['0'] : [];
13109      });
13110
13111      var actual = lodashStable.map(primitives, func);
13112      assert.deepEqual(actual, expected);
13113
13114      // IE 9 doesn't box numbers in for-in loops.
13115      numberProto.a = 1;
13116      assert.deepEqual(func(0), isKeys ? [] : ['a']);
13117      delete numberProto.a;
13118    });
13119
13120    QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
13121      assert.expect(3);
13122
13123      function Foo() {}
13124      Foo.prototype.a = 1;
13125
13126      var expected = ['a'];
13127      assert.deepEqual(func(Foo.prototype), expected);
13128
13129      Foo.prototype = { 'constructor': Foo, 'a': 1 };
13130      assert.deepEqual(func(Foo.prototype), expected);
13131
13132      var Fake = { 'prototype': {} };
13133      Fake.prototype.constructor = Fake;
13134      assert.deepEqual(func(Fake.prototype), ['constructor']);
13135    });
13136
13137    QUnit.test('`_.' + methodName + '` should return an empty array when `object` is nullish', function(assert) {
13138      var values = [, null, undefined],
13139          expected = lodashStable.map(values, stubArray);
13140
13141      var actual = lodashStable.map(values, function(value, index) {
13142        objectProto.a = 1;
13143        var result = index ? func(value) : func();
13144        delete objectProto.a;
13145        return result;
13146      });
13147
13148      assert.deepEqual(actual, expected);
13149    });
13150  });
13151
13152  /*--------------------------------------------------------------------------*/
13153
13154  QUnit.module('lodash.last');
13155
13156  (function() {
13157    var array = [1, 2, 3, 4];
13158
13159    QUnit.test('should return the last element', function(assert) {
13160      assert.expect(1);
13161
13162      assert.strictEqual(_.last(array), 4);
13163    });
13164
13165    QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
13166      assert.expect(1);
13167
13168      var array = [];
13169      array['-1'] = 1;
13170
13171      assert.strictEqual(_.last([]), undefined);
13172    });
13173
13174    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
13175      assert.expect(1);
13176
13177      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
13178          actual = lodashStable.map(array, _.last);
13179
13180      assert.deepEqual(actual, [3, 6, 9]);
13181    });
13182
13183    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
13184      assert.expect(1);
13185
13186      if (!isNpm) {
13187        assert.strictEqual(_(array).last(), 4);
13188      }
13189      else {
13190        skipAssert(assert);
13191      }
13192    });
13193
13194    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
13195      assert.expect(1);
13196
13197      if (!isNpm) {
13198        assert.ok(_(array).chain().last() instanceof _);
13199      }
13200      else {
13201        skipAssert(assert);
13202      }
13203    });
13204
13205    QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
13206      assert.expect(1);
13207
13208      if (!isNpm) {
13209        var wrapped = _(array).chain().last();
13210        assert.strictEqual(wrapped.__wrapped__, array);
13211      }
13212      else {
13213        skipAssert(assert);
13214      }
13215    });
13216
13217    QUnit.test('should work in a lazy sequence', function(assert) {
13218      assert.expect(2);
13219
13220      if (!isNpm) {
13221        var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
13222            smallArray = array;
13223
13224        lodashStable.times(2, function(index) {
13225          var array = index ? largeArray : smallArray,
13226              wrapped = _(array).filter(isEven);
13227
13228          assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
13229        });
13230      }
13231      else {
13232        skipAssert(assert, 2);
13233      }
13234    });
13235  }());
13236
13237  /*--------------------------------------------------------------------------*/
13238
13239  QUnit.module('lodash.lowerCase');
13240
13241  (function() {
13242    QUnit.test('should lowercase as space-separated words', function(assert) {
13243      assert.expect(3);
13244
13245      assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
13246      assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
13247      assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
13248    });
13249  }());
13250
13251  /*--------------------------------------------------------------------------*/
13252
13253  QUnit.module('lodash.lowerFirst');
13254
13255  (function() {
13256    QUnit.test('should lowercase only the first character', function(assert) {
13257      assert.expect(3);
13258
13259      assert.strictEqual(_.lowerFirst('fred'), 'fred');
13260      assert.strictEqual(_.lowerFirst('Fred'), 'fred');
13261      assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
13262    });
13263  }());
13264
13265  /*--------------------------------------------------------------------------*/
13266
13267  QUnit.module('lodash.lt');
13268
13269  (function() {
13270    QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
13271      assert.expect(2);
13272
13273      assert.strictEqual(_.lt(1, 3), true);
13274      assert.strictEqual(_.lt('abc', 'def'), true);
13275    });
13276
13277    QUnit.test('should return `false` if `value` >= `other`', function(assert) {
13278      assert.expect(4);
13279
13280      assert.strictEqual(_.lt(3, 1), false);
13281      assert.strictEqual(_.lt(3, 3), false);
13282      assert.strictEqual(_.lt('def', 'abc'), false);
13283      assert.strictEqual(_.lt('def', 'def'), false);
13284    });
13285  }());
13286
13287  /*--------------------------------------------------------------------------*/
13288
13289  QUnit.module('lodash.lte');
13290
13291  (function() {
13292    QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
13293      assert.expect(4);
13294
13295      assert.strictEqual(_.lte(1, 3), true);
13296      assert.strictEqual(_.lte(3, 3), true);
13297      assert.strictEqual(_.lte('abc', 'def'), true);
13298      assert.strictEqual(_.lte('def', 'def'), true);
13299    });
13300
13301    QUnit.test('should return `false` if `value` > `other`', function(assert) {
13302      assert.expect(2);
13303
13304      assert.strictEqual(_.lt(3, 1), false);
13305      assert.strictEqual(_.lt('def', 'abc'), false);
13306    });
13307  }());
13308
13309  /*--------------------------------------------------------------------------*/
13310
13311  QUnit.module('lodash.findLastIndex and lodash.lastIndexOf');
13312
13313  lodashStable.each(['findLastIndex', 'lastIndexOf'], function(methodName) {
13314    var array = [1, 2, 3, 1, 2, 3],
13315        func = _[methodName],
13316        resolve = methodName == 'findLastIndex' ? lodashStable.curry(lodashStable.eq) : identity;
13317
13318    QUnit.test('`_.' + methodName + '` should return the index of the last matched value', function(assert) {
13319      assert.expect(1);
13320
13321      assert.strictEqual(func(array, resolve(3)), 5);
13322    });
13323
13324    QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) {
13325      assert.expect(1);
13326
13327      assert.strictEqual(func(array, resolve(1), 2), 0);
13328    });
13329
13330    QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) {
13331      assert.expect(1);
13332
13333      var values = [6, 8, Math.pow(2, 32), Infinity],
13334          expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
13335
13336      var actual = lodashStable.map(values, function(fromIndex) {
13337        return [
13338          func(array, resolve(undefined), fromIndex),
13339          func(array, resolve(1), fromIndex),
13340          func(array, resolve(''), fromIndex)
13341        ];
13342      });
13343
13344      assert.deepEqual(actual, expected);
13345    });
13346
13347    QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) {
13348      assert.expect(1);
13349
13350      assert.strictEqual(func(array, resolve(2), -3), 1);
13351    });
13352
13353    QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) {
13354      assert.expect(1);
13355
13356      var values = [-6, -8, -Infinity],
13357          expected = lodashStable.map(values, stubZero);
13358
13359      var actual = lodashStable.map(values, function(fromIndex) {
13360        return func(array, resolve(1), fromIndex);
13361      });
13362
13363      assert.deepEqual(actual, expected);
13364    });
13365
13366    QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values correctly', function(assert) {
13367      assert.expect(1);
13368
13369      var expected = lodashStable.map(falsey, function(value) {
13370        return value === undefined ? 5 : -1;
13371      });
13372
13373      var actual = lodashStable.map(falsey, function(fromIndex) {
13374        return func(array, resolve(3), fromIndex);
13375      });
13376
13377      assert.deepEqual(actual, expected);
13378    });
13379
13380    QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) {
13381      assert.expect(1);
13382
13383      assert.strictEqual(func(array, resolve(2), 4.2), 4);
13384    });
13385  });
13386
13387  /*--------------------------------------------------------------------------*/
13388
13389  QUnit.module('indexOf methods');
13390
13391  lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
13392    var func = _[methodName],
13393        isIndexOf = !/last/i.test(methodName),
13394        isSorted = /^sorted/.test(methodName);
13395
13396    QUnit.test('`_.' + methodName + '` should accept a falsey `array`', function(assert) {
13397      assert.expect(1);
13398
13399      var expected = lodashStable.map(falsey, lodashStable.constant(-1));
13400
13401      var actual = lodashStable.map(falsey, function(array, index) {
13402        try {
13403          return index ? func(array) : func();
13404        } catch (e) {}
13405      });
13406
13407      assert.deepEqual(actual, expected);
13408    });
13409
13410    QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
13411      assert.expect(5);
13412
13413      var array = [1, 2, 3],
13414          empty = [];
13415
13416      assert.strictEqual(func(array, 4), -1);
13417      assert.strictEqual(func(array, 4, true), -1);
13418      assert.strictEqual(func(array, undefined, true), -1);
13419
13420      assert.strictEqual(func(empty, undefined), -1);
13421      assert.strictEqual(func(empty, undefined, true), -1);
13422    });
13423
13424    QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
13425      assert.expect(2);
13426
13427      var array = [];
13428      array[-1] = 0;
13429
13430      assert.strictEqual(func(array, undefined), -1);
13431      assert.strictEqual(func(array, 0, true), -1);
13432    });
13433
13434    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
13435      assert.expect(3);
13436
13437      var array = isSorted
13438        ? [1, 2, NaN, NaN]
13439        : [1, NaN, 3, NaN, 5, NaN];
13440
13441      if (isSorted) {
13442        assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
13443        skipAssert(assert, 2);
13444      }
13445      else {
13446        assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
13447        assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
13448        assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
13449      }
13450    });
13451
13452    QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13453      assert.expect(2);
13454
13455      assert.strictEqual(func([-0], 0), 0);
13456      assert.strictEqual(func([0], -0), 0);
13457    });
13458  });
13459
13460  /*--------------------------------------------------------------------------*/
13461
13462  QUnit.module('lodash.map');
13463
13464  (function() {
13465    var array = [1, 2];
13466
13467    QUnit.test('should map values in `collection` to a new array', function(assert) {
13468      assert.expect(2);
13469
13470      var object = { 'a': 1, 'b': 2 },
13471          expected = ['1', '2'];
13472
13473      assert.deepEqual(_.map(array, String), expected);
13474      assert.deepEqual(_.map(object, String), expected);
13475    });
13476
13477    QUnit.test('should work with `_.property` shorthands', function(assert) {
13478      assert.expect(1);
13479
13480      var objects = [{ 'a': 'x' }, { 'a': 'y' }];
13481      assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
13482    });
13483
13484    QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
13485      assert.expect(1);
13486
13487      function Foo() {
13488        this.a = 1;
13489      }
13490      Foo.prototype.b = 2;
13491
13492      var actual = _.map(new Foo, identity);
13493      assert.deepEqual(actual, [1]);
13494    });
13495
13496    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13497      assert.expect(2);
13498
13499      var object = { 'a': 1, 'b': 2 },
13500          values = [, null, undefined],
13501          expected = lodashStable.map(values, lodashStable.constant([1, 2]));
13502
13503      lodashStable.each([array, object], function(collection) {
13504        var actual = lodashStable.map(values, function(value, index) {
13505          return index ? _.map(collection, value) : _.map(collection);
13506        });
13507
13508        assert.deepEqual(actual, expected);
13509      });
13510    });
13511
13512    QUnit.test('should accept a falsey `collection`', function(assert) {
13513      assert.expect(1);
13514
13515      var expected = lodashStable.map(falsey, stubArray);
13516
13517      var actual = lodashStable.map(falsey, function(collection, index) {
13518        try {
13519          return index ? _.map(collection) : _.map();
13520        } catch (e) {}
13521      });
13522
13523      assert.deepEqual(actual, expected);
13524    });
13525
13526    QUnit.test('should treat number values for `collection` as empty', function(assert) {
13527      assert.expect(1);
13528
13529      assert.deepEqual(_.map(1), []);
13530    });
13531
13532    QUnit.test('should treat a nodelist as an array-like object', function(assert) {
13533      assert.expect(1);
13534
13535      if (document) {
13536        var actual = _.map(document.getElementsByTagName('body'), function(element) {
13537          return element.nodeName.toLowerCase();
13538        });
13539
13540        assert.deepEqual(actual, ['body']);
13541      }
13542      else {
13543        skipAssert(assert);
13544      }
13545    });
13546
13547    QUnit.test('should work with objects with non-number length properties', function(assert) {
13548      assert.expect(1);
13549
13550      var value = { 'value': 'x' },
13551          object = { 'length': { 'value': 'x' } };
13552
13553      assert.deepEqual(_.map(object, identity), [value]);
13554    });
13555
13556    QUnit.test('should return a wrapped value when chaining', function(assert) {
13557      assert.expect(1);
13558
13559      if (!isNpm) {
13560        assert.ok(_(array).map(noop) instanceof _);
13561      }
13562      else {
13563        skipAssert(assert);
13564      }
13565    });
13566
13567    QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
13568      assert.expect(5);
13569
13570      if (!isNpm) {
13571        var args,
13572            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
13573            expected = [1, 0, _.map(array.slice(1), square)];
13574
13575        _(array).slice(1).map(function(value, index, array) {
13576          args || (args = slice.call(arguments));
13577        }).value();
13578
13579        assert.deepEqual(args, [1, 0, array.slice(1)]);
13580
13581        args = undefined;
13582        _(array).slice(1).map(square).map(function(value, index, array) {
13583          args || (args = slice.call(arguments));
13584        }).value();
13585
13586        assert.deepEqual(args, expected);
13587
13588        args = undefined;
13589        _(array).slice(1).map(square).map(function(value, index) {
13590          args || (args = slice.call(arguments));
13591        }).value();
13592
13593        assert.deepEqual(args, expected);
13594
13595        args = undefined;
13596        _(array).slice(1).map(square).map(function(value) {
13597          args || (args = slice.call(arguments));
13598        }).value();
13599
13600        assert.deepEqual(args, [1]);
13601
13602        args = undefined;
13603        _(array).slice(1).map(square).map(function() {
13604          args || (args = slice.call(arguments));
13605        }).value();
13606
13607        assert.deepEqual(args, expected);
13608      }
13609      else {
13610        skipAssert(assert, 5);
13611      }
13612    });
13613  }());
13614
13615  /*--------------------------------------------------------------------------*/
13616
13617  QUnit.module('lodash.mapKeys');
13618
13619  (function() {
13620    var array = [1, 2],
13621        object = { 'a': 1, 'b': 2 };
13622
13623    QUnit.test('should map keys in `object` to a new object', function(assert) {
13624      assert.expect(1);
13625
13626      var actual = _.mapKeys(object, String);
13627      assert.deepEqual(actual, { '1': 1, '2': 2 });
13628    });
13629
13630    QUnit.test('should treat arrays like objects', function(assert) {
13631      assert.expect(1);
13632
13633      var actual = _.mapKeys(array, String);
13634      assert.deepEqual(actual, { '1': 1, '2': 2 });
13635    });
13636
13637    QUnit.test('should work with `_.property` shorthands', function(assert) {
13638      assert.expect(1);
13639
13640      var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
13641      assert.deepEqual(actual, { 'c': { 'b': 'c' } });
13642    });
13643
13644    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13645      assert.expect(1);
13646
13647      var object = { 'a': 1, 'b': 2 },
13648          values = [, null, undefined],
13649          expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
13650
13651      var actual = lodashStable.map(values, function(value, index) {
13652        return index ? _.mapKeys(object, value) : _.mapKeys(object);
13653      });
13654
13655      assert.deepEqual(actual, expected);
13656    });
13657  }());
13658
13659  /*--------------------------------------------------------------------------*/
13660
13661  QUnit.module('lodash.mapValues');
13662
13663  (function() {
13664    var array = [1, 2],
13665        object = { 'a': 1, 'b': 2 };
13666
13667    QUnit.test('should map values in `object` to a new object', function(assert) {
13668      assert.expect(1);
13669
13670      var actual = _.mapValues(object, String);
13671      assert.deepEqual(actual, { 'a': '1', 'b': '2' });
13672    });
13673
13674    QUnit.test('should treat arrays like objects', function(assert) {
13675      assert.expect(1);
13676
13677      var actual = _.mapValues(array, String);
13678      assert.deepEqual(actual, { '0': '1', '1': '2' });
13679    });
13680
13681    QUnit.test('should work with `_.property` shorthands', function(assert) {
13682      assert.expect(1);
13683
13684      var actual = _.mapValues({ 'a': { 'b': 2 } }, 'b');
13685      assert.deepEqual(actual, { 'a': 2 });
13686    });
13687
13688    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13689      assert.expect(1);
13690
13691      var object = { 'a': 1, 'b': 2 },
13692          values = [, null, undefined],
13693          expected = lodashStable.map(values, lodashStable.constant([true, false]));
13694
13695      var actual = lodashStable.map(values, function(value, index) {
13696        var result = index ? _.mapValues(object, value) : _.mapValues(object);
13697        return [lodashStable.isEqual(result, object), result === object];
13698      });
13699
13700      assert.deepEqual(actual, expected);
13701    });
13702  }());
13703
13704  /*--------------------------------------------------------------------------*/
13705
13706  QUnit.module('lodash.mapKeys and lodash.mapValues');
13707
13708  lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
13709    var func = _[methodName],
13710        object = { 'a': 1, 'b': 2 };
13711
13712    QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
13713      assert.expect(1);
13714
13715      function Foo() {
13716        this.a = 'a';
13717      }
13718      Foo.prototype.b = 'b';
13719
13720      var actual = func(new Foo, function(value, key) { return key; });
13721      assert.deepEqual(actual, { 'a': 'a' });
13722    });
13723
13724    QUnit.test('`_.' + methodName + '` should accept a falsey `object`', function(assert) {
13725      assert.expect(1);
13726
13727      var expected = lodashStable.map(falsey, stubObject);
13728
13729      var actual = lodashStable.map(falsey, function(object, index) {
13730        try {
13731          return index ? func(object) : func();
13732        } catch (e) {}
13733      });
13734
13735      assert.deepEqual(actual, expected);
13736    });
13737
13738    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
13739      assert.expect(1);
13740
13741      if (!isNpm) {
13742        assert.ok(_(object)[methodName](noop) instanceof _);
13743      }
13744      else {
13745        skipAssert(assert);
13746      }
13747    });
13748  });
13749
13750  QUnit.module('lodash.matches');
13751
13752  (function() {
13753    QUnit.test('should not change behavior if `source` is modified', function(assert) {
13754      assert.expect(9);
13755
13756      var sources = [
13757        { 'a': { 'b': 2, 'c': 3 } },
13758        { 'a': 1, 'b': 2 },
13759        { 'a': 1 }
13760      ];
13761
13762      lodashStable.each(sources, function(source, index) {
13763        var object = lodashStable.cloneDeep(source),
13764            par = _.matches(source);
13765
13766        assert.strictEqual(par(object), true);
13767
13768        if (index) {
13769          source.a = 2;
13770          source.b = 1;
13771          source.c = 3;
13772        } else {
13773          source.a.b = 1;
13774          source.a.c = 2;
13775          source.a.d = 3;
13776        }
13777        assert.strictEqual(par(object), true);
13778        assert.strictEqual(par(source), false);
13779      });
13780    });
13781  }());
13782
13783  /*--------------------------------------------------------------------------*/
13784
13785  QUnit.module('matches methods');
13786
13787  lodashStable.each(['matches', 'isMatch'], function(methodName) {
13788    var isMatches = methodName == 'matches';
13789
13790    function matches(source) {
13791      return isMatches ? _.matches(source) : function(object) {
13792        return _.isMatch(object, source);
13793      };
13794    }
13795
13796    QUnit.test('`_.' + methodName + '` should perform a deep comparison between `source` and `object`', function(assert) {
13797      assert.expect(5);
13798
13799      var object = { 'a': 1, 'b': 2, 'c': 3 },
13800          par = matches({ 'a': 1 });
13801
13802      assert.strictEqual(par(object), true);
13803
13804      par = matches({ 'b': 1 });
13805      assert.strictEqual(par(object), false);
13806
13807      par = matches({ 'a': 1, 'c': 3 });
13808      assert.strictEqual(par(object), true);
13809
13810      par = matches({ 'c': 3, 'd': 4 });
13811      assert.strictEqual(par(object), false);
13812
13813      object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13814      par = matches({ 'a': { 'b': { 'c': 1 } } });
13815
13816      assert.strictEqual(par(object), true);
13817    });
13818
13819    QUnit.test('`_.' + methodName + '` should match inherited string keyed `object` properties', function(assert) {
13820      assert.expect(1);
13821
13822      function Foo() {
13823        this.a = 1;
13824      }
13825      Foo.prototype.b = 2;
13826
13827      var object = { 'a': new Foo },
13828          par = matches({ 'a': { 'b': 2 } });
13829
13830      assert.strictEqual(par(object), true);
13831    });
13832
13833    QUnit.test('`_.' + methodName + '` should not match by inherited `source` properties', function(assert) {
13834      assert.expect(1);
13835
13836      function Foo() {
13837        this.a = 1;
13838      }
13839      Foo.prototype.b = 2;
13840
13841      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
13842          source = new Foo,
13843          actual = lodashStable.map(objects, matches(source)),
13844          expected = lodashStable.map(objects, stubTrue);
13845
13846      assert.deepEqual(actual, expected);
13847    });
13848
13849    QUnit.test('`_.' + methodName + '` should compare a variety of `source` property values', function(assert) {
13850      assert.expect(2);
13851
13852      var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13853          object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13854          par = matches(object1);
13855
13856      assert.strictEqual(par(object1), true);
13857      assert.strictEqual(par(object2), false);
13858    });
13859
13860    QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13861      assert.expect(2);
13862
13863      var object1 = { 'a': -0 },
13864          object2 = { 'a': 0 },
13865          par = matches(object1);
13866
13867      assert.strictEqual(par(object2), true);
13868
13869      par = matches(object2);
13870      assert.strictEqual(par(object1), true);
13871    });
13872
13873    QUnit.test('`_.' + methodName + '` should compare functions by reference', function(assert) {
13874      assert.expect(3);
13875
13876      var object1 = { 'a': lodashStable.noop },
13877          object2 = { 'a': noop },
13878          object3 = { 'a': {} },
13879          par = matches(object1);
13880
13881      assert.strictEqual(par(object1), true);
13882      assert.strictEqual(par(object2), false);
13883      assert.strictEqual(par(object3), false);
13884    });
13885
13886    QUnit.test('`_.' + methodName + '` should work with a function for `object`', function(assert) {
13887      assert.expect(1);
13888
13889      function Foo() {}
13890      Foo.a = { 'b': 2, 'c': 3 };
13891
13892      var par = matches({ 'a': { 'b': 2 } });
13893      assert.strictEqual(par(Foo), true);
13894    });
13895
13896    QUnit.test('`_.' + methodName + '` should work with a function for `source`', function(assert) {
13897      assert.expect(1);
13898
13899      function Foo() {}
13900      Foo.a = 1;
13901      Foo.b = function() {};
13902      Foo.c = 3;
13903
13904      var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
13905          actual = lodashStable.map(objects, matches(Foo));
13906
13907      assert.deepEqual(actual, [false, true]);
13908    });
13909
13910    QUnit.test('`_.' + methodName + '` should work with a non-plain `object`', function(assert) {
13911      assert.expect(1);
13912
13913      function Foo(object) { lodashStable.assign(this, object); }
13914
13915      var object = new Foo({ 'a': new Foo({ 'b': 2, 'c': 3 }) }),
13916          par = matches({ 'a': { 'b': 2 } });
13917
13918      assert.strictEqual(par(object), true);
13919    });
13920
13921    QUnit.test('`_.' + methodName + '` should partial match arrays', function(assert) {
13922      assert.expect(3);
13923
13924      var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13925          actual = lodashStable.filter(objects, matches({ 'a': ['d'] }));
13926
13927      assert.deepEqual(actual, [objects[1]]);
13928
13929      actual = lodashStable.filter(objects, matches({ 'a': ['b', 'd'] }));
13930      assert.deepEqual(actual, []);
13931
13932      actual = lodashStable.filter(objects, matches({ 'a': ['d', 'b'] }));
13933      assert.deepEqual(actual, []);
13934    });
13935
13936    QUnit.test('`_.' + methodName + '` should partial match arrays with duplicate values', function(assert) {
13937      assert.expect(1);
13938
13939      var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
13940          actual = lodashStable.filter(objects, matches({ 'a': [2, 2] }));
13941
13942      assert.deepEqual(actual, [objects[1]]);
13943    });
13944
13945    QUnit.test('should partial match arrays of objects', function(assert) {
13946      assert.expect(1);
13947
13948      var objects = [
13949        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
13950        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
13951      ];
13952
13953      var actual = lodashStable.filter(objects, matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
13954      assert.deepEqual(actual, [objects[0]]);
13955    });
13956
13957    QUnit.test('`_.' + methodName + '` should partial match maps', function(assert) {
13958      assert.expect(3);
13959
13960      if (Map) {
13961        var objects = [{ 'a': new Map }, { 'a': new Map }];
13962        objects[0].a.set('a', 1);
13963        objects[1].a.set('a', 1);
13964        objects[1].a.set('b', 2);
13965
13966        var map = new Map;
13967        map.set('b', 2);
13968        var actual = lodashStable.filter(objects, matches({ 'a': map }));
13969
13970        assert.deepEqual(actual, [objects[1]]);
13971
13972        map.delete('b');
13973        actual = lodashStable.filter(objects, matches({ 'a': map }));
13974
13975        assert.deepEqual(actual, objects);
13976
13977        map.set('c', 3);
13978        actual = lodashStable.filter(objects, matches({ 'a': map }));
13979
13980        assert.deepEqual(actual, []);
13981      }
13982      else {
13983        skipAssert(assert, 3);
13984      }
13985    });
13986
13987    QUnit.test('`_.' + methodName + '` should partial match sets', function(assert) {
13988      assert.expect(3);
13989
13990      if (Set) {
13991        var objects = [{ 'a': new Set }, { 'a': new Set }];
13992        objects[0].a.add(1);
13993        objects[1].a.add(1);
13994        objects[1].a.add(2);
13995
13996        var set = new Set;
13997        set.add(2);
13998        var actual = lodashStable.filter(objects, matches({ 'a': set }));
13999
14000        assert.deepEqual(actual, [objects[1]]);
14001
14002        set.delete(2);
14003        actual = lodashStable.filter(objects, matches({ 'a': set }));
14004
14005        assert.deepEqual(actual, objects);
14006
14007        set.add(3);
14008        actual = lodashStable.filter(objects, matches({ 'a': set }));
14009
14010        assert.deepEqual(actual, []);
14011      }
14012      else {
14013        skipAssert(assert, 3);
14014      }
14015    });
14016
14017    QUnit.test('`_.' + methodName + '` should match `undefined` values', function(assert) {
14018      assert.expect(3);
14019
14020      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14021          actual = lodashStable.map(objects, matches({ 'b': undefined })),
14022          expected = [false, false, true];
14023
14024      assert.deepEqual(actual, expected);
14025
14026      actual = lodashStable.map(objects, matches({ 'a': 1, 'b': undefined }));
14027
14028      assert.deepEqual(actual, expected);
14029
14030      objects = [{ 'a': { 'b': 2 } }, { 'a': { 'b': 2, 'c': 3 } }, { 'a': { 'b': 2, 'c': undefined } }];
14031      actual = lodashStable.map(objects, matches({ 'a': { 'c': undefined } }));
14032
14033      assert.deepEqual(actual, expected);
14034    });
14035
14036    QUnit.test('`_.' + methodName + '` should match `undefined` values on primitives', function(assert) {
14037      assert.expect(3);
14038
14039      numberProto.a = 1;
14040      numberProto.b = undefined;
14041
14042      try {
14043        var par = matches({ 'b': undefined });
14044        assert.strictEqual(par(1), true);
14045      } catch (e) {
14046        assert.ok(false, e.message);
14047      }
14048      try {
14049        par = matches({ 'a': 1, 'b': undefined });
14050        assert.strictEqual(par(1), true);
14051      } catch (e) {
14052        assert.ok(false, e.message);
14053      }
14054      numberProto.a = { 'b': 1, 'c': undefined };
14055      try {
14056        par = matches({ 'a': { 'c': undefined } });
14057        assert.strictEqual(par(1), true);
14058      } catch (e) {
14059        assert.ok(false, e.message);
14060      }
14061      delete numberProto.a;
14062      delete numberProto.b;
14063    });
14064
14065    QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
14066      assert.expect(1);
14067
14068      var values = [, null, undefined],
14069          expected = lodashStable.map(values, stubFalse),
14070          par = matches({ 'a': 1 });
14071
14072      var actual = lodashStable.map(values, function(value, index) {
14073        try {
14074          return index ? par(value) : par();
14075        } catch (e) {}
14076      });
14077
14078      assert.deepEqual(actual, expected);
14079    });
14080
14081    QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source`', function(assert) {
14082      assert.expect(1);
14083
14084      var object = { 'a': 1 },
14085          expected = lodashStable.map(empties, stubTrue);
14086
14087      var actual = lodashStable.map(empties, function(value) {
14088        var par = matches(value);
14089        return par(object);
14090      });
14091
14092      assert.deepEqual(actual, expected);
14093    });
14094
14095    QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
14096      assert.expect(1);
14097
14098      var values = [, null, undefined],
14099          expected = lodashStable.map(values, stubTrue),
14100          par = matches({});
14101
14102      var actual = lodashStable.map(values, function(value, index) {
14103        try {
14104          return index ? par(value) : par();
14105        } catch (e) {}
14106      });
14107
14108      assert.deepEqual(actual, expected);
14109    });
14110
14111    QUnit.test('`_.' + methodName + '` should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
14112      assert.expect(1);
14113
14114      var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14115          actual = lodashStable.filter(objects, matches({ 'a': [], 'b': {} }));
14116
14117      assert.deepEqual(actual, objects);
14118    });
14119  });
14120
14121  /*--------------------------------------------------------------------------*/
14122
14123  QUnit.module('lodash.matchesProperty');
14124
14125  (function() {
14126    QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
14127      assert.expect(6);
14128
14129      var object = { 'a': 1, 'b': 2, 'c': 3 },
14130          matches = _.matchesProperty('a', 1);
14131
14132      assert.strictEqual(matches.length, 1);
14133      assert.strictEqual(matches(object), true);
14134
14135      matches = _.matchesProperty('b', 3);
14136      assert.strictEqual(matches(object), false);
14137
14138      matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
14139      assert.strictEqual(matches({ 'a': object }), true);
14140
14141      matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
14142      assert.strictEqual(matches(object), false);
14143
14144      object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
14145      matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
14146
14147      assert.strictEqual(matches(object), true);
14148    });
14149
14150    QUnit.test('should support deep paths', function(assert) {
14151      assert.expect(2);
14152
14153      var object = { 'a': { 'b': 2 } };
14154
14155      lodashStable.each(['a.b', ['a', 'b']], function(path) {
14156        var matches = _.matchesProperty(path, 2);
14157        assert.strictEqual(matches(object), true);
14158      });
14159    });
14160
14161    QUnit.test('should work with a non-string `path`', function(assert) {
14162      assert.expect(2);
14163
14164      var array = [1, 2, 3];
14165
14166      lodashStable.each([1, [1]], function(path) {
14167        var matches = _.matchesProperty(path, 2);
14168        assert.strictEqual(matches(array), true);
14169      });
14170    });
14171
14172    QUnit.test('should preserve the sign of `0`', function(assert) {
14173      assert.expect(1);
14174
14175      var object1 = { '-0': 'a' },
14176          object2 = { '0': 'b' },
14177          pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
14178          props = [-0, Object(-0), 0, Object(0)],
14179          values = ['a', 'a', 'b', 'b'],
14180          expected = lodashStable.map(props, lodashStable.constant([true, false]));
14181
14182      var actual = lodashStable.map(props, function(key, index) {
14183        var matches = _.matchesProperty(key, values[index]),
14184            pair = pairs[index];
14185
14186        return [matches(pair[0]), matches(pair[1])];
14187      });
14188
14189      assert.deepEqual(actual, expected);
14190    });
14191
14192    QUnit.test('should coerce `path` to a string', function(assert) {
14193      assert.expect(2);
14194
14195      function fn() {}
14196      fn.toString = lodashStable.constant('fn');
14197
14198      var object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
14199          paths = [null, undefined, fn, {}],
14200          expected = lodashStable.map(paths, stubTrue);
14201
14202      lodashStable.times(2, function(index) {
14203        var actual = lodashStable.map(paths, function(path) {
14204          var matches = _.matchesProperty(index ? [path] : path, object[path]);
14205          return matches(object);
14206        });
14207
14208        assert.deepEqual(actual, expected);
14209      });
14210    });
14211
14212    QUnit.test('should match a key over a path', function(assert) {
14213      assert.expect(2);
14214
14215      var object = { 'a.b': 1, 'a': { 'b': 2 } };
14216
14217      lodashStable.each(['a.b', ['a.b']], function(path) {
14218        var matches = _.matchesProperty(path, 1);
14219        assert.strictEqual(matches(object), true);
14220      });
14221    });
14222
14223    QUnit.test('should return `false` when `object` is nullish', function(assert) {
14224      assert.expect(2);
14225
14226      var values = [, null, undefined],
14227          expected = lodashStable.map(values, stubFalse);
14228
14229      lodashStable.each(['constructor', ['constructor']], function(path) {
14230        var matches = _.matchesProperty(path, 1);
14231
14232        var actual = lodashStable.map(values, function(value, index) {
14233          try {
14234            return index ? matches(value) : matches();
14235          } catch (e) {}
14236        });
14237
14238        assert.deepEqual(actual, expected);
14239      });
14240    });
14241
14242    QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
14243      assert.expect(2);
14244
14245      var values = [, null, undefined],
14246          expected = lodashStable.map(values, stubFalse);
14247
14248      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
14249        var matches = _.matchesProperty(path, 1);
14250
14251        var actual = lodashStable.map(values, function(value, index) {
14252          try {
14253            return index ? matches(value) : matches();
14254          } catch (e) {}
14255        });
14256
14257        assert.deepEqual(actual, expected);
14258      });
14259    });
14260
14261    QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
14262      assert.expect(4);
14263
14264      var object = {};
14265
14266      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
14267        var matches = _.matchesProperty(path, 1);
14268        assert.strictEqual(matches(object), false);
14269      });
14270    });
14271
14272    QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
14273      assert.expect(2);
14274
14275      function Foo() {}
14276      Foo.prototype.b = 2;
14277
14278      var object = { 'a': new Foo };
14279
14280      lodashStable.each(['a', ['a']], function(path) {
14281        var matches = _.matchesProperty(path, { 'b': 2 });
14282        assert.strictEqual(matches(object), true);
14283      });
14284    });
14285
14286    QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
14287      assert.expect(2);
14288
14289      function Foo() {
14290        this.a = 1;
14291      }
14292      Foo.prototype.b = 2;
14293
14294      var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
14295          expected = lodashStable.map(objects, stubTrue);
14296
14297      lodashStable.each(['a', ['a']], function(path) {
14298        assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
14299      });
14300    });
14301
14302    QUnit.test('should compare a variety of values', function(assert) {
14303      assert.expect(2);
14304
14305      var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
14306          object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
14307          matches = _.matchesProperty('a', object1);
14308
14309      assert.strictEqual(matches({ 'a': object1 }), true);
14310      assert.strictEqual(matches({ 'a': object2 }), false);
14311    });
14312
14313    QUnit.test('should match `-0` as `0`', function(assert) {
14314      assert.expect(2);
14315
14316      var matches = _.matchesProperty('a', -0);
14317      assert.strictEqual(matches({ 'a': 0 }), true);
14318
14319      matches = _.matchesProperty('a', 0);
14320      assert.strictEqual(matches({ 'a': -0 }), true);
14321    });
14322
14323    QUnit.test('should compare functions by reference', function(assert) {
14324      assert.expect(3);
14325
14326      var object1 = { 'a': lodashStable.noop },
14327          object2 = { 'a': noop },
14328          object3 = { 'a': {} },
14329          matches = _.matchesProperty('a', object1);
14330
14331      assert.strictEqual(matches({ 'a': object1 }), true);
14332      assert.strictEqual(matches({ 'a': object2 }), false);
14333      assert.strictEqual(matches({ 'a': object3 }), false);
14334    });
14335
14336    QUnit.test('should work with a function for `srcValue`', function(assert) {
14337      assert.expect(1);
14338
14339      function Foo() {}
14340      Foo.a = 1;
14341      Foo.b = function() {};
14342      Foo.c = 3;
14343
14344      var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
14345          actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
14346
14347      assert.deepEqual(actual, [false, true]);
14348    });
14349
14350    QUnit.test('should work with a non-plain `srcValue`', function(assert) {
14351      assert.expect(1);
14352
14353      function Foo(object) { lodashStable.assign(this, object); }
14354
14355      var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
14356          matches = _.matchesProperty('a', { 'b': 1 });
14357
14358      assert.strictEqual(matches(object), true);
14359    });
14360
14361    QUnit.test('should partial match arrays', function(assert) {
14362      assert.expect(3);
14363
14364      var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
14365          actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
14366
14367      assert.deepEqual(actual, [objects[1]]);
14368
14369      actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
14370      assert.deepEqual(actual, []);
14371
14372      actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
14373      assert.deepEqual(actual, []);
14374    });
14375
14376    QUnit.test('should partial match arrays with duplicate values', function(assert) {
14377      assert.expect(1);
14378
14379      var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }],
14380          actual = lodashStable.filter(objects, _.matchesProperty('a', [2, 2]));
14381
14382      assert.deepEqual(actual, [objects[1]]);
14383    });
14384
14385    QUnit.test('should partial match arrays of objects', function(assert) {
14386      assert.expect(1);
14387
14388      var objects = [
14389        { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
14390        { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
14391      ];
14392
14393      var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
14394      assert.deepEqual(actual, [objects[0]]);
14395    });
14396    QUnit.test('should partial match maps', function(assert) {
14397      assert.expect(3);
14398
14399      if (Map) {
14400        var objects = [{ 'a': new Map }, { 'a': new Map }];
14401        objects[0].a.set('a', 1);
14402        objects[1].a.set('a', 1);
14403        objects[1].a.set('b', 2);
14404
14405        var map = new Map;
14406        map.set('b', 2);
14407        var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14408
14409        assert.deepEqual(actual, [objects[1]]);
14410
14411        map.delete('b');
14412        actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14413
14414        assert.deepEqual(actual, objects);
14415
14416        map.set('c', 3);
14417        actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14418
14419        assert.deepEqual(actual, []);
14420      }
14421      else {
14422        skipAssert(assert, 3);
14423      }
14424    });
14425
14426    QUnit.test('should partial match sets', function(assert) {
14427      assert.expect(3);
14428
14429      if (Set) {
14430        var objects = [{ 'a': new Set }, { 'a': new Set }];
14431        objects[0].a.add(1);
14432        objects[1].a.add(1);
14433        objects[1].a.add(2);
14434
14435        var set = new Set;
14436        set.add(2);
14437        var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14438
14439        assert.deepEqual(actual, [objects[1]]);
14440
14441        set.delete(2);
14442        actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14443
14444        assert.deepEqual(actual, objects);
14445
14446        set.add(3);
14447        actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14448
14449        assert.deepEqual(actual, []);
14450      }
14451      else {
14452        skipAssert(assert, 3);
14453      }
14454    });
14455
14456    QUnit.test('should match `undefined` values', function(assert) {
14457      assert.expect(2);
14458
14459      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14460          actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
14461          expected = [false, false, true];
14462
14463      assert.deepEqual(actual, expected);
14464
14465      objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
14466      actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
14467
14468      assert.deepEqual(actual, expected);
14469    });
14470
14471    QUnit.test('should match `undefined` values of nested objects', function(assert) {
14472      assert.expect(4);
14473
14474      var object = { 'a': { 'b': undefined } };
14475
14476      lodashStable.each(['a.b', ['a', 'b']], function(path) {
14477        var matches = _.matchesProperty(path, undefined);
14478        assert.strictEqual(matches(object), true);
14479      });
14480
14481      lodashStable.each(['a.a', ['a', 'a']], function(path) {
14482        var matches = _.matchesProperty(path, undefined);
14483        assert.strictEqual(matches(object), false);
14484      });
14485    });
14486
14487    QUnit.test('should match `undefined` values on primitives', function(assert) {
14488      assert.expect(2);
14489
14490      numberProto.a = 1;
14491      numberProto.b = undefined;
14492
14493      try {
14494        var matches = _.matchesProperty('b', undefined);
14495        assert.strictEqual(matches(1), true);
14496      } catch (e) {
14497        assert.ok(false, e.message);
14498      }
14499      numberProto.a = { 'b': 1, 'c': undefined };
14500      try {
14501        matches = _.matchesProperty('a', { 'c': undefined });
14502        assert.strictEqual(matches(1), true);
14503      } catch (e) {
14504        assert.ok(false, e.message);
14505      }
14506      delete numberProto.a;
14507      delete numberProto.b;
14508    });
14509
14510    QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
14511      assert.expect(1);
14512
14513      var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14514          matches = _.matchesProperty('a', { 'a': [], 'b': {} });
14515
14516      var actual = lodashStable.filter(objects, function(object) {
14517        return matches({ 'a': object });
14518      });
14519
14520      assert.deepEqual(actual, objects);
14521    });
14522
14523    QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
14524      assert.expect(9);
14525
14526      lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
14527        var object = lodashStable.cloneDeep(source),
14528            matches = _.matchesProperty('a', source);
14529
14530        assert.strictEqual(matches({ 'a': object }), true);
14531
14532        if (index) {
14533          source.a = 2;
14534          source.b = 1;
14535          source.c = 3;
14536        } else {
14537          source.a.b = 1;
14538          source.a.c = 2;
14539          source.a.d = 3;
14540        }
14541        assert.strictEqual(matches({ 'a': object }), true);
14542        assert.strictEqual(matches({ 'a': source }), false);
14543      });
14544    });
14545  }());
14546
14547  /*--------------------------------------------------------------------------*/
14548
14549  QUnit.module('lodash.max');
14550
14551  (function() {
14552    QUnit.test('should return the largest value from a collection', function(assert) {
14553      assert.expect(1);
14554
14555      assert.strictEqual(_.max([1, 2, 3]), 3);
14556    });
14557
14558    QUnit.test('should return `undefined` for empty collections', function(assert) {
14559      assert.expect(1);
14560
14561      var values = falsey.concat([[]]),
14562          expected = lodashStable.map(values, noop);
14563
14564      var actual = lodashStable.map(values, function(value, index) {
14565        try {
14566          return index ? _.max(value) : _.max();
14567        } catch (e) {}
14568      });
14569
14570      assert.deepEqual(actual, expected);
14571    });
14572
14573    QUnit.test('should work with non-numeric collection values', function(assert) {
14574      assert.expect(1);
14575
14576      assert.strictEqual(_.max(['a', 'b']), 'b');
14577    });
14578  }());
14579
14580  /*--------------------------------------------------------------------------*/
14581
14582  QUnit.module('lodash.mean');
14583
14584  (function() {
14585    QUnit.test('should return the mean of an array of numbers', function(assert) {
14586      assert.expect(1);
14587
14588      var array = [4, 2, 8, 6];
14589      assert.strictEqual(_.mean(array), 5);
14590    });
14591
14592    QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
14593      assert.expect(1);
14594
14595      var expected = lodashStable.map(empties, stubNaN),
14596          actual = lodashStable.map(empties, _.mean);
14597
14598      assert.deepEqual(actual, expected);
14599    });
14600  }());
14601
14602  /*--------------------------------------------------------------------------*/
14603
14604  QUnit.module('lodash.meanBy');
14605
14606  (function() {
14607    var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
14608
14609    QUnit.test('should work with an `iteratee`', function(assert) {
14610      assert.expect(1);
14611
14612      var actual = _.meanBy(objects, function(object) {
14613        return object.a;
14614      });
14615
14616      assert.deepEqual(actual, 2);
14617    });
14618
14619    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
14620      assert.expect(1);
14621
14622      var args;
14623
14624      _.meanBy(objects, function() {
14625        args || (args = slice.call(arguments));
14626      });
14627
14628      assert.deepEqual(args, [{ 'a': 2 }]);
14629    });
14630
14631    QUnit.test('should work with `_.property` shorthands', function(assert) {
14632      assert.expect(2);
14633
14634      var arrays = [[2], [3], [1]];
14635      assert.strictEqual(_.meanBy(arrays, 0), 2);
14636      assert.strictEqual(_.meanBy(objects, 'a'), 2);
14637    });
14638  }());
14639
14640  /*--------------------------------------------------------------------------*/
14641
14642  QUnit.module('lodash.memoize');
14643
14644  (function() {
14645    function CustomCache() {
14646      this.clear();
14647    }
14648
14649    CustomCache.prototype = {
14650      'clear': function() {
14651        this.__data__ = [];
14652        return this;
14653      },
14654      'get': function(key) {
14655        var entry = lodashStable.find(this.__data__, ['key', key]);
14656        return entry && entry.value;
14657      },
14658      'has': function(key) {
14659        return lodashStable.some(this.__data__, ['key', key]);
14660      },
14661      'set': function(key, value) {
14662        this.__data__.push({ 'key': key, 'value': value });
14663        return this;
14664      }
14665    };
14666
14667    function ImmutableCache() {
14668      this.__data__ = [];
14669    }
14670
14671    ImmutableCache.prototype = lodashStable.create(CustomCache.prototype, {
14672      'constructor': ImmutableCache,
14673      'clear': function() {
14674        return new ImmutableCache;
14675      },
14676      'set': function(key, value) {
14677        var result = new ImmutableCache;
14678        result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
14679        return result;
14680      }
14681    });
14682
14683    QUnit.test('should memoize results based on the first argument given', function(assert) {
14684      assert.expect(2);
14685
14686      var memoized = _.memoize(function(a, b, c) {
14687        return a + b + c;
14688      });
14689
14690      assert.strictEqual(memoized(1, 2, 3), 6);
14691      assert.strictEqual(memoized(1, 3, 5), 6);
14692    });
14693
14694    QUnit.test('should support a `resolver`', function(assert) {
14695      assert.expect(2);
14696
14697      var fn = function(a, b, c) { return a + b + c; },
14698          memoized = _.memoize(fn, fn);
14699
14700      assert.strictEqual(memoized(1, 2, 3), 6);
14701      assert.strictEqual(memoized(1, 3, 5), 9);
14702    });
14703
14704    QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
14705      assert.expect(2);
14706
14707      var fn = function(a, b, c) { return a + this.b + this.c; },
14708          memoized = _.memoize(fn, fn);
14709
14710      var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
14711      assert.strictEqual(object.memoized(1), 6);
14712
14713      object.b = 3;
14714      object.c = 5;
14715      assert.strictEqual(object.memoized(1), 9);
14716    });
14717
14718    QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
14719      assert.expect(1);
14720
14721      assert.raises(function() { _.memoize(noop, true); }, TypeError);
14722    });
14723
14724    QUnit.test('should not error if `resolver` is nullish', function(assert) {
14725      assert.expect(1);
14726
14727      var values = [, null, undefined],
14728          expected = lodashStable.map(values, stubTrue);
14729
14730      var actual = lodashStable.map(values, function(resolver, index) {
14731        try {
14732          return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
14733        } catch (e) {}
14734      });
14735
14736      assert.deepEqual(actual, expected);
14737    });
14738
14739    QUnit.test('should check cache for own properties', function(assert) {
14740      assert.expect(1);
14741
14742      var props = [
14743        'constructor',
14744        'hasOwnProperty',
14745        'isPrototypeOf',
14746        'propertyIsEnumerable',
14747        'toLocaleString',
14748        'toString',
14749        'valueOf'
14750      ];
14751
14752      var memoized = _.memoize(identity);
14753
14754      var actual = lodashStable.map(props, function(value) {
14755        return memoized(value);
14756      });
14757
14758      assert.deepEqual(actual, props);
14759    });
14760
14761    QUnit.test('should cache the `__proto__` key', function(assert) {
14762      assert.expect(8);
14763
14764      var array = [],
14765          key = '__proto__';
14766
14767      lodashStable.times(2, function(index) {
14768        var count = 0,
14769            resolver = index ? identity : undefined;
14770
14771        var memoized = _.memoize(function() {
14772          count++;
14773          return array;
14774        }, resolver);
14775
14776        var cache = memoized.cache;
14777
14778        memoized(key);
14779        memoized(key);
14780
14781        assert.strictEqual(count, 1);
14782        assert.strictEqual(cache.get(key), array);
14783        assert.notOk(cache.__data__ instanceof Array);
14784        assert.strictEqual(cache.delete(key), true);
14785      });
14786    });
14787
14788    QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
14789      assert.expect(4);
14790
14791      var oldCache = _.memoize.Cache;
14792      _.memoize.Cache = CustomCache;
14793
14794      var memoized = _.memoize(function(object) {
14795        return object.id;
14796      });
14797
14798      var cache = memoized.cache,
14799          key1 = { 'id': 'a' },
14800          key2 = { 'id': 'b' };
14801
14802      assert.strictEqual(memoized(key1), 'a');
14803      assert.strictEqual(cache.has(key1), true);
14804
14805      assert.strictEqual(memoized(key2), 'b');
14806      assert.strictEqual(cache.has(key2), true);
14807
14808      _.memoize.Cache = oldCache;
14809    });
14810
14811    QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
14812      assert.expect(2);
14813
14814      var oldCache = _.memoize.Cache;
14815      _.memoize.Cache = ImmutableCache;
14816
14817      var memoized = _.memoize(function(object) {
14818        return object.id;
14819      });
14820
14821      var key1 = { 'id': 'a' },
14822          key2 = { 'id': 'b' };
14823
14824      memoized(key1);
14825      memoized(key2);
14826
14827      var cache = memoized.cache;
14828      assert.strictEqual(cache.has(key1), true);
14829      assert.strictEqual(cache.has(key2), true);
14830
14831      _.memoize.Cache = oldCache;
14832    });
14833  }());
14834
14835  /*--------------------------------------------------------------------------*/
14836
14837  QUnit.module('memoizeCapped');
14838
14839  (function() {
14840    var func = _._memoizeCapped;
14841
14842    QUnit.test('should enforce a max cache size of `MAX_MEMOIZE_SIZE`', function(assert) {
14843      assert.expect(2);
14844
14845      if (func) {
14846        var memoized = func(identity),
14847            cache = memoized.cache;
14848
14849        lodashStable.times(MAX_MEMOIZE_SIZE, memoized);
14850        assert.strictEqual(cache.size, MAX_MEMOIZE_SIZE);
14851
14852        memoized(MAX_MEMOIZE_SIZE);
14853        assert.strictEqual(cache.size, 1);
14854      }
14855      else {
14856        skipAssert(assert, 2);
14857      }
14858    });
14859  }());
14860
14861  /*--------------------------------------------------------------------------*/
14862
14863  QUnit.module('lodash.merge');
14864
14865  (function() {
14866    QUnit.test('should merge `source` into `object`', function(assert) {
14867      assert.expect(1);
14868
14869      var names = {
14870        'characters': [
14871          { 'name': 'barney' },
14872          { 'name': 'fred' }
14873        ]
14874      };
14875
14876      var ages = {
14877        'characters': [
14878          { 'age': 36 },
14879          { 'age': 40 }
14880        ]
14881      };
14882
14883      var heights = {
14884        'characters': [
14885          { 'height': '5\'4"' },
14886          { 'height': '5\'5"' }
14887        ]
14888      };
14889
14890      var expected = {
14891        'characters': [
14892          { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
14893          { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
14894        ]
14895      };
14896
14897      assert.deepEqual(_.merge(names, ages, heights), expected);
14898    });
14899
14900    QUnit.test('should merge sources containing circular references', function(assert) {
14901      assert.expect(2);
14902
14903      var object = {
14904        'foo': { 'a': 1 },
14905        'bar': { 'a': 2 }
14906      };
14907
14908      var source = {
14909        'foo': { 'b': { 'c': { 'd': {} } } },
14910        'bar': {}
14911      };
14912
14913      source.foo.b.c.d = source;
14914      source.bar.b = source.foo.b;
14915
14916      var actual = _.merge(object, source);
14917
14918      assert.notStrictEqual(actual.bar.b, actual.foo.b);
14919      assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
14920    });
14921
14922    QUnit.test('should work with four arguments', function(assert) {
14923      assert.expect(1);
14924
14925      var expected = { 'a': 4 },
14926          actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
14927
14928      assert.deepEqual(actual, expected);
14929    });
14930
14931    QUnit.test('should merge onto function `object` values', function(assert) {
14932      assert.expect(2);
14933
14934      function Foo() {}
14935
14936      var source = { 'a': 1 },
14937          actual = _.merge(Foo, source);
14938
14939      assert.strictEqual(actual, Foo);
14940      assert.strictEqual(Foo.a, 1);
14941    });
14942
14943    QUnit.test('should merge first source object properties to function', function(assert) {
14944      assert.expect(1);
14945
14946      var fn = function() {},
14947          object = { 'prop': {} },
14948          actual = _.merge({ 'prop': fn }, object);
14949
14950      assert.deepEqual(actual, object);
14951    });
14952
14953    QUnit.test('should merge first and second source object properties to function', function(assert) {
14954      assert.expect(1);
14955
14956      var fn = function() {},
14957          object = { 'prop': {} },
14958          actual = _.merge({ 'prop': fn }, { 'prop': fn }, object);
14959
14960      assert.deepEqual(actual, object);
14961    });
14962
14963    QUnit.test('should not merge onto function values of sources', function(assert) {
14964      assert.expect(3);
14965
14966      var source1 = { 'a': function() {} },
14967          source2 = { 'a': { 'b': 2 } },
14968          expected = { 'a': { 'b': 2 } },
14969          actual = _.merge({}, source1, source2);
14970
14971      assert.deepEqual(actual, expected);
14972      assert.notOk('b' in source1.a);
14973
14974      actual = _.merge(source1, source2);
14975      assert.deepEqual(actual, expected);
14976    });
14977
14978    QUnit.test('should merge onto non-plain `object` values', function(assert) {
14979      assert.expect(2);
14980
14981      function Foo() {}
14982
14983      var object = new Foo,
14984          actual = _.merge(object, { 'a': 1 });
14985
14986      assert.strictEqual(actual, object);
14987      assert.strictEqual(object.a, 1);
14988    });
14989
14990    QUnit.test('should treat sparse array sources as dense', function(assert) {
14991      assert.expect(2);
14992
14993      var array = [1];
14994      array[2] = 3;
14995
14996      var actual = _.merge([], array),
14997          expected = array.slice();
14998
14999      expected[1] = undefined;
15000
15001      assert.ok('1' in actual);
15002      assert.deepEqual(actual, expected);
15003    });
15004
15005    QUnit.test('should merge `arguments` objects', function(assert) {
15006      assert.expect(7);
15007
15008      var object1 = { 'value': args },
15009          object2 = { 'value': { '3': 4 } },
15010          expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
15011          actual = _.merge(object1, object2);
15012
15013      assert.notOk('3' in args);
15014      assert.notOk(_.isArguments(actual.value));
15015      assert.deepEqual(actual.value, expected);
15016      object1.value = args;
15017
15018      actual = _.merge(object2, object1);
15019      assert.notOk(_.isArguments(actual.value));
15020      assert.deepEqual(actual.value, expected);
15021
15022      expected = { '0': 1, '1': 2, '2': 3 };
15023
15024      actual = _.merge({}, object1);
15025      assert.notOk(_.isArguments(actual.value));
15026      assert.deepEqual(actual.value, expected);
15027    });
15028
15029    QUnit.test('should merge typed arrays', function(assert) {
15030      assert.expect(4);
15031
15032      var array1 = [0],
15033          array2 = [0, 0],
15034          array3 = [0, 0, 0, 0],
15035          array4 = [0, 0, 0, 0, 0, 0, 0, 0];
15036
15037      var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
15038          buffer = ArrayBuffer && new ArrayBuffer(8);
15039
15040      var expected = lodashStable.map(typedArrays, function(type, index) {
15041        var array = arrays[index].slice();
15042        array[0] = 1;
15043        return root[type] ? { 'value': array } : false;
15044      });
15045
15046      var actual = lodashStable.map(typedArrays, function(type) {
15047        var Ctor = root[type];
15048        return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
15049      });
15050
15051      assert.ok(lodashStable.isArray(actual));
15052      assert.deepEqual(actual, expected);
15053
15054      expected = lodashStable.map(typedArrays, function(type, index) {
15055        var array = arrays[index].slice();
15056        array.push(1);
15057        return root[type] ? { 'value': array } : false;
15058      });
15059
15060      actual = lodashStable.map(typedArrays, function(type, index) {
15061        var Ctor = root[type],
15062            array = lodashStable.range(arrays[index].length);
15063
15064        array.push(1);
15065        return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
15066      });
15067
15068      assert.ok(lodashStable.isArray(actual));
15069      assert.deepEqual(actual, expected);
15070    });
15071
15072    QUnit.test('should assign `null` values', function(assert) {
15073      assert.expect(1);
15074
15075      var actual = _.merge({ 'a': 1 }, { 'a': null });
15076      assert.strictEqual(actual.a, null);
15077    });
15078
15079    QUnit.test('should assign non array/buffer/typed-array/plain-object source values directly', function(assert) {
15080      assert.expect(1);
15081
15082      function Foo() {}
15083
15084      var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
15085          expected = lodashStable.map(values, stubTrue);
15086
15087      var actual = lodashStable.map(values, function(value) {
15088        var object = _.merge({}, { 'a': value, 'b': { 'c': value } });
15089        return object.a === value && object.b.c === value;
15090      });
15091
15092      assert.deepEqual(actual, expected);
15093    });
15094
15095    QUnit.test('should clone buffer source values', function(assert) {
15096      assert.expect(3);
15097
15098      if (Buffer) {
15099        var buffer = new Buffer([1]),
15100            actual = _.merge({}, { 'value': buffer }).value;
15101
15102        assert.ok(lodashStable.isBuffer(actual));
15103        assert.strictEqual(actual[0], buffer[0]);
15104        assert.notStrictEqual(actual, buffer);
15105      }
15106      else {
15107        skipAssert(assert, 3);
15108      }
15109    });
15110
15111    QUnit.test('should deep clone array/typed-array/plain-object source values', function(assert) {
15112      assert.expect(1);
15113
15114      var typedArray = Uint8Array
15115        ? new Uint8Array([1])
15116        : { 'buffer': [1] };
15117
15118      var props = ['0', 'buffer', 'a'],
15119          values = [[{ 'a': 1 }], typedArray, { 'a': [1] }],
15120          expected = lodashStable.map(values, stubTrue);
15121
15122      var actual = lodashStable.map(values, function(value, index) {
15123        var key = props[index],
15124            object = _.merge({}, { 'value': value }),
15125            subValue = value[key],
15126            newValue = object.value,
15127            newSubValue = newValue[key];
15128
15129        return (
15130          newValue !== value &&
15131          newSubValue !== subValue &&
15132          lodashStable.isEqual(newValue, value)
15133        );
15134      });
15135
15136      assert.deepEqual(actual, expected);
15137    });
15138
15139    QUnit.test('should not augment source objects', function(assert) {
15140      assert.expect(6);
15141
15142      var source1 = { 'a': [{ 'a': 1 }] },
15143          source2 = { 'a': [{ 'b': 2 }] },
15144          actual = _.merge({}, source1, source2);
15145
15146      assert.deepEqual(source1.a, [{ 'a': 1 }]);
15147      assert.deepEqual(source2.a, [{ 'b': 2 }]);
15148      assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
15149
15150      var source1 = { 'a': [[1, 2, 3]] },
15151          source2 = { 'a': [[3, 4]] },
15152          actual = _.merge({}, source1, source2);
15153
15154      assert.deepEqual(source1.a, [[1, 2, 3]]);
15155      assert.deepEqual(source2.a, [[3, 4]]);
15156      assert.deepEqual(actual.a, [[3, 4, 3]]);
15157    });
15158
15159    QUnit.test('should merge plain objects onto non-plain objects', function(assert) {
15160      assert.expect(4);
15161
15162      function Foo(object) {
15163        lodashStable.assign(this, object);
15164      }
15165
15166      var object = { 'a': 1 },
15167          actual = _.merge(new Foo, object);
15168
15169      assert.ok(actual instanceof Foo);
15170      assert.deepEqual(actual, new Foo(object));
15171
15172      actual = _.merge([new Foo], [object]);
15173      assert.ok(actual[0] instanceof Foo);
15174      assert.deepEqual(actual, [new Foo(object)]);
15175    });
15176
15177    QUnit.test('should not overwrite existing values with `undefined` values of object sources', function(assert) {
15178      assert.expect(1);
15179
15180      var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
15181      assert.deepEqual(actual, { 'a': 1, 'b': undefined });
15182    });
15183
15184    QUnit.test('should not overwrite existing values with `undefined` values of array sources', function(assert) {
15185      assert.expect(2);
15186
15187      var array = [1];
15188      array[2] = 3;
15189
15190      var actual = _.merge([4, 5, 6], array),
15191          expected = [1, 5, 3];
15192
15193      assert.deepEqual(actual, expected);
15194
15195      array = [1, , 3];
15196      array[1] = undefined;
15197
15198      actual = _.merge([4, 5, 6], array);
15199      assert.deepEqual(actual, expected);
15200    });
15201
15202    QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
15203      assert.expect(1);
15204
15205      var object = {},
15206          pass = true;
15207
15208      defineProperty(object, 'a', {
15209        'configurable': true,
15210        'enumerable': true,
15211        'get': function() { pass = false; },
15212        'set': function() { pass = false; }
15213      });
15214
15215      _.merge(object, object);
15216      assert.ok(pass);
15217    });
15218
15219    QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
15220      assert.expect(2);
15221
15222      var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
15223          actual = _.merge(object, { 'a': ['x'] });
15224
15225      assert.deepEqual(actual, { 'a': ['x', 'y'] });
15226
15227      actual = _.merge({ 'a': {} }, { 'a': [] });
15228      assert.deepEqual(actual, { 'a': [] });
15229    });
15230
15231    QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
15232      assert.expect(1);
15233
15234      var object = { 'a': 'abcde' },
15235          actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
15236
15237      assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
15238    });
15239
15240    QUnit.test('should not error on DOM elements', function(assert) {
15241      assert.expect(1);
15242
15243      var object1 = { 'el': document && document.createElement('div') },
15244          object2 = { 'el': document && document.createElement('div') },
15245          pairs = [[{}, object1], [object1, object2]],
15246          expected = lodashStable.map(pairs, stubTrue);
15247
15248      var actual = lodashStable.map(pairs, function(pair) {
15249        try {
15250          return _.merge(pair[0], pair[1]).el === pair[1].el;
15251        } catch (e) {}
15252      });
15253
15254      assert.deepEqual(actual, expected);
15255    });
15256  }());
15257
15258  /*--------------------------------------------------------------------------*/
15259
15260  QUnit.module('lodash.mergeWith');
15261
15262  (function() {
15263    QUnit.test('should handle merging when `customizer` returns `undefined`', function(assert) {
15264      assert.expect(2);
15265
15266      var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
15267      assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
15268
15269      actual = _.mergeWith([], [undefined], identity);
15270      assert.deepEqual(actual, [undefined]);
15271    });
15272
15273    QUnit.test('should clone sources when `customizer` returns `undefined`', function(assert) {
15274      assert.expect(1);
15275
15276      var source1 = { 'a': { 'b': { 'c': 1 } } },
15277          source2 = { 'a': { 'b': { 'd': 2 } } };
15278
15279      _.mergeWith({}, source1, source2, noop);
15280      assert.deepEqual(source1.a.b, { 'c': 1 });
15281    });
15282
15283    QUnit.test('should defer to `customizer` for non `undefined` results', function(assert) {
15284      assert.expect(1);
15285
15286      var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
15287        return lodashStable.isArray(a) ? a.concat(b) : undefined;
15288      });
15289
15290      assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
15291    });
15292
15293    QUnit.test('should provide `stack` to `customizer`', function(assert) {
15294      assert.expect(4);
15295
15296      var actual = [];
15297
15298      _.mergeWith({}, { 'z': 1, 'a': { 'b': 2 } }, function() {
15299        actual.push(_.last(arguments));
15300      });
15301
15302      assert.strictEqual(actual.length, 3);
15303      _.each(actual, function(a) {
15304        assert.ok(isNpm
15305          ? a.constructor.name == 'Stack'
15306          : a instanceof mapCaches.Stack
15307        );
15308      });
15309    });
15310
15311    QUnit.test('should overwrite primitives with source object clones', function(assert) {
15312      assert.expect(1);
15313
15314      var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
15315        return lodashStable.isArray(a) ? a.concat(b) : undefined;
15316      });
15317
15318      assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
15319    });
15320
15321    QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
15322      assert.expect(1);
15323
15324      var array = ['b', 'c'],
15325          object = { 'a': ['a'] },
15326          source = { 'a': array, 'b': array };
15327
15328      var actual = _.mergeWith(object, source, function(a, b) {
15329        return lodashStable.isArray(a) ? a.concat(b) : undefined;
15330      });
15331
15332      assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
15333    });
15334  }());
15335
15336  /*--------------------------------------------------------------------------*/
15337
15338  QUnit.module('lodash.method');
15339
15340  (function() {
15341    QUnit.test('should create a function that calls a method of a given object', function(assert) {
15342      assert.expect(4);
15343
15344      var object = { 'a': stubOne };
15345
15346      lodashStable.each(['a', ['a']], function(path) {
15347        var method = _.method(path);
15348        assert.strictEqual(method.length, 1);
15349        assert.strictEqual(method(object), 1);
15350      });
15351    });
15352
15353    QUnit.test('should work with deep property values', function(assert) {
15354      assert.expect(2);
15355
15356      var object = { 'a': { 'b': stubTwo } };
15357
15358      lodashStable.each(['a.b', ['a', 'b']], function(path) {
15359        var method = _.method(path);
15360        assert.strictEqual(method(object), 2);
15361      });
15362    });
15363
15364    QUnit.test('should work with a non-string `path`', function(assert) {
15365      assert.expect(2);
15366
15367      var array = lodashStable.times(3, _.constant);
15368
15369      lodashStable.each([1, [1]], function(path) {
15370        var method = _.method(path);
15371        assert.strictEqual(method(array), 1);
15372      });
15373    });
15374
15375    QUnit.test('should coerce `path` to a string', function(assert) {
15376      assert.expect(2);
15377
15378      function fn() {}
15379      fn.toString = lodashStable.constant('fn');
15380
15381      var expected = [1, 2, 3, 4],
15382          object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour },
15383          paths = [null, undefined, fn, {}];
15384
15385      lodashStable.times(2, function(index) {
15386        var actual = lodashStable.map(paths, function(path) {
15387          var method = _.method(index ? [path] : path);
15388          return method(object);
15389        });
15390
15391        assert.deepEqual(actual, expected);
15392      });
15393    });
15394
15395    QUnit.test('should work with inherited property values', function(assert) {
15396      assert.expect(2);
15397
15398      function Foo() {}
15399      Foo.prototype.a = stubOne;
15400
15401      lodashStable.each(['a', ['a']], function(path) {
15402        var method = _.method(path);
15403        assert.strictEqual(method(new Foo), 1);
15404      });
15405    });
15406
15407    QUnit.test('should use a key over a path', function(assert) {
15408      assert.expect(2);
15409
15410      var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15411
15412      lodashStable.each(['a.b', ['a.b']], function(path) {
15413        var method = _.method(path);
15414        assert.strictEqual(method(object), 1);
15415      });
15416    });
15417
15418    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15419      assert.expect(2);
15420
15421      var values = [, null, undefined],
15422          expected = lodashStable.map(values, noop);
15423
15424      lodashStable.each(['constructor', ['constructor']], function(path) {
15425        var method = _.method(path);
15426
15427        var actual = lodashStable.map(values, function(value, index) {
15428          return index ? method(value) : method();
15429        });
15430
15431        assert.deepEqual(actual, expected);
15432      });
15433    });
15434
15435    QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
15436      assert.expect(2);
15437
15438      var values = [, null, undefined],
15439          expected = lodashStable.map(values, noop);
15440
15441      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15442        var method = _.method(path);
15443
15444        var actual = lodashStable.map(values, function(value, index) {
15445          return index ? method(value) : method();
15446        });
15447
15448        assert.deepEqual(actual, expected);
15449      });
15450    });
15451
15452    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15453      assert.expect(4);
15454
15455      var object = {};
15456
15457      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15458        var method = _.method(path);
15459        assert.strictEqual(method(object), undefined);
15460      });
15461    });
15462
15463    QUnit.test('should apply partial arguments to function', function(assert) {
15464      assert.expect(2);
15465
15466      var object = {
15467        'fn': function() {
15468          return slice.call(arguments);
15469        }
15470      };
15471
15472      lodashStable.each(['fn', ['fn']], function(path) {
15473        var method = _.method(path, 1, 2, 3);
15474        assert.deepEqual(method(object), [1, 2, 3]);
15475      });
15476    });
15477
15478    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15479      assert.expect(2);
15480
15481      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
15482
15483      lodashStable.each(['a.b', ['a', 'b']], function(path) {
15484        var method = _.method(path);
15485        assert.strictEqual(method(object), 1);
15486      });
15487    });
15488  }());
15489
15490  /*--------------------------------------------------------------------------*/
15491
15492  QUnit.module('lodash.methodOf');
15493
15494  (function() {
15495    QUnit.test('should create a function that calls a method of a given key', function(assert) {
15496      assert.expect(4);
15497
15498      var object = { 'a': stubOne };
15499
15500      lodashStable.each(['a', ['a']], function(path) {
15501        var methodOf = _.methodOf(object);
15502        assert.strictEqual(methodOf.length, 1);
15503        assert.strictEqual(methodOf(path), 1);
15504      });
15505    });
15506
15507    QUnit.test('should work with deep property values', function(assert) {
15508      assert.expect(2);
15509
15510      var object = { 'a': { 'b': stubTwo } };
15511
15512      lodashStable.each(['a.b', ['a', 'b']], function(path) {
15513        var methodOf = _.methodOf(object);
15514        assert.strictEqual(methodOf(path), 2);
15515      });
15516    });
15517
15518    QUnit.test('should work with a non-string `path`', function(assert) {
15519      assert.expect(2);
15520
15521      var array = lodashStable.times(3, _.constant);
15522
15523      lodashStable.each([1, [1]], function(path) {
15524        var methodOf = _.methodOf(array);
15525        assert.strictEqual(methodOf(path), 1);
15526      });
15527    });
15528
15529    QUnit.test('should coerce `path` to a string', function(assert) {
15530      assert.expect(2);
15531
15532      function fn() {}
15533      fn.toString = lodashStable.constant('fn');
15534
15535      var expected = [1, 2, 3, 4],
15536          object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour },
15537          paths = [null, undefined, fn, {}];
15538
15539      lodashStable.times(2, function(index) {
15540        var actual = lodashStable.map(paths, function(path) {
15541          var methodOf = _.methodOf(object);
15542          return methodOf(index ? [path] : path);
15543        });
15544
15545        assert.deepEqual(actual, expected);
15546      });
15547    });
15548
15549    QUnit.test('should work with inherited property values', function(assert) {
15550      assert.expect(2);
15551
15552      function Foo() {}
15553      Foo.prototype.a = stubOne;
15554
15555      lodashStable.each(['a', ['a']], function(path) {
15556        var methodOf = _.methodOf(new Foo);
15557        assert.strictEqual(methodOf(path), 1);
15558      });
15559    });
15560
15561    QUnit.test('should use a key over a path', function(assert) {
15562      assert.expect(2);
15563
15564      var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } };
15565
15566      lodashStable.each(['a.b', ['a.b']], function(path) {
15567        var methodOf = _.methodOf(object);
15568        assert.strictEqual(methodOf(path), 1);
15569      });
15570    });
15571
15572    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15573      assert.expect(2);
15574
15575      var values = [, null, undefined],
15576          expected = lodashStable.map(values, noop);
15577
15578      lodashStable.each(['constructor', ['constructor']], function(path) {
15579        var actual = lodashStable.map(values, function(value, index) {
15580          var methodOf = index ? _.methodOf() : _.methodOf(value);
15581          return methodOf(path);
15582        });
15583
15584        assert.deepEqual(actual, expected);
15585      });
15586    });
15587
15588    QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
15589      assert.expect(2);
15590
15591      var values = [, null, undefined],
15592          expected = lodashStable.map(values, noop);
15593
15594      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15595        var actual = lodashStable.map(values, function(value, index) {
15596          var methodOf = index ? _.methodOf() : _.methodOf(value);
15597          return methodOf(path);
15598        });
15599
15600        assert.deepEqual(actual, expected);
15601      });
15602    });
15603
15604    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15605      assert.expect(4);
15606
15607      var object = {},
15608          methodOf = _.methodOf(object);
15609
15610      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15611        assert.strictEqual(methodOf(path), undefined);
15612      });
15613    });
15614
15615    QUnit.test('should apply partial arguments to function', function(assert) {
15616      assert.expect(2);
15617
15618      var object = {
15619        'fn': function() {
15620          return slice.call(arguments);
15621        }
15622      };
15623
15624      var methodOf = _.methodOf(object, 1, 2, 3);
15625
15626      lodashStable.each(['fn', ['fn']], function(path) {
15627        assert.deepEqual(methodOf(path), [1, 2, 3]);
15628      });
15629    });
15630
15631    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15632      assert.expect(2);
15633
15634      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
15635          methodOf = _.methodOf(object);
15636
15637      lodashStable.each(['a.b', ['a', 'b']], function(path) {
15638        assert.strictEqual(methodOf(path), 1);
15639      });
15640    });
15641  }());
15642
15643  /*--------------------------------------------------------------------------*/
15644
15645  QUnit.module('lodash.min');
15646
15647  (function() {
15648    QUnit.test('should return the smallest value from a collection', function(assert) {
15649      assert.expect(1);
15650
15651      assert.strictEqual(_.min([1, 2, 3]), 1);
15652    });
15653
15654    QUnit.test('should return `undefined` for empty collections', function(assert) {
15655      assert.expect(1);
15656
15657      var values = falsey.concat([[]]),
15658          expected = lodashStable.map(values, noop);
15659
15660      var actual = lodashStable.map(values, function(value, index) {
15661        try {
15662          return index ? _.min(value) : _.min();
15663        } catch (e) {}
15664      });
15665
15666      assert.deepEqual(actual, expected);
15667    });
15668
15669    QUnit.test('should work with non-numeric collection values', function(assert) {
15670      assert.expect(1);
15671
15672      assert.strictEqual(_.min(['a', 'b']), 'a');
15673    });
15674  }());
15675
15676  /*--------------------------------------------------------------------------*/
15677
15678  QUnit.module('extremum methods');
15679
15680  lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
15681    var func = _[methodName],
15682        isMax = /^max/.test(methodName);
15683
15684    QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
15685      assert.expect(1);
15686
15687      var curr = new Date,
15688          past = new Date(0);
15689
15690      assert.strictEqual(func([curr, past]), isMax ? curr : past);
15691    });
15692
15693    QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
15694      assert.expect(1);
15695
15696      var array = lodashStable.range(0, 5e5);
15697      assert.strictEqual(func(array), isMax ? 499999 : 0);
15698    });
15699
15700    QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
15701      assert.expect(1);
15702
15703      if (!isNpm) {
15704        var actual = _([40])[methodName]();
15705        assert.strictEqual(actual, 40);
15706      }
15707      else {
15708        skipAssert(assert);
15709      }
15710    });
15711  });
15712
15713  lodashStable.each(['maxBy', 'minBy'], function(methodName) {
15714    var array = [1, 2, 3],
15715        func = _[methodName],
15716        isMax = methodName == 'maxBy';
15717
15718    QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) {
15719      assert.expect(1);
15720
15721      var actual = func(array, function(n) {
15722        return -n;
15723      });
15724
15725      assert.strictEqual(actual, isMax ? 1 : 3);
15726    });
15727
15728    QUnit.test('should work with `_.property` shorthands', function(assert) {
15729      assert.expect(2);
15730
15731      var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
15732          actual = func(objects, 'a');
15733
15734      assert.deepEqual(actual, objects[isMax ? 1 : 2]);
15735
15736      var arrays = [[2], [3], [1]];
15737      actual = func(arrays, 0);
15738
15739      assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
15740    });
15741
15742    QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
15743      assert.expect(1);
15744
15745      var value = isMax ? -Infinity : Infinity,
15746          object = { 'a': value };
15747
15748      var actual = func([object, { 'a': value }], function(object) {
15749        return object.a;
15750      });
15751
15752      assert.strictEqual(actual, object);
15753    });
15754  });
15755
15756  /*--------------------------------------------------------------------------*/
15757
15758  QUnit.module('lodash.mixin');
15759
15760  (function() {
15761    function reset(wrapper) {
15762      delete wrapper.a;
15763      delete wrapper.prototype.a;
15764      delete wrapper.b;
15765      delete wrapper.prototype.b;
15766    }
15767
15768    function Wrapper(value) {
15769      if (!(this instanceof Wrapper)) {
15770        return new Wrapper(value);
15771      }
15772      if (_.has(value, '__wrapped__')) {
15773        var actions = slice.call(value.__actions__),
15774            chain = value.__chain__;
15775
15776        value = value.__wrapped__;
15777      }
15778      this.__wrapped__ = value;
15779      this.__actions__ = actions || [];
15780      this.__chain__ = chain || false;
15781    }
15782
15783    Wrapper.prototype.value = function() {
15784      return getUnwrappedValue(this);
15785    };
15786
15787    var array = ['a'],
15788        source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
15789
15790    QUnit.test('should mixin `source` methods into lodash', function(assert) {
15791      assert.expect(4);
15792
15793      if (!isNpm) {
15794        _.mixin(source);
15795
15796        assert.strictEqual(_.a(array), 'a');
15797        assert.strictEqual(_(array).a().value(), 'a');
15798        assert.notOk('b' in _);
15799        assert.notOk('b' in _.prototype);
15800
15801        reset(_);
15802      }
15803      else {
15804        skipAssert(assert, 4);
15805      }
15806    });
15807
15808    QUnit.test('should mixin chaining methods by reference', function(assert) {
15809      assert.expect(2);
15810
15811      if (!isNpm) {
15812        _.mixin(source);
15813        _.a = stubB;
15814
15815        assert.strictEqual(_.a(array), 'b');
15816        assert.strictEqual(_(array).a().value(), 'a');
15817
15818        reset(_);
15819      }
15820      else {
15821        skipAssert(assert, 2);
15822      }
15823    });
15824
15825    QUnit.test('should use a default `object` of `this`', function(assert) {
15826      assert.expect(3);
15827
15828      var object = lodashStable.create(_);
15829      object.mixin(source);
15830
15831      assert.strictEqual(object.a(array), 'a');
15832      assert.notOk('a' in _);
15833      assert.notOk('a' in _.prototype);
15834
15835      reset(_);
15836    });
15837
15838    QUnit.test('should accept an `object`', function(assert) {
15839      assert.expect(1);
15840
15841      var object = {};
15842      _.mixin(object, source);
15843      assert.strictEqual(object.a(array), 'a');
15844    });
15845
15846    QUnit.test('should accept a function `object`', function(assert) {
15847      assert.expect(2);
15848
15849      _.mixin(Wrapper, source);
15850
15851      var wrapped = Wrapper(array),
15852          actual = wrapped.a();
15853
15854      assert.strictEqual(actual.value(), 'a');
15855      assert.ok(actual instanceof Wrapper);
15856
15857      reset(Wrapper);
15858    });
15859
15860    QUnit.test('should return `object`', function(assert) {
15861      assert.expect(3);
15862
15863      var object = {};
15864      assert.strictEqual(_.mixin(object, source), object);
15865      assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
15866      assert.strictEqual(_.mixin(), _);
15867
15868      reset(Wrapper);
15869    });
15870
15871    QUnit.test('should not assign inherited `source` methods', function(assert) {
15872      assert.expect(1);
15873
15874      function Foo() {}
15875      Foo.prototype.a = noop;
15876
15877      var object = {};
15878      assert.strictEqual(_.mixin(object, new Foo), object);
15879    });
15880
15881    QUnit.test('should accept an `options`', function(assert) {
15882      assert.expect(8);
15883
15884      function message(func, chain) {
15885        return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
15886      }
15887
15888      lodashStable.each([_, Wrapper], function(func) {
15889        lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
15890          if (!isNpm) {
15891            if (func === _) {
15892              _.mixin(source, options);
15893            } else {
15894              _.mixin(func, source, options);
15895            }
15896            var wrapped = func(array),
15897                actual = wrapped.a();
15898
15899            if (options.chain) {
15900              assert.strictEqual(actual.value(), 'a', message(func, true));
15901              assert.ok(actual instanceof func, message(func, true));
15902            } else {
15903              assert.strictEqual(actual, 'a', message(func, false));
15904              assert.notOk(actual instanceof func, message(func, false));
15905            }
15906            reset(func);
15907          }
15908          else {
15909            skipAssert(assert, 2);
15910          }
15911        });
15912      });
15913    });
15914
15915    QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
15916      assert.expect(1);
15917
15918      _.mixin({ 'a': noop }, {});
15919      assert.notOk('a' in _);
15920      reset(_);
15921    });
15922
15923    QUnit.test('should not error for non-object `options` values', function(assert) {
15924      assert.expect(2);
15925
15926      var pass = true;
15927
15928      try {
15929        _.mixin({}, source, 1);
15930      } catch (e) {
15931        pass = false;
15932      }
15933      assert.ok(pass);
15934
15935      pass = true;
15936
15937      try {
15938        _.mixin(source, 1);
15939      } catch (e) {
15940        pass = false;
15941      }
15942      assert.ok(pass);
15943
15944      reset(_);
15945    });
15946
15947    QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
15948      assert.expect(2);
15949
15950      lodashStable.each([_, Wrapper], function(func) {
15951        if (!isNpm) {
15952          if (func === _) {
15953            var wrapped = _(source),
15954                actual = wrapped.mixin();
15955
15956            assert.strictEqual(actual.value(), _);
15957          }
15958          else {
15959            wrapped = _(func);
15960            actual = wrapped.mixin(source);
15961            assert.notStrictEqual(actual, wrapped);
15962          }
15963          reset(func);
15964        }
15965        else {
15966          skipAssert(assert);
15967        }
15968      });
15969    });
15970
15971    QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
15972      assert.expect(1);
15973
15974      if (!isNpm) {
15975        _.mixin({ 'a': _.countBy, 'b': _.filter });
15976
15977        var array = lodashStable.range(LARGE_ARRAY_SIZE),
15978            actual = _(array).a().map(square).b(isEven).take().value();
15979
15980        assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
15981
15982        reset(_);
15983      }
15984      else {
15985        skipAssert(assert);
15986      }
15987    });
15988  }());
15989
15990  /*--------------------------------------------------------------------------*/
15991
15992  QUnit.module('lodash.multiply');
15993
15994  (function() {
15995    QUnit.test('should multiply two numbers', function(assert) {
15996      assert.expect(3);
15997
15998      assert.strictEqual(_.multiply(6, 4), 24);
15999      assert.strictEqual(_.multiply(-6, 4), -24);
16000      assert.strictEqual(_.multiply(-6, -4), 24);
16001    });
16002
16003    QUnit.test('should coerce arguments to numbers', function(assert) {
16004      assert.expect(2);
16005
16006      assert.strictEqual(_.multiply('6', '4'), 24);
16007      assert.deepEqual(_.multiply('x', 'y'), NaN);
16008    });
16009  }());
16010
16011  /*--------------------------------------------------------------------------*/
16012
16013  QUnit.module('lodash.orderBy');
16014
16015  (function() {
16016    var objects = [
16017      { 'a': 'x', 'b': 3 },
16018      { 'a': 'y', 'b': 4 },
16019      { 'a': 'x', 'b': 1 },
16020      { 'a': 'y', 'b': 2 }
16021    ];
16022
16023    QUnit.test('should sort by a single property by a specified order', function(assert) {
16024      assert.expect(1);
16025
16026      var actual = _.orderBy(objects, 'a', 'desc');
16027      assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
16028    });
16029
16030    QUnit.test('should sort by multiple properties by specified orders', function(assert) {
16031      assert.expect(1);
16032
16033      var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
16034      assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
16035    });
16036
16037    QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
16038      assert.expect(2);
16039
16040      var expected = [objects[2], objects[0], objects[3], objects[1]],
16041          actual = _.orderBy(objects, ['a', 'b']);
16042
16043      assert.deepEqual(actual, expected);
16044
16045      expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
16046
16047      actual = lodashStable.map(falsey, function(order, index) {
16048        return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
16049      });
16050
16051      assert.deepEqual(actual, expected);
16052    });
16053
16054    QUnit.test('should work with `orders` specified as string objects', function(assert) {
16055      assert.expect(1);
16056
16057      var actual = _.orderBy(objects, ['a'], [Object('desc')]);
16058      assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
16059    });
16060  }());
16061
16062  /*--------------------------------------------------------------------------*/
16063
16064  QUnit.module('lodash.overArgs');
16065
16066  (function() {
16067    function fn() {
16068      return slice.call(arguments);
16069    }
16070
16071    QUnit.test('should transform each argument', function(assert) {
16072      assert.expect(1);
16073
16074      var over = _.overArgs(fn, doubled, square);
16075      assert.deepEqual(over(5, 10), [10, 100]);
16076    });
16077
16078    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16079      assert.expect(1);
16080
16081      var over = _.overArgs(fn, undefined, null);
16082      assert.deepEqual(over('a', 'b'), ['a', 'b']);
16083    });
16084
16085    QUnit.test('should work with `_.property` shorthands', function(assert) {
16086      assert.expect(1);
16087
16088      var over = _.overArgs(fn, 'b', 'a');
16089      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
16090    });
16091
16092    QUnit.test('should work with `_.matches` shorthands', function(assert) {
16093      assert.expect(1);
16094
16095      var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
16096      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16097    });
16098
16099    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16100      assert.expect(1);
16101
16102      var over = _.overArgs(fn, [['b', 1], ['a', 1]]);
16103      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
16104    });
16105
16106    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16107      assert.expect(2);
16108
16109      var over = _.overArgs(fn, ['a', 1]);
16110      assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
16111
16112      over = _.overArgs(fn, [['a', 1]]);
16113      assert.deepEqual(over({ 'a': 1 }), [true]);
16114    });
16115
16116    QUnit.test('should flatten `transforms`', function(assert) {
16117      assert.expect(1);
16118
16119      var over = _.overArgs(fn, [doubled, square], String);
16120      assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
16121    });
16122
16123    QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
16124      assert.expect(1);
16125
16126      var over = _.overArgs(fn, doubled, square);
16127      assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
16128    });
16129
16130    QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
16131      assert.expect(1);
16132
16133      var over = _.overArgs(fn);
16134      assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
16135    });
16136
16137    QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
16138      assert.expect(1);
16139
16140      var over = _.overArgs(fn, doubled, identity);
16141      assert.deepEqual(over(5), [10]);
16142    });
16143
16144    QUnit.test('should provide the correct argument to each transform', function(assert) {
16145      assert.expect(1);
16146
16147      var argsList = [],
16148          transform = function() { argsList.push(slice.call(arguments)); },
16149          over = _.overArgs(noop, transform, transform, transform);
16150
16151      over('a', 'b');
16152      assert.deepEqual(argsList, [['a'], ['b']]);
16153    });
16154
16155    QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
16156      assert.expect(1);
16157
16158      var over = _.overArgs(function(x) {
16159        return this[x];
16160      }, function(x) {
16161        return this === x;
16162      });
16163
16164      var object = { 'over': over, 'true': 1 };
16165      assert.strictEqual(object.over(object), 1);
16166    });
16167  }());
16168
16169  /*--------------------------------------------------------------------------*/
16170
16171  QUnit.module('lodash.negate');
16172
16173  (function() {
16174    QUnit.test('should create a function that negates the result of `func`', function(assert) {
16175      assert.expect(2);
16176
16177      var negate = _.negate(isEven);
16178
16179      assert.strictEqual(negate(1), true);
16180      assert.strictEqual(negate(2), false);
16181    });
16182
16183    QUnit.test('should create a function that negates the result of `func`', function(assert) {
16184      assert.expect(2);
16185
16186      var negate = _.negate(isEven);
16187
16188      assert.strictEqual(negate(1), true);
16189      assert.strictEqual(negate(2), false);
16190    });
16191
16192    QUnit.test('should create a function that accepts multiple arguments', function(assert) {
16193      assert.expect(1);
16194
16195      var argCount,
16196          count = 5,
16197          negate = _.negate(function() { argCount = arguments.length; }),
16198          expected = lodashStable.times(count, stubTrue);
16199
16200      var actual = lodashStable.times(count, function(index) {
16201        switch (index) {
16202          case 0: negate(); break;
16203          case 1: negate(1); break;
16204          case 2: negate(1, 2); break;
16205          case 3: negate(1, 2, 3); break;
16206          case 4: negate(1, 2, 3, 4);
16207        }
16208        return argCount == index;
16209      });
16210
16211      assert.deepEqual(actual, expected);
16212    });
16213  }());
16214
16215  /*--------------------------------------------------------------------------*/
16216
16217  QUnit.module('lodash.noConflict');
16218
16219  (function() {
16220    QUnit.test('should return the `lodash` function', function(assert) {
16221      assert.expect(2);
16222
16223      if (!isModularize) {
16224        assert.strictEqual(_.noConflict(), oldDash);
16225        assert.notStrictEqual(root._, oldDash);
16226        root._ = oldDash;
16227      }
16228      else {
16229        skipAssert(assert, 2);
16230      }
16231    });
16232
16233    QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
16234      assert.expect(2);
16235
16236      if (!isModularize) {
16237        var object = root._ = {};
16238        assert.strictEqual(_.noConflict(), oldDash);
16239        assert.strictEqual(root._, object);
16240        root._ = oldDash;
16241      }
16242      else {
16243        skipAssert(assert, 2);
16244      }
16245    });
16246
16247    QUnit.test('should work with a `root` of `this`', function(assert) {
16248      assert.expect(2);
16249
16250      if (!coverage && !document && !isModularize && realm.object) {
16251        var fs = require('fs'),
16252            vm = require('vm'),
16253            expected = {},
16254            context = vm.createContext({ '_': expected, 'console': console }),
16255            source = fs.readFileSync(filePath, 'utf8');
16256
16257        vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
16258
16259        assert.strictEqual(context._, expected);
16260        assert.ok(context.lodash);
16261      }
16262      else {
16263        skipAssert(assert, 2);
16264      }
16265    });
16266  }());
16267
16268  /*--------------------------------------------------------------------------*/
16269
16270  QUnit.module('lodash.now');
16271
16272  (function() {
16273    QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
16274      assert.expect(2);
16275
16276      var done = assert.async();
16277
16278      var stamp = +new Date,
16279          actual = _.now();
16280
16281      assert.ok(actual >= stamp);
16282
16283      setTimeout(function() {
16284        assert.ok(_.now() > actual);
16285        done();
16286      }, 32);
16287    });
16288
16289    QUnit.test('should work with mocked `Date.now`', function(assert) {
16290      assert.expect(1);
16291
16292      var now = Date.now;
16293      Date.now = stubA;
16294
16295      var actual = _.now();
16296      Date.now = now;
16297
16298      assert.strictEqual(actual, 'a');
16299    });
16300  }());
16301
16302  /*--------------------------------------------------------------------------*/
16303
16304  QUnit.module('lodash.nth');
16305
16306  (function() {
16307    var array = ['a', 'b', 'c', 'd'];
16308
16309    QUnit.test('should get the nth element of `array`', function(assert) {
16310      assert.expect(1);
16311
16312      var actual = lodashStable.map(array, function(value, index) {
16313        return _.nth(array, index);
16314      });
16315
16316      assert.deepEqual(actual, array);
16317    });
16318
16319    QUnit.test('should work with a negative `n`', function(assert) {
16320      assert.expect(1);
16321
16322      var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
16323        return _.nth(array, -n);
16324      });
16325
16326      assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16327    });
16328
16329    QUnit.test('should coerce `n` to an integer', function(assert) {
16330      assert.expect(2);
16331
16332      var values = falsey,
16333          expected = lodashStable.map(values, stubA);
16334
16335      var actual = lodashStable.map(values, function(n) {
16336        return n ? _.nth(array, n) : _.nth(array);
16337      });
16338
16339      assert.deepEqual(actual, expected);
16340
16341      values = ['1', 1.6];
16342      expected = lodashStable.map(values, stubB);
16343
16344      actual = lodashStable.map(values, function(n) {
16345        return _.nth(array, n);
16346      });
16347
16348      assert.deepEqual(actual, expected);
16349    });
16350
16351    QUnit.test('should return `undefined` for empty arrays', function(assert) {
16352      assert.expect(1);
16353
16354      var values = [null, undefined, []],
16355          expected = lodashStable.map(values, noop);
16356
16357      var actual = lodashStable.map(values, function(array) {
16358        return _.nth(array, 1);
16359      });
16360
16361      assert.deepEqual(actual, expected);
16362    });
16363
16364    QUnit.test('should return `undefined` for non-indexes', function(assert) {
16365      assert.expect(1);
16366
16367      var array = [1, 2],
16368          values = [Infinity, array.length],
16369          expected = lodashStable.map(values, noop);
16370
16371      array[-1] = 3;
16372
16373      var actual = lodashStable.map(values, function(n) {
16374        return _.nth(array, n);
16375      });
16376
16377      assert.deepEqual(actual, expected);
16378    });
16379  }());
16380
16381  /*--------------------------------------------------------------------------*/
16382
16383  QUnit.module('lodash.nthArg');
16384
16385  (function() {
16386    var args = ['a', 'b', 'c', 'd'];
16387
16388    QUnit.test('should create a function that returns its nth argument', function(assert) {
16389      assert.expect(1);
16390
16391      var actual = lodashStable.map(args, function(value, index) {
16392        var func = _.nthArg(index);
16393        return func.apply(undefined, args);
16394      });
16395
16396      assert.deepEqual(actual, args);
16397    });
16398
16399    QUnit.test('should work with a negative `n`', function(assert) {
16400      assert.expect(1);
16401
16402      var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
16403        var func = _.nthArg(-n);
16404        return func.apply(undefined, args);
16405      });
16406
16407      assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16408    });
16409
16410    QUnit.test('should coerce `n` to an integer', function(assert) {
16411      assert.expect(2);
16412
16413      var values = falsey,
16414          expected = lodashStable.map(values, stubA);
16415
16416      var actual = lodashStable.map(values, function(n) {
16417        var func = n ? _.nthArg(n) : _.nthArg();
16418        return func.apply(undefined, args);
16419      });
16420
16421      assert.deepEqual(actual, expected);
16422
16423      values = ['1', 1.6];
16424      expected = lodashStable.map(values, stubB);
16425
16426      actual = lodashStable.map(values, function(n) {
16427        var func = _.nthArg(n);
16428        return func.apply(undefined, args);
16429      });
16430
16431      assert.deepEqual(actual, expected);
16432    });
16433
16434    QUnit.test('should return `undefined` for empty arrays', function(assert) {
16435      assert.expect(1);
16436
16437      var func = _.nthArg(1);
16438      assert.strictEqual(func(), undefined);
16439    });
16440
16441    QUnit.test('should return `undefined` for non-indexes', function(assert) {
16442      assert.expect(1);
16443
16444      var values = [Infinity, args.length],
16445          expected = lodashStable.map(values, noop);
16446
16447      var actual = lodashStable.map(values, function(n) {
16448        var func = _.nthArg(n);
16449        return func.apply(undefined, args);
16450      });
16451
16452      assert.deepEqual(actual, expected);
16453    });
16454  }());
16455
16456  /*--------------------------------------------------------------------------*/
16457
16458  QUnit.module('lodash.omit');
16459
16460  (function() {
16461    var args = toArgs(['a', 'c']),
16462        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16463        nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } };
16464
16465    QUnit.test('should flatten `paths`', function(assert) {
16466      assert.expect(2);
16467
16468      assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
16469      assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
16470    });
16471
16472    QUnit.test('should support deep paths', function(assert) {
16473      assert.expect(1);
16474
16475      assert.deepEqual(_.omit(nested, 'b.c'), { 'a': 1, 'b': { 'd': 3} });
16476    });
16477
16478    QUnit.test('should support path arrays', function(assert) {
16479      assert.expect(1);
16480
16481      var object = { 'a.b': 1, 'a': { 'b': 2 } },
16482          actual = _.omit(object, [['a.b']]);
16483
16484      assert.deepEqual(actual, { 'a': { 'b': 2 } });
16485    });
16486
16487    QUnit.test('should omit a key over a path', function(assert) {
16488      assert.expect(2);
16489
16490      var object = { 'a.b': 1, 'a': { 'b': 2 } };
16491
16492      lodashStable.each(['a.b', ['a.b']], function(path) {
16493        assert.deepEqual(_.omit(object, path), { 'a': { 'b': 2 } });
16494      });
16495    });
16496
16497    QUnit.test('should coerce `paths` to strings', function(assert) {
16498      assert.expect(1);
16499
16500      assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
16501    });
16502
16503    QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16504      assert.expect(2);
16505
16506      lodashStable.each([null, undefined], function(value) {
16507        objectProto.a = 1;
16508        var actual = _.omit(value, 'valueOf');
16509        delete objectProto.a;
16510        assert.deepEqual(actual, {});
16511      });
16512    });
16513
16514    QUnit.test('should work with a primitive `object`', function(assert) {
16515      assert.expect(1);
16516
16517      stringProto.a = 1;
16518      stringProto.b = 2;
16519
16520      assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
16521
16522      delete stringProto.a;
16523      delete stringProto.b;
16524    });
16525
16526    QUnit.test('should work with `arguments` object `paths`', function(assert) {
16527      assert.expect(1);
16528
16529      assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
16530    });
16531
16532    QUnit.test('should not mutate `object`', function(assert) {
16533      assert.expect(4);
16534
16535      lodashStable.each(['a', ['a'], 'a.b', ['a.b']], function(path) {
16536        var object = { 'a': { 'b': 2 } };
16537        _.omit(object, path);
16538        assert.deepEqual(object, { 'a': { 'b': 2 } });
16539      });
16540    });
16541  }());
16542
16543  /*--------------------------------------------------------------------------*/
16544
16545  QUnit.module('lodash.omitBy');
16546
16547  (function() {
16548    QUnit.test('should work with a predicate argument', function(assert) {
16549      assert.expect(1);
16550
16551      var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16552
16553      var actual = _.omitBy(object, function(n) {
16554        return n != 2 && n != 4;
16555      });
16556
16557      assert.deepEqual(actual, { 'b': 2, 'd': 4 });
16558    });
16559  }());
16560
16561  /*--------------------------------------------------------------------------*/
16562
16563  QUnit.module('omit methods');
16564
16565  lodashStable.each(['omit', 'omitBy'], function(methodName) {
16566    var expected = { 'b': 2, 'd': 4 },
16567        func = _[methodName],
16568        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16569        resolve = lodashStable.nthArg(1);
16570
16571    if (methodName == 'omitBy') {
16572      resolve = function(object, props) {
16573        props = lodashStable.castArray(props);
16574        return function(value) {
16575          return lodashStable.some(props, function(key) {
16576            key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
16577            return object[key] === value;
16578          });
16579        };
16580      };
16581    }
16582    QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
16583      assert.expect(2);
16584
16585      assert.deepEqual(func(object, resolve(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
16586      assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
16587    });
16588
16589    QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
16590      assert.expect(1);
16591
16592      function Foo() {}
16593      Foo.prototype = object;
16594
16595      assert.deepEqual(func(new Foo, resolve(object, ['a', 'c'])), expected);
16596    });
16597
16598    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
16599      assert.expect(1);
16600
16601      var object = { '-0': 'a', '0': 'b' },
16602          props = [-0, Object(-0), 0, Object(0)],
16603          expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
16604
16605      var actual = lodashStable.map(props, function(key) {
16606        return func(object, resolve(object, key));
16607      });
16608
16609      assert.deepEqual(actual, expected);
16610    });
16611
16612    QUnit.test('`_.' + methodName + '` should include symbols', function(assert) {
16613      assert.expect(3);
16614
16615      function Foo() {
16616        this.a = 0;
16617        this[symbol] = 1;
16618      }
16619
16620      if (Symbol) {
16621        var symbol2 = Symbol('b');
16622        Foo.prototype[symbol2] = 2;
16623
16624        var symbol3 = Symbol('c');
16625        defineProperty(Foo.prototype, symbol3, {
16626          'configurable': true,
16627          'enumerable': false,
16628          'writable': true,
16629          'value': 3
16630        });
16631
16632        var foo = new Foo,
16633            actual = func(foo, resolve(foo, 'a'));
16634
16635        assert.strictEqual(actual[symbol], 1);
16636        assert.strictEqual(actual[symbol2], 2);
16637        assert.notOk(symbol3 in actual);
16638      }
16639      else {
16640        skipAssert(assert, 3);
16641      }
16642    });
16643
16644    QUnit.test('`_.' + methodName + '` should create an object with omitted symbols', function(assert) {
16645      assert.expect(8);
16646
16647      function Foo() {
16648        this.a = 0;
16649        this[symbol] = 1;
16650      }
16651
16652      if (Symbol) {
16653        var symbol2 = Symbol('b');
16654        Foo.prototype[symbol2] = 2;
16655
16656        var symbol3 = Symbol('c');
16657        defineProperty(Foo.prototype, symbol3, {
16658          'configurable': true,
16659          'enumerable': false,
16660          'writable': true,
16661          'value': 3
16662        });
16663
16664        var foo = new Foo,
16665            actual = func(foo, resolve(foo, symbol));
16666
16667        assert.strictEqual(actual.a, 0);
16668        assert.notOk(symbol in actual);
16669        assert.strictEqual(actual[symbol2], 2);
16670        assert.notOk(symbol3 in actual);
16671
16672        actual = func(foo, resolve(foo, symbol2));
16673
16674        assert.strictEqual(actual.a, 0);
16675        assert.strictEqual(actual[symbol], 1);
16676        assert.notOk(symbol2 in actual);
16677        assert.notOk(symbol3 in actual);
16678      }
16679      else {
16680        skipAssert(assert, 8);
16681      }
16682    });
16683
16684    QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) {
16685      assert.expect(1);
16686
16687      var array = [1, 2, 3];
16688      assert.deepEqual(func(array, resolve(array, ['0', '2'])), { '1': 2 });
16689    });
16690  });
16691
16692  /*--------------------------------------------------------------------------*/
16693
16694  QUnit.module('lodash.once');
16695
16696  (function() {
16697    QUnit.test('should invoke `func` once', function(assert) {
16698      assert.expect(2);
16699
16700      var count = 0,
16701          once = _.once(function() { return ++count; });
16702
16703      once();
16704      assert.strictEqual(once(), 1);
16705      assert.strictEqual(count, 1);
16706    });
16707
16708    QUnit.test('should ignore recursive calls', function(assert) {
16709      assert.expect(2);
16710
16711      var count = 0;
16712
16713      var once = _.once(function() {
16714        once();
16715        return ++count;
16716      });
16717
16718      assert.strictEqual(once(), 1);
16719      assert.strictEqual(count, 1);
16720    });
16721
16722    QUnit.test('should not throw more than once', function(assert) {
16723      assert.expect(2);
16724
16725      var once = _.once(function() {
16726        throw new Error;
16727      });
16728
16729      assert.raises(once);
16730
16731      once();
16732      assert.ok(true);
16733    });
16734  }());
16735
16736  /*--------------------------------------------------------------------------*/
16737
16738  QUnit.module('lodash.over');
16739
16740  (function() {
16741    QUnit.test('should create a function that invokes `iteratees`', function(assert) {
16742      assert.expect(1);
16743
16744      var over = _.over(Math.max, Math.min);
16745      assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
16746    });
16747
16748    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16749      assert.expect(1);
16750
16751      var over = _.over(undefined, null);
16752      assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
16753    });
16754
16755    QUnit.test('should work with `_.property` shorthands', function(assert) {
16756      assert.expect(1);
16757
16758      var over = _.over('b', 'a');
16759      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
16760    });
16761
16762    QUnit.test('should work with `_.matches` shorthands', function(assert) {
16763      assert.expect(1);
16764
16765      var over = _.over({ 'b': 1 }, { 'a': 1 });
16766      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
16767    });
16768
16769    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16770      assert.expect(2);
16771
16772      var over = _.over([['b', 2], ['a', 2]]);
16773
16774      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
16775      assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
16776    });
16777
16778    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16779      assert.expect(4);
16780
16781      var over = _.over(['a', 1]);
16782
16783      assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
16784      assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
16785
16786      over = _.over([['a', 1]]);
16787
16788      assert.deepEqual(over({ 'a': 1 }), [true]);
16789      assert.deepEqual(over({ 'a': 2 }), [false]);
16790    });
16791
16792    QUnit.test('should provide arguments to predicates', function(assert) {
16793      assert.expect(1);
16794
16795      var over = _.over(function() {
16796        return slice.call(arguments);
16797      });
16798
16799      assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
16800    });
16801
16802    QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
16803      assert.expect(1);
16804
16805      var over = _.over(function() { return this.b; }, function() { return this.a; }),
16806          object = { 'over': over, 'a': 1, 'b': 2 };
16807
16808      assert.deepEqual(object.over(), [2, 1]);
16809    });
16810  }());
16811
16812  /*--------------------------------------------------------------------------*/
16813
16814  QUnit.module('lodash.overEvery');
16815
16816  (function() {
16817    QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
16818      assert.expect(1);
16819
16820      var over = _.overEvery(stubTrue, stubOne, stubA);
16821      assert.strictEqual(over(), true);
16822    });
16823
16824    QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
16825      assert.expect(2);
16826
16827      var count = 0,
16828          countFalse = function() { count++; return false; },
16829          countTrue = function() { count++; return true; },
16830          over = _.overEvery(countTrue, countFalse, countTrue);
16831
16832      assert.strictEqual(over(), false);
16833      assert.strictEqual(count, 2);
16834    });
16835
16836    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16837      assert.expect(2);
16838
16839      var over = _.overEvery(undefined, null);
16840
16841      assert.strictEqual(over(true), true);
16842      assert.strictEqual(over(false), false);
16843    });
16844
16845    QUnit.test('should work with `_.property` shorthands', function(assert) {
16846      assert.expect(2);
16847
16848      var over = _.overEvery('b', 'a');
16849
16850      assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
16851      assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
16852    });
16853
16854    QUnit.test('should work with `_.matches` shorthands', function(assert) {
16855      assert.expect(2);
16856
16857      var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
16858
16859      assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16860      assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16861    });
16862
16863    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16864      assert.expect(2);
16865
16866      var over = _.overEvery([['b', 2], ['a', 1]]);
16867
16868      assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16869      assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16870    });
16871
16872    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16873      assert.expect(5);
16874
16875      var over = _.overEvery(['a', 1]);
16876
16877      assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
16878      assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
16879      assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
16880
16881      over = _.overEvery([['a', 1]]);
16882
16883      assert.strictEqual(over({ 'a': 1 }), true);
16884      assert.strictEqual(over({ 'a': 2 }), false);
16885    });
16886
16887    QUnit.test('should flatten `predicates`', function(assert) {
16888      assert.expect(1);
16889
16890      var over = _.overEvery(stubTrue, [stubFalse]);
16891      assert.strictEqual(over(), false);
16892    });
16893
16894    QUnit.test('should provide arguments to predicates', function(assert) {
16895      assert.expect(1);
16896
16897      var args;
16898
16899      var over = _.overEvery(function() {
16900        args = slice.call(arguments);
16901      });
16902
16903      over('a', 'b', 'c');
16904      assert.deepEqual(args, ['a', 'b', 'c']);
16905    });
16906
16907    QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16908      assert.expect(2);
16909
16910      var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
16911          object = { 'over': over, 'a': 1, 'b': 2 };
16912
16913      assert.strictEqual(object.over(), true);
16914
16915      object.a = 0;
16916      assert.strictEqual(object.over(), false);
16917    });
16918  }());
16919
16920  /*--------------------------------------------------------------------------*/
16921
16922  QUnit.module('lodash.overSome');
16923
16924  (function() {
16925    QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
16926      assert.expect(2);
16927
16928      var over = _.overSome(stubFalse, stubOne, stubString);
16929      assert.strictEqual(over(), true);
16930
16931      over = _.overSome(stubNull, stubA, stubZero);
16932      assert.strictEqual(over(), true);
16933    });
16934
16935    QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
16936      assert.expect(2);
16937
16938      var count = 0,
16939          countFalse = function() { count++; return false; },
16940          countTrue = function() { count++; return true; },
16941          over = _.overSome(countFalse, countTrue, countFalse);
16942
16943      assert.strictEqual(over(), true);
16944      assert.strictEqual(count, 2);
16945    });
16946
16947    QUnit.test('should return `false` if all predicates return falsey', function(assert) {
16948      assert.expect(2);
16949
16950      var over = _.overSome(stubFalse, stubFalse, stubFalse);
16951      assert.strictEqual(over(), false);
16952
16953      over = _.overSome(stubNull, stubZero, stubString);
16954      assert.strictEqual(over(), false);
16955    });
16956
16957    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16958      assert.expect(2);
16959
16960      var over = _.overSome(undefined, null);
16961
16962      assert.strictEqual(over(true), true);
16963      assert.strictEqual(over(false), false);
16964    });
16965
16966    QUnit.test('should work with `_.property` shorthands', function(assert) {
16967      assert.expect(2);
16968
16969      var over = _.overSome('b', 'a');
16970
16971      assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
16972      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16973    });
16974
16975    QUnit.test('should work with `_.matches` shorthands', function(assert) {
16976      assert.expect(2);
16977
16978      var over = _.overSome({ 'b': 2 }, { 'a': 1 });
16979
16980      assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16981      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16982    });
16983
16984    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16985      assert.expect(2);
16986
16987      var over = _.overSome([['b', 2], ['a', 1]]);
16988
16989      assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16990      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16991    });
16992
16993    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16994      assert.expect(5);
16995
16996      var over = _.overSome(['a', 1]);
16997
16998      assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
16999      assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
17000      assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
17001
17002      over = _.overSome([['a', 1]]);
17003
17004      assert.strictEqual(over({ 'a': 1 }), true);
17005      assert.strictEqual(over({ 'a': 2 }), false);
17006    });
17007
17008    QUnit.test('should flatten `predicates`', function(assert) {
17009      assert.expect(1);
17010
17011      var over = _.overSome(stubFalse, [stubTrue]);
17012      assert.strictEqual(over(), true);
17013    });
17014
17015    QUnit.test('should provide arguments to predicates', function(assert) {
17016      assert.expect(1);
17017
17018      var args;
17019
17020      var over = _.overSome(function() {
17021        args = slice.call(arguments);
17022      });
17023
17024      over('a', 'b', 'c');
17025      assert.deepEqual(args, ['a', 'b', 'c']);
17026    });
17027
17028    QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
17029      assert.expect(2);
17030
17031      var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
17032          object = { 'over': over, 'a': 1, 'b': 2 };
17033
17034      assert.strictEqual(object.over(), true);
17035
17036      object.a = object.b = 0;
17037      assert.strictEqual(object.over(), false);
17038    });
17039  }());
17040
17041  /*--------------------------------------------------------------------------*/
17042
17043  QUnit.module('lodash.pad');
17044
17045  (function() {
17046    var string = 'abc';
17047
17048    QUnit.test('should pad a string to a given length', function(assert) {
17049      assert.expect(1);
17050
17051      var values = [, undefined],
17052          expected = lodashStable.map(values, lodashStable.constant(' abc  '));
17053
17054      var actual = lodashStable.map(values, function(value, index) {
17055        return index ? _.pad(string, 6, value) : _.pad(string, 6);
17056      });
17057
17058      assert.deepEqual(actual, expected);
17059    });
17060
17061    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17062      assert.expect(2);
17063
17064      assert.strictEqual(_.pad(string, 8), '  abc   ');
17065      assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
17066    });
17067
17068    QUnit.test('should coerce `string` to a string', function(assert) {
17069      assert.expect(1);
17070
17071      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17072          expected = lodashStable.map(values, stubTrue);
17073
17074      var actual = lodashStable.map(values, function(value) {
17075        return _.pad(value, 6) === ' abc  ';
17076      });
17077
17078      assert.deepEqual(actual, expected);
17079    });
17080  }());
17081
17082  /*--------------------------------------------------------------------------*/
17083
17084  QUnit.module('lodash.padEnd');
17085
17086  (function() {
17087    var string = 'abc';
17088
17089    QUnit.test('should pad a string to a given length', function(assert) {
17090      assert.expect(1);
17091
17092      var values = [, undefined],
17093          expected = lodashStable.map(values, lodashStable.constant('abc   '));
17094
17095      var actual = lodashStable.map(values, function(value, index) {
17096        return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
17097      });
17098
17099      assert.deepEqual(actual, expected);
17100    });
17101
17102    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17103      assert.expect(1);
17104
17105      assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
17106    });
17107
17108    QUnit.test('should coerce `string` to a string', function(assert) {
17109      assert.expect(1);
17110
17111      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17112          expected = lodashStable.map(values, stubTrue);
17113
17114      var actual = lodashStable.map(values, function(value) {
17115        return _.padEnd(value, 6) === 'abc   ';
17116      });
17117
17118      assert.deepEqual(actual, expected);
17119    });
17120  }());
17121
17122  /*--------------------------------------------------------------------------*/
17123
17124  QUnit.module('lodash.padStart');
17125
17126  (function() {
17127    var string = 'abc';
17128
17129    QUnit.test('should pad a string to a given length', function(assert) {
17130      assert.expect(1);
17131
17132      var values = [, undefined],
17133          expected = lodashStable.map(values, lodashStable.constant('   abc'));
17134
17135      var actual = lodashStable.map(values, function(value, index) {
17136        return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
17137      });
17138
17139      assert.deepEqual(actual, expected);
17140    });
17141
17142    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
17143      assert.expect(1);
17144
17145      assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
17146    });
17147
17148    QUnit.test('should coerce `string` to a string', function(assert) {
17149      assert.expect(1);
17150
17151      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
17152          expected = lodashStable.map(values, stubTrue);
17153
17154      var actual = lodashStable.map(values, function(value) {
17155        return _.padStart(value, 6) === '   abc';
17156      });
17157
17158      assert.deepEqual(actual, expected);
17159    });
17160  }());
17161
17162  /*--------------------------------------------------------------------------*/
17163
17164  QUnit.module('pad methods');
17165
17166  lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
17167    var func = _[methodName],
17168        isPad = methodName == 'pad',
17169        isStart = methodName == 'padStart',
17170        string = 'abc';
17171
17172    QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
17173      assert.expect(2);
17174
17175      assert.strictEqual(func(string, 2), string);
17176      assert.strictEqual(func(string, 3), string);
17177    });
17178
17179    QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
17180      assert.expect(2);
17181
17182      lodashStable.each([0, -2], function(length) {
17183        assert.strictEqual(func(string, length), string);
17184      });
17185    });
17186
17187    QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
17188      assert.expect(2);
17189
17190      lodashStable.each(['', '4'], function(length) {
17191        var actual = length ? (isStart ? ' abc' : 'abc ') : string;
17192        assert.strictEqual(func(string, length), actual);
17193      });
17194    });
17195
17196    QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
17197      assert.expect(6);
17198
17199      lodashStable.each([undefined, '_-'], function(chars) {
17200        var expected = chars ? (isPad ? '__' : chars) : '  ';
17201        assert.strictEqual(func(null, 2, chars), expected);
17202        assert.strictEqual(func(undefined, 2, chars), expected);
17203        assert.strictEqual(func('', 2, chars), expected);
17204      });
17205    });
17206
17207    QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
17208      assert.expect(1);
17209
17210      var values = ['', Object('')],
17211          expected = lodashStable.map(values, lodashStable.constant(string));
17212
17213      var actual = lodashStable.map(values, function(value) {
17214        return _.pad(string, 6, value);
17215      });
17216
17217      assert.deepEqual(actual, expected);
17218    });
17219  });
17220
17221  /*--------------------------------------------------------------------------*/
17222
17223  QUnit.module('lodash.parseInt');
17224
17225  (function() {
17226    QUnit.test('should accept a `radix`', function(assert) {
17227      assert.expect(1);
17228
17229      var expected = lodashStable.range(2, 37);
17230
17231      var actual = lodashStable.map(expected, function(radix) {
17232        return _.parseInt('10', radix);
17233      });
17234
17235      assert.deepEqual(actual, expected);
17236    });
17237
17238    QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17239      assert.expect(4);
17240
17241      assert.strictEqual(_.parseInt('10'), 10);
17242      assert.strictEqual(_.parseInt('10', 0), 10);
17243      assert.strictEqual(_.parseInt('10', 10), 10);
17244      assert.strictEqual(_.parseInt('10', undefined), 10);
17245    });
17246
17247    QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
17248      assert.expect(8);
17249
17250      lodashStable.each(['0x20', '0X20'], function(string) {
17251        assert.strictEqual(_.parseInt(string), 32);
17252        assert.strictEqual(_.parseInt(string, 0), 32);
17253        assert.strictEqual(_.parseInt(string, 16), 32);
17254        assert.strictEqual(_.parseInt(string, undefined), 32);
17255      });
17256    });
17257
17258    QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
17259      assert.expect(2);
17260
17261      assert.strictEqual(_.parseInt('08'), 8);
17262      assert.strictEqual(_.parseInt('08', 10), 8);
17263    });
17264
17265    QUnit.test('should parse strings with leading whitespace', function(assert) {
17266      assert.expect(2);
17267
17268      var expected = [8, 8, 10, 10, 32, 32, 32, 32];
17269
17270      lodashStable.times(2, function(index) {
17271        var actual = [],
17272            func = (index ? (lodashBizarro || {}) : _).parseInt;
17273
17274        if (func) {
17275          lodashStable.times(2, function(otherIndex) {
17276            var string = otherIndex ? '10' : '08';
17277            actual.push(
17278              func(whitespace + string, 10),
17279              func(whitespace + string)
17280            );
17281          });
17282
17283          lodashStable.each(['0x20', '0X20'], function(string) {
17284            actual.push(
17285              func(whitespace + string),
17286              func(whitespace + string, 16)
17287            );
17288          });
17289
17290          assert.deepEqual(actual, expected);
17291        }
17292        else {
17293          skipAssert(assert);
17294        }
17295      });
17296    });
17297
17298    QUnit.test('should coerce `radix` to a number', function(assert) {
17299      assert.expect(2);
17300
17301      var object = { 'valueOf': stubZero };
17302      assert.strictEqual(_.parseInt('08', object), 8);
17303      assert.strictEqual(_.parseInt('0x20', object), 32);
17304    });
17305
17306    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
17307      assert.expect(2);
17308
17309      var strings = lodashStable.map(['6', '08', '10'], Object),
17310          actual = lodashStable.map(strings, _.parseInt);
17311
17312      assert.deepEqual(actual, [6, 8, 10]);
17313
17314      actual = lodashStable.map('123', _.parseInt);
17315      assert.deepEqual(actual, [1, 2, 3]);
17316    });
17317  }());
17318
17319  /*--------------------------------------------------------------------------*/
17320
17321  QUnit.module('partial methods');
17322
17323  lodashStable.each(['partial', 'partialRight'], function(methodName) {
17324    var func = _[methodName],
17325        isPartial = methodName == 'partial',
17326        ph = func.placeholder;
17327
17328    QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
17329      assert.expect(1);
17330
17331      var par = func(identity, 'a');
17332      assert.strictEqual(par(), 'a');
17333    });
17334
17335    QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
17336      assert.expect(1);
17337
17338      var fn = function(a, b) { return [a, b]; },
17339          par = func(fn, 'a'),
17340          expected = isPartial ? ['a', 'b'] : ['b', 'a'];
17341
17342      assert.deepEqual(par('b'), expected);
17343    });
17344
17345    QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
17346      assert.expect(1);
17347
17348      var fn = function() { return arguments.length; },
17349          par = func(fn);
17350
17351      assert.strictEqual(par(), 0);
17352    });
17353
17354    QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
17355      assert.expect(1);
17356
17357      var par = func(identity);
17358      assert.strictEqual(par('a'), 'a');
17359    });
17360
17361    QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
17362      assert.expect(4);
17363
17364      var fn = function() { return slice.call(arguments); },
17365          par = func(fn, ph, 'b', ph);
17366
17367      assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
17368      assert.deepEqual(par('a'), ['a', 'b', undefined]);
17369      assert.deepEqual(par(), [undefined, 'b', undefined]);
17370
17371      if (isPartial) {
17372        assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
17373      } else {
17374        par = func(fn, ph, 'c', ph);
17375        assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
17376      }
17377    });
17378
17379    QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
17380      assert.expect(1);
17381
17382      if (!isModularize) {
17383        var _ph = _.placeholder = {},
17384            fn = function() { return slice.call(arguments); },
17385            par = func(fn, _ph, 'b', ph),
17386            expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
17387
17388        assert.deepEqual(par('a', 'c'), expected);
17389        delete _.placeholder;
17390      }
17391      else {
17392        skipAssert(assert);
17393      }
17394    });
17395
17396    QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
17397      assert.expect(1);
17398
17399      var fn = function(a, b, c) {},
17400          par = func(fn, 'a');
17401
17402      assert.strictEqual(par.length, 0);
17403    });
17404
17405    QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
17406      assert.expect(2);
17407
17408      function Foo(value) {
17409        return value && object;
17410      }
17411
17412      var object = {},
17413          par = func(Foo);
17414
17415      assert.ok(new par instanceof Foo);
17416      assert.strictEqual(new par(true), object);
17417    });
17418
17419    QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
17420      assert.expect(3);
17421
17422      function greet(greeting, name) {
17423        return greeting + ' ' + name;
17424      }
17425
17426      var par1 = func(greet, 'hi'),
17427          par2 = func(par1, 'barney'),
17428          par3 = func(par1, 'pebbles');
17429
17430      assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
17431      assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
17432      assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
17433    });
17434
17435    QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
17436      assert.expect(2);
17437
17438      var fn = function(a, b, c) { return a + b + c; },
17439          curried = _.curry(func(fn, 1), 2);
17440
17441      assert.strictEqual(curried(2, 3), 6);
17442      assert.strictEqual(curried(2)(3), 6);
17443    });
17444
17445    QUnit.test('should work with placeholders and curried functions', function(assert) {
17446      assert.expect(1);
17447
17448      var fn = function() { return slice.call(arguments); },
17449          curried = _.curry(fn),
17450          par = func(curried, ph, 'b', ph, 'd');
17451
17452      assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
17453    });
17454  });
17455
17456  /*--------------------------------------------------------------------------*/
17457
17458  QUnit.module('lodash.partialRight');
17459
17460  (function() {
17461    QUnit.test('should work as a deep `_.defaults`', function(assert) {
17462      assert.expect(1);
17463
17464      var object = { 'a': { 'b': 2 } },
17465          source = { 'a': { 'b': 3, 'c': 3 } },
17466          expected = { 'a': { 'b': 2, 'c': 3 } };
17467
17468      var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
17469        return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
17470      });
17471
17472      assert.deepEqual(defaultsDeep(object, source), expected);
17473    });
17474  }());
17475
17476  /*--------------------------------------------------------------------------*/
17477
17478  QUnit.module('methods using `createWrapper`');
17479
17480  (function() {
17481    function fn() {
17482      return slice.call(arguments);
17483    }
17484
17485    var ph1 = _.bind.placeholder,
17486        ph2 = _.bindKey.placeholder,
17487        ph3 = _.partial.placeholder,
17488        ph4 = _.partialRight.placeholder;
17489
17490    QUnit.test('should work with combinations of partial functions', function(assert) {
17491      assert.expect(1);
17492
17493      var a = _.partial(fn),
17494          b = _.partialRight(a, 3),
17495          c = _.partial(b, 1);
17496
17497      assert.deepEqual(c(2), [1, 2, 3]);
17498    });
17499
17500    QUnit.test('should work with combinations of bound and partial functions', function(assert) {
17501      assert.expect(3);
17502
17503      var fn = function() {
17504        var result = [this.a];
17505        push.apply(result, arguments);
17506        return result;
17507      };
17508
17509      var expected = [1, 2, 3, 4],
17510          object = { 'a': 1, 'fn': fn };
17511
17512      var a = _.bindKey(object, 'fn'),
17513          b = _.partialRight(a, 4),
17514          c = _.partial(b, 2);
17515
17516      assert.deepEqual(c(3), expected);
17517
17518      a = _.bind(fn, object);
17519      b = _.partialRight(a, 4);
17520      c = _.partial(b, 2);
17521
17522      assert.deepEqual(c(3), expected);
17523
17524      a = _.partial(fn, 2);
17525      b = _.bind(a, object);
17526      c = _.partialRight(b, 4);
17527
17528      assert.deepEqual(c(3), expected);
17529    });
17530
17531    QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
17532      assert.expect(2);
17533
17534      function Foo(a, b, c) {
17535        return b === 0 && object;
17536      }
17537
17538      var combo = _.partial(_.partialRight(Foo, 3), 1),
17539          object = {};
17540
17541      assert.ok(new combo(2) instanceof Foo);
17542      assert.strictEqual(new combo(0), object);
17543    });
17544
17545    QUnit.test('should work with combinations of functions with placeholders', function(assert) {
17546      assert.expect(3);
17547
17548      var expected = [1, 2, 3, 4, 5, 6],
17549          object = { 'fn': fn };
17550
17551      var a = _.bindKey(object, 'fn', ph2, 2),
17552          b = _.partialRight(a, ph4, 6),
17553          c = _.partial(b, 1, ph3, 4);
17554
17555      assert.deepEqual(c(3, 5), expected);
17556
17557      a = _.bind(fn, object, ph1, 2);
17558      b = _.partialRight(a, ph4, 6);
17559      c = _.partial(b, 1, ph3, 4);
17560
17561      assert.deepEqual(c(3, 5), expected);
17562
17563      a = _.partial(fn, ph3, 2);
17564      b = _.bind(a, object, 1, ph1, 4);
17565      c = _.partialRight(b, ph4, 6);
17566
17567      assert.deepEqual(c(3, 5), expected);
17568    });
17569
17570    QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
17571      assert.expect(3);
17572
17573      var expected = [1, 2, 3, 4],
17574          object = { 'fn': fn };
17575
17576      var a = _.bindKey(object, 'fn', ph2, 2),
17577          b = _.partialRight(a, ph4, 4),
17578          c = _.partial(b, ph3, 3);
17579
17580      assert.deepEqual(c(1), expected);
17581
17582      a = _.bind(fn, object, ph1, 2);
17583      b = _.partialRight(a, ph4, 4);
17584      c = _.partial(b, ph3, 3);
17585
17586      assert.deepEqual(c(1), expected);
17587
17588      a = _.partial(fn, ph3, 2);
17589      b = _.bind(a, object, ph1, 3);
17590      c = _.partialRight(b, ph4, 4);
17591
17592      assert.deepEqual(c(1), expected);
17593    });
17594
17595    QUnit.test('should work with recursively bound functions', function(assert) {
17596      assert.expect(1);
17597
17598      var fn = function() {
17599        return this.a;
17600      };
17601
17602      var a = _.bind(fn, { 'a': 1 }),
17603          b = _.bind(a,  { 'a': 2 }),
17604          c = _.bind(b,  { 'a': 3 });
17605
17606      assert.strictEqual(c(), 1);
17607    });
17608
17609    QUnit.test('should work when hot', function(assert) {
17610      assert.expect(12);
17611
17612      lodashStable.times(2, function(index) {
17613        var fn = function() {
17614          var result = [this];
17615          push.apply(result, arguments);
17616          return result;
17617        };
17618
17619        var object = {},
17620            bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17621            expected = [object, 1, 2, 3];
17622
17623        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17624          var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17625          return index ? bound2(3) : bound2(1, 2, 3);
17626        }));
17627
17628        assert.deepEqual(actual, expected);
17629
17630        actual = _.last(lodashStable.times(HOT_COUNT, function() {
17631          var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17632              bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17633
17634          return index ? bound2(3) : bound2(1, 2, 3);
17635        }));
17636
17637        assert.deepEqual(actual, expected);
17638      });
17639
17640      lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
17641        var fn = function(a, b, c) { return [a, b, c]; },
17642            curried = _[methodName](fn),
17643            expected = index ? [3, 2, 1] :  [1, 2, 3];
17644
17645        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17646          return curried(1)(2)(3);
17647        }));
17648
17649        assert.deepEqual(actual, expected);
17650
17651        actual = _.last(lodashStable.times(HOT_COUNT, function() {
17652          var curried = _[methodName](fn);
17653          return curried(1)(2)(3);
17654        }));
17655
17656        assert.deepEqual(actual, expected);
17657      });
17658
17659      lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
17660        var func = _[methodName],
17661            fn = function() { return slice.call(arguments); },
17662            par1 = func(fn, 1),
17663            expected = index ? [3, 2, 1] : [1, 2, 3];
17664
17665        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17666          var par2 = func(par1, 2);
17667          return par2(3);
17668        }));
17669
17670        assert.deepEqual(actual, expected);
17671
17672        actual = _.last(lodashStable.times(HOT_COUNT, function() {
17673          var par1 = func(fn, 1),
17674              par2 = func(par1, 2);
17675
17676          return par2(3);
17677        }));
17678
17679        assert.deepEqual(actual, expected);
17680      });
17681    });
17682  }());
17683
17684  /*--------------------------------------------------------------------------*/
17685
17686  QUnit.module('lodash.partition');
17687
17688  (function() {
17689    var array = [1, 0, 1];
17690
17691    QUnit.test('should split elements into two groups by `predicate`', function(assert) {
17692      assert.expect(3);
17693
17694      assert.deepEqual(_.partition([], identity), [[], []]);
17695      assert.deepEqual(_.partition(array, stubTrue), [array, []]);
17696      assert.deepEqual(_.partition(array, stubFalse), [[], array]);
17697    });
17698
17699    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17700      assert.expect(1);
17701
17702      var values = [, null, undefined],
17703          expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
17704
17705      var actual = lodashStable.map(values, function(value, index) {
17706        return index ? _.partition(array, value) : _.partition(array);
17707      });
17708
17709      assert.deepEqual(actual, expected);
17710    });
17711
17712    QUnit.test('should work with `_.property` shorthands', function(assert) {
17713      assert.expect(1);
17714
17715      var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
17716          actual = _.partition(objects, 'a');
17717
17718      assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
17719    });
17720
17721    QUnit.test('should work with a number for `predicate`', function(assert) {
17722      assert.expect(2);
17723
17724      var array = [
17725        [1, 0],
17726        [0, 1],
17727        [1, 0]
17728      ];
17729
17730      assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
17731      assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
17732    });
17733
17734    QUnit.test('should work with an object for `collection`', function(assert) {
17735      assert.expect(1);
17736
17737      var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
17738      assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
17739    });
17740  }());
17741
17742  /*--------------------------------------------------------------------------*/
17743
17744  QUnit.module('lodash.pick');
17745
17746  (function() {
17747    var args = toArgs(['a', 'c']),
17748        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17749        nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } };
17750
17751    QUnit.test('should flatten `paths`', function(assert) {
17752      assert.expect(2);
17753
17754      assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
17755      assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
17756    });
17757
17758    QUnit.test('should support deep paths', function(assert) {
17759      assert.expect(1);
17760
17761      assert.deepEqual(_.pick(nested, 'b.c'), { 'b': { 'c': 2 } });
17762    });
17763
17764    QUnit.test('should support path arrays', function(assert) {
17765      assert.expect(1);
17766
17767      var object = { 'a.b': 1, 'a': { 'b': 2 } },
17768          actual = _.pick(object, [['a.b']]);
17769
17770      assert.deepEqual(actual, { 'a.b': 1 });
17771    });
17772
17773    QUnit.test('should pick a key over a path', function(assert) {
17774      assert.expect(2);
17775
17776      var object = { 'a.b': 1, 'a': { 'b': 2 } };
17777
17778      lodashStable.each(['a.b', ['a.b']], function(path) {
17779        assert.deepEqual(_.pick(object, path), { 'a.b': 1 });
17780      });
17781    });
17782
17783    QUnit.test('should coerce `paths` to strings', function(assert) {
17784      assert.expect(1);
17785
17786      assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
17787    });
17788
17789    QUnit.test('should return an empty object when `object` is nullish', function(assert) {
17790      assert.expect(2);
17791
17792      lodashStable.each([null, undefined], function(value) {
17793        assert.deepEqual(_.pick(value, 'valueOf'), {});
17794      });
17795    });
17796
17797    QUnit.test('should work with a primitive `object`', function(assert) {
17798      assert.expect(1);
17799
17800      assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
17801    });
17802
17803    QUnit.test('should work with `arguments` object `paths`', function(assert) {
17804      assert.expect(1);
17805
17806      assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
17807    });
17808  }());
17809
17810  /*--------------------------------------------------------------------------*/
17811
17812  QUnit.module('lodash.pickBy');
17813
17814  (function() {
17815    QUnit.test('should work with a predicate argument', function(assert) {
17816      assert.expect(1);
17817
17818      var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17819
17820      var actual = _.pickBy(object, function(n) {
17821        return n == 1 || n == 3;
17822      });
17823
17824      assert.deepEqual(actual, { 'a': 1, 'c': 3 });
17825    });
17826
17827    QUnit.test('should not treat keys with dots as deep paths', function(assert) {
17828      assert.expect(1);
17829
17830      var object = { 'a.b.c': 1 },
17831          actual = _.pickBy(object, stubTrue);
17832
17833      assert.deepEqual(actual, { 'a.b.c': 1 });
17834    });
17835  }());
17836
17837  /*--------------------------------------------------------------------------*/
17838
17839  QUnit.module('pick methods');
17840
17841  lodashStable.each(['pick', 'pickBy'], function(methodName) {
17842    var expected = { 'a': 1, 'c': 3 },
17843        func = _[methodName],
17844        isPick = methodName == 'pick',
17845        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17846        resolve = lodashStable.nthArg(1);
17847
17848    if (methodName == 'pickBy') {
17849      resolve = function(object, props) {
17850        props = lodashStable.castArray(props);
17851        return function(value) {
17852          return lodashStable.some(props, function(key) {
17853            key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
17854            return object[key] === value;
17855          });
17856        };
17857      };
17858    }
17859    QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
17860      assert.expect(2);
17861
17862      assert.deepEqual(func(object, resolve(object, 'a')), { 'a': 1 });
17863      assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected);
17864    });
17865
17866    QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
17867      assert.expect(1);
17868
17869      function Foo() {}
17870      Foo.prototype = object;
17871
17872      var foo = new Foo;
17873      assert.deepEqual(func(foo, resolve(foo, ['a', 'c'])), expected);
17874    });
17875
17876    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
17877      assert.expect(1);
17878
17879      var object = { '-0': 'a', '0': 'b' },
17880          props = [-0, Object(-0), 0, Object(0)],
17881          expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
17882
17883      var actual = lodashStable.map(props, function(key) {
17884        return func(object, resolve(object, key));
17885      });
17886
17887      assert.deepEqual(actual, expected);
17888    });
17889
17890    QUnit.test('`_.' + methodName + '` should pick symbols', function(assert) {
17891      assert.expect(3);
17892
17893      function Foo() {
17894        this[symbol] = 1;
17895      }
17896
17897      if (Symbol) {
17898        var symbol2 = Symbol('b');
17899        Foo.prototype[symbol2] = 2;
17900
17901        var symbol3 = Symbol('c');
17902        defineProperty(Foo.prototype, symbol3, {
17903          'configurable': true,
17904          'enumerable': false,
17905          'writable': true,
17906          'value': 3
17907        });
17908
17909        var foo = new Foo,
17910            actual = func(foo, resolve(foo, [symbol, symbol2, symbol3]));
17911
17912        assert.strictEqual(actual[symbol], 1);
17913        assert.strictEqual(actual[symbol2], 2);
17914
17915        if (isPick) {
17916          assert.strictEqual(actual[symbol3], 3);
17917        } else {
17918          assert.notOk(symbol3 in actual);
17919        }
17920      }
17921      else {
17922        skipAssert(assert, 3);
17923      }
17924    });
17925
17926    QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) {
17927      assert.expect(1);
17928
17929      var array = [1, 2, 3];
17930      assert.deepEqual(func(array, resolve(array, '1')), { '1': 2 });
17931    });
17932  });
17933
17934  /*--------------------------------------------------------------------------*/
17935
17936  QUnit.module('lodash.property');
17937
17938  (function() {
17939    QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
17940      assert.expect(4);
17941
17942      var object = { 'a': 1 };
17943
17944      lodashStable.each(['a', ['a']], function(path) {
17945        var prop = _.property(path);
17946        assert.strictEqual(prop.length, 1);
17947        assert.strictEqual(prop(object), 1);
17948      });
17949    });
17950
17951    QUnit.test('should pluck deep property values', function(assert) {
17952      assert.expect(2);
17953
17954      var object = { 'a': { 'b': 2 } };
17955
17956      lodashStable.each(['a.b', ['a', 'b']], function(path) {
17957        var prop = _.property(path);
17958        assert.strictEqual(prop(object), 2);
17959      });
17960    });
17961
17962    QUnit.test('should pluck inherited property values', function(assert) {
17963      assert.expect(2);
17964
17965      function Foo() {}
17966      Foo.prototype.a = 1;
17967
17968      lodashStable.each(['a', ['a']], function(path) {
17969        var prop = _.property(path);
17970        assert.strictEqual(prop(new Foo), 1);
17971      });
17972    });
17973
17974    QUnit.test('should work with a non-string `path`', function(assert) {
17975      assert.expect(2);
17976
17977      var array = [1, 2, 3];
17978
17979      lodashStable.each([1, [1]], function(path) {
17980        var prop = _.property(path);
17981        assert.strictEqual(prop(array), 2);
17982      });
17983    });
17984
17985    QUnit.test('should preserve the sign of `0`', function(assert) {
17986      assert.expect(1);
17987
17988      var object = { '-0': 'a', '0': 'b' },
17989          props = [-0, Object(-0), 0, Object(0)];
17990
17991      var actual = lodashStable.map(props, function(key) {
17992        var prop = _.property(key);
17993        return prop(object);
17994      });
17995
17996      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17997    });
17998
17999    QUnit.test('should coerce `path` to a string', function(assert) {
18000      assert.expect(2);
18001
18002      function fn() {}
18003      fn.toString = lodashStable.constant('fn');
18004
18005      var expected = [1, 2, 3, 4],
18006          object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
18007          paths = [null, undefined, fn, {}];
18008
18009      lodashStable.times(2, function(index) {
18010        var actual = lodashStable.map(paths, function(path) {
18011          var prop = _.property(index ? [path] : path);
18012          return prop(object);
18013        });
18014
18015        assert.deepEqual(actual, expected);
18016      });
18017    });
18018
18019    QUnit.test('should pluck a key over a path', function(assert) {
18020      assert.expect(2);
18021
18022      var object = { 'a.b': 1, 'a': { 'b': 2 } };
18023
18024      lodashStable.each(['a.b', ['a.b']], function(path) {
18025        var prop = _.property(path);
18026        assert.strictEqual(prop(object), 1);
18027      });
18028    });
18029
18030    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
18031      assert.expect(2);
18032
18033      var values = [, null, undefined],
18034          expected = lodashStable.map(values, noop);
18035
18036      lodashStable.each(['constructor', ['constructor']], function(path) {
18037        var prop = _.property(path);
18038
18039        var actual = lodashStable.map(values, function(value, index) {
18040          return index ? prop(value) : prop();
18041        });
18042
18043        assert.deepEqual(actual, expected);
18044      });
18045    });
18046
18047    QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
18048      assert.expect(2);
18049
18050      var values = [, null, undefined],
18051          expected = lodashStable.map(values, noop);
18052
18053      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
18054        var prop = _.property(path);
18055
18056        var actual = lodashStable.map(values, function(value, index) {
18057          return index ? prop(value) : prop();
18058        });
18059
18060        assert.deepEqual(actual, expected);
18061      });
18062    });
18063
18064    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
18065      assert.expect(4);
18066
18067      var object = {};
18068
18069      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
18070        var prop = _.property(path);
18071        assert.strictEqual(prop(object), undefined);
18072      });
18073    });
18074  }());
18075
18076  /*--------------------------------------------------------------------------*/
18077
18078  QUnit.module('lodash.propertyOf');
18079
18080  (function() {
18081    QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
18082      assert.expect(3);
18083
18084      var object = { 'a': 1 },
18085          propOf = _.propertyOf(object);
18086
18087      assert.strictEqual(propOf.length, 1);
18088      lodashStable.each(['a', ['a']], function(path) {
18089        assert.strictEqual(propOf(path), 1);
18090      });
18091    });
18092
18093    QUnit.test('should pluck deep property values', function(assert) {
18094      assert.expect(2);
18095
18096      var object = { 'a': { 'b': 2 } },
18097          propOf = _.propertyOf(object);
18098
18099      lodashStable.each(['a.b', ['a', 'b']], function(path) {
18100        assert.strictEqual(propOf(path), 2);
18101      });
18102    });
18103
18104    QUnit.test('should pluck inherited property values', function(assert) {
18105      assert.expect(2);
18106
18107      function Foo() {
18108        this.a = 1;
18109      }
18110      Foo.prototype.b = 2;
18111
18112      var propOf = _.propertyOf(new Foo);
18113
18114      lodashStable.each(['b', ['b']], function(path) {
18115        assert.strictEqual(propOf(path), 2);
18116      });
18117    });
18118
18119    QUnit.test('should work with a non-string `path`', function(assert) {
18120      assert.expect(2);
18121
18122      var array = [1, 2, 3],
18123          propOf = _.propertyOf(array);
18124
18125      lodashStable.each([1, [1]], function(path) {
18126        assert.strictEqual(propOf(path), 2);
18127      });
18128    });
18129
18130    QUnit.test('should preserve the sign of `0`', function(assert) {
18131      assert.expect(1);
18132
18133      var object = { '-0': 'a', '0': 'b' },
18134          props = [-0, Object(-0), 0, Object(0)];
18135
18136      var actual = lodashStable.map(props, function(key) {
18137        var propOf = _.propertyOf(object);
18138        return propOf(key);
18139      });
18140
18141      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
18142    });
18143
18144    QUnit.test('should coerce `path` to a string', function(assert) {
18145      assert.expect(2);
18146
18147      function fn() {}
18148      fn.toString = lodashStable.constant('fn');
18149
18150      var expected = [1, 2, 3, 4],
18151          object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 },
18152          paths = [null, undefined, fn, {}];
18153
18154      lodashStable.times(2, function(index) {
18155        var actual = lodashStable.map(paths, function(path) {
18156          var propOf = _.propertyOf(object);
18157          return propOf(index ? [path] : path);
18158        });
18159
18160        assert.deepEqual(actual, expected);
18161      });
18162    });
18163
18164    QUnit.test('should pluck a key over a path', function(assert) {
18165      assert.expect(2);
18166
18167      var object = { 'a.b': 1, 'a': { 'b': 2 } },
18168          propOf = _.propertyOf(object);
18169
18170      lodashStable.each(['a.b', ['a.b']], function(path) {
18171        assert.strictEqual(propOf(path), 1);
18172      });
18173    });
18174
18175    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
18176      assert.expect(2);
18177
18178      var values = [, null, undefined],
18179          expected = lodashStable.map(values, noop);
18180
18181      lodashStable.each(['constructor', ['constructor']], function(path) {
18182        var actual = lodashStable.map(values, function(value, index) {
18183          var propOf = index ? _.propertyOf(value) : _.propertyOf();
18184          return propOf(path);
18185        });
18186
18187        assert.deepEqual(actual, expected);
18188      });
18189    });
18190
18191    QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) {
18192      assert.expect(2);
18193
18194      var values = [, null, undefined],
18195          expected = lodashStable.map(values, noop);
18196
18197      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
18198        var actual = lodashStable.map(values, function(value, index) {
18199          var propOf = index ? _.propertyOf(value) : _.propertyOf();
18200          return propOf(path);
18201        });
18202
18203        assert.deepEqual(actual, expected);
18204      });
18205    });
18206
18207    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
18208      assert.expect(4);
18209
18210      var propOf = _.propertyOf({});
18211
18212      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
18213        assert.strictEqual(propOf(path), undefined);
18214      });
18215    });
18216  }());
18217
18218  /*--------------------------------------------------------------------------*/
18219
18220  QUnit.module('lodash.pullAll');
18221
18222  (function() {
18223    QUnit.test('should work with the same value for `array` and `values`', function(assert) {
18224      assert.expect(1);
18225
18226      var array = [{ 'a': 1 }, { 'b': 2 }],
18227          actual = _.pullAll(array, array);
18228
18229      assert.deepEqual(actual, []);
18230    });
18231  }());
18232
18233  /*--------------------------------------------------------------------------*/
18234
18235  QUnit.module('lodash.pullAllBy');
18236
18237  (function() {
18238    QUnit.test('should accept an `iteratee`', function(assert) {
18239      assert.expect(1);
18240
18241      var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18242
18243      var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
18244        return object.x;
18245      });
18246
18247      assert.deepEqual(actual, [{ 'x': 2 }]);
18248    });
18249
18250    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
18251      assert.expect(1);
18252
18253      var args,
18254          array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
18255
18256      _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
18257        args || (args = slice.call(arguments));
18258      });
18259
18260      assert.deepEqual(args, [{ 'x': 1 }]);
18261    });
18262  }());
18263
18264  /*--------------------------------------------------------------------------*/
18265
18266  QUnit.module('lodash.pullAllWith');
18267
18268  (function() {
18269    QUnit.test('should work with a `comparator`', function(assert) {
18270      assert.expect(1);
18271
18272      var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
18273          expected = [objects[0], objects[2]],
18274          actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
18275
18276      assert.deepEqual(actual, expected);
18277    });
18278  }());
18279
18280  /*--------------------------------------------------------------------------*/
18281
18282  QUnit.module('pull methods');
18283
18284  lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
18285    var func = _[methodName],
18286        isPull = methodName == 'pull';
18287
18288    function pull(array, values) {
18289      return isPull
18290        ? func.apply(undefined, [array].concat(values))
18291        : func(array, values);
18292    }
18293
18294    QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
18295      assert.expect(2);
18296
18297      var array = [1, 2, 3],
18298          actual = pull(array, [1, 3]);
18299
18300      assert.strictEqual(actual, array);
18301      assert.deepEqual(array, [2]);
18302    });
18303
18304    QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
18305      assert.expect(2);
18306
18307      var array = [1, 2, 3, 4];
18308      delete array[1];
18309      delete array[3];
18310
18311      pull(array, [1]);
18312      assert.notOk('0' in array);
18313      assert.notOk('2' in array);
18314    });
18315
18316    QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
18317      assert.expect(1);
18318
18319      var array = [1, 2, 3];
18320      delete array[1];
18321
18322      pull(array, [undefined]);
18323      assert.deepEqual(array, [1, 3]);
18324    });
18325
18326    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
18327      assert.expect(1);
18328
18329      var array = [1, NaN, 3, NaN];
18330
18331      pull(array, [NaN]);
18332      assert.deepEqual(array, [1, 3]);
18333    });
18334  });
18335
18336  /*--------------------------------------------------------------------------*/
18337
18338  QUnit.module('lodash.pullAt');
18339
18340  (function() {
18341    QUnit.test('should modify the array and return removed elements', function(assert) {
18342      assert.expect(2);
18343
18344      var array = [1, 2, 3],
18345          actual = _.pullAt(array, [0, 1]);
18346
18347      assert.deepEqual(array, [3]);
18348      assert.deepEqual(actual, [1, 2]);
18349    });
18350
18351    QUnit.test('should work with unsorted indexes', function(assert) {
18352      assert.expect(2);
18353
18354      var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
18355          actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
18356
18357      assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
18358      assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
18359    });
18360
18361    QUnit.test('should work with repeated indexes', function(assert) {
18362      assert.expect(2);
18363
18364      var array = [1, 2, 3, 4],
18365          actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
18366
18367      assert.deepEqual(array, [4]);
18368      assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
18369    });
18370
18371    QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18372      assert.expect(2);
18373
18374      var array = ['a', 'b', 'c'],
18375          actual = _.pullAt(array, [2, 4, 0]);
18376
18377      assert.deepEqual(array, ['b']);
18378      assert.deepEqual(actual, ['c', undefined, 'a']);
18379    });
18380
18381    QUnit.test('should flatten `indexes`', function(assert) {
18382      assert.expect(4);
18383
18384      var array = ['a', 'b', 'c'];
18385      assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
18386      assert.deepEqual(array, ['b']);
18387
18388      array = ['a', 'b', 'c', 'd'];
18389      assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
18390      assert.deepEqual(array, ['b']);
18391    });
18392
18393    QUnit.test('should return an empty array when no indexes are given', function(assert) {
18394      assert.expect(4);
18395
18396      var array = ['a', 'b', 'c'],
18397          actual = _.pullAt(array);
18398
18399      assert.deepEqual(array, ['a', 'b', 'c']);
18400      assert.deepEqual(actual, []);
18401
18402      actual = _.pullAt(array, [], []);
18403
18404      assert.deepEqual(array, ['a', 'b', 'c']);
18405      assert.deepEqual(actual, []);
18406    });
18407
18408    QUnit.test('should work with non-index paths', function(assert) {
18409      assert.expect(2);
18410
18411      var values = lodashStable.reject(empties, function(value) {
18412        return (value === 0) || lodashStable.isArray(value);
18413      }).concat(-1, 1.1);
18414
18415      var array = lodashStable.transform(values, function(result, value) {
18416        result[value] = 1;
18417      }, []);
18418
18419      var expected = lodashStable.map(values, stubOne),
18420          actual = _.pullAt(array, values);
18421
18422      assert.deepEqual(actual, expected);
18423
18424      expected = lodashStable.map(values, noop);
18425      actual = lodashStable.at(array, values);
18426
18427      assert.deepEqual(actual, expected);
18428    });
18429
18430    QUnit.test('should preserve the sign of `0`', function(assert) {
18431      assert.expect(1);
18432
18433      var props = [-0, Object(-0), 0, Object(0)];
18434
18435      var actual = lodashStable.map(props, function(key) {
18436        var array = [-1];
18437        array['-0'] = -2;
18438        return _.pullAt(array, key);
18439      });
18440
18441      assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
18442    });
18443
18444    QUnit.test('should support deep paths', function(assert) {
18445      assert.expect(3);
18446
18447      var array = [];
18448      array.a = { 'b': 2 };
18449
18450      var actual = _.pullAt(array, 'a.b');
18451
18452      assert.deepEqual(actual, [2]);
18453      assert.deepEqual(array.a, {});
18454
18455      try {
18456        actual = _.pullAt(array, 'a.b.c');
18457      } catch (e) {}
18458
18459      assert.deepEqual(actual, [undefined]);
18460    });
18461
18462    QUnit.test('should work with a falsey `array` when keys are given', function(assert) {
18463      assert.expect(1);
18464
18465      var values = falsey.slice(),
18466          expected = lodashStable.map(values, lodashStable.constant(Array(4)));
18467
18468      var actual = lodashStable.map(values, function(array) {
18469        try {
18470          return _.pullAt(array, 0, 1, 'pop', 'push');
18471        } catch (e) {}
18472      });
18473
18474      assert.deepEqual(actual, expected);
18475    });
18476  }());
18477
18478  /*--------------------------------------------------------------------------*/
18479
18480  QUnit.module('lodash.random');
18481
18482  (function() {
18483    var array = Array(1000);
18484
18485    QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
18486      assert.expect(1);
18487
18488      var actual = lodashStable.uniq(lodashStable.map(array, function() {
18489        return _.random();
18490      })).sort();
18491
18492      assert.deepEqual(actual, [0, 1]);
18493    });
18494
18495    QUnit.test('should support a `min` and `max`', function(assert) {
18496      assert.expect(1);
18497
18498      var min = 5,
18499          max = 10;
18500
18501      assert.ok(lodashStable.some(array, function() {
18502        var result = _.random(min, max);
18503        return result >= min && result <= max;
18504      }));
18505    });
18506
18507    QUnit.test('should support not providing a `max`', function(assert) {
18508      assert.expect(1);
18509
18510      var min = 0,
18511          max = 5;
18512
18513      assert.ok(lodashStable.some(array, function() {
18514        var result = _.random(max);
18515        return result >= min && result <= max;
18516      }));
18517    });
18518
18519    QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
18520      assert.expect(1);
18521
18522      var min = 4,
18523          max = 2,
18524          expected = [2, 3, 4];
18525
18526      var actual = lodashStable.uniq(lodashStable.map(array, function() {
18527        return _.random(min, max);
18528      })).sort();
18529
18530      assert.deepEqual(actual, expected);
18531    });
18532
18533    QUnit.test('should support large integer values', function(assert) {
18534      assert.expect(2);
18535
18536      var min = Math.pow(2, 31),
18537          max = Math.pow(2, 62);
18538
18539      assert.ok(lodashStable.every(array, function() {
18540        var result = _.random(min, max);
18541        return result >= min && result <= max;
18542      }));
18543
18544      assert.ok(lodashStable.some(array, function() {
18545        return _.random(MAX_INTEGER);
18546      }));
18547    });
18548
18549    QUnit.test('should coerce arguments to finite numbers', function(assert) {
18550      assert.expect(1);
18551
18552      var actual = [
18553        _.random(NaN, NaN),
18554        _.random('1', '1'),
18555        _.random(Infinity, Infinity)
18556      ];
18557
18558      assert.deepEqual(actual, [0, 1, MAX_INTEGER]);
18559    });
18560
18561    QUnit.test('should support floats', function(assert) {
18562      assert.expect(2);
18563
18564      var min = 1.5,
18565          max = 1.6,
18566          actual = _.random(min, max);
18567
18568      assert.ok(actual % 1);
18569      assert.ok(actual >= min && actual <= max);
18570    });
18571
18572    QUnit.test('should support providing a `floating`', function(assert) {
18573      assert.expect(3);
18574
18575      var actual = _.random(true);
18576      assert.ok(actual % 1 && actual >= 0 && actual <= 1);
18577
18578      actual = _.random(2, true);
18579      assert.ok(actual % 1 && actual >= 0 && actual <= 2);
18580
18581      actual = _.random(2, 4, true);
18582      assert.ok(actual % 1 && actual >= 2 && actual <= 4);
18583    });
18584
18585    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18586      assert.expect(1);
18587
18588      var array = [1, 2, 3],
18589          expected = lodashStable.map(array, stubTrue),
18590          randoms = lodashStable.map(array, _.random);
18591
18592      var actual = lodashStable.map(randoms, function(result, index) {
18593        return result >= 0 && result <= array[index] && (result % 1) == 0;
18594      });
18595
18596      assert.deepEqual(actual, expected);
18597    });
18598  }());
18599
18600  /*--------------------------------------------------------------------------*/
18601
18602  QUnit.module('range methods');
18603
18604  lodashStable.each(['range', 'rangeRight'], function(methodName) {
18605    var func = _[methodName],
18606        isRange = methodName == 'range';
18607
18608    function resolve(range) {
18609      return isRange ? range : range.reverse();
18610    }
18611
18612    QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
18613      assert.expect(2);
18614
18615      assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
18616      assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
18617    });
18618
18619    QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
18620      assert.expect(2);
18621
18622      assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
18623      assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
18624    });
18625
18626    QUnit.test('`_.' + methodName + '` should work with a `start`, `end`, and `step`', function(assert) {
18627      assert.expect(3);
18628
18629      assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18630      assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
18631      assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
18632    });
18633
18634    QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
18635      assert.expect(1);
18636
18637      assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
18638    });
18639
18640    QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
18641      assert.expect(1);
18642
18643      assert.deepEqual(func(1, 5, 20), [1]);
18644    });
18645
18646    QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
18647      assert.expect(2);
18648
18649      assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18650      assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
18651    });
18652
18653    QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
18654      assert.expect(1);
18655
18656      var actual = func(-0, 1);
18657      assert.strictEqual(1 / actual[0], -Infinity);
18658    });
18659
18660    QUnit.test('`_.' + methodName + '` should treat falsey `start` as `0`', function(assert) {
18661      assert.expect(13);
18662
18663      lodashStable.each(falsey, function(value, index) {
18664        if (index) {
18665          assert.deepEqual(func(value), []);
18666          assert.deepEqual(func(value, 1), [0]);
18667        } else {
18668          assert.deepEqual(func(), []);
18669        }
18670      });
18671    });
18672
18673    QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
18674      assert.expect(1);
18675
18676      var actual = [
18677        func('1'),
18678        func('0', 1),
18679        func(0, 1, '1'),
18680        func(NaN),
18681        func(NaN, NaN)
18682      ];
18683
18684      assert.deepEqual(actual, [[0], [0], [0], [], []]);
18685    });
18686
18687    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
18688      assert.expect(2);
18689
18690      var array = [1, 2, 3],
18691          object = { 'a': 1, 'b': 2, 'c': 3 },
18692          expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
18693
18694      lodashStable.each([array, object], function(collection) {
18695        var actual = lodashStable.map(collection, func);
18696        assert.deepEqual(actual, expected);
18697      });
18698    });
18699  });
18700
18701  /*--------------------------------------------------------------------------*/
18702
18703  QUnit.module('lodash.rearg');
18704
18705  (function() {
18706    function fn() {
18707      return slice.call(arguments);
18708    }
18709
18710    QUnit.test('should reorder arguments provided to `func`', function(assert) {
18711      assert.expect(1);
18712
18713      var rearged = _.rearg(fn, [2, 0, 1]);
18714      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18715    });
18716
18717    QUnit.test('should work with repeated indexes', function(assert) {
18718      assert.expect(1);
18719
18720      var rearged = _.rearg(fn, [1, 1, 1]);
18721      assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
18722    });
18723
18724    QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18725      assert.expect(1);
18726
18727      var rearged = _.rearg(fn, [1, 4]);
18728      assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
18729    });
18730
18731    QUnit.test('should use `undefined` for non-index values', function(assert) {
18732      assert.expect(1);
18733
18734      var values = lodashStable.reject(empties, function(value) {
18735        return (value === 0) || lodashStable.isArray(value);
18736      }).concat(-1, 1.1);
18737
18738      var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
18739
18740      var actual = lodashStable.map(values, function(value) {
18741        var rearged = _.rearg(fn, [value]);
18742        return rearged('a', 'b', 'c');
18743      });
18744
18745      assert.deepEqual(actual, expected);
18746    });
18747
18748    QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
18749      assert.expect(2);
18750
18751      var rearged = _.rearg(fn);
18752      assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18753
18754      rearged = _.rearg(fn, [], []);
18755      assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18756    });
18757
18758    QUnit.test('should accept multiple index arguments', function(assert) {
18759      assert.expect(1);
18760
18761      var rearged = _.rearg(fn, 2, 0, 1);
18762      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18763    });
18764
18765    QUnit.test('should accept multiple arrays of indexes', function(assert) {
18766      assert.expect(1);
18767
18768      var rearged = _.rearg(fn, [2], [0, 1]);
18769      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18770    });
18771
18772    QUnit.test('should work with fewer indexes than arguments', function(assert) {
18773      assert.expect(1);
18774
18775      var rearged = _.rearg(fn, [1, 0]);
18776      assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
18777    });
18778
18779    QUnit.test('should work on functions that have been rearged', function(assert) {
18780      assert.expect(1);
18781
18782      var rearged1 = _.rearg(fn, 2, 1, 0),
18783          rearged2 = _.rearg(rearged1, 1, 0, 2);
18784
18785      assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
18786    });
18787  }());
18788
18789  /*--------------------------------------------------------------------------*/
18790
18791  QUnit.module('lodash.reduce');
18792
18793  (function() {
18794    var array = [1, 2, 3];
18795
18796    QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
18797      assert.expect(1);
18798
18799      assert.strictEqual(_.reduce(array), 1);
18800    });
18801
18802    QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) {
18803      assert.expect(2);
18804
18805      var args;
18806
18807      _.reduce(array, function() {
18808        args || (args = slice.call(arguments));
18809      }, 0);
18810
18811      assert.deepEqual(args, [0, 1, 0, array]);
18812
18813      args = undefined;
18814      _.reduce(array, function() {
18815        args || (args = slice.call(arguments));
18816      });
18817
18818      assert.deepEqual(args, [1, 2, 1, array]);
18819    });
18820
18821    QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) {
18822      assert.expect(2);
18823
18824      var args,
18825          object = { 'a': 1, 'b': 2 },
18826          firstKey = _.head(_.keys(object));
18827
18828      var expected = firstKey == 'a'
18829        ? [0, 1, 'a', object]
18830        : [0, 2, 'b', object];
18831
18832      _.reduce(object, function() {
18833        args || (args = slice.call(arguments));
18834      }, 0);
18835
18836      assert.deepEqual(args, expected);
18837
18838      args = undefined;
18839      expected = firstKey == 'a'
18840        ? [1, 2, 'b', object]
18841        : [2, 1, 'a', object];
18842
18843      _.reduce(object, function() {
18844        args || (args = slice.call(arguments));
18845      });
18846
18847      assert.deepEqual(args, expected);
18848    });
18849  }());
18850
18851  /*--------------------------------------------------------------------------*/
18852
18853  QUnit.module('lodash.reduceRight');
18854
18855  (function() {
18856    var array = [1, 2, 3];
18857
18858    QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
18859      assert.expect(1);
18860
18861      assert.strictEqual(_.reduceRight(array), 3);
18862    });
18863
18864    QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) {
18865      assert.expect(2);
18866
18867      var args;
18868
18869      _.reduceRight(array, function() {
18870        args || (args = slice.call(arguments));
18871      }, 0);
18872
18873      assert.deepEqual(args, [0, 3, 2, array]);
18874
18875      args = undefined;
18876      _.reduceRight(array, function() {
18877        args || (args = slice.call(arguments));
18878      });
18879
18880      assert.deepEqual(args, [3, 2, 1, array]);
18881    });
18882
18883    QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) {
18884      assert.expect(2);
18885
18886      var args,
18887          object = { 'a': 1, 'b': 2 },
18888          isFIFO = lodashStable.keys(object)[0] == 'a';
18889
18890      var expected = isFIFO
18891        ? [0, 2, 'b', object]
18892        : [0, 1, 'a', object];
18893
18894      _.reduceRight(object, function() {
18895        args || (args = slice.call(arguments));
18896      }, 0);
18897
18898      assert.deepEqual(args, expected);
18899
18900      args = undefined;
18901      expected = isFIFO
18902        ? [2, 1, 'a', object]
18903        : [1, 2, 'b', object];
18904
18905      _.reduceRight(object, function() {
18906        args || (args = slice.call(arguments));
18907      });
18908
18909      assert.deepEqual(args, expected);
18910    });
18911  }());
18912
18913  /*--------------------------------------------------------------------------*/
18914
18915  QUnit.module('reduce methods');
18916
18917  lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
18918    var func = _[methodName],
18919        array = [1, 2, 3],
18920        isReduce = methodName == 'reduce';
18921
18922    QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
18923      assert.expect(1);
18924
18925      var actual = func(['a', 'b', 'c'], function(accumulator, value) {
18926        return accumulator + value;
18927      }, '');
18928
18929      assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
18930    });
18931
18932    QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
18933      assert.expect(1);
18934
18935      var actual = [],
18936          expected = lodashStable.map(empties, noop);
18937
18938      lodashStable.each(empties, function(value) {
18939        try {
18940          actual.push(func(value, noop));
18941        } catch (e) {}
18942      });
18943
18944      assert.deepEqual(actual, expected);
18945    });
18946
18947    QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
18948      assert.expect(1);
18949
18950      var expected = lodashStable.map(empties, lodashStable.constant('x'));
18951
18952      var actual = lodashStable.map(empties, function(value) {
18953        try {
18954          return func(value, noop, 'x');
18955        } catch (e) {}
18956      });
18957
18958      assert.deepEqual(actual, expected);
18959    });
18960
18961    QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
18962      assert.expect(1);
18963
18964      var actual = func([], noop, undefined);
18965      assert.strictEqual(actual, undefined);
18966    });
18967
18968    QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
18969      assert.expect(2);
18970
18971      var array = [],
18972          object = { '0': 1, 'length': 0 };
18973
18974      if ('__proto__' in array) {
18975        array.__proto__ = object;
18976        assert.strictEqual(func(array, noop), undefined);
18977      }
18978      else {
18979        skipAssert(assert);
18980      }
18981      assert.strictEqual(func(object, noop), undefined);
18982    });
18983
18984    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
18985      assert.expect(1);
18986
18987      if (!isNpm) {
18988        assert.strictEqual(_(array)[methodName](add), 6);
18989      }
18990      else {
18991        skipAssert(assert);
18992      }
18993    });
18994
18995    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
18996      assert.expect(1);
18997
18998      if (!isNpm) {
18999        assert.ok(_(array).chain()[methodName](add) instanceof _);
19000      }
19001      else {
19002        skipAssert(assert);
19003      }
19004    });
19005  });
19006
19007  /*--------------------------------------------------------------------------*/
19008
19009  QUnit.module('lodash.reject');
19010
19011  (function() {
19012    var array = [1, 2, 3];
19013
19014    QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
19015      assert.expect(1);
19016
19017      assert.deepEqual(_.reject(array, isEven), [1, 3]);
19018    });
19019  }());
19020
19021  /*--------------------------------------------------------------------------*/
19022
19023  QUnit.module('filter methods');
19024
19025  lodashStable.each(['filter', 'reject'], function(methodName) {
19026    var array = [1, 2, 3, 4],
19027        func = _[methodName],
19028        isFilter = methodName == 'filter',
19029        objects = [{ 'a': 0 }, { 'a': 1 }];
19030
19031    QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
19032      assert.expect(1);
19033
19034      var actual = func([0], function(value, index, array) {
19035        array[index] = 1;
19036        return isFilter;
19037      });
19038
19039      assert.deepEqual(actual, [0]);
19040    });
19041
19042    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
19043      assert.expect(1);
19044
19045      assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
19046    });
19047
19048    QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
19049      assert.expect(1);
19050
19051      assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
19052    });
19053
19054    QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
19055      assert.expect(2);
19056
19057      if (!isNpm) {
19058        var wrapped = _(array);
19059
19060        var actual = wrapped[methodName](function(n) {
19061          return n < 3;
19062        });
19063
19064        assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
19065
19066        actual = wrapped[methodName](function(n) {
19067          return n > 2;
19068        });
19069
19070        assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
19071      }
19072      else {
19073        skipAssert(assert, 2);
19074      }
19075    });
19076
19077    QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
19078      assert.expect(2);
19079
19080      if (!isNpm) {
19081        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19082            predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); };
19083
19084        var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
19085          return ['key' + index, index];
19086        }));
19087
19088        var actual = _(array).slice(1).map(square)[methodName](predicate).value();
19089        assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
19090
19091        actual = _(object).mapValues(square)[methodName](predicate).value();
19092        assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
19093      }
19094      else {
19095        skipAssert(assert, 2);
19096      }
19097    });
19098
19099    QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments in a lazy sequence', function(assert) {
19100      assert.expect(5);
19101
19102      if (!isNpm) {
19103        var args,
19104            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
19105            expected = [1, 0, lodashStable.map(array.slice(1), square)];
19106
19107        _(array).slice(1)[methodName](function(value, index, array) {
19108          args || (args = slice.call(arguments));
19109        }).value();
19110
19111        assert.deepEqual(args, [1, 0, array.slice(1)]);
19112
19113        args = undefined;
19114        _(array).slice(1).map(square)[methodName](function(value, index, array) {
19115          args || (args = slice.call(arguments));
19116        }).value();
19117
19118        assert.deepEqual(args, expected);
19119
19120        args = undefined;
19121        _(array).slice(1).map(square)[methodName](function(value, index) {
19122          args || (args = slice.call(arguments));
19123        }).value();
19124
19125        assert.deepEqual(args, expected);
19126
19127        args = undefined;
19128        _(array).slice(1).map(square)[methodName](function(value) {
19129          args || (args = slice.call(arguments));
19130        }).value();
19131
19132        assert.deepEqual(args, [1]);
19133
19134        args = undefined;
19135        _(array).slice(1).map(square)[methodName](function() {
19136          args || (args = slice.call(arguments));
19137        }).value();
19138
19139        assert.deepEqual(args, expected);
19140      }
19141      else {
19142        skipAssert(assert, 5);
19143      }
19144    });
19145  });
19146
19147  /*--------------------------------------------------------------------------*/
19148
19149  QUnit.module('lodash.remove');
19150
19151  (function() {
19152    QUnit.test('should modify the array and return removed elements', function(assert) {
19153      assert.expect(2);
19154
19155      var array = [1, 2, 3, 4],
19156          actual = _.remove(array, isEven);
19157
19158      assert.deepEqual(array, [1, 3]);
19159      assert.deepEqual(actual, [2, 4]);
19160    });
19161
19162    QUnit.test('should provide correct `predicate` arguments', function(assert) {
19163      assert.expect(1);
19164
19165      var argsList = [],
19166          array = [1, 2, 3],
19167          clone = array.slice();
19168
19169      _.remove(array, function(n, index) {
19170        var args = slice.call(arguments);
19171        args[2] = args[2].slice();
19172        argsList.push(args);
19173        return isEven(index);
19174      });
19175
19176      assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
19177    });
19178
19179    QUnit.test('should work with `_.matches` shorthands', function(assert) {
19180      assert.expect(1);
19181
19182      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19183      _.remove(objects, { 'a': 1 });
19184      assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19185    });
19186
19187    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
19188      assert.expect(1);
19189
19190      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
19191      _.remove(objects, ['a', 1]);
19192      assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
19193    });
19194
19195    QUnit.test('should work with `_.property` shorthands', function(assert) {
19196      assert.expect(1);
19197
19198      var objects = [{ 'a': 0 }, { 'a': 1 }];
19199      _.remove(objects, 'a');
19200      assert.deepEqual(objects, [{ 'a': 0 }]);
19201    });
19202
19203    QUnit.test('should preserve holes in arrays', function(assert) {
19204      assert.expect(2);
19205
19206      var array = [1, 2, 3, 4];
19207      delete array[1];
19208      delete array[3];
19209
19210      _.remove(array, function(n) {
19211        return n === 1;
19212      });
19213
19214      assert.notOk('0' in array);
19215      assert.notOk('2' in array);
19216    });
19217
19218    QUnit.test('should treat holes as `undefined`', function(assert) {
19219      assert.expect(1);
19220
19221      var array = [1, 2, 3];
19222      delete array[1];
19223
19224      _.remove(array, function(n) {
19225        return n == null;
19226      });
19227
19228      assert.deepEqual(array, [1, 3]);
19229    });
19230
19231    QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
19232      assert.expect(1);
19233
19234      var array = [1, 2, 3];
19235
19236      _.remove(array, function(n, index) {
19237        return isEven(index);
19238      });
19239
19240      assert.deepEqual(array, [2]);
19241    });
19242  }());
19243
19244  /*--------------------------------------------------------------------------*/
19245
19246  QUnit.module('lodash.repeat');
19247
19248  (function() {
19249    var string = 'abc';
19250
19251    QUnit.test('should repeat a string `n` times', function(assert) {
19252      assert.expect(2);
19253
19254      assert.strictEqual(_.repeat('*', 3), '***');
19255      assert.strictEqual(_.repeat(string, 2), 'abcabc');
19256    });
19257
19258    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
19259      assert.expect(1);
19260
19261      var expected = lodashStable.map(falsey, function(value) {
19262        return value === undefined ? string : '';
19263      });
19264
19265      var actual = lodashStable.map(falsey, function(n, index) {
19266        return index ? _.repeat(string, n) : _.repeat(string);
19267      });
19268
19269      assert.deepEqual(actual, expected);
19270    });
19271
19272    QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
19273      assert.expect(2);
19274
19275      assert.strictEqual(_.repeat(string, 0), '');
19276      assert.strictEqual(_.repeat(string, -2), '');
19277    });
19278
19279    QUnit.test('should coerce `n` to an integer', function(assert) {
19280      assert.expect(3);
19281
19282      assert.strictEqual(_.repeat(string, '2'), 'abcabc');
19283      assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
19284      assert.strictEqual(_.repeat('*', { 'valueOf': stubThree }), '***');
19285    });
19286
19287    QUnit.test('should coerce `string` to a string', function(assert) {
19288      assert.expect(2);
19289
19290      assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
19291      assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
19292    });
19293
19294    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19295      assert.expect(1);
19296
19297      var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
19298      assert.deepEqual(actual, ['a', 'b', 'c']);
19299    });
19300  }());
19301
19302  /*--------------------------------------------------------------------------*/
19303
19304  QUnit.module('lodash.replace');
19305
19306  (function() {
19307    QUnit.test('should replace the matched pattern', function(assert) {
19308      assert.expect(2);
19309
19310      var string = 'abcde';
19311      assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
19312      assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
19313    });
19314  }());
19315
19316  /*--------------------------------------------------------------------------*/
19317
19318  QUnit.module('lodash.result');
19319
19320  (function() {
19321    var object = { 'a': 1, 'b': stubB };
19322
19323    QUnit.test('should invoke function values', function(assert) {
19324      assert.expect(1);
19325
19326      assert.strictEqual(_.result(object, 'b'), 'b');
19327    });
19328
19329    QUnit.test('should invoke default function values', function(assert) {
19330      assert.expect(1);
19331
19332      var actual = _.result(object, 'c', object.b);
19333      assert.strictEqual(actual, 'b');
19334    });
19335
19336    QUnit.test('should invoke nested function values', function(assert) {
19337      assert.expect(2);
19338
19339      var value = { 'a': lodashStable.constant({ 'b': stubB }) };
19340
19341      lodashStable.each(['a.b', ['a', 'b']], function(path) {
19342        assert.strictEqual(_.result(value, path), 'b');
19343      });
19344    });
19345
19346    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
19347      assert.expect(2);
19348
19349      var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
19350
19351      lodashStable.each(['a.b', ['a', 'b']], function(path) {
19352        assert.strictEqual(_.result(value, path), 1);
19353      });
19354    });
19355  }());
19356
19357  /*--------------------------------------------------------------------------*/
19358
19359  QUnit.module('lodash.get and lodash.result');
19360
19361  lodashStable.each(['get', 'result'], function(methodName) {
19362    var func = _[methodName];
19363
19364    QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
19365      assert.expect(2);
19366
19367      var object = { 'a': 1 };
19368
19369      lodashStable.each(['a', ['a']], function(path) {
19370        assert.strictEqual(func(object, path), 1);
19371      });
19372    });
19373
19374    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19375      assert.expect(1);
19376
19377      var object = { '-0': 'a', '0': 'b' },
19378          props = [-0, Object(-0), 0, Object(0)];
19379
19380      var actual = lodashStable.map(props, function(key) {
19381        return func(object, key);
19382      });
19383
19384      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
19385    });
19386
19387    QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
19388      assert.expect(1);
19389
19390      if (Symbol) {
19391        var object = {};
19392        object[symbol] = 1;
19393
19394        assert.strictEqual(func(object, symbol), 1);
19395      }
19396      else {
19397        skipAssert(assert);
19398      }
19399    });
19400
19401    QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
19402      assert.expect(2);
19403
19404      var object = { 'a': { 'b': 2 } };
19405
19406      lodashStable.each(['a.b', ['a', 'b']], function(path) {
19407        assert.strictEqual(func(object, path), 2);
19408      });
19409    });
19410
19411    QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
19412      assert.expect(2);
19413
19414      var object = { 'a.b': 1, 'a': { 'b': 2 } };
19415
19416      lodashStable.each(['a.b', ['a.b']], function(path) {
19417        assert.strictEqual(func(object, path), 1);
19418      });
19419    });
19420
19421    QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
19422      assert.expect(1);
19423
19424      var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
19425      assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
19426    });
19427
19428    QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
19429      assert.expect(1);
19430
19431      var object = { 'a': { '': 1 } };
19432      assert.strictEqual(func(object, 'a[]'), 1);
19433    });
19434
19435    QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
19436      assert.expect(4);
19437
19438      lodashStable.each([['', ''], [[], ['']]], function(pair) {
19439        assert.strictEqual(func({}, pair[0]), undefined);
19440        assert.strictEqual(func({ '': 3 }, pair[1]), 3);
19441      });
19442    });
19443
19444    QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
19445      assert.expect(2);
19446
19447      var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
19448
19449      var paths = [
19450        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19451        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19452      ];
19453
19454      lodashStable.each(paths, function(path) {
19455        assert.strictEqual(func(object, path), 8);
19456      });
19457    });
19458
19459    QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
19460      assert.expect(4);
19461
19462      lodashStable.each(['constructor', ['constructor']], function(path) {
19463        assert.strictEqual(func(null, path), undefined);
19464        assert.strictEqual(func(undefined, path), undefined);
19465      });
19466    });
19467
19468    QUnit.test('`_.' + methodName + '` should return `undefined` for deep paths when `object` is nullish', function(assert) {
19469      assert.expect(2);
19470
19471      var values = [null, undefined],
19472          expected = lodashStable.map(values, noop),
19473          paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
19474
19475      lodashStable.each(paths, function(path) {
19476        var actual = lodashStable.map(values, function(value) {
19477          return func(value, path);
19478        });
19479
19480        assert.deepEqual(actual, expected);
19481      });
19482    });
19483
19484    QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
19485      assert.expect(2);
19486
19487      var object = { 'a': [, null] };
19488
19489      lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19490        assert.strictEqual(func(object, path), undefined);
19491      });
19492    });
19493
19494    QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
19495      assert.expect(2);
19496
19497      var object = { 'a': { 'b': null } };
19498
19499      lodashStable.each(['a.b', ['a', 'b']], function(path) {
19500        assert.strictEqual(func(object, path), null);
19501      });
19502    });
19503
19504    QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19505      assert.expect(2);
19506
19507      var paths = ['a.b', ['a', 'b']];
19508
19509      lodashStable.each(paths, function(path) {
19510        numberProto.a = { 'b': 2 };
19511        assert.strictEqual(func(0, path), 2);
19512        delete numberProto.a;
19513      });
19514    });
19515
19516    QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
19517      assert.expect(2);
19518
19519      var object = { 'a': {} },
19520          values = empties.concat(true, new Date, 1, /x/, 'a'),
19521          expected = lodashStable.map(values, function(value) { return [value, value]; });
19522
19523      lodashStable.each(['a.b', ['a', 'b']], function(path) {
19524        var actual = lodashStable.map(values, function(value) {
19525          return [func(object, path, value), func(null, path, value)];
19526        });
19527
19528        assert.deepEqual(actual, expected);
19529      });
19530    });
19531
19532    QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
19533      assert.expect(1);
19534
19535      assert.strictEqual(func({}, [], 'a'), 'a');
19536    });
19537  });
19538
19539  /*--------------------------------------------------------------------------*/
19540
19541  QUnit.module('lodash.rest');
19542
19543  (function() {
19544    function fn(a, b, c) {
19545      return slice.call(arguments);
19546    }
19547
19548    QUnit.test('should apply a rest parameter to `func`', function(assert) {
19549      assert.expect(1);
19550
19551      var rest = _.rest(fn);
19552      assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
19553    });
19554
19555    QUnit.test('should work with `start`', function(assert) {
19556      assert.expect(1);
19557
19558      var rest = _.rest(fn, 1);
19559      assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
19560    });
19561
19562    QUnit.test('should treat `start` as `0` for `NaN` or negative values', function(assert) {
19563      assert.expect(1);
19564
19565      var values = [-1, NaN, 'a'],
19566          expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
19567
19568      var actual = lodashStable.map(values, function(value) {
19569        var rest = _.rest(fn, value);
19570        return rest(1, 2, 3, 4);
19571      });
19572
19573      assert.deepEqual(actual, expected);
19574    });
19575
19576    QUnit.test('should coerce `start` to an integer', function(assert) {
19577      assert.expect(1);
19578
19579      var rest = _.rest(fn, 1.6);
19580      assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
19581    });
19582
19583    QUnit.test('should use an empty array when `start` is not reached', function(assert) {
19584      assert.expect(1);
19585
19586      var rest = _.rest(fn);
19587      assert.deepEqual(rest(1), [1, undefined, []]);
19588    });
19589
19590    QUnit.test('should work on functions with more than three parameters', function(assert) {
19591      assert.expect(1);
19592
19593      var rest = _.rest(function(a, b, c, d) {
19594        return slice.call(arguments);
19595      });
19596
19597      assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
19598    });
19599  }());
19600
19601  /*--------------------------------------------------------------------------*/
19602
19603  QUnit.module('lodash.reverse');
19604
19605  (function() {
19606    var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
19607        smallArray = [0, 1, 2, null];
19608
19609    QUnit.test('should reverse `array`', function(assert) {
19610      assert.expect(2);
19611
19612      var array = [1, 2, 3],
19613          actual = _.reverse(array);
19614
19615      assert.strictEqual(actual, array);
19616      assert.deepEqual(array, [3, 2, 1]);
19617    });
19618
19619    QUnit.test('should return the wrapped reversed `array`', function(assert) {
19620      assert.expect(6);
19621
19622      if (!isNpm) {
19623        lodashStable.times(2, function(index) {
19624          var array = (index ? largeArray : smallArray).slice(),
19625              clone = array.slice(),
19626              wrapped = _(array).reverse(),
19627              actual = wrapped.value();
19628
19629          assert.ok(wrapped instanceof _);
19630          assert.strictEqual(actual, array);
19631          assert.deepEqual(actual, clone.slice().reverse());
19632        });
19633      }
19634      else {
19635        skipAssert(assert, 6);
19636      }
19637    });
19638
19639    QUnit.test('should work in a lazy sequence', function(assert) {
19640      assert.expect(4);
19641
19642      if (!isNpm) {
19643        lodashStable.times(2, function(index) {
19644          var array = (index ? largeArray : smallArray).slice(),
19645              expected = array.slice(),
19646              actual = _(array).slice(1).reverse().value();
19647
19648          assert.deepEqual(actual, expected.slice(1).reverse());
19649          assert.deepEqual(array, expected);
19650        });
19651      }
19652      else {
19653        skipAssert(assert, 4);
19654      }
19655    });
19656
19657    QUnit.test('should be lazy when in a lazy sequence', function(assert) {
19658      assert.expect(3);
19659
19660      if (!isNpm) {
19661        var spy = {
19662          'toString': function() {
19663            throw new Error('spy was revealed');
19664          }
19665        };
19666
19667        var array = largeArray.concat(spy),
19668            expected = array.slice();
19669
19670        try {
19671          var wrapped = _(array).slice(1).map(String).reverse(),
19672              actual = wrapped.last();
19673        } catch (e) {}
19674
19675        assert.ok(wrapped instanceof _);
19676        assert.strictEqual(actual, '1');
19677        assert.deepEqual(array, expected);
19678      }
19679      else {
19680        skipAssert(assert, 3);
19681      }
19682    });
19683
19684    QUnit.test('should work in a hybrid sequence', function(assert) {
19685      assert.expect(8);
19686
19687      if (!isNpm) {
19688        lodashStable.times(2, function(index) {
19689          var clone = (index ? largeArray : smallArray).slice();
19690
19691          lodashStable.each(['map', 'filter'], function(methodName) {
19692            var array = clone.slice(),
19693                expected = clone.slice(1, -1).reverse(),
19694                actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
19695
19696            assert.deepEqual(actual, expected);
19697
19698            array = clone.slice();
19699            actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
19700
19701            assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
19702          });
19703        });
19704      }
19705      else {
19706        skipAssert(assert, 8);
19707      }
19708    });
19709
19710    QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
19711      assert.expect(6);
19712
19713      if (!isNpm) {
19714        lodashStable.times(2, function(index) {
19715          var array = (index ? largeArray : smallArray).slice(),
19716              expected = array.slice().reverse(),
19717              wrapped = _(array).chain().reverse().head();
19718
19719          assert.ok(wrapped instanceof _);
19720          assert.strictEqual(wrapped.value(), _.head(expected));
19721          assert.deepEqual(array, expected);
19722        });
19723      }
19724      else {
19725        skipAssert(assert, 6);
19726      }
19727    });
19728  }());
19729
19730  /*--------------------------------------------------------------------------*/
19731
19732  QUnit.module('round methods');
19733
19734  lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
19735    var func = _[methodName],
19736        isCeil = methodName == 'ceil',
19737        isFloor = methodName == 'floor';
19738
19739    QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
19740      assert.expect(1);
19741
19742      var actual = func(4.006);
19743      assert.strictEqual(actual, isCeil ? 5 : 4);
19744    });
19745
19746    QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
19747      assert.expect(1);
19748
19749      var actual = func(4.006, 0);
19750      assert.strictEqual(actual, isCeil ? 5 : 4);
19751    });
19752
19753    QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
19754      assert.expect(2);
19755
19756      var actual = func(4.016, 2);
19757      assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
19758
19759      actual = func(4.1, 2);
19760      assert.strictEqual(actual, 4.1);
19761    });
19762
19763    QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
19764      assert.expect(1);
19765
19766      var actual = func(4160, -2);
19767      assert.strictEqual(actual, isFloor ? 4100 : 4200);
19768    });
19769
19770    QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
19771      assert.expect(3);
19772
19773      var actual = func(4.006, NaN);
19774      assert.strictEqual(actual, isCeil ? 5 : 4);
19775
19776      var expected = isFloor ? 4.01 : 4.02;
19777
19778      actual = func(4.016, 2.6);
19779      assert.strictEqual(actual, expected);
19780
19781      actual = func(4.016, '+2');
19782      assert.strictEqual(actual, expected);
19783    });
19784
19785    QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
19786      assert.expect(3);
19787
19788      var actual = func(5e1, 2);
19789      assert.deepEqual(actual, 50);
19790
19791      actual = func('5e', 1);
19792      assert.deepEqual(actual, NaN);
19793
19794      actual = func('5e1e1', 1);
19795      assert.deepEqual(actual, NaN);
19796    });
19797
19798    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19799      assert.expect(1);
19800
19801      var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
19802          expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
19803
19804      var actual = lodashStable.map(values, function(args) {
19805        return 1 / func.apply(undefined, args);
19806      });
19807
19808      assert.deepEqual(actual, expected);
19809    });
19810
19811    QUnit.test('`_.' + methodName + '` should not return `NaN` for large `precision` values', function(assert) {
19812      assert.expect(1);
19813
19814      var results = [
19815        _.round(10.0000001, 1000),
19816        _.round(MAX_SAFE_INTEGER, 293)
19817      ];
19818
19819      var expected = lodashStable.map(results, stubFalse),
19820          actual = lodashStable.map(results, lodashStable.isNaN);
19821
19822      assert.deepEqual(actual, expected);
19823    });
19824
19825    QUnit.test('`_.' + methodName + '` should return `Infinity` given `Infinity` regardless of `precision`', function(assert) {
19826      assert.expect(6);
19827
19828      var actual = func(Infinity);
19829      assert.strictEqual(actual, Infinity);
19830
19831      actual = func(Infinity, 0);
19832      assert.strictEqual(actual, Infinity);
19833
19834      actual = func(Infinity, 2);
19835      assert.strictEqual(actual, Infinity);
19836
19837      actual = func(Infinity, -2);
19838      assert.strictEqual(actual, Infinity);
19839
19840      actual = func(Infinity, 2);
19841      assert.strictEqual(actual, isFloor ? Infinity : Infinity);
19842
19843      actual = func(Infinity, 2);
19844      assert.strictEqual(actual, isCeil ? Infinity : Infinity);
19845    });
19846
19847    QUnit.test('`_.' + methodName + '` should return `-Infinity` given `-Infinity` regardless of `precision`', function(assert) {
19848      assert.expect(6);
19849
19850      var actual = func(-Infinity);
19851      assert.strictEqual(actual, -Infinity);
19852
19853      actual = func(-Infinity, 0);
19854      assert.strictEqual(actual, -Infinity);
19855
19856      actual = func(-Infinity, 2);
19857      assert.strictEqual(actual, -Infinity);
19858
19859      actual = func(-Infinity, -2);
19860      assert.strictEqual(actual, -Infinity);
19861
19862      actual = func(-Infinity, 2);
19863      assert.strictEqual(actual, isFloor ? -Infinity : -Infinity);
19864
19865      actual = func(-Infinity, 2);
19866      assert.strictEqual(actual, isCeil ? -Infinity : -Infinity);
19867    });
19868
19869    QUnit.test('`_.' + methodName + '` should return `NaN` given `NaN` regardless of `precision`', function(assert) {
19870      assert.expect(6);
19871
19872      var actual = func(NaN);
19873      assert.deepEqual(actual, NaN);
19874
19875      actual = func(NaN, 0);
19876      assert.deepEqual(actual, NaN);
19877
19878      actual = func(NaN, 2);
19879      assert.deepEqual(actual, NaN);
19880
19881      actual = func(NaN, -2);
19882      assert.deepEqual(actual, NaN);
19883
19884      actual = func(NaN, 2);
19885      assert.deepEqual(actual, isFloor ? NaN : NaN);
19886
19887      actual = func(NaN, 2);
19888      assert.deepEqual(actual, isCeil ? NaN : NaN);
19889    });
19890  });
19891
19892  /*--------------------------------------------------------------------------*/
19893
19894  QUnit.module('lodash.runInContext');
19895
19896  (function() {
19897    QUnit.test('should not require a fully populated `context` object', function(assert) {
19898      assert.expect(1);
19899
19900      if (!isModularize) {
19901        var lodash = _.runInContext({
19902          'setTimeout': function(func) { func(); }
19903        });
19904
19905        var pass = false;
19906        lodash.delay(function() { pass = true; }, 32);
19907        assert.ok(pass);
19908      }
19909      else {
19910        skipAssert(assert);
19911      }
19912    });
19913
19914    QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
19915      assert.expect(3);
19916
19917      if (!isModularize) {
19918        lodashStable.times(2, _.uniqueId);
19919
19920        var oldId = Number(_.uniqueId()),
19921            lodash = _.runInContext();
19922
19923        assert.ok(_.uniqueId() > oldId);
19924
19925        var id = lodash.uniqueId();
19926        assert.strictEqual(id, '1');
19927        assert.ok(id < oldId);
19928      }
19929      else {
19930        skipAssert(assert, 3);
19931      }
19932    });
19933  }());
19934
19935  /*--------------------------------------------------------------------------*/
19936
19937  QUnit.module('lodash.sample');
19938
19939  (function() {
19940    var array = [1, 2, 3];
19941
19942    QUnit.test('should return a random element', function(assert) {
19943      assert.expect(1);
19944
19945      var actual = _.sample(array);
19946      assert.ok(lodashStable.includes(array, actual));
19947    });
19948
19949    QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
19950      assert.expect(1);
19951
19952      var expected = lodashStable.map(empties, noop);
19953
19954      var actual = lodashStable.transform(empties, function(result, value) {
19955        try {
19956          result.push(_.sample(value));
19957        } catch (e) {}
19958      });
19959
19960      assert.deepEqual(actual, expected);
19961    });
19962
19963    QUnit.test('should sample an object', function(assert) {
19964      assert.expect(1);
19965
19966      var object = { 'a': 1, 'b': 2, 'c': 3 },
19967          actual = _.sample(object);
19968
19969      assert.ok(lodashStable.includes(array, actual));
19970    });
19971  }());
19972
19973  /*--------------------------------------------------------------------------*/
19974
19975  QUnit.module('lodash.sampleSize');
19976
19977  (function() {
19978    var array = [1, 2, 3];
19979
19980    QUnit.test('should return an array of random elements', function(assert) {
19981      assert.expect(2);
19982
19983      var actual = _.sampleSize(array, 2);
19984
19985      assert.strictEqual(actual.length, 2);
19986      assert.deepEqual(lodashStable.difference(actual, array), []);
19987    });
19988
19989    QUnit.test('should contain elements of the collection', function(assert) {
19990      assert.expect(1);
19991
19992      var actual = _.sampleSize(array, array.length).sort();
19993
19994      assert.deepEqual(actual, array);
19995    });
19996
19997    QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
19998      assert.expect(1);
19999
20000      var expected = lodashStable.map(falsey, function(value) {
20001        return value === undefined ? ['a'] : [];
20002      });
20003
20004      var actual = lodashStable.map(falsey, function(size, index) {
20005        return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
20006      });
20007
20008      assert.deepEqual(actual, expected);
20009    });
20010
20011    QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
20012      assert.expect(3);
20013
20014      lodashStable.each([0, -1, -Infinity], function(n) {
20015        assert.deepEqual(_.sampleSize(array, n), []);
20016      });
20017    });
20018
20019    QUnit.test('should return all elements when `n` >= `length`', function(assert) {
20020      assert.expect(4);
20021
20022      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
20023        var actual = _.sampleSize(array, n).sort();
20024        assert.deepEqual(actual, array);
20025      });
20026    });
20027
20028    QUnit.test('should coerce `n` to an integer', function(assert) {
20029      assert.expect(1);
20030
20031      var actual = _.sampleSize(array, 1.6);
20032      assert.strictEqual(actual.length, 1);
20033    });
20034
20035    QUnit.test('should return an empty array for empty collections', function(assert) {
20036      assert.expect(1);
20037
20038      var expected = lodashStable.map(empties, stubArray);
20039
20040      var actual = lodashStable.transform(empties, function(result, value) {
20041        try {
20042          result.push(_.sampleSize(value, 1));
20043        } catch (e) {}
20044      });
20045
20046      assert.deepEqual(actual, expected);
20047    });
20048
20049    QUnit.test('should sample an object', function(assert) {
20050      assert.expect(2);
20051
20052      var object = { 'a': 1, 'b': 2, 'c': 3 },
20053          actual = _.sampleSize(object, 2);
20054
20055      assert.strictEqual(actual.length, 2);
20056      assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
20057    });
20058
20059    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20060      assert.expect(1);
20061
20062      var actual = lodashStable.map([['a']], _.sampleSize);
20063      assert.deepEqual(actual, [['a']]);
20064    });
20065  }());
20066
20067  /*--------------------------------------------------------------------------*/
20068
20069  QUnit.module('lodash.setWith');
20070
20071  (function() {
20072    QUnit.test('should work with a `customizer` callback', function(assert) {
20073      assert.expect(1);
20074
20075      var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
20076        return lodashStable.isObject(value) ? undefined : {};
20077      });
20078
20079      assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
20080    });
20081
20082    QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
20083      assert.expect(1);
20084
20085      var actual = _.setWith({}, 'a[0].b.c', 4, noop);
20086      assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
20087    });
20088  }());
20089
20090  /*--------------------------------------------------------------------------*/
20091
20092  QUnit.module('set methods');
20093
20094  lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
20095    var func = _[methodName],
20096        isUpdate = /^update/.test(methodName);
20097
20098    var oldValue = 1,
20099        value = 2,
20100        updater = isUpdate ? lodashStable.constant(value) : value;
20101
20102    QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
20103      assert.expect(4);
20104
20105      lodashStable.each(['a', ['a']], function(path) {
20106        var object = { 'a': oldValue },
20107            actual = func(object, path, updater);
20108
20109        assert.strictEqual(actual, object);
20110        assert.strictEqual(object.a, value);
20111      });
20112    });
20113
20114    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
20115      assert.expect(1);
20116
20117      var props = [-0, Object(-0), 0, Object(0)],
20118          expected = lodashStable.map(props, lodashStable.constant(value));
20119
20120      var actual = lodashStable.map(props, function(key) {
20121        var object = { '-0': 'a', '0': 'b' };
20122        func(object, key, updater);
20123        return object[lodashStable.toString(key)];
20124      });
20125
20126      assert.deepEqual(actual, expected);
20127    });
20128
20129    QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
20130      assert.expect(2);
20131
20132      if (Symbol) {
20133        var object = {};
20134        object[symbol] = 1;
20135
20136        assert.strictEqual(_.unset(object, symbol), true);
20137        assert.notOk(symbol in object);
20138      }
20139      else {
20140        skipAssert(assert, 2);
20141      }
20142    });
20143
20144    QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
20145      assert.expect(4);
20146
20147      lodashStable.each(['a.b', ['a', 'b']], function(path) {
20148        var object = { 'a': { 'b': oldValue } },
20149            actual = func(object, path, updater);
20150
20151        assert.strictEqual(actual, object);
20152        assert.strictEqual(object.a.b, value);
20153      });
20154    });
20155
20156    QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
20157      assert.expect(4);
20158
20159      lodashStable.each(['a.b', ['a.b']], function(path) {
20160        var object = { 'a.b': oldValue },
20161            actual = func(object, path, updater);
20162
20163        assert.strictEqual(actual, object);
20164        assert.deepEqual(object, { 'a.b': value });
20165      });
20166    });
20167
20168    QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
20169      assert.expect(1);
20170
20171      var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
20172
20173      func(object, ['a', 'b', 'c'], updater);
20174      assert.strictEqual(object.a.b.c, value);
20175    });
20176
20177    QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) {
20178      assert.expect(1);
20179
20180      var object = {};
20181
20182      func(object, 'a[]', updater);
20183      assert.deepEqual(object, { 'a': { '': value } });
20184    });
20185
20186    QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
20187      assert.expect(4);
20188
20189      lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
20190        var object = {};
20191
20192        func(object, pair[0], updater);
20193        assert.deepEqual(object, index ? {} : { '': value });
20194
20195        func(object, pair[1], updater);
20196        assert.deepEqual(object, { '': value });
20197      });
20198    });
20199
20200    QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
20201      assert.expect(2);
20202
20203      var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
20204
20205      var paths = [
20206        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
20207        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
20208      ];
20209
20210      lodashStable.each(paths, function(path) {
20211        func(object, path, updater);
20212        assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
20213        object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
20214      });
20215    });
20216
20217    QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
20218      assert.expect(6);
20219
20220      var object = {};
20221
20222      lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
20223        var actual = func(object, path, updater);
20224
20225        assert.strictEqual(actual, object);
20226        assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
20227        assert.notOk('0' in object.a);
20228
20229        delete object.a;
20230      });
20231    });
20232
20233    QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
20234      assert.expect(1);
20235
20236      var values = [null, undefined],
20237          expected = [[null, null], [undefined, undefined]];
20238
20239      var actual = lodashStable.map(values, function(value) {
20240        try {
20241          return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
20242        } catch (e) {
20243          return e.message;
20244        }
20245      });
20246
20247      assert.deepEqual(actual, expected);
20248    });
20249
20250    QUnit.test('`_.' + methodName + '` should overwrite primitives in the path', function(assert) {
20251      assert.expect(2);
20252
20253      lodashStable.each(['a.b', ['a', 'b']], function(path) {
20254        var object = { 'a': '' };
20255
20256        func(object, path, updater);
20257        assert.deepEqual(object, { 'a': { 'b': 2 } });
20258      });;
20259    });
20260
20261    QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
20262      assert.expect(1);
20263
20264      var object = {};
20265
20266      func(object, ['1a', '2b', '3c'], updater);
20267      assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
20268    });
20269
20270    QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
20271      assert.expect(4);
20272
20273      lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
20274        var object = {},
20275            pass = true,
20276            updater = isUpdate ? lodashStable.constant(value) : value;
20277
20278        defineProperty(object, 'a', {
20279          'configurable': true,
20280          'enumerable': true,
20281          'get': lodashStable.constant(value),
20282          'set': function() { pass = false; }
20283        });
20284
20285        func(object, 'a', updater);
20286        assert.ok(pass);
20287      });
20288    });
20289  });
20290
20291  /*--------------------------------------------------------------------------*/
20292
20293  QUnit.module('lodash.shuffle');
20294
20295  (function() {
20296    var array = [1, 2, 3],
20297        object = { 'a': 1, 'b': 2, 'c': 3 };
20298
20299    QUnit.test('should return a new array', function(assert) {
20300      assert.expect(1);
20301
20302      assert.notStrictEqual(_.shuffle(array), array);
20303    });
20304
20305    QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
20306      assert.expect(2);
20307
20308      assert.deepEqual(_.shuffle(array).sort(), array);
20309      assert.deepEqual(_.shuffle(object).sort(), array);
20310    });
20311
20312    QUnit.test('should shuffle small collections', function(assert) {
20313      assert.expect(1);
20314
20315      var actual = lodashStable.times(1000, function(assert) {
20316        return _.shuffle([1, 2]);
20317      });
20318
20319      assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
20320    });
20321
20322    QUnit.test('should treat number values for `collection` as empty', function(assert) {
20323      assert.expect(1);
20324
20325      assert.deepEqual(_.shuffle(1), []);
20326    });
20327  }());
20328
20329  /*--------------------------------------------------------------------------*/
20330
20331  QUnit.module('lodash.size');
20332
20333  (function() {
20334    var array = [1, 2, 3];
20335
20336    QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
20337      assert.expect(1);
20338
20339      assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
20340    });
20341
20342    QUnit.test('should return the length of an array', function(assert) {
20343      assert.expect(1);
20344
20345      assert.strictEqual(_.size(array), 3);
20346    });
20347
20348    QUnit.test('should accept a falsey `object`', function(assert) {
20349      assert.expect(1);
20350
20351      var expected = lodashStable.map(falsey, stubZero);
20352
20353      var actual = lodashStable.map(falsey, function(object, index) {
20354        try {
20355          return index ? _.size(object) : _.size();
20356        } catch (e) {}
20357      });
20358
20359      assert.deepEqual(actual, expected);
20360    });
20361
20362    QUnit.test('should work with `arguments` objects', function(assert) {
20363      assert.expect(1);
20364
20365      assert.strictEqual(_.size(args), 3);
20366    });
20367
20368    QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
20369      assert.expect(1);
20370
20371      function Foo(elements) {
20372        push.apply(this, elements);
20373      }
20374      Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
20375
20376      assert.strictEqual(_.size(new Foo(array)), 3);
20377    });
20378
20379    QUnit.test('should work with maps', function(assert) {
20380      assert.expect(2);
20381
20382      if (Map) {
20383        lodashStable.each([new Map, realm.map], function(map) {
20384          map.set('a', 1);
20385          map.set('b', 2);
20386          assert.strictEqual(_.size(map), 2);
20387          map.clear();
20388        });
20389      }
20390      else {
20391        skipAssert(assert, 2);
20392      }
20393    });
20394
20395    QUnit.test('should work with sets', function(assert) {
20396      assert.expect(2);
20397
20398      if (Set) {
20399        lodashStable.each([new Set, realm.set], function(set) {
20400          set.add(1);
20401          set.add(2);
20402          assert.strictEqual(_.size(set), 2);
20403          set.clear();
20404        });
20405      }
20406      else {
20407        skipAssert(assert, 2);
20408      }
20409    });
20410
20411    QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
20412      assert.expect(1);
20413
20414      assert.strictEqual(_.size({ 'length': -1 }), 1);
20415    });
20416
20417    QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
20418      assert.expect(1);
20419
20420      assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
20421    });
20422
20423    QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
20424      assert.expect(1);
20425
20426      assert.strictEqual(_.size({ 'length': '0' }), 1);
20427    });
20428  }());
20429
20430  /*--------------------------------------------------------------------------*/
20431
20432  QUnit.module('lodash.slice');
20433
20434  (function() {
20435    var array = [1, 2, 3];
20436
20437    QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) {
20438      assert.expect(2);
20439
20440      var actual = _.slice(array);
20441      assert.deepEqual(actual, array);
20442      assert.notStrictEqual(actual, array);
20443    });
20444
20445    QUnit.test('should work with a positive `start`', function(assert) {
20446      assert.expect(2);
20447
20448      assert.deepEqual(_.slice(array, 1), [2, 3]);
20449      assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
20450    });
20451
20452    QUnit.test('should work with a `start` >= `length`', function(assert) {
20453      assert.expect(4);
20454
20455      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
20456        assert.deepEqual(_.slice(array, start), []);
20457      });
20458    });
20459
20460    QUnit.test('should treat falsey `start` values as `0`', function(assert) {
20461      assert.expect(1);
20462
20463      var expected = lodashStable.map(falsey, lodashStable.constant(array));
20464
20465      var actual = lodashStable.map(falsey, function(start) {
20466        return _.slice(array, start);
20467      });
20468
20469      assert.deepEqual(actual, expected);
20470    });
20471
20472    QUnit.test('should work with a negative `start`', function(assert) {
20473      assert.expect(1);
20474
20475      assert.deepEqual(_.slice(array, -1), [3]);
20476    });
20477
20478    QUnit.test('should work with a negative `start` <= negative `length`', function(assert) {
20479      assert.expect(3);
20480
20481      lodashStable.each([-3, -4, -Infinity], function(start) {
20482        assert.deepEqual(_.slice(array, start), array);
20483      });
20484    });
20485
20486    QUnit.test('should work with `start` >= `end`', function(assert) {
20487      assert.expect(2);
20488
20489      lodashStable.each([2, 3], function(start) {
20490        assert.deepEqual(_.slice(array, start, 2), []);
20491      });
20492    });
20493
20494    QUnit.test('should work with a positive `end`', function(assert) {
20495      assert.expect(1);
20496
20497      assert.deepEqual(_.slice(array, 0, 1), [1]);
20498    });
20499
20500    QUnit.test('should work with a `end` >= `length`', function(assert) {
20501      assert.expect(4);
20502
20503      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
20504        assert.deepEqual(_.slice(array, 0, end), array);
20505      });
20506    });
20507
20508    QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
20509      assert.expect(1);
20510
20511      var expected = lodashStable.map(falsey, function(value) {
20512        return value === undefined ? array : [];
20513      });
20514
20515      var actual = lodashStable.map(falsey, function(end, index) {
20516        return index ? _.slice(array, 0, end) : _.slice(array, 0);
20517      });
20518
20519      assert.deepEqual(actual, expected);
20520    });
20521
20522    QUnit.test('should work with a negative `end`', function(assert) {
20523      assert.expect(1);
20524
20525      assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
20526    });
20527
20528    QUnit.test('should work with a negative `end` <= negative `length`', function(assert) {
20529      assert.expect(3);
20530
20531      lodashStable.each([-3, -4, -Infinity], function(end) {
20532        assert.deepEqual(_.slice(array, 0, end), []);
20533      });
20534    });
20535
20536    QUnit.test('should coerce `start` and `end` to integers', function(assert) {
20537      assert.expect(1);
20538
20539      var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
20540
20541      var actual = lodashStable.map(positions, function(pos) {
20542        return _.slice.apply(_, [array].concat(pos));
20543      });
20544
20545      assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
20546    });
20547
20548    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20549      assert.expect(2);
20550
20551      var array = [[1], [2, 3]],
20552          actual = lodashStable.map(array, _.slice);
20553
20554      assert.deepEqual(actual, array);
20555      assert.notStrictEqual(actual, array);
20556    });
20557
20558    QUnit.test('should work in a lazy sequence', function(assert) {
20559      assert.expect(38);
20560
20561      if (!isNpm) {
20562        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
20563            length = array.length,
20564            wrapped = _(array);
20565
20566        lodashStable.each(['map', 'filter'], function(methodName) {
20567          assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
20568          assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
20569          assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
20570          assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
20571
20572          assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
20573          assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
20574          assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
20575          assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
20576
20577          assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
20578          assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
20579          assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
20580
20581          assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
20582          assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
20583
20584          assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
20585          assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
20586          assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
20587          assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
20588          assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
20589          assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
20590        });
20591      }
20592      else {
20593        skipAssert(assert, 38);
20594      }
20595    });
20596  }());
20597
20598  /*--------------------------------------------------------------------------*/
20599
20600  QUnit.module('lodash.some');
20601
20602  (function() {
20603    QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
20604      assert.expect(2);
20605
20606      assert.strictEqual(_.some([false, 1, ''], identity), true);
20607      assert.strictEqual(_.some([null, 'a', 0], identity), true);
20608    });
20609
20610    QUnit.test('should return `false` for empty collections', function(assert) {
20611      assert.expect(1);
20612
20613      var expected = lodashStable.map(empties, stubFalse);
20614
20615      var actual = lodashStable.map(empties, function(value) {
20616        try {
20617          return _.some(value, identity);
20618        } catch (e) {}
20619      });
20620
20621      assert.deepEqual(actual, expected);
20622    });
20623
20624    QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
20625      assert.expect(2);
20626
20627      var count = 0;
20628
20629      assert.strictEqual(_.some([null, true, null], function(value) {
20630        count++;
20631        return value;
20632      }), true);
20633
20634      assert.strictEqual(count, 2);
20635    });
20636
20637    QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
20638      assert.expect(2);
20639
20640      assert.strictEqual(_.some([false, false, false], identity), false);
20641      assert.strictEqual(_.some([null, 0, ''], identity), false);
20642    });
20643
20644    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
20645      assert.expect(2);
20646
20647      var values = [, null, undefined],
20648          expected = lodashStable.map(values, stubFalse);
20649
20650      var actual = lodashStable.map(values, function(value, index) {
20651        var array = [0, 0];
20652        return index ? _.some(array, value) : _.some(array);
20653      });
20654
20655      assert.deepEqual(actual, expected);
20656
20657      expected = lodashStable.map(values, stubTrue);
20658      actual = lodashStable.map(values, function(value, index) {
20659        var array = [0, 1];
20660        return index ? _.some(array, value) : _.some(array);
20661      });
20662
20663      assert.deepEqual(actual, expected);
20664    });
20665
20666    QUnit.test('should work with `_.property` shorthands', function(assert) {
20667      assert.expect(2);
20668
20669      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
20670      assert.strictEqual(_.some(objects, 'a'), false);
20671      assert.strictEqual(_.some(objects, 'b'), true);
20672    });
20673
20674    QUnit.test('should work with `_.matches` shorthands', function(assert) {
20675      assert.expect(2);
20676
20677      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
20678      assert.strictEqual(_.some(objects, { 'a': 0 }), true);
20679      assert.strictEqual(_.some(objects, { 'b': 2 }), false);
20680    });
20681
20682    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20683      assert.expect(1);
20684
20685      var actual = lodashStable.map([[1]], _.some);
20686      assert.deepEqual(actual, [true]);
20687    });
20688  }());
20689
20690  /*--------------------------------------------------------------------------*/
20691
20692  QUnit.module('lodash.sortBy');
20693
20694  (function() {
20695    var objects = [
20696      { 'a': 'x', 'b': 3 },
20697      { 'a': 'y', 'b': 4 },
20698      { 'a': 'x', 'b': 1 },
20699      { 'a': 'y', 'b': 2 }
20700    ];
20701
20702    QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
20703      assert.expect(1);
20704
20705      var actual = lodashStable.map(_.sortBy(objects, function(object) {
20706        return object.b;
20707      }), 'b');
20708
20709      assert.deepEqual(actual, [1, 2, 3, 4]);
20710    });
20711
20712    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20713      assert.expect(1);
20714
20715      var array = [3, 2, 1],
20716          values = [, null, undefined],
20717          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
20718
20719      var actual = lodashStable.map(values, function(value, index) {
20720        return index ? _.sortBy(array, value) : _.sortBy(array);
20721      });
20722
20723      assert.deepEqual(actual, expected);
20724    });
20725
20726    QUnit.test('should work with `_.property` shorthands', function(assert) {
20727      assert.expect(1);
20728
20729      var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
20730      assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
20731    });
20732
20733    QUnit.test('should work with an object for `collection`', function(assert) {
20734      assert.expect(1);
20735
20736      var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
20737      assert.deepEqual(actual, [3, 1, 2]);
20738    });
20739
20740    QUnit.test('should move `NaN`, nullish, and symbol values to the end', function(assert) {
20741      assert.expect(2);
20742
20743      var symbol1 = Symbol ? Symbol('a') : null,
20744          symbol2 = Symbol ? Symbol('b') : null,
20745          array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
20746          expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20747
20748      assert.deepEqual(_.sortBy(array), expected);
20749
20750      array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
20751      expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20752
20753      assert.deepEqual(_.sortBy(array), expected);
20754    });
20755
20756    QUnit.test('should treat number values for `collection` as empty', function(assert) {
20757      assert.expect(1);
20758
20759      assert.deepEqual(_.sortBy(1), []);
20760    });
20761
20762    QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
20763      assert.expect(1);
20764
20765      var actual = _.sortBy(objects, function(object) {
20766        var result = [object.a, object.b];
20767        result.toString = function() { return String(this[0]); };
20768        return result;
20769      });
20770
20771      assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
20772    });
20773
20774    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20775      assert.expect(1);
20776
20777      var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
20778      assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
20779    });
20780  }());
20781
20782  /*--------------------------------------------------------------------------*/
20783
20784  QUnit.module('sortBy methods');
20785
20786  lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
20787    var func = _[methodName];
20788
20789    function Pair(a, b, c) {
20790      this.a = a;
20791      this.b = b;
20792      this.c = c;
20793    }
20794
20795    var objects = [
20796      { 'a': 'x', 'b': 3 },
20797      { 'a': 'y', 'b': 4 },
20798      { 'a': 'x', 'b': 1 },
20799      { 'a': 'y', 'b': 2 }
20800    ];
20801
20802    var stableArray = [
20803      new Pair(1, 1, 1), new Pair(1, 2, 1),
20804      new Pair(1, 1, 1), new Pair(1, 2, 1),
20805      new Pair(1, 3, 1), new Pair(1, 4, 1),
20806      new Pair(1, 5, 1), new Pair(1, 6, 1),
20807      new Pair(2, 1, 2), new Pair(2, 2, 2),
20808      new Pair(2, 3, 2), new Pair(2, 4, 2),
20809      new Pair(2, 5, 2), new Pair(2, 6, 2),
20810      new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
20811      new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
20812      new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
20813    ];
20814
20815    var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
20816
20817    QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
20818      assert.expect(1);
20819
20820      var actual = func(objects, ['a', 'b']);
20821      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20822    });
20823
20824    QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
20825      assert.expect(1);
20826
20827      var actual = func(objects, ['a', function(object) { return object.b; }]);
20828      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20829    });
20830
20831    QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
20832      assert.expect(2);
20833
20834      lodashStable.each([stableArray, stableObject], function(value, index) {
20835        var actual = func(value, ['a', 'c']);
20836        assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
20837      });
20838    });
20839
20840    QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
20841      assert.expect(1);
20842
20843      try {
20844        var actual = func(objects.concat(null, undefined), ['a', 'b']);
20845      } catch (e) {}
20846
20847      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
20848    });
20849
20850    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
20851      assert.expect(3);
20852
20853      var objects = [
20854        { 'a': 'x', '0': 3 },
20855        { 'a': 'y', '0': 4 },
20856        { 'a': 'x', '0': 1 },
20857        { 'a': 'y', '0': 2 }
20858      ];
20859
20860      var funcs = [func, lodashStable.partialRight(func, 'bogus')];
20861
20862      lodashStable.each(['a', 0, [0]], function(props, index) {
20863        var expected = lodashStable.map(funcs, lodashStable.constant(
20864          index
20865            ? [objects[2], objects[3], objects[0], objects[1]]
20866            : [objects[0], objects[2], objects[1], objects[3]]
20867        ));
20868
20869        var actual = lodashStable.map(funcs, function(func) {
20870          return lodashStable.reduce([props], func, objects);
20871        });
20872
20873        assert.deepEqual(actual, expected);
20874      });
20875    });
20876  });
20877
20878  /*--------------------------------------------------------------------------*/
20879
20880  QUnit.module('sortedIndex methods');
20881
20882  lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
20883    var func = _[methodName],
20884        isSortedIndex = methodName == 'sortedIndex';
20885
20886    QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
20887      assert.expect(1);
20888
20889      var array = [30, 50],
20890          values = [30, 40, 50],
20891          expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20892
20893      var actual = lodashStable.map(values, function(value) {
20894        return func(array, value);
20895      });
20896
20897      assert.deepEqual(actual, expected);
20898    });
20899
20900    QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
20901      assert.expect(1);
20902
20903      var array = ['a', 'c'],
20904          values = ['a', 'b', 'c'],
20905          expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20906
20907      var actual = lodashStable.map(values, function(value) {
20908        return func(array, value);
20909      });
20910
20911      assert.deepEqual(actual, expected);
20912    });
20913
20914    QUnit.test('`_.' + methodName + '` should accept a nullish `array` and a `value`', function(assert) {
20915      assert.expect(1);
20916
20917      var values = [null, undefined],
20918          expected = lodashStable.map(values, lodashStable.constant([0, 0, 0]));
20919
20920      var actual = lodashStable.map(values, function(array) {
20921        return [func(array, 1), func(array, undefined), func(array, NaN)];
20922      });
20923
20924      assert.deepEqual(actual, expected);
20925    });
20926
20927    QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
20928      assert.expect(12);
20929
20930      var symbol1 = Symbol ? Symbol('a') : null,
20931          symbol2 = Symbol ? Symbol('b') : null,
20932          symbol3 = Symbol ? Symbol('c') : null,
20933          expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
20934
20935      lodashStable.each([
20936        [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
20937        ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
20938      ], function(array) {
20939        assert.deepEqual(_.sortBy(array), expected);
20940        assert.strictEqual(func(expected, 3), 2);
20941        assert.strictEqual(func(expected, symbol3), isSortedIndex ? 3 : (Symbol ? 5 : 6));
20942        assert.strictEqual(func(expected, null), isSortedIndex ? (Symbol ? 5 : 3) : 6);
20943        assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
20944        assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
20945      });
20946    });
20947
20948    QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for nulls', function(assert) {
20949      assert.expect(3);
20950
20951      var array = [null, null];
20952
20953      assert.strictEqual(func(array, null), isSortedIndex ? 0 : 2);
20954      assert.strictEqual(func(array, 1), 0);
20955      assert.strictEqual(func(array, 'a'), 0);
20956    });
20957
20958    QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for symbols', function(assert) {
20959      assert.expect(3);
20960
20961      var symbol1 = Symbol ? Symbol('a') : null,
20962          symbol2 = Symbol ? Symbol('b') : null,
20963          symbol3 = Symbol ? Symbol('c') : null,
20964          array = [symbol1, symbol2];
20965
20966      assert.strictEqual(func(array, symbol3), isSortedIndex ? 0 : 2);
20967      assert.strictEqual(func(array, 1), 0);
20968      assert.strictEqual(func(array, 'a'), 0);
20969    });
20970  });
20971
20972  /*--------------------------------------------------------------------------*/
20973
20974  QUnit.module('sortedIndexBy methods');
20975
20976  lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
20977    var func = _[methodName],
20978        isSortedIndexBy = methodName == 'sortedIndexBy';
20979
20980    QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) {
20981      assert.expect(1);
20982
20983      var args;
20984
20985      func([30, 50], 40, function(assert) {
20986        args || (args = slice.call(arguments));
20987      });
20988
20989      assert.deepEqual(args, [40]);
20990    });
20991
20992    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
20993      assert.expect(1);
20994
20995      var objects = [{ 'x': 30 }, { 'x': 50 }],
20996          actual = func(objects, { 'x': 40 }, 'x');
20997
20998      assert.strictEqual(actual, 1);
20999    });
21000
21001    QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
21002      assert.expect(12);
21003
21004      lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
21005        var array = [],
21006            values = [MAX_ARRAY_LENGTH, NaN, undefined];
21007
21008        array.length = length;
21009
21010        lodashStable.each(values, function(value) {
21011          var steps = 0;
21012
21013          var actual = func(array, value, function(value) {
21014            steps++;
21015            return value;
21016          });
21017
21018          var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
21019            ? 0
21020            : Math.min(length, MAX_ARRAY_INDEX);
21021
21022          assert.ok(steps == 32 || steps == 33);
21023          assert.strictEqual(actual, expected);
21024        });
21025      });
21026    });
21027  });
21028
21029  /*--------------------------------------------------------------------------*/
21030
21031  QUnit.module('sortedIndexOf methods');
21032
21033  lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
21034    var func = _[methodName],
21035        isSortedIndexOf = methodName == 'sortedIndexOf';
21036
21037    QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
21038      assert.expect(1);
21039
21040      var sorted = [4, 4, 5, 5, 6, 6];
21041      assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
21042    });
21043  });
21044
21045  /*--------------------------------------------------------------------------*/
21046
21047  QUnit.module('lodash.sortedUniq');
21048
21049  (function() {
21050    QUnit.test('should return unique values of a sorted array', function(assert) {
21051      assert.expect(3);
21052
21053      var expected = [1, 2, 3];
21054
21055      lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
21056        assert.deepEqual(_.sortedUniq(array), expected);
21057      });
21058    });
21059  }());
21060
21061  /*--------------------------------------------------------------------------*/
21062
21063  QUnit.module('lodash.split');
21064
21065  (function() {
21066    QUnit.test('should split a string by `separator`', function(assert) {
21067      assert.expect(3);
21068
21069      var string = 'abcde';
21070      assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
21071      assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
21072      assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
21073    });
21074
21075    QUnit.test('should return an array containing an empty string for empty values', function(assert) {
21076      assert.expect(1);
21077
21078      var values = [, null, undefined, ''],
21079          expected = lodashStable.map(values, lodashStable.constant(['']));
21080
21081      var actual = lodashStable.map(values, function(value, index) {
21082        return index ? _.split(value) : _.split();
21083      });
21084
21085      assert.deepEqual(actual, expected);
21086    });
21087
21088    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21089      assert.expect(1);
21090
21091      var strings = ['abc', 'def', 'ghi'],
21092          actual = lodashStable.map(strings, _.split);
21093
21094      assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
21095    });
21096
21097    QUnit.test('should allow mixed string and array prototype methods', function(assert) {
21098      assert.expect(1);
21099
21100      if (!isNpm) {
21101        var wrapped = _('abc');
21102        assert.strictEqual(wrapped.split('b').join(','), 'a,c');
21103      }
21104      else {
21105        skipAssert(assert);
21106      }
21107    });
21108  }());
21109
21110  /*--------------------------------------------------------------------------*/
21111
21112  QUnit.module('lodash.spread');
21113
21114  (function() {
21115    function fn(a, b, c) {
21116      return slice.call(arguments);
21117    }
21118
21119    QUnit.test('should spread arguments to `func`', function(assert) {
21120      assert.expect(2);
21121
21122      var spread = _.spread(fn),
21123          expected = [1, 2];
21124
21125      assert.deepEqual(spread([1, 2]), expected);
21126      assert.deepEqual(spread([1, 2], 3), expected);
21127    });
21128
21129    QUnit.test('should accept a falsey `array`', function(assert) {
21130      assert.expect(1);
21131
21132      var spread = _.spread(stubTrue),
21133          expected = lodashStable.map(falsey, stubTrue);
21134
21135      var actual = lodashStable.map(falsey, function(array, index) {
21136        try {
21137          return index ? spread(array) : spread();
21138        } catch (e) {}
21139      });
21140
21141      assert.deepEqual(actual, expected);
21142    });
21143
21144    QUnit.test('should work with `start`', function(assert) {
21145      assert.expect(2);
21146
21147      var spread = _.spread(fn, 1),
21148          expected = [1, 2, 3];
21149
21150      assert.deepEqual(spread(1, [2, 3]), expected);
21151      assert.deepEqual(spread(1, [2, 3], 4), expected);
21152    });
21153
21154    QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
21155      assert.expect(1);
21156
21157      var values = [-1, NaN, 'a'],
21158          expected = lodashStable.map(values, lodashStable.constant([1, 2]));
21159
21160      var actual = lodashStable.map(values, function(value) {
21161        var spread = _.spread(fn, value);
21162        return spread([1, 2]);
21163      });
21164
21165      assert.deepEqual(actual, expected);
21166    });
21167
21168    QUnit.test('should coerce `start` to an integer', function(assert) {
21169      assert.expect(2);
21170
21171      var spread = _.spread(fn, 1.6),
21172          expected = [1, 2, 3];
21173
21174      assert.deepEqual(spread(1, [2, 3]), expected);
21175      assert.deepEqual(spread(1, [2, 3], 4), expected);
21176    });
21177  }());
21178
21179  /*--------------------------------------------------------------------------*/
21180
21181  QUnit.module('lodash.startCase');
21182
21183  (function() {
21184    QUnit.test('should uppercase only the first character of each word', function(assert) {
21185      assert.expect(3);
21186
21187      assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
21188      assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
21189      assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
21190    });
21191  }());
21192
21193  /*--------------------------------------------------------------------------*/
21194
21195  QUnit.module('lodash.startsWith');
21196
21197  (function() {
21198    var string = 'abc';
21199
21200    QUnit.test('should return `true` if a string starts with `target`', function(assert) {
21201      assert.expect(1);
21202
21203      assert.strictEqual(_.startsWith(string, 'a'), true);
21204    });
21205
21206    QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
21207      assert.expect(1);
21208
21209      assert.strictEqual(_.startsWith(string, 'b'), false);
21210    });
21211
21212    QUnit.test('should work with a `position`', function(assert) {
21213      assert.expect(1);
21214
21215      assert.strictEqual(_.startsWith(string, 'b', 1), true);
21216    });
21217
21218    QUnit.test('should work with `position` >= `length`', function(assert) {
21219      assert.expect(4);
21220
21221      lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
21222        assert.strictEqual(_.startsWith(string, 'a', position), false);
21223      });
21224    });
21225
21226    QUnit.test('should treat falsey `position` values as `0`', function(assert) {
21227      assert.expect(1);
21228
21229      var expected = lodashStable.map(falsey, stubTrue);
21230
21231      var actual = lodashStable.map(falsey, function(position) {
21232        return _.startsWith(string, 'a', position);
21233      });
21234
21235      assert.deepEqual(actual, expected);
21236    });
21237
21238    QUnit.test('should treat a negative `position` as `0`', function(assert) {
21239      assert.expect(6);
21240
21241      lodashStable.each([-1, -3, -Infinity], function(position) {
21242        assert.strictEqual(_.startsWith(string, 'a', position), true);
21243        assert.strictEqual(_.startsWith(string, 'b', position), false);
21244      });
21245    });
21246
21247    QUnit.test('should coerce `position` to an integer', function(assert) {
21248      assert.expect(1);
21249
21250      assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
21251    });
21252  }());
21253
21254  /*--------------------------------------------------------------------------*/
21255
21256  QUnit.module('lodash.startsWith and lodash.endsWith');
21257
21258  lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
21259    var func = _[methodName],
21260        isStartsWith = methodName == 'startsWith';
21261
21262    var string = 'abc',
21263        chr = isStartsWith ? 'a' : 'c';
21264
21265    QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
21266      assert.expect(2);
21267
21268      assert.strictEqual(func(Object(string), chr), true);
21269      assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
21270    });
21271
21272    QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
21273      assert.expect(2);
21274
21275      assert.strictEqual(func(string, Object(chr)), true);
21276      assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
21277    });
21278
21279    QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
21280      assert.expect(2);
21281
21282      var position = isStartsWith ? 1 : 2;
21283
21284      assert.strictEqual(func(string, 'b', Object(position)), true);
21285      assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
21286    });
21287
21288    QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
21289      assert.expect(1);
21290
21291      var positions = [-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity];
21292
21293      assert.ok(lodashStable.every(positions, function(position) {
21294        return func(string, '', position);
21295      }));
21296    });
21297  });
21298
21299  /*--------------------------------------------------------------------------*/
21300
21301  QUnit.module('stub methods');
21302
21303  lodashStable.each(['noop', 'stubTrue', 'stubFalse', 'stubArray', 'stubObject', 'stubString'], function(methodName) {
21304    var func = _[methodName];
21305
21306    var pair = ({
21307      'stubArray': [[], 'an empty array'],
21308      'stubFalse': [false, '`false`'],
21309      'stubObject': [{}, 'an empty object'],
21310      'stubString': ['', 'an empty string'],
21311      'stubTrue': [true, '`true`'],
21312      'noop': [undefined, '`undefined`']
21313    })[methodName];
21314
21315    var values = Array(2).concat(empties, true, 1, 'a'),
21316        expected = lodashStable.map(values, lodashStable.constant(pair[0]));
21317
21318    QUnit.test('`_.' + methodName + '` should return ' + pair[1], function(assert) {
21319      assert.expect(1);
21320
21321      var actual = lodashStable.map(values, function(value, index) {
21322        if (index < 2) {
21323          return index ? func.call({}) : func();
21324        }
21325        return func(value);
21326      });
21327
21328      assert.deepEqual(actual, expected);
21329    });
21330  });
21331
21332  /*--------------------------------------------------------------------------*/
21333
21334  QUnit.module('lodash.subtract');
21335
21336  (function() {
21337    QUnit.test('should subtract two numbers', function(assert) {
21338      assert.expect(3);
21339
21340      assert.strictEqual(_.subtract(6, 4), 2);
21341      assert.strictEqual(_.subtract(-6, 4), -10);
21342      assert.strictEqual(_.subtract(-6, -4), -2);
21343    });
21344
21345    QUnit.test('should coerce arguments to numbers', function(assert) {
21346      assert.expect(2);
21347
21348      assert.strictEqual(_.subtract('6', '4'), 2);
21349      assert.deepEqual(_.subtract('x', 'y'), NaN);
21350    });
21351  }());
21352
21353  /*--------------------------------------------------------------------------*/
21354
21355  QUnit.module('math operator methods');
21356
21357  lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
21358    var func = _[methodName],
21359        isAddSub = methodName == 'add' || methodName == 'subtract';
21360
21361    QUnit.test('`_.' + methodName + '` should return `' + (isAddSub ? 0 : 1) + '` when no arguments are given', function(assert) {
21362      assert.expect(1);
21363
21364      assert.strictEqual(func(), isAddSub ? 0 : 1);
21365    });
21366
21367    QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
21368      assert.expect(3);
21369
21370      assert.strictEqual(func(6), 6);
21371      assert.strictEqual(func(6, undefined), 6);
21372      assert.strictEqual(func(undefined, 4), 4);
21373    });
21374
21375    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
21376      assert.expect(2);
21377
21378      var values = [0, '0', -0, '-0'],
21379          expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
21380
21381      lodashStable.times(2, function(index) {
21382        var actual = lodashStable.map(values, function(value) {
21383          var result = index ? func(undefined, value) : func(value);
21384          return [result, 1 / result];
21385        });
21386
21387        assert.deepEqual(actual, expected);
21388      });
21389    });
21390
21391    QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
21392      assert.expect(2);
21393
21394      assert.deepEqual(func(0, {}), NaN);
21395      assert.deepEqual(func({}, 0), NaN);
21396    });
21397
21398    QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
21399      assert.expect(2);
21400
21401      if (Symbol) {
21402        assert.deepEqual(func(0, symbol), NaN);
21403        assert.deepEqual(func(symbol, 0), NaN);
21404      }
21405      else {
21406        skipAssert(assert, 2);
21407      }
21408    });
21409
21410    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
21411      assert.expect(1);
21412
21413      if (!isNpm) {
21414        var actual = _(1)[methodName](2);
21415        assert.notOk(actual instanceof _);
21416      }
21417      else {
21418        skipAssert(assert);
21419      }
21420    });
21421
21422    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
21423      assert.expect(1);
21424
21425      if (!isNpm) {
21426        var actual = _(1).chain()[methodName](2);
21427        assert.ok(actual instanceof _);
21428      }
21429      else {
21430        skipAssert(assert);
21431      }
21432    });
21433  });
21434
21435  /*--------------------------------------------------------------------------*/
21436
21437  QUnit.module('lodash.sumBy');
21438
21439  (function() {
21440    var array = [6, 4, 2],
21441        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
21442
21443    QUnit.test('should work with an `iteratee`', function(assert) {
21444      assert.expect(1);
21445
21446      var actual = _.sumBy(objects, function(object) {
21447        return object.a;
21448      });
21449
21450      assert.deepEqual(actual, 6);
21451    });
21452
21453    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
21454      assert.expect(1);
21455
21456      var args;
21457
21458      _.sumBy(array, function() {
21459        args || (args = slice.call(arguments));
21460      });
21461
21462      assert.deepEqual(args, [6]);
21463    });
21464
21465    QUnit.test('should work with `_.property` shorthands', function(assert) {
21466      assert.expect(2);
21467
21468      var arrays = [[2], [3], [1]];
21469      assert.strictEqual(_.sumBy(arrays, 0), 6);
21470      assert.strictEqual(_.sumBy(objects, 'a'), 6);
21471    });
21472  }());
21473
21474  /*--------------------------------------------------------------------------*/
21475
21476  QUnit.module('sum methods');
21477
21478  lodashStable.each(['sum', 'sumBy'], function(methodName) {
21479    var array = [6, 4, 2],
21480        func = _[methodName];
21481
21482    QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
21483      assert.expect(1);
21484
21485      assert.strictEqual(func(array), 12);
21486    });
21487
21488    QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
21489      assert.expect(1);
21490
21491      var expected = lodashStable.map(empties, stubZero);
21492
21493      var actual = lodashStable.map(empties, function(value) {
21494        return func(value);
21495      });
21496
21497      assert.deepEqual(actual, expected);
21498    });
21499
21500    QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
21501      assert.expect(1);
21502
21503      assert.strictEqual(func([1, undefined]), 1);
21504    });
21505
21506    QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
21507      assert.expect(1);
21508
21509      assert.deepEqual(func([1, NaN]), NaN);
21510    });
21511
21512    QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
21513      assert.expect(1);
21514
21515      assert.strictEqual(func(['1', '2']), '12');
21516    });
21517  });
21518
21519  /*--------------------------------------------------------------------------*/
21520
21521  QUnit.module('lodash.tail');
21522
21523  (function() {
21524    var array = [1, 2, 3];
21525
21526    QUnit.test('should accept a falsey `array`', function(assert) {
21527      assert.expect(1);
21528
21529      var expected = lodashStable.map(falsey, stubArray);
21530
21531      var actual = lodashStable.map(falsey, function(array, index) {
21532        try {
21533          return index ? _.tail(array) : _.tail();
21534        } catch (e) {}
21535      });
21536
21537      assert.deepEqual(actual, expected);
21538    });
21539
21540    QUnit.test('should exclude the first element', function(assert) {
21541      assert.expect(1);
21542
21543      assert.deepEqual(_.tail(array), [2, 3]);
21544    });
21545
21546    QUnit.test('should return an empty when querying empty arrays', function(assert) {
21547      assert.expect(1);
21548
21549      assert.deepEqual(_.tail([]), []);
21550    });
21551
21552    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21553      assert.expect(1);
21554
21555      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21556          actual = lodashStable.map(array, _.tail);
21557
21558      assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
21559    });
21560
21561    QUnit.test('should work in a lazy sequence', function(assert) {
21562      assert.expect(4);
21563
21564      if (!isNpm) {
21565        var array = lodashStable.range(LARGE_ARRAY_SIZE),
21566            values = [];
21567
21568        var actual = _(array).tail().filter(function(value) {
21569          values.push(value);
21570          return false;
21571        })
21572        .value();
21573
21574        assert.deepEqual(actual, []);
21575        assert.deepEqual(values, array.slice(1));
21576
21577        values = [];
21578
21579        actual = _(array).filter(function(value) {
21580          values.push(value);
21581          return isEven(value);
21582        })
21583        .tail()
21584        .value();
21585
21586        assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
21587        assert.deepEqual(values, array);
21588      }
21589      else {
21590        skipAssert(assert, 4);
21591      }
21592    });
21593
21594    QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
21595      assert.expect(4);
21596
21597      if (!isNpm) {
21598        var array = lodashStable.range(LARGE_ARRAY_SIZE),
21599            iteratee = function() { pass = false; },
21600            pass = true,
21601            actual = _(array).slice(0, 1).tail().map(iteratee).value();
21602
21603        assert.ok(pass);
21604        assert.deepEqual(actual, []);
21605
21606        pass = true;
21607        actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
21608
21609        assert.ok(pass);
21610        assert.deepEqual(actual, []);
21611      }
21612      else {
21613        skipAssert(assert, 4);
21614      }
21615    });
21616  }());
21617
21618  /*--------------------------------------------------------------------------*/
21619
21620  QUnit.module('lodash.take');
21621
21622  (function() {
21623    var array = [1, 2, 3];
21624
21625    QUnit.test('should take the first two elements', function(assert) {
21626      assert.expect(1);
21627
21628      assert.deepEqual(_.take(array, 2), [1, 2]);
21629    });
21630
21631    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21632      assert.expect(1);
21633
21634      var expected = lodashStable.map(falsey, function(value) {
21635        return value === undefined ? [1] : [];
21636      });
21637
21638      var actual = lodashStable.map(falsey, function(n) {
21639        return _.take(array, n);
21640      });
21641
21642      assert.deepEqual(actual, expected);
21643    });
21644
21645    QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21646      assert.expect(3);
21647
21648      lodashStable.each([0, -1, -Infinity], function(n) {
21649        assert.deepEqual(_.take(array, n), []);
21650      });
21651    });
21652
21653    QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21654      assert.expect(4);
21655
21656      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21657        assert.deepEqual(_.take(array, n), array);
21658      });
21659    });
21660
21661    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21662      assert.expect(1);
21663
21664      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21665          actual = lodashStable.map(array, _.take);
21666
21667      assert.deepEqual(actual, [[1], [4], [7]]);
21668    });
21669
21670    QUnit.test('should work in a lazy sequence', function(assert) {
21671      assert.expect(6);
21672
21673      if (!isNpm) {
21674        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
21675            predicate = function(value) { values.push(value); return isEven(value); },
21676            values = [],
21677            actual = _(array).take(2).take().value();
21678
21679        assert.deepEqual(actual, _.take(_.take(array, 2)));
21680
21681        actual = _(array).filter(predicate).take(2).take().value();
21682        assert.deepEqual(values, [1, 2]);
21683        assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
21684
21685        actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
21686        assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
21687
21688        values = [];
21689
21690        actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
21691        assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
21692        assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
21693      }
21694      else {
21695        skipAssert(assert, 6);
21696      }
21697    });
21698  }());
21699
21700  /*--------------------------------------------------------------------------*/
21701
21702  QUnit.module('lodash.takeRight');
21703
21704  (function() {
21705    var array = [1, 2, 3];
21706
21707    QUnit.test('should take the last two elements', function(assert) {
21708      assert.expect(1);
21709
21710      assert.deepEqual(_.takeRight(array, 2), [2, 3]);
21711    });
21712
21713    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21714      assert.expect(1);
21715
21716      var expected = lodashStable.map(falsey, function(value) {
21717        return value === undefined ? [3] : [];
21718      });
21719
21720      var actual = lodashStable.map(falsey, function(n) {
21721        return _.takeRight(array, n);
21722      });
21723
21724      assert.deepEqual(actual, expected);
21725    });
21726
21727    QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21728      assert.expect(3);
21729
21730      lodashStable.each([0, -1, -Infinity], function(n) {
21731        assert.deepEqual(_.takeRight(array, n), []);
21732      });
21733    });
21734
21735    QUnit.test('should return all elements when `n` >= `length`', function(assert) {
21736      assert.expect(4);
21737
21738      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21739        assert.deepEqual(_.takeRight(array, n), array);
21740      });
21741    });
21742
21743    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21744      assert.expect(1);
21745
21746      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21747          actual = lodashStable.map(array, _.takeRight);
21748
21749      assert.deepEqual(actual, [[3], [6], [9]]);
21750    });
21751
21752    QUnit.test('should work in a lazy sequence', function(assert) {
21753      assert.expect(6);
21754
21755      if (!isNpm) {
21756        var array = lodashStable.range(LARGE_ARRAY_SIZE),
21757            predicate = function(value) { values.push(value); return isEven(value); },
21758            values = [],
21759            actual = _(array).takeRight(2).takeRight().value();
21760
21761        assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
21762
21763        actual = _(array).filter(predicate).takeRight(2).takeRight().value();
21764        assert.deepEqual(values, array);
21765        assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
21766
21767        actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
21768        assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
21769
21770        values = [];
21771
21772        actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
21773        assert.deepEqual(values, array);
21774        assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
21775      }
21776      else {
21777        skipAssert(assert, 6);
21778      }
21779    });
21780  }());
21781
21782  /*--------------------------------------------------------------------------*/
21783
21784  QUnit.module('lodash.takeRightWhile');
21785
21786  (function() {
21787    var array = [1, 2, 3, 4];
21788
21789    var objects = [
21790      { 'a': 0, 'b': 0 },
21791      { 'a': 1, 'b': 1 },
21792      { 'a': 2, 'b': 2 }
21793    ];
21794
21795    QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21796      assert.expect(1);
21797
21798      var actual = _.takeRightWhile(array, function(n) {
21799        return n > 2;
21800      });
21801
21802      assert.deepEqual(actual, [3, 4]);
21803    });
21804
21805    QUnit.test('should provide correct `predicate` arguments', function(assert) {
21806      assert.expect(1);
21807
21808      var args;
21809
21810      _.takeRightWhile(array, function() {
21811        args = slice.call(arguments);
21812      });
21813
21814      assert.deepEqual(args, [4, 3, array]);
21815    });
21816
21817    QUnit.test('should work with `_.matches` shorthands', function(assert) {
21818      assert.expect(1);
21819
21820      assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
21821    });
21822
21823    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21824      assert.expect(1);
21825
21826      assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
21827    });
21828
21829    QUnit.test('should work with `_.property` shorthands', function(assert) {
21830      assert.expect(1);
21831
21832      assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
21833    });
21834
21835    QUnit.test('should work in a lazy sequence', function(assert) {
21836      assert.expect(3);
21837
21838      if (!isNpm) {
21839        var array = lodashStable.range(LARGE_ARRAY_SIZE),
21840            predicate = function(n) { return n > 2; },
21841            expected = _.takeRightWhile(array, predicate),
21842            wrapped = _(array).takeRightWhile(predicate);
21843
21844        assert.deepEqual(wrapped.value(), expected);
21845        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21846        assert.strictEqual(wrapped.last(), _.last(expected));
21847      }
21848      else {
21849        skipAssert(assert, 3);
21850      }
21851    });
21852
21853    QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
21854      assert.expect(5);
21855
21856      if (!isNpm) {
21857        var args,
21858            array = lodashStable.range(LARGE_ARRAY_SIZE + 1);
21859
21860        var expected = [
21861          square(LARGE_ARRAY_SIZE),
21862          LARGE_ARRAY_SIZE - 1,
21863          lodashStable.map(array.slice(1), square)
21864        ];
21865
21866        _(array).slice(1).takeRightWhile(function(value, index, array) {
21867          args = slice.call(arguments);
21868        }).value();
21869
21870        assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
21871
21872        _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
21873          args = slice.call(arguments);
21874        }).value();
21875
21876        assert.deepEqual(args, expected);
21877
21878        _(array).slice(1).map(square).takeRightWhile(function(value, index) {
21879          args = slice.call(arguments);
21880        }).value();
21881
21882        assert.deepEqual(args, expected);
21883
21884        _(array).slice(1).map(square).takeRightWhile(function(index) {
21885          args = slice.call(arguments);
21886        }).value();
21887
21888        assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
21889
21890        _(array).slice(1).map(square).takeRightWhile(function() {
21891          args = slice.call(arguments);
21892        }).value();
21893
21894        assert.deepEqual(args, expected);
21895      }
21896      else {
21897        skipAssert(assert, 5);
21898      }
21899    });
21900  }());
21901
21902  /*--------------------------------------------------------------------------*/
21903
21904  QUnit.module('lodash.takeWhile');
21905
21906  (function() {
21907    var array = [1, 2, 3, 4];
21908
21909    var objects = [
21910      { 'a': 2, 'b': 2 },
21911      { 'a': 1, 'b': 1 },
21912      { 'a': 0, 'b': 0 }
21913    ];
21914
21915    QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21916      assert.expect(1);
21917
21918      var actual = _.takeWhile(array, function(n) {
21919        return n < 3;
21920      });
21921
21922      assert.deepEqual(actual, [1, 2]);
21923    });
21924
21925    QUnit.test('should provide correct `predicate` arguments', function(assert) {
21926      assert.expect(1);
21927
21928      var args;
21929
21930      _.takeWhile(array, function() {
21931        args = slice.call(arguments);
21932      });
21933
21934      assert.deepEqual(args, [1, 0, array]);
21935    });
21936
21937    QUnit.test('should work with `_.matches` shorthands', function(assert) {
21938      assert.expect(1);
21939
21940      assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
21941    });
21942
21943    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21944      assert.expect(1);
21945
21946      assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
21947    });
21948    QUnit.test('should work with `_.property` shorthands', function(assert) {
21949      assert.expect(1);
21950
21951      assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
21952    });
21953
21954    QUnit.test('should work in a lazy sequence', function(assert) {
21955      assert.expect(3);
21956
21957      if (!isNpm) {
21958        var array = lodashStable.range(LARGE_ARRAY_SIZE),
21959            predicate = function(n) { return n < 3; },
21960            expected = _.takeWhile(array, predicate),
21961            wrapped = _(array).takeWhile(predicate);
21962
21963        assert.deepEqual(wrapped.value(), expected);
21964        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21965        assert.strictEqual(wrapped.last(), _.last(expected));
21966      }
21967      else {
21968        skipAssert(assert, 3);
21969      }
21970    });
21971
21972    QUnit.test('should work in a lazy sequence with `take`', function(assert) {
21973      assert.expect(1);
21974
21975      if (!isNpm) {
21976        var array = lodashStable.range(LARGE_ARRAY_SIZE);
21977
21978        var actual = _(array)
21979          .takeWhile(function(n) { return n < 4; })
21980          .take(2)
21981          .takeWhile(function(n) { return n == 0; })
21982          .value();
21983
21984        assert.deepEqual(actual, [0]);
21985      }
21986      else {
21987        skipAssert(assert);
21988      }
21989    });
21990
21991    QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) {
21992      assert.expect(5);
21993
21994      if (!isNpm) {
21995        var args,
21996            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21997            expected = [1, 0, lodashStable.map(array.slice(1), square)];
21998
21999        _(array).slice(1).takeWhile(function(value, index, array) {
22000          args = slice.call(arguments);
22001        }).value();
22002
22003        assert.deepEqual(args, [1, 0, array.slice(1)]);
22004
22005        _(array).slice(1).map(square).takeWhile(function(value, index, array) {
22006          args = slice.call(arguments);
22007        }).value();
22008
22009        assert.deepEqual(args, expected);
22010
22011        _(array).slice(1).map(square).takeWhile(function(value, index) {
22012          args = slice.call(arguments);
22013        }).value();
22014
22015        assert.deepEqual(args, expected);
22016
22017        _(array).slice(1).map(square).takeWhile(function(value) {
22018          args = slice.call(arguments);
22019        }).value();
22020
22021        assert.deepEqual(args, [1]);
22022
22023        _(array).slice(1).map(square).takeWhile(function() {
22024          args = slice.call(arguments);
22025        }).value();
22026
22027        assert.deepEqual(args, expected);
22028      }
22029      else {
22030        skipAssert(assert, 5);
22031      }
22032    });
22033  }());
22034
22035  /*--------------------------------------------------------------------------*/
22036
22037  QUnit.module('lodash.tap');
22038
22039  (function() {
22040    QUnit.test('should intercept and return the given value', function(assert) {
22041      assert.expect(2);
22042
22043      if (!isNpm) {
22044        var intercepted,
22045            array = [1, 2, 3];
22046
22047        var actual = _.tap(array, function(value) {
22048          intercepted = value;
22049        });
22050
22051        assert.strictEqual(actual, array);
22052        assert.strictEqual(intercepted, array);
22053      }
22054      else {
22055        skipAssert(assert, 2);
22056      }
22057    });
22058
22059    QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
22060      assert.expect(2);
22061
22062      if (!isNpm) {
22063        var intercepted,
22064            array = [1, 2, 3];
22065
22066        var wrapped = _(array).tap(function(value) {
22067          intercepted = value;
22068          value.pop();
22069        });
22070
22071        assert.ok(wrapped instanceof _);
22072
22073        wrapped.value();
22074        assert.strictEqual(intercepted, array);
22075      }
22076      else {
22077        skipAssert(assert, 2);
22078      }
22079    });
22080  }());
22081
22082  /*--------------------------------------------------------------------------*/
22083
22084  QUnit.module('lodash.template');
22085
22086  (function() {
22087    QUnit.test('should escape values in "escape" delimiters', function(assert) {
22088      assert.expect(1);
22089
22090      var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
22091          expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;/</p>')),
22092          data = { 'value': '&<>"\'/' };
22093
22094      var actual = lodashStable.map(strings, function(string) {
22095        return _.template(string)(data);
22096      });
22097
22098      assert.deepEqual(actual, expected);
22099    });
22100
22101    QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
22102      assert.expect(1);
22103
22104      var compiled = _.template('<%= typeof __e %>');
22105      assert.strictEqual(compiled({}), 'undefined');
22106    });
22107
22108    QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
22109      assert.expect(1);
22110
22111      var compiled = _.template(
22112        '<ul><%\
22113        for (var key in collection) {\
22114          %><li><%= collection[key] %></li><%\
22115        } %></ul>'
22116      );
22117
22118      var data = { 'collection': { 'a': 'A', 'b': 'B' } },
22119          actual = compiled(data);
22120
22121      assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
22122    });
22123
22124    QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
22125      assert.expect(1);
22126
22127      var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
22128          data = { 'value': true };
22129
22130      assert.strictEqual(compiled(data), 'yap');
22131    });
22132
22133    QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
22134      assert.expect(1);
22135
22136      var compiled = _.template('<% var b = a; %><%= b.value %>'),
22137          data = { 'a': { 'value': 1 } };
22138
22139      assert.strictEqual(compiled(data), '1');
22140    });
22141
22142    QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
22143      assert.expect(1);
22144
22145      var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
22146          expected = lodashStable.map(strings, lodashStable.constant('ABC')),
22147          data = { 'a': 'A' };
22148
22149      var actual = lodashStable.map(strings, function(string) {
22150        return _.template(string)(data);
22151      });
22152
22153      assert.deepEqual(actual, expected);
22154    });
22155
22156    QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
22157      assert.expect(1);
22158
22159      var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
22160          data = { 'a': true };
22161
22162      assert.strictEqual(compiled(data), 'a="A"');
22163    });
22164
22165    QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
22166      assert.expect(1);
22167
22168      var compiled = _.template('<%= value ? value : "b" %>'),
22169          data = { 'value': 'a' };
22170
22171      assert.strictEqual(compiled(data), 'a');
22172    });
22173
22174    QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
22175      assert.expect(1);
22176
22177      var compiled = _.template('<%= typeof Math.abs %>');
22178
22179      try {
22180        var actual = compiled();
22181      } catch (e) {}
22182
22183      assert.strictEqual(actual, 'function');
22184    });
22185
22186    QUnit.test('should support complex "interpolate" delimiters', function(assert) {
22187      assert.expect(22);
22188
22189      lodashStable.forOwn({
22190        '<%= a + b %>': '3',
22191        '<%= b - a %>': '1',
22192        '<%= a = b %>': '2',
22193        '<%= !a %>': 'false',
22194        '<%= ~a %>': '-2',
22195        '<%= a * b %>': '2',
22196        '<%= a / b %>': '0.5',
22197        '<%= a % b %>': '1',
22198        '<%= a >> b %>': '0',
22199        '<%= a << b %>': '4',
22200        '<%= a & b %>': '0',
22201        '<%= a ^ b %>': '3',
22202        '<%= a | b %>': '3',
22203        '<%= {}.toString.call(0) %>': numberTag,
22204        '<%= a.toFixed(2) %>': '1.00',
22205        '<%= obj["a"] %>': '1',
22206        '<%= delete a %>': 'true',
22207        '<%= "a" in obj %>': 'true',
22208        '<%= obj instanceof Object %>': 'true',
22209        '<%= new Boolean %>': 'false',
22210        '<%= typeof a %>': 'number',
22211        '<%= void a %>': ''
22212      },
22213      function(value, key) {
22214        var compiled = _.template(key),
22215            data = { 'a': 1, 'b': 2 };
22216
22217        assert.strictEqual(compiled(data), value, key);
22218      });
22219    });
22220
22221    QUnit.test('should support ES6 template delimiters', function(assert) {
22222      assert.expect(2);
22223
22224      var data = { 'value': 2 };
22225      assert.strictEqual(_.template('1${value}3')(data), '123');
22226      assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
22227    });
22228
22229    QUnit.test('should support the "imports" option', function(assert) {
22230      assert.expect(1);
22231
22232      var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
22233      assert.strictEqual(compiled({}), '1');
22234    });
22235
22236    QUnit.test('should support the "variable" options', function(assert) {
22237      assert.expect(1);
22238
22239      var compiled = _.template(
22240        '<% _.each( data.a, function( value ) { %>' +
22241            '<%= value.valueOf() %>' +
22242        '<% }) %>', { 'variable': 'data' }
22243      );
22244
22245      var data = { 'a': [1, 2, 3] };
22246
22247      try {
22248        assert.strictEqual(compiled(data), '123');
22249      } catch (e) {
22250        assert.ok(false, e.message);
22251      }
22252    });
22253
22254    QUnit.test('should support custom delimiters', function(assert) {
22255      assert.expect(2);
22256
22257      lodashStable.times(2, function(index) {
22258        var settingsClone = lodashStable.clone(_.templateSettings);
22259
22260        var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22261          'escape': /\{\{-([\s\S]+?)\}\}/g,
22262          'evaluate': /\{\{([\s\S]+?)\}\}/g,
22263          'interpolate': /\{\{=([\s\S]+?)\}\}/g
22264        });
22265
22266        var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22267            compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
22268            data = { 'collection': ['a & A', 'b & B'] };
22269
22270        assert.strictEqual(compiled(data), expected);
22271        lodashStable.assign(_.templateSettings, settingsClone);
22272      });
22273    });
22274
22275    QUnit.test('should support custom delimiters containing special characters', function(assert) {
22276      assert.expect(2);
22277
22278      lodashStable.times(2, function(index) {
22279        var settingsClone = lodashStable.clone(_.templateSettings);
22280
22281        var settings = lodashStable.assign(index ? _.templateSettings : {}, {
22282          'escape': /<\?-([\s\S]+?)\?>/g,
22283          'evaluate': /<\?([\s\S]+?)\?>/g,
22284          'interpolate': /<\?=([\s\S]+?)\?>/g
22285        });
22286
22287        var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
22288            compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
22289            data = { 'collection': ['a & A', 'b & B'] };
22290
22291        assert.strictEqual(compiled(data), expected);
22292        lodashStable.assign(_.templateSettings, settingsClone);
22293      });
22294    });
22295
22296    QUnit.test('should use a `with` statement by default', function(assert) {
22297      assert.expect(1);
22298
22299      var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
22300          actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
22301
22302      assert.strictEqual(actual, '1b012');
22303    });
22304
22305    QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
22306      assert.expect(1);
22307
22308      var lodash = _.templateSettings.imports._,
22309          settingsClone = lodashStable.clone(lodash.templateSettings);
22310
22311      lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
22312        'interpolate': /\{\{=([\s\S]+?)\}\}/g
22313      });
22314
22315      var compiled = _.template('{{= a }}');
22316      assert.strictEqual(compiled({ 'a': 1 }), '1');
22317
22318      if (settingsClone) {
22319        lodashStable.assign(lodash.templateSettings, settingsClone);
22320      } else {
22321        delete lodash.templateSettings;
22322      }
22323    });
22324
22325    QUnit.test('should fallback to `_.templateSettings`', function(assert) {
22326      assert.expect(1);
22327
22328      var lodash = _.templateSettings.imports._,
22329          delimiter = _.templateSettings.interpolate;
22330
22331      _.templateSettings.imports._ = { 'escape': lodashStable.escape };
22332      _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
22333
22334      var compiled = _.template('{{= a }}');
22335      assert.strictEqual(compiled({ 'a': 1 }), '1');
22336
22337      _.templateSettings.imports._ = lodash;
22338      _.templateSettings.interpolate = delimiter;
22339    });
22340
22341    QUnit.test('should ignore `null` delimiters', function(assert) {
22342      assert.expect(3);
22343
22344      var delimiter = {
22345        'escape': /\{\{-([\s\S]+?)\}\}/g,
22346        'evaluate': /\{\{([\s\S]+?)\}\}/g,
22347        'interpolate': /\{\{=([\s\S]+?)\}\}/g
22348      };
22349
22350      lodashStable.forOwn({
22351        'escape': '{{- a }}',
22352        'evaluate': '{{ print(a) }}',
22353        'interpolate': '{{= a }}'
22354      },
22355      function(value, key) {
22356        var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
22357        settings[key] = delimiter[key];
22358
22359        var expected = '1 <%- a %> <% print(a) %> <%= a %>',
22360            compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
22361            data = { 'a': 1 };
22362
22363        assert.strictEqual(compiled(data), expected);
22364      });
22365    });
22366
22367    QUnit.test('should work without delimiters', function(assert) {
22368      assert.expect(1);
22369
22370      var expected = 'abc';
22371      assert.strictEqual(_.template(expected)({}), expected);
22372    });
22373
22374    QUnit.test('should work with `this` references', function(assert) {
22375      assert.expect(2);
22376
22377      var compiled = _.template('a<%= this.String("b") %>c');
22378      assert.strictEqual(compiled(), 'abc');
22379
22380      var object = { 'b': 'B' };
22381      object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
22382      assert.strictEqual(object.compiled(), 'ABC');
22383    });
22384
22385    QUnit.test('should work with backslashes', function(assert) {
22386      assert.expect(1);
22387
22388      var compiled = _.template('<%= a %> \\b'),
22389          data = { 'a': 'A' };
22390
22391      assert.strictEqual(compiled(data), 'A \\b');
22392    });
22393
22394    QUnit.test('should work with escaped characters in string literals', function(assert) {
22395      assert.expect(2);
22396
22397      var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
22398      assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
22399
22400      var data = { 'a': 'A' };
22401      compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
22402      assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
22403    });
22404
22405    QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
22406      assert.expect(1);
22407
22408      var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
22409      assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
22410    });
22411
22412    QUnit.test('should work with statements containing quotes', function(assert) {
22413      assert.expect(1);
22414
22415      var compiled = _.template("<%\
22416        if (a == 'A' || a == \"a\") {\
22417          %>'a',\"A\"<%\
22418        } %>"
22419      );
22420
22421      var data = { 'a': 'A' };
22422      assert.strictEqual(compiled(data), "'a',\"A\"");
22423    });
22424
22425    QUnit.test('should work with templates containing newlines and comments', function(assert) {
22426      assert.expect(1);
22427
22428      var compiled = _.template('<%\n\
22429        // A code comment.\n\
22430        if (value) { value += 3; }\n\
22431        %><p><%= value %></p>'
22432      );
22433
22434      assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
22435    });
22436
22437    QUnit.test('should tokenize delimiters', function(assert) {
22438      assert.expect(1);
22439
22440      var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
22441          data = { 'type': 1 };
22442
22443      assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
22444    });
22445
22446    QUnit.test('should evaluate delimiters once', function(assert) {
22447      assert.expect(1);
22448
22449      var actual = [],
22450          compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
22451          data = { 'func': function(value) { actual.push(value); } };
22452
22453      compiled(data);
22454      assert.deepEqual(actual, ['a', 'b', 'c']);
22455    });
22456
22457    QUnit.test('should match delimiters before escaping text', function(assert) {
22458      assert.expect(1);
22459
22460      var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
22461      assert.strictEqual(compiled(), '<<\n a \n>>');
22462    });
22463
22464    QUnit.test('should resolve nullish values to an empty string', function(assert) {
22465      assert.expect(3);
22466
22467      var compiled = _.template('<%= a %><%- a %>'),
22468          data = { 'a': null };
22469
22470      assert.strictEqual(compiled(data), '');
22471
22472      data = { 'a': undefined };
22473      assert.strictEqual(compiled(data), '');
22474
22475      data = { 'a': {} };
22476      compiled = _.template('<%= a.b %><%- a.b %>');
22477      assert.strictEqual(compiled(data), '');
22478    });
22479
22480    QUnit.test('should return an empty string for empty values', function(assert) {
22481      assert.expect(1);
22482
22483      var values = [, null, undefined, ''],
22484          expected = lodashStable.map(values, stubString),
22485          data = { 'a': 1 };
22486
22487      var actual = lodashStable.map(values, function(value, index) {
22488        var compiled = index ? _.template(value) : _.template();
22489        return compiled(data);
22490      });
22491
22492      assert.deepEqual(actual, expected);
22493    });
22494
22495    QUnit.test('should parse delimiters without newlines', function(assert) {
22496      assert.expect(1);
22497
22498      var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
22499          compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
22500          data = { 'value': true };
22501
22502      assert.strictEqual(compiled(data), expected);
22503    });
22504
22505    QUnit.test('should support recursive calls', function(assert) {
22506      assert.expect(1);
22507
22508      var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
22509          data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
22510
22511      assert.strictEqual(compiled(data), 'AB');
22512    });
22513
22514    QUnit.test('should coerce `text` to a string', function(assert) {
22515      assert.expect(1);
22516
22517      var object = { 'toString': lodashStable.constant('<%= a %>') },
22518          data = { 'a': 1 };
22519
22520      assert.strictEqual(_.template(object)(data), '1');
22521    });
22522
22523    QUnit.test('should not modify the `options` object', function(assert) {
22524      assert.expect(1);
22525
22526      var options = {};
22527      _.template('', options);
22528      assert.deepEqual(options, {});
22529    });
22530
22531    QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
22532      assert.expect(2);
22533
22534      var data = { 'a': 1 };
22535
22536      assert.notOk('a' in _.templateSettings);
22537      _.template('', {}, data);
22538      assert.notOk('a' in _.templateSettings);
22539
22540      delete _.templateSettings.a;
22541    });
22542
22543    QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
22544      assert.expect(2);
22545
22546      _.template('')(1);
22547      assert.ok(true, '`data` value');
22548
22549      _.template('', 1)(1);
22550      assert.ok(true, '`options` value');
22551    });
22552
22553    QUnit.test('should expose the source on compiled templates', function(assert) {
22554      assert.expect(1);
22555
22556      var compiled = _.template('x'),
22557          values = [String(compiled), compiled.source],
22558          expected = lodashStable.map(values, stubTrue);
22559
22560      var actual = lodashStable.map(values, function(value) {
22561        return lodashStable.includes(value, '__p');
22562      });
22563
22564      assert.deepEqual(actual, expected);
22565    });
22566
22567    QUnit.test('should expose the source on SyntaxErrors', function(assert) {
22568      assert.expect(1);
22569
22570      try {
22571        _.template('<% if x %>');
22572      } catch (e) {
22573        var source = e.source;
22574      }
22575      assert.ok(lodashStable.includes(source, '__p'));
22576    });
22577
22578    QUnit.test('should not include sourceURLs in the source', function(assert) {
22579      assert.expect(1);
22580
22581      var options = { 'sourceURL': '/a/b/c' },
22582          compiled = _.template('x', options),
22583          values = [compiled.source, undefined];
22584
22585      try {
22586        _.template('<% if x %>', options);
22587      } catch (e) {
22588        values[1] = e.source;
22589      }
22590      var expected = lodashStable.map(values, stubFalse);
22591
22592      var actual = lodashStable.map(values, function(value) {
22593        return lodashStable.includes(value, 'sourceURL');
22594      });
22595
22596      assert.deepEqual(actual, expected);
22597    });
22598
22599    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22600      assert.expect(1);
22601
22602      var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
22603          compiles = lodashStable.map(array, _.template),
22604          data = { 'a': 'one', 'b': '"two"', 'c': 'three' };
22605
22606      var actual = lodashStable.map(compiles, function(compiled) {
22607        return compiled(data);
22608      });
22609
22610      assert.deepEqual(actual, ['one', '&quot;two&quot;', 'three']);
22611    });
22612  }());
22613
22614  /*--------------------------------------------------------------------------*/
22615
22616  QUnit.module('lodash.truncate');
22617
22618  (function() {
22619    var string = 'hi-diddly-ho there, neighborino';
22620
22621    QUnit.test('should use a default `length` of `30`', function(assert) {
22622      assert.expect(1);
22623
22624      assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
22625    });
22626
22627    QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
22628      assert.expect(2);
22629
22630      assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
22631      assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
22632    });
22633
22634    QUnit.test('should truncate string the given length', function(assert) {
22635      assert.expect(1);
22636
22637      assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
22638    });
22639
22640    QUnit.test('should support a `omission` option', function(assert) {
22641      assert.expect(1);
22642
22643      assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
22644    });
22645
22646    QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
22647      assert.expect(2);
22648
22649      assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
22650      assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
22651    });
22652
22653    QUnit.test('should support a `length` option', function(assert) {
22654      assert.expect(1);
22655
22656      assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
22657    });
22658
22659    QUnit.test('should support a `separator` option', function(assert) {
22660      assert.expect(3);
22661
22662      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
22663      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
22664      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
22665    });
22666
22667    QUnit.test('should treat negative `length` as `0`', function(assert) {
22668      assert.expect(2);
22669
22670      lodashStable.each([0, -2], function(length) {
22671        assert.strictEqual(_.truncate(string, { 'length': length }), '...');
22672      });
22673    });
22674
22675    QUnit.test('should coerce `length` to an integer', function(assert) {
22676      assert.expect(4);
22677
22678      lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
22679        var actual = index > 1 ? 'h...' : '...';
22680        assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
22681      });
22682    });
22683
22684    QUnit.test('should coerce `string` to a string', function(assert) {
22685      assert.expect(2);
22686
22687      assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
22688      assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
22689    });
22690
22691    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22692      assert.expect(1);
22693
22694      var actual = lodashStable.map([string, string, string], _.truncate),
22695          truncated = 'hi-diddly-ho there, neighbo...';
22696
22697      assert.deepEqual(actual, [truncated, truncated, truncated]);
22698    });
22699  }());
22700
22701  /*--------------------------------------------------------------------------*/
22702
22703  QUnit.module('lodash.throttle');
22704
22705  (function() {
22706    QUnit.test('should throttle a function', function(assert) {
22707      assert.expect(2);
22708
22709      var done = assert.async();
22710
22711      var callCount = 0,
22712          throttled = _.throttle(function() { callCount++; }, 32);
22713
22714      throttled();
22715      throttled();
22716      throttled();
22717
22718      var lastCount = callCount;
22719      assert.ok(callCount);
22720
22721      setTimeout(function() {
22722        assert.ok(callCount > lastCount);
22723        done();
22724      }, 64);
22725    });
22726
22727    QUnit.test('subsequent calls should return the result of the first call', function(assert) {
22728      assert.expect(5);
22729
22730      var done = assert.async();
22731
22732      var throttled = _.throttle(identity, 32),
22733          results = [throttled('a'), throttled('b')];
22734
22735      assert.deepEqual(results, ['a', 'a']);
22736
22737      setTimeout(function() {
22738        var results = [throttled('c'), throttled('d')];
22739        assert.notEqual(results[0], 'a');
22740        assert.notStrictEqual(results[0], undefined);
22741
22742        assert.notEqual(results[1], 'd');
22743        assert.notStrictEqual(results[1], undefined);
22744        done();
22745      }, 64);
22746    });
22747
22748    QUnit.test('should clear timeout when `func` is called', function(assert) {
22749      assert.expect(1);
22750
22751      var done = assert.async();
22752
22753      if (!isModularize) {
22754        var callCount = 0,
22755            dateCount = 0;
22756
22757        var lodash = _.runInContext({
22758          'Date': {
22759            'now': function() {
22760              return ++dateCount == 5 ? Infinity : +new Date;
22761            }
22762          }
22763        });
22764
22765        var throttled = lodash.throttle(function() { callCount++; }, 32);
22766
22767        throttled();
22768        throttled();
22769
22770        setTimeout(function() {
22771          assert.strictEqual(callCount, 2);
22772          done();
22773        }, 64);
22774      }
22775      else {
22776        skipAssert(assert);
22777        done();
22778      }
22779    });
22780
22781    QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
22782      assert.expect(2);
22783
22784      var done = assert.async();
22785
22786      var callCount = 0,
22787          throttled = _.throttle(function() { callCount++; }, 32);
22788
22789      throttled();
22790      assert.strictEqual(callCount, 1);
22791
22792      setTimeout(function() {
22793        assert.strictEqual(callCount, 1);
22794        done();
22795      }, 64);
22796    });
22797
22798    lodashStable.times(2, function(index) {
22799      QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
22800        assert.expect(1);
22801
22802        var done = assert.async();
22803
22804        var callCount = 0,
22805            limit = (argv || isPhantom) ? 1000 : 320,
22806            options = index ? { 'leading': false } : {},
22807            throttled = _.throttle(function() { callCount++; }, 32, options);
22808
22809        var start = +new Date;
22810        while ((new Date - start) < limit) {
22811          throttled();
22812        }
22813        var actual = callCount > 1;
22814        setTimeout(function() {
22815          assert.ok(actual);
22816          done();
22817        }, 1);
22818      });
22819    });
22820
22821    QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
22822      assert.expect(3);
22823
22824      var done = assert.async();
22825
22826      var callCount = 0;
22827
22828      var throttled = _.throttle(function() {
22829        callCount++;
22830      }, 128, { 'leading': false });
22831
22832      throttled();
22833
22834      setTimeout(function() {
22835        assert.strictEqual(callCount, 1);
22836        throttled();
22837      }, 192);
22838
22839      setTimeout(function() {
22840        assert.strictEqual(callCount, 1);
22841      }, 254);
22842
22843      setTimeout(function() {
22844        assert.strictEqual(callCount, 2);
22845        done();
22846      }, 384);
22847    });
22848
22849    QUnit.test('should apply default options', function(assert) {
22850      assert.expect(2);
22851
22852      var done = assert.async();
22853
22854      var callCount = 0,
22855          throttled = _.throttle(function() { callCount++; }, 32, {});
22856
22857      throttled();
22858      throttled();
22859      assert.strictEqual(callCount, 1);
22860
22861      setTimeout(function() {
22862        assert.strictEqual(callCount, 2);
22863        done();
22864      }, 128);
22865    });
22866
22867    QUnit.test('should support a `leading` option', function(assert) {
22868      assert.expect(2);
22869
22870      var withLeading = _.throttle(identity, 32, { 'leading': true });
22871      assert.strictEqual(withLeading('a'), 'a');
22872
22873      var withoutLeading = _.throttle(identity, 32, { 'leading': false });
22874      assert.strictEqual(withoutLeading('a'), undefined);
22875    });
22876
22877    QUnit.test('should support a `trailing` option', function(assert) {
22878      assert.expect(6);
22879
22880      var done = assert.async();
22881
22882      var withCount = 0,
22883          withoutCount = 0;
22884
22885      var withTrailing = _.throttle(function(value) {
22886        withCount++;
22887        return value;
22888      }, 64, { 'trailing': true });
22889
22890      var withoutTrailing = _.throttle(function(value) {
22891        withoutCount++;
22892        return value;
22893      }, 64, { 'trailing': false });
22894
22895      assert.strictEqual(withTrailing('a'), 'a');
22896      assert.strictEqual(withTrailing('b'), 'a');
22897
22898      assert.strictEqual(withoutTrailing('a'), 'a');
22899      assert.strictEqual(withoutTrailing('b'), 'a');
22900
22901      setTimeout(function() {
22902        assert.strictEqual(withCount, 2);
22903        assert.strictEqual(withoutCount, 1);
22904        done();
22905      }, 256);
22906    });
22907
22908    QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
22909      assert.expect(1);
22910
22911      var done = assert.async();
22912
22913      var callCount = 0;
22914
22915      var throttled = _.throttle(function() {
22916        callCount++;
22917      }, 64, { 'trailing': false });
22918
22919      throttled();
22920      throttled();
22921
22922      setTimeout(function() {
22923        throttled();
22924        throttled();
22925      }, 96);
22926
22927      setTimeout(function() {
22928        assert.ok(callCount > 1);
22929        done();
22930      }, 192);
22931    });
22932
22933    QUnit.test('should work with a system time of `0`', function(assert) {
22934      assert.expect(3);
22935
22936      var done = assert.async();
22937
22938      if (!isModularize) {
22939        var callCount = 0,
22940            dateCount = 0;
22941
22942        var lodash = _.runInContext({
22943          'Date': {
22944            'now': function() {
22945              return ++dateCount < 4 ? 0 : +new Date;
22946            }
22947          }
22948        });
22949
22950        var throttled = lodash.throttle(function(value) {
22951          callCount++;
22952          return value;
22953        }, 32);
22954
22955        var results = [throttled('a'), throttled('b'), throttled('c')];
22956        assert.deepEqual(results, ['a', 'a', 'a']);
22957        assert.strictEqual(callCount, 1);
22958
22959        setTimeout(function() {
22960          assert.strictEqual(callCount, 2);
22961          done();
22962        }, 64);
22963      }
22964      else {
22965        skipAssert(assert, 3);
22966        done();
22967      }
22968    });
22969  }());
22970
22971  /*--------------------------------------------------------------------------*/
22972
22973  QUnit.module('lodash.debounce and lodash.throttle');
22974
22975  lodashStable.each(['debounce', 'throttle'], function(methodName) {
22976    var func = _[methodName],
22977        isDebounce = methodName == 'debounce';
22978
22979    QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
22980      assert.expect(1);
22981
22982      func(noop, 32, 1);
22983      assert.ok(true);
22984    });
22985
22986    QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
22987      assert.expect(1);
22988
22989      var done = assert.async();
22990
22991      var callCount = 0,
22992          funced = func(function() { callCount++; });
22993
22994      funced();
22995
22996      setTimeout(function() {
22997        funced();
22998        assert.strictEqual(callCount, isDebounce ? 1 : 2);
22999        done();
23000      }, 32);
23001    });
23002
23003    QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
23004      assert.expect(1);
23005
23006      var done = assert.async();
23007
23008      var actual = [],
23009          object = { 'funced': func(function() { actual.push(this); }, 32) },
23010          expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
23011
23012      object.funced();
23013      if (!isDebounce) {
23014        object.funced();
23015      }
23016      setTimeout(function() {
23017        assert.deepEqual(actual, expected);
23018        done();
23019      }, 64);
23020    });
23021
23022    QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
23023      assert.expect(2);
23024
23025      var done = assert.async();
23026
23027      var actual = [],
23028          args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
23029          expected = args.slice(),
23030          queue = args.slice();
23031
23032      var funced = func(function() {
23033        var current = [this];
23034        push.apply(current, arguments);
23035        actual.push(current);
23036
23037        var next = queue.shift();
23038        if (next) {
23039          funced.call(next[0], next[1]);
23040        }
23041      }, 32);
23042
23043      var next = queue.shift();
23044      funced.call(next[0], next[1]);
23045      assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
23046
23047      setTimeout(function() {
23048        assert.deepEqual(actual, expected.slice(0, actual.length));
23049        done();
23050      }, 256);
23051    });
23052
23053    QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
23054      assert.expect(1);
23055
23056      var done = assert.async();
23057
23058      if (!isModularize) {
23059        var callCount = 0,
23060            dateCount = 0;
23061
23062        var lodash = _.runInContext({
23063          'Date': {
23064            'now': function() {
23065              return ++dateCount == 4
23066                ? +new Date(2012, 3, 23, 23, 27, 18)
23067                : +new Date;
23068            }
23069          }
23070        });
23071
23072        var funced = lodash[methodName](function() {
23073          callCount++;
23074        }, 32);
23075
23076        funced();
23077
23078        setTimeout(function() {
23079          funced();
23080          assert.strictEqual(callCount, isDebounce ? 1 : 2);
23081          done();
23082        }, 64);
23083      }
23084      else {
23085        skipAssert(assert);
23086        done();
23087      }
23088    });
23089
23090    QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
23091      assert.expect(1);
23092
23093      var done = assert.async();
23094
23095      var callCount = 0;
23096
23097      var funced = func(function() {
23098        callCount++;
23099      }, 32, { 'leading': false });
23100
23101      funced();
23102      funced.cancel();
23103
23104      setTimeout(function() {
23105        assert.strictEqual(callCount, 0);
23106        done();
23107      }, 64);
23108    });
23109
23110    QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
23111      assert.expect(3);
23112
23113      var done = assert.async();
23114
23115      var callCount = 0;
23116
23117      var funced = func(function() {
23118        return ++callCount;
23119      }, 32, { 'leading': true });
23120
23121      assert.strictEqual(funced(), 1);
23122      funced.cancel();
23123
23124      assert.strictEqual(funced(), 2);
23125      funced();
23126
23127      setTimeout(function() {
23128        assert.strictEqual(callCount, 3);
23129        done();
23130      }, 64);
23131    });
23132
23133    QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
23134      assert.expect(2);
23135
23136      var done = assert.async();
23137
23138      var callCount = 0;
23139
23140      var funced = func(function() {
23141        return ++callCount;
23142      }, 32, { 'leading': false });
23143
23144      funced();
23145      assert.strictEqual(funced.flush(), 1);
23146
23147      setTimeout(function() {
23148        assert.strictEqual(callCount, 1);
23149        done();
23150      }, 64);
23151    });
23152
23153    QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
23154      assert.expect(2);
23155
23156      var done = assert.async();
23157
23158      var callCount = 0,
23159          funced = func(function() { callCount++; }, 32);
23160
23161      funced.cancel();
23162      assert.strictEqual(funced.flush(), undefined);
23163
23164      setTimeout(function() {
23165        assert.strictEqual(callCount, 0);
23166        done();
23167      }, 64);
23168    });
23169  });
23170
23171  /*--------------------------------------------------------------------------*/
23172
23173  QUnit.module('lodash.times');
23174
23175  (function() {
23176    QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
23177      assert.expect(3);
23178
23179      lodashStable.each([-Infinity, NaN, Infinity], function(n) {
23180        assert.deepEqual(_.times(n), []);
23181      });
23182    });
23183
23184    QUnit.test('should coerce `n` to an integer', function(assert) {
23185      assert.expect(1);
23186
23187      var actual = _.times(2.6, _.identity);
23188      assert.deepEqual(actual, [0, 1]);
23189    });
23190
23191    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
23192      assert.expect(1);
23193
23194      var args;
23195
23196      _.times(1, function(assert) {
23197        args || (args = slice.call(arguments));
23198      });
23199
23200      assert.deepEqual(args, [0]);
23201    });
23202
23203    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
23204      assert.expect(1);
23205
23206      var values = [, null, undefined],
23207          expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
23208
23209      var actual = lodashStable.map(values, function(value, index) {
23210        return index ? _.times(3, value) : _.times(3);
23211      });
23212
23213      assert.deepEqual(actual, expected);
23214    });
23215
23216    QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
23217      assert.expect(1);
23218
23219      assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
23220    });
23221
23222    QUnit.test('should return an empty array for falsey and negative `n` values', function(assert) {
23223      assert.expect(1);
23224
23225      var values = falsey.concat(-1, -Infinity),
23226          expected = lodashStable.map(values, stubArray);
23227
23228      var actual = lodashStable.map(values, function(value, index) {
23229        return index ? _.times(value) : _.times();
23230      });
23231
23232      assert.deepEqual(actual, expected);
23233    });
23234
23235    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
23236      assert.expect(1);
23237
23238      if (!isNpm) {
23239        assert.deepEqual(_(3).times(), [0, 1, 2]);
23240      }
23241      else {
23242        skipAssert(assert);
23243      }
23244    });
23245
23246    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
23247      assert.expect(1);
23248
23249      if (!isNpm) {
23250        assert.ok(_(3).chain().times() instanceof _);
23251      }
23252      else {
23253        skipAssert(assert);
23254      }
23255    });
23256  }());
23257
23258  /*--------------------------------------------------------------------------*/
23259
23260  QUnit.module('lodash.toArray');
23261
23262  (function() {
23263    QUnit.test('should convert objects to arrays', function(assert) {
23264      assert.expect(1);
23265
23266      assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
23267    });
23268
23269    QUnit.test('should convert iterables to arrays', function(assert) {
23270      assert.expect(1);
23271
23272      if (Symbol && Symbol.iterator) {
23273        var object = { '0': 'a', 'length': 1 };
23274        object[Symbol.iterator] = arrayProto[Symbol.iterator];
23275
23276        assert.deepEqual(_.toArray(object), ['a']);
23277      }
23278      else {
23279        skipAssert(assert);
23280      }
23281    });
23282
23283    QUnit.test('should convert maps to arrays', function(assert) {
23284      assert.expect(1);
23285
23286      if (Map) {
23287        var map = new Map;
23288        map.set('a', 1);
23289        map.set('b', 2);
23290        assert.deepEqual(_.toArray(map), [['a', 1], ['b', 2]]);
23291      }
23292      else {
23293        skipAssert(assert);
23294      }
23295    });
23296
23297    QUnit.test('should convert strings to arrays', function(assert) {
23298      assert.expect(3);
23299
23300      assert.deepEqual(_.toArray(''), []);
23301      assert.deepEqual(_.toArray('ab'), ['a', 'b']);
23302      assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
23303    });
23304
23305    QUnit.test('should work in a lazy sequence', function(assert) {
23306      assert.expect(2);
23307
23308      if (!isNpm) {
23309        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1);
23310
23311        var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
23312          return ['key' + index, index];
23313        }));
23314
23315        var actual = _(array).slice(1).map(String).toArray().value();
23316        assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
23317
23318        actual = _(object).toArray().slice(1).map(String).value();
23319        assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
23320      }
23321      else {
23322        skipAssert(assert, 2);
23323      }
23324    });
23325  }());
23326
23327  /*--------------------------------------------------------------------------*/
23328
23329  QUnit.module('lodash.toLower');
23330
23331  (function() {
23332    QUnit.test('should convert whole string to lower case', function(assert) {
23333      assert.expect(3);
23334
23335      assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
23336      assert.deepEqual(_.toLower('fooBar'), 'foobar');
23337      assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
23338    });
23339  }());
23340
23341  /*--------------------------------------------------------------------------*/
23342
23343  QUnit.module('lodash.toUpper');
23344
23345  (function() {
23346    QUnit.test('should convert whole string to upper case', function(assert) {
23347      assert.expect(3);
23348
23349      assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
23350      assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
23351      assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
23352    });
23353  }());
23354
23355  /*--------------------------------------------------------------------------*/
23356
23357  QUnit.module('lodash.slice and lodash.toArray');
23358
23359  lodashStable.each(['slice', 'toArray'], function(methodName) {
23360    var array = [1, 2, 3],
23361        func = _[methodName];
23362
23363    QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
23364      assert.expect(3);
23365
23366      var sparse = Array(3);
23367      sparse[1] = 2;
23368
23369      var actual = func(sparse);
23370
23371      assert.ok('0' in actual);
23372      assert.ok('2' in actual);
23373      assert.deepEqual(actual, sparse);
23374    });
23375
23376    QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
23377      assert.expect(2);
23378
23379      var object = { '0': 'a', 'length': 1 };
23380      assert.deepEqual(func(object), ['a']);
23381      assert.deepEqual(func(args), array);
23382    });
23383
23384    QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
23385      assert.expect(2);
23386
23387      var actual = func(array);
23388      assert.deepEqual(actual, array);
23389      assert.notStrictEqual(actual, array);
23390    });
23391
23392    QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
23393      assert.expect(1);
23394
23395      if (document) {
23396        try {
23397          var actual = func(document.getElementsByTagName('body'));
23398        } catch (e) {}
23399
23400        assert.deepEqual(actual, [body]);
23401      }
23402      else {
23403        skipAssert(assert);
23404      }
23405    });
23406  });
23407
23408  /*--------------------------------------------------------------------------*/
23409
23410  QUnit.module('toInteger methods');
23411
23412  lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
23413    var func = _[methodName],
23414        isSafe = methodName == 'toSafeInteger';
23415
23416    QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
23417      assert.expect(6);
23418
23419      assert.strictEqual(func(-5.6), -5);
23420      assert.strictEqual(func('5.6'), 5);
23421      assert.strictEqual(func(), 0);
23422      assert.strictEqual(func(NaN), 0);
23423
23424      var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
23425      assert.strictEqual(func(Infinity), expected);
23426      assert.strictEqual(func(-Infinity), -expected);
23427    });
23428
23429    QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
23430      assert.expect(1);
23431
23432      assert.strictEqual(1 / func(-0), -Infinity);
23433    });
23434  });
23435
23436  /*--------------------------------------------------------------------------*/
23437
23438  QUnit.module('lodash.toLength');
23439
23440  (function() {
23441    QUnit.test('should return a valid length', function(assert) {
23442      assert.expect(4);
23443
23444      assert.strictEqual(_.toLength(-1), 0);
23445      assert.strictEqual(_.toLength('1'), 1);
23446      assert.strictEqual(_.toLength(1.1), 1);
23447      assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
23448    });
23449
23450    QUnit.test('should return `value` if a valid length', function(assert) {
23451      assert.expect(3);
23452
23453      assert.strictEqual(_.toLength(0), 0);
23454      assert.strictEqual(_.toLength(3), 3);
23455      assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
23456    });
23457
23458    QUnit.test('should convert `-0` to `0`', function(assert) {
23459      assert.expect(1);
23460
23461      assert.strictEqual(1 / _.toLength(-0), Infinity);
23462    });
23463  }());
23464
23465  /*--------------------------------------------------------------------------*/
23466
23467  QUnit.module('number coercion methods');
23468
23469  lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
23470    var func = _[methodName];
23471
23472    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
23473      assert.expect(2);
23474
23475      var values = [0, '0', -0, '-0'],
23476          expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
23477
23478      lodashStable.times(2, function(index) {
23479        var others = lodashStable.map(values, index ? Object : identity);
23480
23481        var actual = lodashStable.map(others, function(value) {
23482          var result = func(value);
23483          return [result, 1 / result];
23484        });
23485
23486        assert.deepEqual(actual, expected);
23487      });
23488    });
23489  });
23490
23491  lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
23492    var func = _[methodName],
23493        isToFinite = methodName == 'toFinite',
23494        isToLength = methodName == 'toLength',
23495        isToNumber = methodName == 'toNumber',
23496        isToSafeInteger = methodName == 'toSafeInteger';
23497
23498    function negative(string) {
23499      return '-' + string;
23500    }
23501
23502    function pad(string) {
23503      return whitespace + string + whitespace;
23504    }
23505
23506    function positive(string) {
23507      return '+' + string;
23508    }
23509
23510    QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
23511      assert.expect(1);
23512
23513      var values = [0, 1, NaN];
23514
23515      var expected = lodashStable.map(values, function(value) {
23516        return (!isToNumber && value !== value) ? 0 : value;
23517      });
23518
23519      var actual = lodashStable.map(values, func);
23520
23521      assert.deepEqual(actual, expected);
23522    });
23523
23524    QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
23525      assert.expect(1);
23526
23527      var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
23528
23529      var expected = lodashStable.map(values, function(value) {
23530        if (!isToNumber) {
23531          if (!isToFinite && value == 1.2) {
23532            value = 1;
23533          }
23534          else if (value == Infinity) {
23535            value = MAX_INTEGER;
23536          }
23537          else if (value !== value) {
23538            value = 0;
23539          }
23540          if (isToLength || isToSafeInteger) {
23541            value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23542          }
23543        }
23544        var neg = isToLength ? 0 : -value;
23545        return [value, value, neg, neg];
23546      });
23547
23548      var actual = lodashStable.map(values, function(value) {
23549        return [func(value), func(Object(value)), func(-value), func(Object(-value))];
23550      });
23551
23552      assert.deepEqual(actual, expected);
23553    });
23554
23555    QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
23556      assert.expect(1);
23557
23558      var transforms = [identity, pad, positive, negative];
23559
23560      var values = [
23561        '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
23562        '1e+308', '1e308', '1E+308', '1E308',
23563        '5e-324', '5E-324',
23564        'Infinity', 'NaN'
23565      ];
23566
23567      var expected = lodashStable.map(values, function(value) {
23568        var n = +value;
23569        if (!isToNumber) {
23570          if (!isToFinite && n == 1.234567890) {
23571            n = 1;
23572          }
23573          else if (n == Infinity) {
23574            n = MAX_INTEGER;
23575          }
23576          else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) {
23577            n = 0;
23578          }
23579          if (isToLength || isToSafeInteger) {
23580            n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23581          }
23582        }
23583        var neg = isToLength ? 0 : -n;
23584        return [n, n, n, n, n, n, neg, neg];
23585      });
23586
23587      var actual = lodashStable.map(values, function(value) {
23588        return lodashStable.flatMap(transforms, function(mod) {
23589          return [func(mod(value)), func(Object(mod(value)))];
23590        });
23591      });
23592
23593      assert.deepEqual(actual, expected);
23594    });
23595
23596    QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
23597      assert.expect(1);
23598
23599      var numbers = [42, 5349, 1715004],
23600          transforms = [identity, pad],
23601          values = ['0b101010', '0o12345', '0x1a2b3c'];
23602
23603      var expected = lodashStable.map(numbers, function(n) {
23604        return lodashStable.times(8, lodashStable.constant(n));
23605      });
23606
23607      var actual = lodashStable.map(values, function(value) {
23608        var upper = value.toUpperCase();
23609        return lodashStable.flatMap(transforms, function(mod) {
23610          return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
23611        });
23612      });
23613
23614      assert.deepEqual(actual, expected);
23615    });
23616
23617    QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23618      assert.expect(1);
23619
23620      var transforms = [identity, pad, positive, negative],
23621          values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
23622
23623      var expected = lodashStable.map(values, function(n) {
23624        return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
23625      });
23626
23627      var actual = lodashStable.map(values, function(value) {
23628        return lodashStable.flatMap(transforms, function(mod) {
23629          return [func(mod(value)), func(Object(mod(value)))];
23630        });
23631      });
23632
23633      assert.deepEqual(actual, expected);
23634    });
23635
23636    QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23637      assert.expect(1);
23638
23639      if (Symbol) {
23640        var object1 = Object(symbol),
23641            object2 = Object(symbol),
23642            values = [symbol, object1, object2],
23643            expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
23644
23645        object2.valueOf = undefined;
23646        var actual = lodashStable.map(values, func);
23647
23648        assert.deepEqual(actual, expected);
23649      }
23650      else {
23651        skipAssert(assert);
23652      }
23653    });
23654
23655    QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
23656      assert.expect(1);
23657
23658      var values = falsey.concat(whitespace);
23659
23660      var expected = lodashStable.map(values, function(value) {
23661        return (isToNumber && value !== whitespace) ? Number(value) : 0;
23662      });
23663
23664      var actual = lodashStable.map(values, function(value, index) {
23665        return index ? func(value) : func();
23666      });
23667
23668      assert.deepEqual(actual, expected);
23669    });
23670
23671    QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
23672      assert.expect(1);
23673
23674      var values = [
23675        {},
23676        [],
23677        [1],
23678        [1, 2],
23679        { 'valueOf': '1.1' },
23680        { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
23681        { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
23682        { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
23683        { 'valueOf': lodashStable.constant('-0x1a2b3c') },
23684        { 'toString': lodashStable.constant('-0x1a2b3c') },
23685        { 'valueOf': lodashStable.constant('0o12345') },
23686        { 'toString': lodashStable.constant('0o12345') },
23687        { 'valueOf': lodashStable.constant('0b101010') },
23688        { 'toString': lodashStable.constant('0b101010') }
23689      ];
23690
23691      var expected = [
23692        NaN,  0,   1,   NaN,
23693        NaN,  2.2, 1.1, 1.1,
23694        NaN,  NaN,
23695        5349, 5349,
23696        42,   42
23697      ];
23698
23699      if (isToFinite) {
23700        expected = [
23701          0,    0,    1,   0,
23702          0,    2.2,  1.1, 1.1,
23703          0,    0,
23704          5349, 5349,
23705          42,   42
23706        ];
23707      }
23708      else if (!isToNumber) {
23709        expected = [
23710          0,    0,    1, 0,
23711          0,    2,    1, 1,
23712          0,    0,
23713          5349, 5349,
23714          42,   42
23715        ];
23716      }
23717      var actual = lodashStable.map(values, func);
23718
23719      assert.deepEqual(actual, expected);
23720    });
23721  });
23722
23723  /*--------------------------------------------------------------------------*/
23724
23725  QUnit.module('lodash.toPairs');
23726
23727  (function() {
23728    QUnit.test('should be aliased', function(assert) {
23729      assert.expect(1);
23730
23731      assert.strictEqual(_.entries, _.toPairs);
23732    });
23733  }());
23734
23735  /*--------------------------------------------------------------------------*/
23736
23737  QUnit.module('lodash.toPairsIn');
23738
23739  (function() {
23740    QUnit.test('should be aliased', function(assert) {
23741      assert.expect(1);
23742
23743      assert.strictEqual(_.entriesIn, _.toPairsIn);
23744    });
23745  }());
23746
23747  /*--------------------------------------------------------------------------*/
23748
23749  QUnit.module('toPairs methods');
23750
23751  lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
23752    var func = _[methodName],
23753        isToPairs = methodName == 'toPairs';
23754
23755    QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
23756      assert.expect(1);
23757
23758      var object = { 'a': 1, 'b': 2 },
23759          actual = lodashStable.sortBy(func(object), 0);
23760
23761      assert.deepEqual(actual, [['a', 1], ['b', 2]]);
23762    });
23763
23764    QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
23765      assert.expect(1);
23766
23767      function Foo() {
23768        this.a = 1;
23769      }
23770      Foo.prototype.b = 2;
23771
23772      var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
23773          actual = lodashStable.sortBy(func(new Foo), 0);
23774
23775      assert.deepEqual(actual, expected);
23776    });
23777
23778    QUnit.test('`_.' + methodName + '` should convert objects with a `length` property', function(assert) {
23779      assert.expect(1);
23780
23781      var object = { '0': 'a', '1': 'b', 'length': 2 },
23782          actual = lodashStable.sortBy(func(object), 0);
23783
23784      assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
23785    });
23786
23787    QUnit.test('`_.' + methodName + '` should convert maps', function(assert) {
23788      assert.expect(1);
23789
23790      if (Map) {
23791        var map = new Map;
23792        map.set('a', 1);
23793        map.set('b', 2);
23794        assert.deepEqual(func(map), [['a', 1], ['b', 2]]);
23795      }
23796      else {
23797        skipAssert(assert);
23798      }
23799    });
23800
23801    QUnit.test('`_.' + methodName + '` should convert sets', function(assert) {
23802      assert.expect(1);
23803
23804      if (Set) {
23805        var set = new Set;
23806        set.add(1);
23807        set.add(2);
23808        assert.deepEqual(func(set), [[1, 1], [2, 2]]);
23809      }
23810      else {
23811        skipAssert(assert);
23812      }
23813    });
23814
23815    QUnit.test('`_.' + methodName + '` should convert strings', function(assert) {
23816      assert.expect(2);
23817
23818      lodashStable.each(['xo', Object('xo')], function(string) {
23819        var actual = lodashStable.sortBy(func(string), 0);
23820        assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
23821      });
23822    });
23823  });
23824
23825  /*--------------------------------------------------------------------------*/
23826
23827  QUnit.module('lodash.toPath');
23828
23829  (function() {
23830    QUnit.test('should convert a string to a path', function(assert) {
23831      assert.expect(2);
23832
23833      assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
23834      assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
23835    });
23836
23837    QUnit.test('should coerce array elements to strings', function(assert) {
23838      assert.expect(4);
23839
23840      var array = ['a', 'b', 'c'];
23841
23842      lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
23843        var actual = _.toPath(value);
23844        assert.deepEqual(actual, array);
23845        assert.notStrictEqual(actual, array);
23846      });
23847    });
23848
23849    QUnit.test('should return new path array', function(assert) {
23850      assert.expect(1);
23851
23852      assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
23853    });
23854
23855    QUnit.test('should not coerce symbols to strings', function(assert) {
23856      assert.expect(4);
23857
23858      if (Symbol) {
23859        var object = Object(symbol);
23860        lodashStable.each([symbol, object, [symbol], [object]], function(value) {
23861          var actual = _.toPath(value);
23862          assert.ok(lodashStable.isSymbol(actual[0]));
23863        });
23864      }
23865      else {
23866        skipAssert(assert, 4);
23867      }
23868    });
23869
23870    QUnit.test('should handle complex paths', function(assert) {
23871      assert.expect(1);
23872
23873      var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
23874      assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
23875    });
23876
23877    QUnit.test('should handle consecutive empty brackets and dots', function(assert) {
23878      assert.expect(12);
23879
23880      var expected = ['', 'a'];
23881      assert.deepEqual(_.toPath('.a'), expected);
23882      assert.deepEqual(_.toPath('[].a'), expected);
23883
23884      expected = ['', '', 'a'];
23885      assert.deepEqual(_.toPath('..a'), expected);
23886      assert.deepEqual(_.toPath('[][].a'), expected);
23887
23888      expected = ['a', '', 'b'];
23889      assert.deepEqual(_.toPath('a..b'), expected);
23890      assert.deepEqual(_.toPath('a[].b'), expected);
23891
23892      expected = ['a', '', '', 'b'];
23893      assert.deepEqual(_.toPath('a...b'), expected);
23894      assert.deepEqual(_.toPath('a[][].b'), expected);
23895
23896      expected = ['a', ''];
23897      assert.deepEqual(_.toPath('a.'), expected);
23898      assert.deepEqual(_.toPath('a[]'), expected);
23899
23900      expected = ['a', '', ''];
23901      assert.deepEqual(_.toPath('a..'), expected);
23902      assert.deepEqual(_.toPath('a[][]'), expected);
23903    });
23904  }());
23905
23906  /*--------------------------------------------------------------------------*/
23907
23908  QUnit.module('lodash.toPlainObject');
23909
23910  (function() {
23911    QUnit.test('should flatten inherited string keyed properties', function(assert) {
23912      assert.expect(1);
23913
23914      function Foo() {
23915        this.b = 2;
23916      }
23917      Foo.prototype.c = 3;
23918
23919      var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
23920      assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
23921    });
23922
23923    QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
23924      assert.expect(1);
23925
23926      var actual = _.toPlainObject(args),
23927          expected = { '0': 1, '1': 2, '2': 3 };
23928
23929      assert.deepEqual(actual, expected);
23930    });
23931
23932    QUnit.test('should convert arrays to plain objects', function(assert) {
23933      assert.expect(1);
23934
23935      var actual = _.toPlainObject(['a', 'b', 'c']),
23936          expected = { '0': 'a', '1': 'b', '2': 'c' };
23937
23938      assert.deepEqual(actual, expected);
23939    });
23940  }());
23941
23942  /*--------------------------------------------------------------------------*/
23943
23944  QUnit.module('lodash.toString');
23945
23946  (function() {
23947    QUnit.test('should treat nullish values as empty strings', function(assert) {
23948      assert.expect(1);
23949
23950      var values = [, null, undefined],
23951          expected = lodashStable.map(values, stubString);
23952
23953      var actual = lodashStable.map(values, function(value, index) {
23954        return index ? _.toString(value) : _.toString();
23955      });
23956
23957      assert.deepEqual(actual, expected);
23958    });
23959
23960    QUnit.test('should preserve the sign of `0`', function(assert) {
23961      assert.expect(1);
23962
23963      var values = [-0, Object(-0), 0, Object(0)],
23964          expected = ['-0', '-0', '0', '0'],
23965          actual = lodashStable.map(values, _.toString);
23966
23967      assert.deepEqual(actual, expected);
23968    });
23969
23970    QUnit.test('should preserve the sign of `0` in an array', function(assert) {
23971      assert.expect(1);
23972
23973      var values = [-0, Object(-0), 0, Object(0)];
23974      assert.deepEqual(_.toString(values), '-0,-0,0,0');
23975    });
23976
23977    QUnit.test('should not error on symbols', function(assert) {
23978      assert.expect(1);
23979
23980      if (Symbol) {
23981        try {
23982          assert.strictEqual(_.toString(symbol), 'Symbol(a)');
23983        } catch (e) {
23984          assert.ok(false, e.message);
23985        }
23986      }
23987      else {
23988        skipAssert(assert);
23989      }
23990    });
23991
23992    QUnit.test('should not error on an array of symbols', function(assert) {
23993      assert.expect(1);
23994
23995      if (Symbol) {
23996        try {
23997          assert.strictEqual(_.toString([symbol]), 'Symbol(a)');
23998        } catch (e) {
23999          assert.ok(false, e.message);
24000        }
24001      }
24002      else {
24003        skipAssert(assert);
24004      }
24005    });
24006
24007    QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
24008      assert.expect(1);
24009
24010      if (!isNpm) {
24011        var wrapped = _([1, 2, 3]);
24012        assert.strictEqual(wrapped.toString(), '1,2,3');
24013      }
24014      else {
24015        skipAssert(assert);
24016      }
24017    });
24018  }());
24019
24020  /*--------------------------------------------------------------------------*/
24021
24022  QUnit.module('lodash.transform');
24023
24024  (function() {
24025    function Foo() {
24026      this.a = 1;
24027      this.b = 2;
24028      this.c = 3;
24029    }
24030
24031    QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
24032      assert.expect(4);
24033
24034      var accumulators = [, null, undefined],
24035          object = new Foo,
24036          expected = lodashStable.map(accumulators, stubTrue);
24037
24038      var iteratee = function(result, value, key) {
24039        result[key] = square(value);
24040      };
24041
24042      var mapper = function(accumulator, index) {
24043        return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
24044      };
24045
24046      var results = lodashStable.map(accumulators, mapper);
24047
24048      var actual = lodashStable.map(results, function(result) {
24049        return result instanceof Foo;
24050      });
24051
24052      assert.deepEqual(actual, expected);
24053
24054      expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
24055      actual = lodashStable.map(results, lodashStable.toPlainObject);
24056
24057      assert.deepEqual(actual, expected);
24058
24059      object = { 'a': 1, 'b': 2, 'c': 3 };
24060      actual = lodashStable.map(accumulators, mapper);
24061
24062      assert.deepEqual(actual, expected);
24063
24064      object = [1, 2, 3];
24065      expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
24066      actual = lodashStable.map(accumulators, mapper);
24067
24068      assert.deepEqual(actual, expected);
24069    });
24070
24071    QUnit.test('should create regular arrays from typed arrays', function(assert) {
24072      assert.expect(1);
24073
24074      var expected = lodashStable.map(typedArrays, stubTrue);
24075
24076      var actual = lodashStable.map(typedArrays, function(type) {
24077        var Ctor = root[type],
24078            array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
24079
24080        return lodashStable.isArray(_.transform(array, noop));
24081      });
24082
24083      assert.deepEqual(actual, expected);
24084    });
24085
24086    QUnit.test('should support an `accumulator` value', function(assert) {
24087      assert.expect(6);
24088
24089      var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
24090          expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
24091
24092      var actual = lodashStable.map(values, function(value) {
24093        return _.transform(value, function(result, value) {
24094          result.push(square(value));
24095        }, []);
24096      });
24097
24098      assert.deepEqual(actual, expected);
24099
24100      var object = { 'a': 1, 'b': 4, 'c': 9 },
24101      expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
24102
24103      actual = lodashStable.map(values, function(value) {
24104        return _.transform(value, function(result, value, key) {
24105          result[key] = square(value);
24106        }, {});
24107      });
24108
24109      assert.deepEqual(actual, expected);
24110
24111      lodashStable.each([[], {}], function(accumulator) {
24112        var actual = lodashStable.map(values, function(value) {
24113          return _.transform(value, noop, accumulator);
24114        });
24115
24116        assert.ok(lodashStable.every(actual, function(result) {
24117          return result === accumulator;
24118        }));
24119
24120        assert.strictEqual(_.transform(null, null, accumulator), accumulator);
24121      });
24122    });
24123
24124    QUnit.test('should treat sparse arrays as dense', function(assert) {
24125      assert.expect(1);
24126
24127      var actual = _.transform(Array(1), function(result, value, index) {
24128        result[index] = String(value);
24129      });
24130
24131      assert.deepEqual(actual, ['undefined']);
24132    });
24133
24134    QUnit.test('should work without an `iteratee`', function(assert) {
24135      assert.expect(1);
24136
24137      assert.ok(_.transform(new Foo) instanceof Foo);
24138    });
24139
24140    QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
24141      assert.expect(2);
24142
24143      var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
24144          values = [false, true, 0, 1, NaN, '', 'a'],
24145          expected = lodashStable.map(values, stubObject);
24146
24147      var results = lodashStable.map(values, function(value) {
24148        return _.transform(value);
24149      });
24150
24151      assert.deepEqual(results, expected);
24152
24153      expected = lodashStable.map(values, stubFalse);
24154
24155      var actual = lodashStable.map(results, function(value, index) {
24156        return value instanceof Ctors[index];
24157      });
24158
24159      assert.deepEqual(actual, expected);
24160    });
24161
24162    QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
24163      assert.expect(1);
24164
24165      Foo.prototype.constructor = null;
24166      assert.notOk(_.transform(new Foo) instanceof Foo);
24167      Foo.prototype.constructor = Foo;
24168    });
24169
24170    QUnit.test('should create an empty object when given a falsey `object`', function(assert) {
24171      assert.expect(1);
24172
24173      var expected = lodashStable.map(falsey, stubObject);
24174
24175      var actual = lodashStable.map(falsey, function(object, index) {
24176        return index ? _.transform(object) : _.transform();
24177      });
24178
24179      assert.deepEqual(actual, expected);
24180    });
24181
24182    lodashStable.each({
24183      'array': [1, 2, 3],
24184      'object': { 'a': 1, 'b': 2, 'c': 3 }
24185    },
24186    function(object, key) {
24187      QUnit.test('should provide correct `iteratee` arguments when transforming an ' + key, function(assert) {
24188        assert.expect(2);
24189
24190        var args;
24191
24192        _.transform(object, function() {
24193          args || (args = slice.call(arguments));
24194        });
24195
24196        var first = args[0];
24197        if (key == 'array') {
24198          assert.ok(first !== object && lodashStable.isArray(first));
24199          assert.deepEqual(args, [first, 1, 0, object]);
24200        } else {
24201          assert.ok(first !== object && lodashStable.isPlainObject(first));
24202          assert.deepEqual(args, [first, 1, 'a', object]);
24203        }
24204      });
24205    });
24206
24207    QUnit.test('should create an object from the same realm as `object`', function(assert) {
24208      assert.expect(1);
24209
24210      var objects = lodashStable.filter(realm, function(value) {
24211        return lodashStable.isObject(value) && !lodashStable.isElement(value);
24212      });
24213
24214      var expected = lodashStable.map(objects, stubTrue);
24215
24216      var actual = lodashStable.map(objects, function(object) {
24217        var Ctor = object.constructor,
24218            result = _.transform(object);
24219
24220        if (result === object) {
24221          return false;
24222        }
24223        if (lodashStable.isTypedArray(object)) {
24224          return result instanceof Array;
24225        }
24226        return result instanceof Ctor || !(new Ctor instanceof Ctor);
24227      });
24228
24229      assert.deepEqual(actual, expected);
24230    });
24231  }());
24232
24233  /*--------------------------------------------------------------------------*/
24234
24235  QUnit.module('trim methods');
24236
24237  lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
24238    var func = _[methodName],
24239        parts = [];
24240
24241    if (index != 2) {
24242      parts.push('leading');
24243    }
24244    if (index != 1) {
24245      parts.push('trailing');
24246    }
24247    parts = parts.join(' and ');
24248
24249    QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
24250      assert.expect(1);
24251
24252      var string = whitespace + 'a b c' + whitespace,
24253          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24254
24255      assert.strictEqual(func(string), expected);
24256    });
24257
24258    QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
24259      assert.expect(1);
24260
24261      var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
24262          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24263
24264      assert.strictEqual(func(object), expected);
24265    });
24266
24267    QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
24268      assert.expect(1);
24269
24270      var string = '-_-a-b-c-_-',
24271          expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24272
24273      assert.strictEqual(func(string, '_-'), expected);
24274    });
24275
24276    QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
24277      assert.expect(1);
24278
24279      var object = { 'toString': lodashStable.constant('_-') },
24280          string = '-_-a-b-c-_-',
24281          expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
24282
24283      assert.strictEqual(func(string, object), expected);
24284    });
24285
24286    QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
24287      assert.expect(6);
24288
24289      lodashStable.each([null, '_-'], function(chars) {
24290        assert.strictEqual(func(null, chars), '');
24291        assert.strictEqual(func(undefined, chars), '');
24292        assert.strictEqual(func('', chars), '');
24293      });
24294    });
24295
24296    QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
24297      assert.expect(2);
24298
24299      var string = whitespace + 'a b c' + whitespace,
24300          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24301
24302      assert.strictEqual(func(string, undefined), expected);
24303      assert.strictEqual(func(string, ''), string);
24304    });
24305
24306    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
24307      assert.expect(1);
24308
24309      var string = Object(whitespace + 'a b c' + whitespace),
24310          trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
24311          actual = lodashStable.map([string, string, string], func);
24312
24313      assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
24314    });
24315
24316    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
24317      assert.expect(1);
24318
24319      if (!isNpm) {
24320        var string = whitespace + 'a b c' + whitespace,
24321            expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
24322
24323        assert.strictEqual(_(string)[methodName](), expected);
24324      }
24325      else {
24326        skipAssert(assert);
24327      }
24328    });
24329
24330    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
24331      assert.expect(1);
24332
24333      if (!isNpm) {
24334        var string = whitespace + 'a b c' + whitespace;
24335        assert.ok(_(string).chain()[methodName]() instanceof _);
24336      }
24337      else {
24338        skipAssert(assert);
24339      }
24340    });
24341  });
24342
24343  /*--------------------------------------------------------------------------*/
24344
24345  QUnit.module('uncommon symbols');
24346
24347  (function() {
24348    var flag = '\ud83c\uddfa\ud83c\uddf8',
24349        heart = '\u2764' + emojiVar,
24350        hearts = '\ud83d\udc95',
24351        comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
24352        hashKeycap = '#' + emojiVar + '\u20e3',
24353        leafs = '\ud83c\udf42',
24354        mic = '\ud83c\udf99',
24355        noMic = mic + '\u20e0',
24356        raisedHand = '\u270B' + emojiVar,
24357        rocket = '\ud83d\ude80',
24358        thumbsUp = '\ud83d\udc4d';
24359
24360    QUnit.test('should account for astral symbols', function(assert) {
24361      assert.expect(34);
24362
24363      var allHearts = _.repeat(hearts, 10),
24364          chars = hearts + comboGlyph,
24365          string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
24366          trimChars = comboGlyph + hearts,
24367          trimString = trimChars + string + trimChars;
24368
24369      assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
24370      assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
24371      assert.strictEqual(_.capitalize(rocket), rocket);
24372
24373      assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
24374      assert.strictEqual(_.padStart(string, 16), '   ' + string);
24375      assert.strictEqual(_.padEnd(string, 16), string + '   ');
24376
24377      assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
24378      assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
24379      assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
24380
24381      assert.strictEqual(_.size(string), 13);
24382      assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
24383      assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
24384      assert.deepEqual(_.split(string, undefined), [string]);
24385      assert.deepEqual(_.split(string, undefined, -1), [string]);
24386      assert.deepEqual(_.split(string, undefined, 0), []);
24387
24388      var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
24389
24390      assert.deepEqual(_.split(string, ''), expected);
24391      assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
24392      assert.deepEqual(_.toArray(string), expected);
24393
24394      assert.strictEqual(_.trim(trimString, chars), string);
24395      assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
24396      assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
24397
24398      assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
24399      assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
24400
24401      assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
24402      assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
24403      assert.deepEqual(_.toArray(noMic), [noMic]);
24404
24405      lodashStable.times(2, function(index) {
24406        var separator = index ? RegExp(hearts) : hearts,
24407            options = { 'length': 4, 'separator': separator },
24408            actual = _.truncate(string, options);
24409
24410        assert.strictEqual(actual, 'A...');
24411        assert.strictEqual(actual.length, 4);
24412
24413        actual = _.truncate(allHearts, options);
24414        assert.strictEqual(actual, hearts + '...');
24415        assert.strictEqual(actual.length, 5);
24416      });
24417    });
24418
24419    QUnit.test('should account for combining diacritical marks', function(assert) {
24420      assert.expect(1);
24421
24422      var values = lodashStable.map(comboMarks, function(mark) {
24423        return 'o' + mark;
24424      });
24425
24426      var expected = lodashStable.map(values, function(value) {
24427        return [1, [value], [value]];
24428      });
24429
24430      var actual = lodashStable.map(values, function(value) {
24431        return [_.size(value), _.toArray(value), _.words(value)];
24432      });
24433
24434      assert.deepEqual(actual, expected);
24435    });
24436
24437    QUnit.test('should account for fitzpatrick modifiers', function(assert) {
24438      assert.expect(1);
24439
24440      var values = lodashStable.map(fitzModifiers, function(modifier) {
24441        return thumbsUp + modifier;
24442      });
24443
24444      var expected = lodashStable.map(values, function(value) {
24445        return [1, [value], [value]];
24446      });
24447
24448      var actual = lodashStable.map(values, function(value) {
24449        return [_.size(value), _.toArray(value), _.words(value)];
24450      });
24451
24452      assert.deepEqual(actual, expected);
24453    });
24454
24455    QUnit.test('should account for regional symbols', function(assert) {
24456      assert.expect(6);
24457
24458      var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
24459          regionals = pair.join(' ');
24460
24461      assert.strictEqual(_.size(flag), 1);
24462      assert.strictEqual(_.size(regionals), 3);
24463
24464      assert.deepEqual(_.toArray(flag), [flag]);
24465      assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
24466
24467      assert.deepEqual(_.words(flag), [flag]);
24468      assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
24469    });
24470
24471    QUnit.test('should account for variation selectors', function(assert) {
24472      assert.expect(3);
24473
24474      assert.strictEqual(_.size(heart), 1);
24475      assert.deepEqual(_.toArray(heart), [heart]);
24476      assert.deepEqual(_.words(heart), [heart]);
24477    });
24478
24479    QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
24480      assert.expect(1);
24481
24482      var values = lodashStable.map(fitzModifiers, function(modifier) {
24483        return raisedHand + modifier;
24484      });
24485
24486      var expected = lodashStable.map(values, function(value) {
24487        return [1, [value], [value]];
24488      });
24489
24490      var actual = lodashStable.map(values, function(value) {
24491        return [_.size(value), _.toArray(value), _.words(value)];
24492      });
24493
24494      assert.deepEqual(actual, expected);
24495    });
24496
24497    QUnit.test('should match lone surrogates', function(assert) {
24498      assert.expect(3);
24499
24500      var pair = hearts.split(''),
24501          surrogates = pair[0] + ' ' + pair[1];
24502
24503      assert.strictEqual(_.size(surrogates), 3);
24504      assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
24505      assert.deepEqual(_.words(surrogates), []);
24506    });
24507
24508    QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
24509      assert.expect(1);
24510
24511      var string = fitzModifiers[0] + fitzModifiers[0];
24512      assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
24513    });
24514  }());
24515
24516  /*--------------------------------------------------------------------------*/
24517
24518  QUnit.module('lodash.unary');
24519
24520  (function() {
24521    function fn() {
24522      return slice.call(arguments);
24523    }
24524
24525    QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
24526      assert.expect(1);
24527
24528      var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
24529      assert.deepEqual(actual, [6, 8, 10]);
24530    });
24531
24532    QUnit.test('should not force a minimum argument count', function(assert) {
24533      assert.expect(1);
24534
24535      var capped = _.unary(fn);
24536      assert.deepEqual(capped(), []);
24537    });
24538
24539    QUnit.test('should use `this` binding of function', function(assert) {
24540      assert.expect(1);
24541
24542      var capped = _.unary(function(a, b) { return this; }),
24543          object = { 'capped': capped };
24544
24545      assert.strictEqual(object.capped(), object);
24546    });
24547  }());
24548
24549  /*--------------------------------------------------------------------------*/
24550
24551  QUnit.module('lodash.unescape');
24552
24553  (function() {
24554    var escaped = '&amp;&lt;&gt;&quot;&#39;/',
24555        unescaped = '&<>"\'/';
24556
24557    escaped += escaped;
24558    unescaped += unescaped;
24559
24560    QUnit.test('should unescape entities in order', function(assert) {
24561      assert.expect(1);
24562
24563      assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
24564    });
24565
24566    QUnit.test('should unescape the proper entities', function(assert) {
24567      assert.expect(1);
24568
24569      assert.strictEqual(_.unescape(escaped), unescaped);
24570    });
24571
24572    QUnit.test('should handle strings with nothing to unescape', function(assert) {
24573      assert.expect(1);
24574
24575      assert.strictEqual(_.unescape('abc'), 'abc');
24576    });
24577
24578    QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
24579      assert.expect(1);
24580
24581      assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
24582    });
24583
24584    lodashStable.each(['&#96;', '&#x2F;'], function(entity) {
24585      QUnit.test('should not unescape the "' + entity + '" entity', function(assert) {
24586        assert.expect(1);
24587
24588        assert.strictEqual(_.unescape(entity), entity);
24589      });
24590    });
24591  }());
24592
24593  /*--------------------------------------------------------------------------*/
24594
24595  QUnit.module('union methods');
24596
24597  lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
24598    var func = _[methodName];
24599
24600    QUnit.test('`_.' + methodName + '` should return the union of two arrays', function(assert) {
24601      assert.expect(1);
24602
24603      var actual = func([2], [1, 2]);
24604      assert.deepEqual(actual, [2, 1]);
24605    });
24606
24607    QUnit.test('`_.' + methodName + '` should return the union of multiple arrays', function(assert) {
24608      assert.expect(1);
24609
24610      var actual = func([2], [1, 2], [2, 3]);
24611      assert.deepEqual(actual, [2, 1, 3]);
24612    });
24613
24614    QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
24615      assert.expect(1);
24616
24617      var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
24618      assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
24619    });
24620
24621    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24622      assert.expect(3);
24623
24624      var array = [0];
24625      assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24626      assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
24627      assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
24628    });
24629  });
24630
24631  /*--------------------------------------------------------------------------*/
24632
24633  QUnit.module('lodash.unionBy');
24634
24635  (function() {
24636    QUnit.test('should accept an `iteratee`', function(assert) {
24637      assert.expect(2);
24638
24639      var actual = _.unionBy([2.1], [1.2, 2.3], Math.floor);
24640      assert.deepEqual(actual, [2.1, 1.2]);
24641
24642      actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
24643      assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
24644    });
24645
24646    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
24647      assert.expect(1);
24648
24649      var args;
24650
24651      _.unionBy([2.1], [1.2, 2.3], function() {
24652        args || (args = slice.call(arguments));
24653      });
24654
24655      assert.deepEqual(args, [2.1]);
24656    });
24657
24658    QUnit.test('should output values from the first possible array', function(assert) {
24659      assert.expect(1);
24660
24661      var actual = _.unionBy([{ 'x': 1, 'y': 1 }], [{ 'x': 1, 'y': 2 }], 'x');
24662      assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]);
24663    });
24664  }());
24665
24666  /*--------------------------------------------------------------------------*/
24667
24668  QUnit.module('lodash.unionWith');
24669
24670  (function() {
24671    QUnit.test('should work with a `comparator`', function(assert) {
24672      assert.expect(1);
24673
24674      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
24675          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
24676          actual = _.unionWith(objects, others, lodashStable.isEqual);
24677
24678      assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
24679    });
24680
24681    QUnit.test('should output values from the first possible array', function(assert) {
24682      assert.expect(1);
24683
24684      var objects = [{ 'x': 1, 'y': 1 }],
24685          others = [{ 'x': 1, 'y': 2 }];
24686
24687      var actual = _.unionWith(objects, others, function(a, b) {
24688        return a.x == b.x;
24689      });
24690
24691      assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]);
24692    });
24693  }());
24694
24695  /*--------------------------------------------------------------------------*/
24696
24697  QUnit.module('uniq methods');
24698
24699  lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
24700    var func = _[methodName],
24701        isSorted = /^sorted/.test(methodName),
24702        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24703
24704    if (isSorted) {
24705      objects = _.sortBy(objects, 'a');
24706    }
24707    else {
24708      QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
24709        assert.expect(1);
24710
24711        var array = [2, 1, 2];
24712        assert.deepEqual(func(array), [2, 1]);
24713      });
24714    }
24715    QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
24716      assert.expect(1);
24717
24718      var array = [1, 2, 2];
24719      assert.deepEqual(func(array), [1, 2]);
24720    });
24721
24722    QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
24723      assert.expect(1);
24724
24725      assert.deepEqual(func(objects), objects);
24726    });
24727
24728    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
24729      assert.expect(1);
24730
24731      var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
24732      assert.deepEqual(actual, ['0']);
24733    });
24734
24735    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
24736      assert.expect(1);
24737
24738      assert.deepEqual(func([NaN, NaN]), [NaN]);
24739    });
24740
24741    QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
24742      assert.expect(1);
24743
24744      var largeArray = [],
24745          expected = [0, {}, 'a'],
24746          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24747
24748      lodashStable.each(expected, function(value) {
24749        lodashStable.times(count, function() {
24750          largeArray.push(value);
24751        });
24752      });
24753
24754      assert.deepEqual(func(largeArray), expected);
24755    });
24756
24757    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
24758      assert.expect(1);
24759
24760      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24761        return isEven(index) ? -0 : 0;
24762      });
24763
24764      var actual = lodashStable.map(func(largeArray), lodashStable.toString);
24765      assert.deepEqual(actual, ['0']);
24766    });
24767
24768    QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
24769      assert.expect(1);
24770
24771      var largeArray = [],
24772          expected = [null, undefined, false, true, NaN],
24773          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24774
24775      lodashStable.each(expected, function(value) {
24776        lodashStable.times(count, function() {
24777          largeArray.push(value);
24778        });
24779      });
24780
24781      assert.deepEqual(func(largeArray), expected);
24782    });
24783
24784    QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
24785      assert.expect(1);
24786
24787      if (Symbol) {
24788        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
24789        assert.deepEqual(func(largeArray), largeArray);
24790      }
24791      else {
24792        skipAssert(assert);
24793      }
24794    });
24795
24796    QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
24797      assert.expect(1);
24798
24799      // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
24800      if (Symbol) {
24801        var expected = [
24802          Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
24803          Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
24804          Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
24805        ];
24806
24807        var largeArray = [],
24808            count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24809
24810        expected = lodashStable.map(expected, function(symbol) {
24811          return symbol || {};
24812        });
24813
24814        lodashStable.each(expected, function(value) {
24815          lodashStable.times(count, function() {
24816            largeArray.push(value);
24817          });
24818        });
24819
24820        assert.deepEqual(func(largeArray), expected);
24821      }
24822      else {
24823        skipAssert(assert);
24824      }
24825    });
24826
24827    QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
24828      assert.expect(1);
24829
24830      var largeArray = [],
24831          expected = ['2', 2, Object('2'), Object(2)],
24832          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24833
24834      lodashStable.each(expected, function(value) {
24835        lodashStable.times(count, function() {
24836          largeArray.push(value);
24837        });
24838      });
24839
24840      assert.deepEqual(func(largeArray), expected);
24841    });
24842  });
24843
24844  /*--------------------------------------------------------------------------*/
24845
24846  QUnit.module('lodash.uniq');
24847
24848  (function() {
24849    QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
24850      assert.expect(1);
24851
24852      var array = [[2, 1, 2], [1, 2, 1]],
24853          actual = lodashStable.map(array, lodashStable.uniq);
24854
24855      assert.deepEqual(actual, [[2, 1], [1, 2]]);
24856    });
24857  }());
24858
24859  /*--------------------------------------------------------------------------*/
24860
24861  QUnit.module('uniqBy methods');
24862
24863  lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
24864    var func = _[methodName],
24865        isSorted = methodName == 'sortedUniqBy',
24866        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24867
24868    if (isSorted) {
24869      objects = _.sortBy(objects, 'a');
24870    }
24871    QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) {
24872      assert.expect(1);
24873
24874      var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
24875
24876      var actual = func(objects, function(object) {
24877        return object.a;
24878      });
24879
24880      assert.deepEqual(actual, expected);
24881    });
24882
24883    QUnit.test('should work with large arrays', function(assert) {
24884      assert.expect(2);
24885
24886      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
24887        return [1, 2];
24888      });
24889
24890      var actual = func(largeArray, String);
24891      assert.strictEqual(actual[0], largeArray[0]);
24892      assert.deepEqual(actual, [[1, 2]]);
24893    });
24894
24895    QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) {
24896      assert.expect(1);
24897
24898      var args;
24899
24900      func(objects, function() {
24901        args || (args = slice.call(arguments));
24902      });
24903
24904      assert.deepEqual(args, [objects[0]]);
24905    });
24906
24907    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
24908      assert.expect(2);
24909
24910      var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
24911          actual = func(objects, 'a');
24912
24913      assert.deepEqual(actual, expected);
24914
24915      var arrays = [[2], [3], [1], [2], [3], [1]];
24916      if (isSorted) {
24917        arrays = lodashStable.sortBy(arrays, 0);
24918      }
24919      expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
24920      actual = func(arrays, 0);
24921
24922      assert.deepEqual(actual, expected);
24923    });
24924
24925    lodashStable.each({
24926      'an array': [0, 'a'],
24927      'an object': { '0': 'a' },
24928      'a number': 0,
24929      'a string': '0'
24930    },
24931    function(iteratee, key) {
24932      QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
24933        assert.expect(1);
24934
24935        var actual = func([['a'], ['a'], ['b']], iteratee);
24936        assert.deepEqual(actual, [['a'], ['b']]);
24937      });
24938    });
24939  });
24940
24941  /*--------------------------------------------------------------------------*/
24942
24943  QUnit.module('lodash.uniqWith');
24944
24945  (function() {
24946    QUnit.test('should work with a `comparator`', function(assert) {
24947      assert.expect(1);
24948
24949      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }],
24950          actual = _.uniqWith(objects, lodashStable.isEqual);
24951
24952      assert.deepEqual(actual, [objects[0], objects[1]]);
24953    });
24954
24955    QUnit.test('should preserve the sign of `0`', function(assert) {
24956      assert.expect(1);
24957
24958      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24959        return isEven(index) ? -0 : 0;
24960      });
24961
24962      var arrays = [[-0, 0], largeArray],
24963          expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
24964
24965      var actual = lodashStable.map(arrays, function(array) {
24966        return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
24967      });
24968
24969      assert.deepEqual(actual, expected);
24970    });
24971  }());
24972
24973  /*--------------------------------------------------------------------------*/
24974
24975  QUnit.module('lodash.uniqueId');
24976
24977  (function() {
24978    QUnit.test('should generate unique ids', function(assert) {
24979      assert.expect(1);
24980
24981      var actual = lodashStable.times(1000, function(assert) {
24982        return _.uniqueId();
24983      });
24984
24985      assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
24986    });
24987
24988    QUnit.test('should return a string value when not providing a `prefix`', function(assert) {
24989      assert.expect(1);
24990
24991      assert.strictEqual(typeof _.uniqueId(), 'string');
24992    });
24993
24994    QUnit.test('should coerce the prefix argument to a string', function(assert) {
24995      assert.expect(1);
24996
24997      var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
24998      assert.ok(/3\d+,2\d+,1\d+/.test(actual));
24999    });
25000  }());
25001
25002  /*--------------------------------------------------------------------------*/
25003
25004  QUnit.module('lodash.unset');
25005
25006  (function() {
25007    QUnit.test('should unset property values', function(assert) {
25008      assert.expect(4);
25009
25010      lodashStable.each(['a', ['a']], function(path) {
25011        var object = { 'a': 1, 'c': 2 };
25012        assert.strictEqual(_.unset(object, path), true);
25013        assert.deepEqual(object, { 'c': 2 });
25014      });
25015    });
25016
25017    QUnit.test('should preserve the sign of `0`', function(assert) {
25018      assert.expect(1);
25019
25020      var props = [-0, Object(-0), 0, Object(0)],
25021          expected = lodashStable.map(props, lodashStable.constant([true, false]));
25022
25023      var actual = lodashStable.map(props, function(key) {
25024        var object = { '-0': 'a', '0': 'b' };
25025        return [_.unset(object, key), lodashStable.toString(key) in object];
25026      });
25027
25028      assert.deepEqual(actual, expected);
25029    });
25030
25031    QUnit.test('should unset symbol keyed property values', function(assert) {
25032      assert.expect(2);
25033
25034      if (Symbol) {
25035        var object = {};
25036        object[symbol] = 1;
25037
25038        assert.strictEqual(_.unset(object, symbol), true);
25039        assert.notOk(symbol in object);
25040      }
25041      else {
25042        skipAssert(assert, 2);
25043      }
25044    });
25045
25046    QUnit.test('should unset deep property values', function(assert) {
25047      assert.expect(4);
25048
25049      lodashStable.each(['a.b', ['a', 'b']], function(path) {
25050        var object = { 'a': { 'b': null } };
25051        assert.strictEqual(_.unset(object, path), true);
25052        assert.deepEqual(object, { 'a': {} });
25053      });
25054    });
25055
25056    QUnit.test('should handle complex paths', function(assert) {
25057      assert.expect(4);
25058
25059      var paths = [
25060        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
25061        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
25062      ];
25063
25064      lodashStable.each(paths, function(path) {
25065        var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
25066        assert.strictEqual(_.unset(object, path), true);
25067        assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
25068      });
25069    });
25070
25071    QUnit.test('should return `true` for nonexistent paths', function(assert) {
25072      assert.expect(5);
25073
25074      var object = { 'a': { 'b': { 'c': null } } };
25075
25076      lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
25077        assert.strictEqual(_.unset(object, path), true);
25078      });
25079
25080      assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
25081    });
25082
25083    QUnit.test('should not error when `object` is nullish', function(assert) {
25084      assert.expect(1);
25085
25086      var values = [null, undefined],
25087          expected = [[true, true], [true, true]];
25088
25089      var actual = lodashStable.map(values, function(value) {
25090        try {
25091          return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
25092        } catch (e) {
25093          return e.message;
25094        }
25095      });
25096
25097      assert.deepEqual(actual, expected);
25098    });
25099
25100    QUnit.test('should follow `path` over non-plain objects', function(assert) {
25101      assert.expect(8);
25102
25103      var object = { 'a': '' },
25104          paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
25105
25106      lodashStable.each(paths, function(path) {
25107        numberProto.a = 1;
25108
25109        var actual = _.unset(0, path);
25110        assert.strictEqual(actual, true);
25111        assert.notOk('a' in numberProto);
25112
25113        delete numberProto.a;
25114      });
25115
25116      lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
25117        stringProto.replace.b = 1;
25118
25119        var actual = _.unset(object, path);
25120        assert.strictEqual(actual, true);
25121        assert.notOk('a' in stringProto.replace);
25122
25123        delete stringProto.replace.b;
25124      });
25125    });
25126
25127    QUnit.test('should return `false` for non-configurable properties', function(assert) {
25128      assert.expect(1);
25129
25130      var object = {};
25131
25132      if (!isStrict) {
25133        defineProperty(object, 'a', {
25134          'configurable': false,
25135          'enumerable': true,
25136          'writable': true,
25137          'value': 1,
25138        });
25139        assert.strictEqual(_.unset(object, 'a'), false);
25140      }
25141      else {
25142        skipAssert(assert);
25143      }
25144    });
25145  }());
25146
25147  /*--------------------------------------------------------------------------*/
25148
25149  QUnit.module('lodash.unzipWith');
25150
25151  (function() {
25152    QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
25153      assert.expect(1);
25154
25155      var array = [[1, 4], [2, 5], [3, 6]];
25156
25157      var actual = _.unzipWith(array, function(a, b, c) {
25158        return a + b + c;
25159      });
25160
25161      assert.deepEqual(actual, [6, 15]);
25162    });
25163
25164    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25165      assert.expect(1);
25166
25167      var args;
25168
25169      _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
25170        args || (args = slice.call(arguments));
25171      });
25172
25173      assert.deepEqual(args, [1, 2]);
25174    });
25175
25176    QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
25177      assert.expect(1);
25178
25179      var array = [[1, 3], [2, 4]],
25180          values = [, null, undefined],
25181          expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
25182
25183      var actual = lodashStable.map(values, function(value, index) {
25184        return index ? _.unzipWith(array, value) : _.unzipWith(array);
25185      });
25186
25187      assert.deepEqual(actual, expected);
25188    });
25189  }());
25190
25191  /*--------------------------------------------------------------------------*/
25192
25193  QUnit.module('lodash.updateWith');
25194
25195  (function() {
25196    QUnit.test('should work with a `customizer` callback', function(assert) {
25197      assert.expect(1);
25198
25199      var actual = _.updateWith({ '0': {} }, '[0][1][2]', stubThree, function(value) {
25200        return lodashStable.isObject(value) ? undefined : {};
25201      });
25202
25203      assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
25204    });
25205
25206    QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
25207      assert.expect(1);
25208
25209      var actual = _.updateWith({}, 'a[0].b.c', stubFour, noop);
25210      assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
25211    });
25212  }());
25213
25214  /*--------------------------------------------------------------------------*/
25215
25216  QUnit.module('update methods');
25217
25218  lodashStable.each(['update', 'updateWith'], function(methodName) {
25219    var func = _[methodName],
25220        oldValue = 1;
25221
25222    QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
25223      assert.expect(4);
25224
25225      var object = { 'a': [{ 'b': { 'c': oldValue } }] },
25226          expected = oldValue + 1;
25227
25228      lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
25229        func(object, path, function(n) {
25230          assert.strictEqual(n, oldValue);
25231          return ++n;
25232        });
25233
25234        assert.strictEqual(object.a[0].b.c, expected);
25235        object.a[0].b.c = oldValue;
25236      });
25237    });
25238  });
25239
25240  /*--------------------------------------------------------------------------*/
25241
25242  QUnit.module('lodash.upperCase');
25243
25244  (function() {
25245    QUnit.test('should uppercase as space-separated words', function(assert) {
25246      assert.expect(3);
25247
25248      assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
25249      assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
25250      assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
25251    });
25252  }());
25253
25254  /*--------------------------------------------------------------------------*/
25255
25256  QUnit.module('lodash.upperFirst');
25257
25258  (function() {
25259    QUnit.test('should uppercase only the first character', function(assert) {
25260      assert.expect(3);
25261
25262      assert.strictEqual(_.upperFirst('fred'), 'Fred');
25263      assert.strictEqual(_.upperFirst('Fred'), 'Fred');
25264      assert.strictEqual(_.upperFirst('FRED'), 'FRED');
25265    });
25266  }());
25267
25268  /*--------------------------------------------------------------------------*/
25269
25270  QUnit.module('values methods');
25271
25272  lodashStable.each(['values', 'valuesIn'], function(methodName) {
25273    var func = _[methodName],
25274        isValues = methodName == 'values';
25275
25276    QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
25277      assert.expect(1);
25278
25279      var object = { 'a': 1, 'b': 2 },
25280          actual = func(object).sort();
25281
25282      assert.deepEqual(actual, [1, 2]);
25283    });
25284
25285    QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
25286      assert.expect(1);
25287
25288      var object = { '0': 'a', '1': 'b', 'length': 2 },
25289          actual = func(object).sort();
25290
25291      assert.deepEqual(actual, [2, 'a', 'b']);
25292    });
25293
25294    QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
25295      assert.expect(1);
25296
25297      function Foo() {
25298        this.a = 1;
25299      }
25300      Foo.prototype.b = 2;
25301
25302      var expected = isValues ? [1] : [1, 2],
25303          actual = func(new Foo).sort();
25304
25305      assert.deepEqual(actual, expected);
25306    });
25307
25308    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
25309      assert.expect(1);
25310
25311      var values = [args, strictArgs],
25312          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
25313
25314      var actual = lodashStable.map(values, function(value) {
25315        return func(value).sort();
25316      });
25317
25318      assert.deepEqual(actual, expected);
25319    });
25320  });
25321
25322  /*--------------------------------------------------------------------------*/
25323
25324  QUnit.module('lodash.without');
25325
25326  (function() {
25327    QUnit.test('should return the difference of values', function(assert) {
25328      assert.expect(1);
25329
25330      var actual = _.without([2, 1, 2, 3], 1, 2);
25331      assert.deepEqual(actual, [3]);
25332    });
25333
25334    QUnit.test('should use strict equality to determine the values to reject', function(assert) {
25335      assert.expect(2);
25336
25337      var object1 = { 'a': 1 },
25338          object2 = { 'b': 2 },
25339          array = [object1, object2];
25340
25341      assert.deepEqual(_.without(array, { 'a': 1 }), array);
25342      assert.deepEqual(_.without(array, object1), [object2]);
25343    });
25344
25345    QUnit.test('should remove all occurrences of each value from an array', function(assert) {
25346      assert.expect(1);
25347
25348      var array = [1, 2, 3, 1, 2, 3];
25349      assert.deepEqual(_.without(array, 1, 2), [3, 3]);
25350    });
25351  }());
25352
25353  /*--------------------------------------------------------------------------*/
25354
25355  QUnit.module('lodash.words');
25356
25357  (function() {
25358    QUnit.test('should match words containing Latin Unicode letters', function(assert) {
25359      assert.expect(1);
25360
25361      var expected = lodashStable.map(burredLetters, function(letter) {
25362        return [letter];
25363      });
25364
25365      var actual = lodashStable.map(burredLetters, function(letter) {
25366        return _.words(letter);
25367      });
25368
25369      assert.deepEqual(actual, expected);
25370    });
25371
25372    QUnit.test('should support a `pattern`', function(assert) {
25373      assert.expect(2);
25374
25375      assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
25376      assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
25377    });
25378
25379    QUnit.test('should work with compound words', function(assert) {
25380      assert.expect(12);
25381
25382      assert.deepEqual(_.words('12ft'), ['12', 'ft']);
25383      assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
25384      assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
25385      assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
25386      assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
25387      assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
25388      assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
25389      assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
25390      assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
25391      assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
25392      assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
25393      assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
25394    });
25395
25396    QUnit.test('should work with compound words containing diacritical marks', function(assert) {
25397      assert.expect(3);
25398
25399      assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
25400      assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
25401      assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
25402    });
25403
25404    QUnit.test('should not treat contractions as separate words', function(assert) {
25405      assert.expect(4);
25406
25407      var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
25408
25409      lodashStable.each(["'", '\u2019'], function(apos) {
25410        lodashStable.times(2, function(index) {
25411          var actual = lodashStable.map(postfixes, function(postfix) {
25412            var string = 'a b' + apos + postfix +  ' c';
25413            return _.words(string[index ? 'toUpperCase' : 'toLowerCase']());
25414          });
25415
25416          var expected = lodashStable.map(postfixes, function(postfix) {
25417            var words = ['a', 'b' + apos + postfix, 'c'];
25418            return lodashStable.map(words, function(word) {
25419              return word[index ? 'toUpperCase' : 'toLowerCase']();
25420            });
25421          });
25422
25423          assert.deepEqual(actual, expected);
25424        });
25425      });
25426    });
25427
25428    QUnit.test('should not treat ordinal numbers as separate words', function(assert) {
25429      assert.expect(2);
25430
25431      var ordinals = ['1st', '2nd', '3rd', '4th'];
25432
25433      lodashStable.times(2, function(index) {
25434        var expected = lodashStable.map(ordinals, function(ordinal) {
25435          return [ordinal[index ? 'toUpperCase' : 'toLowerCase']()];
25436        });
25437
25438        var actual = lodashStable.map(expected, function(words) {
25439          return _.words(words[0]);
25440        });
25441
25442        assert.deepEqual(actual, expected);
25443      });
25444    });
25445
25446    QUnit.test('should not treat mathematical operators as words', function(assert) {
25447      assert.expect(1);
25448
25449      var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
25450          expected = lodashStable.map(operators, stubArray),
25451          actual = lodashStable.map(operators, _.words);
25452
25453      assert.deepEqual(actual, expected);
25454    });
25455
25456    QUnit.test('should not treat punctuation as words', function(assert) {
25457      assert.expect(1);
25458
25459      var marks = [
25460        '\u2012', '\u2013', '\u2014', '\u2015',
25461        '\u2024', '\u2025', '\u2026',
25462        '\u205d', '\u205e'
25463      ];
25464
25465      var expected = lodashStable.map(marks, stubArray),
25466          actual = lodashStable.map(marks, _.words);
25467
25468      assert.deepEqual(actual, expected);
25469    });
25470
25471    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
25472      assert.expect(1);
25473
25474      var strings = lodashStable.map(['a', 'b', 'c'], Object),
25475          actual = lodashStable.map(strings, _.words);
25476
25477      assert.deepEqual(actual, [['a'], ['b'], ['c']]);
25478    });
25479
25480    QUnit.test('should prevent ReDoS', function(assert) {
25481      assert.expect(2);
25482
25483      var largeWordLen = 50000,
25484          largeWord = _.repeat('A', largeWordLen),
25485          maxMs = 1000,
25486          startTime = lodashStable.now();
25487
25488      assert.deepEqual(_.words(largeWord + 'ÆiouAreVowels'), [largeWord, 'Æiou', 'Are', 'Vowels']);
25489
25490      var endTime = lodashStable.now(),
25491          timeSpent = endTime - startTime;
25492
25493      assert.ok(timeSpent < maxMs, 'operation took ' + timeSpent + 'ms');
25494    });
25495  }());
25496
25497  /*--------------------------------------------------------------------------*/
25498
25499  QUnit.module('lodash.wrap');
25500
25501  (function() {
25502    QUnit.test('should create a wrapped function', function(assert) {
25503      assert.expect(1);
25504
25505      var p = _.wrap(lodashStable.escape, function(func, text) {
25506        return '<p>' + func(text) + '</p>';
25507      });
25508
25509      assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
25510    });
25511
25512    QUnit.test('should provide correct `wrapper` arguments', function(assert) {
25513      assert.expect(1);
25514
25515      var args;
25516
25517      var wrapped = _.wrap(noop, function() {
25518        args || (args = slice.call(arguments));
25519      });
25520
25521      wrapped(1, 2, 3);
25522      assert.deepEqual(args, [noop, 1, 2, 3]);
25523    });
25524
25525    QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
25526      assert.expect(1);
25527
25528      var values = [, null, undefined],
25529          expected = lodashStable.map(values, stubA);
25530
25531      var actual = lodashStable.map(values, function(value, index) {
25532        var wrapped = index ? _.wrap('a', value) : _.wrap('a');
25533        return wrapped('b', 'c');
25534      });
25535
25536      assert.deepEqual(actual, expected);
25537    });
25538
25539    QUnit.test('should use `this` binding of function', function(assert) {
25540      assert.expect(1);
25541
25542      var p = _.wrap(lodashStable.escape, function(func) {
25543        return '<p>' + func(this.text) + '</p>';
25544      });
25545
25546      var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
25547      assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
25548    });
25549  }());
25550
25551  /*--------------------------------------------------------------------------*/
25552
25553  QUnit.module('xor methods');
25554
25555  lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
25556    var func = _[methodName];
25557
25558    QUnit.test('`_.' + methodName + '` should return the symmetric difference of two arrays', function(assert) {
25559      assert.expect(1);
25560
25561      var actual = func([2, 1], [2, 3]);
25562      assert.deepEqual(actual, [1, 3]);
25563    });
25564
25565    QUnit.test('`_.' + methodName + '` should return the symmetric difference of multiple arrays', function(assert) {
25566      assert.expect(2);
25567
25568      var actual = func([2, 1], [2, 3], [3, 4]);
25569      assert.deepEqual(actual, [1, 4]);
25570
25571      actual = func([1, 2], [2, 1], [1, 2]);
25572      assert.deepEqual(actual, []);
25573    });
25574
25575    QUnit.test('`_.' + methodName + '` should return an empty array when comparing the same array', function(assert) {
25576      assert.expect(1);
25577
25578      var array = [1],
25579          actual = func(array, array, array);
25580
25581      assert.deepEqual(actual, []);
25582    });
25583
25584    QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
25585      assert.expect(2);
25586
25587      var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
25588      assert.deepEqual(actual, [1, 4]);
25589
25590      actual = func([1, 1]);
25591      assert.deepEqual(actual, [1]);
25592    });
25593
25594    QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
25595      assert.expect(1);
25596
25597      var array = [1];
25598      assert.notStrictEqual(func(array), array);
25599    });
25600
25601    QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
25602      assert.expect(1);
25603
25604      var array = [0];
25605      assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
25606    });
25607
25608    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25609      assert.expect(3);
25610
25611      var array = [1, 2];
25612      assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
25613      assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
25614      assert.deepEqual(func(array, null, args, null), [3]);
25615    });
25616
25617    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
25618      assert.expect(1);
25619
25620      if (!isNpm) {
25621        var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
25622        assert.ok(wrapped instanceof _);
25623      }
25624      else {
25625        skipAssert(assert);
25626      }
25627    });
25628
25629    QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
25630      assert.expect(1);
25631
25632      if (!isNpm) {
25633        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
25634            wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
25635
25636        var actual = lodashStable.map(['head', 'last'], function(methodName) {
25637          return wrapped[methodName]();
25638        });
25639
25640        assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
25641      }
25642      else {
25643        skipAssert(assert);
25644      }
25645    });
25646  });
25647
25648  /*--------------------------------------------------------------------------*/
25649
25650  QUnit.module('lodash.xorBy');
25651
25652  (function() {
25653    QUnit.test('should accept an `iteratee`', function(assert) {
25654      assert.expect(2);
25655
25656      var actual = _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
25657      assert.deepEqual(actual, [1.2, 3.4]);
25658
25659      actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
25660      assert.deepEqual(actual, [{ 'x': 2 }]);
25661    });
25662
25663    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25664      assert.expect(1);
25665
25666      var args;
25667
25668      _.xorBy([2.1, 1.2], [2.3, 3.4], function() {
25669        args || (args = slice.call(arguments));
25670      });
25671
25672      assert.deepEqual(args, [2.3]);
25673    });
25674  }());
25675
25676  /*--------------------------------------------------------------------------*/
25677
25678  QUnit.module('lodash.xorWith');
25679
25680  (function() {
25681    QUnit.test('should work with a `comparator`', function(assert) {
25682      assert.expect(1);
25683
25684      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
25685          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
25686          actual = _.xorWith(objects, others, lodashStable.isEqual);
25687
25688      assert.deepEqual(actual, [objects[1], others[0]]);
25689    });
25690  }());
25691
25692  /*--------------------------------------------------------------------------*/
25693
25694  QUnit.module('zipObject methods');
25695
25696  lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
25697    var func = _[methodName],
25698        object = { 'barney': 36, 'fred': 40 },
25699        isDeep = methodName == 'zipObjectDeep';
25700
25701    QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
25702      assert.expect(1);
25703
25704      var actual = func(['barney', 'fred'], [36, 40]);
25705      assert.deepEqual(actual, object);
25706    });
25707
25708    QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
25709      assert.expect(1);
25710
25711      assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
25712    });
25713
25714    QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
25715      assert.expect(1);
25716
25717      assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
25718    });
25719
25720    QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
25721      assert.expect(2);
25722
25723      lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
25724        var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
25725        assert.deepEqual(func([path], [1]), expected);
25726      });
25727    });
25728
25729    QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
25730      assert.expect(1);
25731
25732      if (!isNpm) {
25733        var values = lodashStable.range(LARGE_ARRAY_SIZE),
25734            props = lodashStable.map(values, function(value) { return 'key' + value; }),
25735            actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
25736
25737        assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
25738      }
25739      else {
25740        skipAssert(assert);
25741      }
25742    });
25743  });
25744
25745  /*--------------------------------------------------------------------------*/
25746
25747  QUnit.module('lodash.zipWith');
25748
25749  (function() {
25750    QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
25751      assert.expect(2);
25752
25753      var array1 = [1, 2, 3],
25754          array2 = [4, 5, 6],
25755          array3 = [7, 8, 9];
25756
25757      var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
25758        return a + b + c;
25759      });
25760
25761      assert.deepEqual(actual, [12, 15, 18]);
25762
25763      var actual = _.zipWith(array1, [], function(a, b) {
25764        return a + (b || 0);
25765      });
25766
25767      assert.deepEqual(actual, [1, 2, 3]);
25768    });
25769
25770    QUnit.test('should provide correct `iteratee` arguments', function(assert) {
25771      assert.expect(1);
25772
25773      var args;
25774
25775      _.zipWith([1, 2], [3, 4], [5, 6], function() {
25776        args || (args = slice.call(arguments));
25777      });
25778
25779      assert.deepEqual(args, [1, 3, 5]);
25780    });
25781
25782    QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
25783      assert.expect(1);
25784
25785      var array1 = [1, 2],
25786          array2 = [3, 4],
25787          values = [, null, undefined],
25788          expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
25789
25790      var actual = lodashStable.map(values, function(value, index) {
25791        return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
25792      });
25793
25794      assert.deepEqual(actual, expected);
25795    });
25796  }());
25797
25798  /*--------------------------------------------------------------------------*/
25799
25800  QUnit.module('lodash.unzip and lodash.zip');
25801
25802  lodashStable.each(['unzip', 'zip'], function(methodName, index) {
25803    var func = _[methodName];
25804    func = lodashStable.bind(index ? func.apply : func.call, func, null);
25805
25806    var object = {
25807      'an empty array': [
25808        [],
25809        []
25810      ],
25811      '0-tuples': [
25812        [[], []],
25813        []
25814      ],
25815      '2-tuples': [
25816        [['barney', 'fred'], [36, 40]],
25817        [['barney', 36], ['fred', 40]]
25818      ],
25819      '3-tuples': [
25820        [['barney', 'fred'], [36, 40], [false, true]],
25821        [['barney', 36, false], ['fred', 40, true]]
25822      ]
25823    };
25824
25825    lodashStable.forOwn(object, function(pair, key) {
25826      QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
25827        assert.expect(2);
25828
25829        var actual = func(pair[0]);
25830        assert.deepEqual(actual, pair[1]);
25831        assert.deepEqual(func(actual), actual.length ? pair[0] : []);
25832      });
25833    });
25834
25835    QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
25836      assert.expect(4);
25837
25838      var pair = [
25839        [['barney', 36], ['fred', 40, false]],
25840        [['barney', 'fred'], [36, 40], [undefined, false]]
25841      ];
25842
25843      var actual = func(pair[0]);
25844      assert.ok('0' in actual[2]);
25845      assert.deepEqual(actual, pair[1]);
25846
25847      actual = func(actual);
25848      assert.ok('2' in actual[0]);
25849      assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
25850    });
25851
25852    QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
25853      assert.expect(1);
25854
25855      var expected = lodashStable.map(falsey, stubArray);
25856
25857      var actual = lodashStable.map(falsey, function(value) {
25858        return func([value, value, value]);
25859      });
25860
25861      assert.deepEqual(actual, expected);
25862    });
25863
25864    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25865      assert.expect(1);
25866
25867      var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
25868      assert.deepEqual(func(array), [[1, 3], [2, 4]]);
25869    });
25870
25871    QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
25872      assert.expect(1);
25873
25874      var expected = [['barney', 'fred'], [36, 40]];
25875      assert.deepEqual(func(func(func(func(expected)))), expected);
25876    });
25877  });
25878
25879  /*--------------------------------------------------------------------------*/
25880
25881  QUnit.module('lodash(...).commit');
25882
25883  (function() {
25884    QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
25885      assert.expect(4);
25886
25887      if (!isNpm) {
25888        var array = [1],
25889            wrapped = _(array).push(2).push(3);
25890
25891        assert.deepEqual(array, [1]);
25892
25893        var otherWrapper = wrapped.commit();
25894        assert.ok(otherWrapper instanceof _);
25895        assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
25896        assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25897      }
25898      else {
25899        skipAssert(assert, 4);
25900      }
25901    });
25902
25903    QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
25904      assert.expect(2);
25905
25906      if (!isNpm) {
25907        var wrapped = _([1]).chain().commit().head();
25908        assert.ok(wrapped instanceof _);
25909        assert.strictEqual(wrapped.value(), 1);
25910      }
25911      else {
25912        skipAssert(assert, 2);
25913      }
25914    });
25915  }());
25916
25917  /*--------------------------------------------------------------------------*/
25918
25919  QUnit.module('lodash(...).next');
25920
25921  lodashStable.each([false, true], function(implicit) {
25922    function chain(value) {
25923      return implicit ? _(value) : _.chain(value);
25924    }
25925
25926    var chainType = 'in an ' + (implicit ? 'implicit' : 'explict') + ' chain';
25927
25928    QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
25929      assert.expect(3);
25930
25931      if (!isNpm) {
25932        var wrapped = chain([1, 2]);
25933
25934        assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
25935        assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
25936        assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
25937      }
25938      else {
25939        skipAssert(assert, 3);
25940      }
25941    });
25942
25943    QUnit.test('should act as an iterable ' + chainType, function(assert) {
25944      assert.expect(2);
25945
25946      if (!isNpm && Symbol && Symbol.iterator) {
25947        var array = [1, 2],
25948            wrapped = chain(array);
25949
25950        assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
25951        assert.deepEqual(lodashStable.toArray(wrapped), array);
25952      }
25953      else {
25954        skipAssert(assert, 2);
25955      }
25956    });
25957
25958    QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
25959      assert.expect(3);
25960
25961      if (!isNpm && Array.from) {
25962        var hearts = '\ud83d\udc95',
25963            values = [[1], { 'a': 1 }, hearts];
25964
25965        lodashStable.each(values, function(value) {
25966          var wrapped = chain(value);
25967          assert.deepEqual(Array.from(wrapped), _.toArray(value));
25968        });
25969      }
25970      else {
25971        skipAssert(assert, 3);
25972      }
25973    });
25974
25975    QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
25976      assert.expect(4);
25977
25978      if (!isNpm && Symbol && Symbol.iterator) {
25979        var array = [1, 2],
25980            wrapped = chain(array);
25981
25982        assert.deepEqual(lodashStable.toArray(wrapped), array);
25983        assert.deepEqual(lodashStable.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
25984
25985        var other = wrapped.filter();
25986        assert.deepEqual(lodashStable.toArray(other), array, 'reset for new chain segments');
25987        assert.deepEqual(lodashStable.toArray(wrapped), [], 'iterator is still exhausted');
25988      }
25989      else {
25990        skipAssert(assert, 4);
25991      }
25992    });
25993
25994    QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
25995      assert.expect(3);
25996
25997      if (!isNpm && Symbol && Symbol.iterator) {
25998        var array = lodashStable.range(LARGE_ARRAY_SIZE),
25999            predicate = function(value) { values.push(value); return isEven(value); },
26000            values = [],
26001            wrapped = chain(array);
26002
26003        assert.deepEqual(lodashStable.toArray(wrapped), array);
26004
26005        wrapped = wrapped.filter(predicate);
26006        assert.deepEqual(lodashStable.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
26007        assert.deepEqual(values, array, 'memoizes iterator values');
26008      }
26009      else {
26010        skipAssert(assert, 3);
26011      }
26012    });
26013  });
26014
26015  /*--------------------------------------------------------------------------*/
26016
26017  QUnit.module('lodash(...).plant');
26018
26019  (function() {
26020    QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
26021      assert.expect(2);
26022
26023      if (!isNpm) {
26024        var array1 = [5, null, 3, null, 1],
26025            array2 = [10, null, 8, null, 6],
26026            wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
26027            wrapped2 = wrapped1.plant(array2);
26028
26029        assert.deepEqual(wrapped2.value(), [36, 64]);
26030        assert.deepEqual(wrapped1.value(), [1, 9]);
26031      }
26032      else {
26033        skipAssert(assert, 2);
26034      }
26035    });
26036
26037    QUnit.test('should clone `chainAll` settings', function(assert) {
26038      assert.expect(1);
26039
26040      if (!isNpm) {
26041        var array1 = [2, 4],
26042            array2 = [6, 8],
26043            wrapped1 = _(array1).chain().map(square),
26044            wrapped2 = wrapped1.plant(array2);
26045
26046        assert.deepEqual(wrapped2.head().value(), 36);
26047      }
26048      else {
26049        skipAssert(assert);
26050      }
26051    });
26052
26053    QUnit.test('should reset iterator data on cloned sequences', function(assert) {
26054      assert.expect(3);
26055
26056      if (!isNpm && Symbol && Symbol.iterator) {
26057        var array1 = [2, 4],
26058            array2 = [6, 8],
26059            wrapped1 = _(array1).map(square);
26060
26061        assert.deepEqual(lodashStable.toArray(wrapped1), [4, 16]);
26062        assert.deepEqual(lodashStable.toArray(wrapped1), []);
26063
26064        var wrapped2 = wrapped1.plant(array2);
26065        assert.deepEqual(lodashStable.toArray(wrapped2), [36, 64]);
26066      }
26067      else {
26068        skipAssert(assert, 3);
26069      }
26070    });
26071  }());
26072
26073  /*--------------------------------------------------------------------------*/
26074
26075  QUnit.module('lodash(...).pop');
26076
26077  (function() {
26078    QUnit.test('should remove elements from the end of `array`', function(assert) {
26079      assert.expect(5);
26080
26081      if (!isNpm) {
26082        var array = [1, 2],
26083            wrapped = _(array);
26084
26085        assert.strictEqual(wrapped.pop(), 2);
26086        assert.deepEqual(wrapped.value(), [1]);
26087        assert.strictEqual(wrapped.pop(), 1);
26088
26089        var actual = wrapped.value();
26090        assert.strictEqual(actual, array);
26091        assert.deepEqual(actual, []);
26092      }
26093      else {
26094        skipAssert(assert, 5);
26095      }
26096    });
26097
26098    QUnit.test('should accept falsey arguments', function(assert) {
26099      assert.expect(1);
26100
26101      if (!isNpm) {
26102        var expected = lodashStable.map(falsey, stubTrue);
26103
26104        var actual = lodashStable.map(falsey, function(value, index) {
26105          try {
26106            var result = index ? _(value).pop() : _().pop();
26107            return result === undefined;
26108          } catch (e) {}
26109        });
26110
26111        assert.deepEqual(actual, expected);
26112      }
26113      else {
26114        skipAssert(assert);
26115      }
26116    });
26117  }());
26118
26119  /*--------------------------------------------------------------------------*/
26120
26121  QUnit.module('lodash(...).push');
26122
26123  (function() {
26124    QUnit.test('should append elements to `array`', function(assert) {
26125      assert.expect(2);
26126
26127      if (!isNpm) {
26128        var array = [1],
26129            wrapped = _(array).push(2, 3),
26130            actual = wrapped.value();
26131
26132        assert.strictEqual(actual, array);
26133        assert.deepEqual(actual, [1, 2, 3]);
26134      }
26135      else {
26136        skipAssert(assert, 2);
26137      }
26138    });
26139
26140    QUnit.test('should accept falsey arguments', function(assert) {
26141      assert.expect(1);
26142
26143      if (!isNpm) {
26144        var expected = lodashStable.map(falsey, stubTrue);
26145
26146        var actual = lodashStable.map(falsey, function(value, index) {
26147          try {
26148            var result = index ? _(value).push(1).value() : _().push(1).value();
26149            return lodashStable.eq(result, value);
26150          } catch (e) {}
26151        });
26152
26153        assert.deepEqual(actual, expected);
26154      }
26155      else {
26156        skipAssert(assert);
26157      }
26158    });
26159  }());
26160
26161  /*--------------------------------------------------------------------------*/
26162
26163  QUnit.module('lodash(...).shift');
26164
26165  (function() {
26166    QUnit.test('should remove elements from the front of `array`', function(assert) {
26167      assert.expect(5);
26168
26169      if (!isNpm) {
26170        var array = [1, 2],
26171            wrapped = _(array);
26172
26173        assert.strictEqual(wrapped.shift(), 1);
26174        assert.deepEqual(wrapped.value(), [2]);
26175        assert.strictEqual(wrapped.shift(), 2);
26176
26177        var actual = wrapped.value();
26178        assert.strictEqual(actual, array);
26179        assert.deepEqual(actual, []);
26180      }
26181      else {
26182        skipAssert(assert, 5);
26183      }
26184    });
26185
26186    QUnit.test('should accept falsey arguments', function(assert) {
26187      assert.expect(1);
26188
26189      if (!isNpm) {
26190        var expected = lodashStable.map(falsey, stubTrue);
26191
26192        var actual = lodashStable.map(falsey, function(value, index) {
26193          try {
26194            var result = index ? _(value).shift() : _().shift();
26195            return result === undefined;
26196          } catch (e) {}
26197        });
26198
26199        assert.deepEqual(actual, expected);
26200      }
26201      else {
26202        skipAssert(assert);
26203      }
26204    });
26205  }());
26206
26207  /*--------------------------------------------------------------------------*/
26208
26209  QUnit.module('lodash(...).sort');
26210
26211  (function() {
26212    QUnit.test('should return the wrapped sorted `array`', function(assert) {
26213      assert.expect(2);
26214
26215      if (!isNpm) {
26216        var array = [3, 1, 2],
26217            wrapped = _(array).sort(),
26218            actual = wrapped.value();
26219
26220        assert.strictEqual(actual, array);
26221        assert.deepEqual(actual, [1, 2, 3]);
26222      }
26223      else {
26224        skipAssert(assert, 2);
26225      }
26226    });
26227
26228    QUnit.test('should accept falsey arguments', function(assert) {
26229      assert.expect(1);
26230
26231      if (!isNpm) {
26232        var expected = lodashStable.map(falsey, stubTrue);
26233
26234        var actual = lodashStable.map(falsey, function(value, index) {
26235          try {
26236            var result = index ? _(value).sort().value() : _().sort().value();
26237            return lodashStable.eq(result, value);
26238          } catch (e) {}
26239        });
26240
26241        assert.deepEqual(actual, expected);
26242      }
26243      else {
26244        skipAssert(assert);
26245      }
26246    });
26247  }());
26248
26249  /*--------------------------------------------------------------------------*/
26250
26251  QUnit.module('lodash(...).splice');
26252
26253  (function() {
26254    QUnit.test('should support removing and inserting elements', function(assert) {
26255      assert.expect(5);
26256
26257      if (!isNpm) {
26258        var array = [1, 2],
26259            wrapped = _(array);
26260
26261        assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
26262        assert.deepEqual(wrapped.value(), [1, 3]);
26263        assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
26264
26265        var actual = wrapped.value();
26266        assert.strictEqual(actual, array);
26267        assert.deepEqual(actual, []);
26268      }
26269      else {
26270        skipAssert(assert, 5);
26271      }
26272    });
26273
26274    QUnit.test('should accept falsey arguments', function(assert) {
26275      assert.expect(1);
26276
26277      if (!isNpm) {
26278        var expected = lodashStable.map(falsey, stubTrue);
26279
26280        var actual = lodashStable.map(falsey, function(value, index) {
26281          try {
26282            var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
26283            return lodashStable.isEqual(result, []);
26284          } catch (e) {}
26285        });
26286
26287        assert.deepEqual(actual, expected);
26288      }
26289      else {
26290        skipAssert(assert);
26291      }
26292    });
26293  }());
26294
26295  /*--------------------------------------------------------------------------*/
26296
26297  QUnit.module('lodash(...).unshift');
26298
26299  (function() {
26300    QUnit.test('should prepend elements to `array`', function(assert) {
26301      assert.expect(2);
26302
26303      if (!isNpm) {
26304        var array = [3],
26305            wrapped = _(array).unshift(1, 2),
26306            actual = wrapped.value();
26307
26308        assert.strictEqual(actual, array);
26309        assert.deepEqual(actual, [1, 2, 3]);
26310      }
26311      else {
26312        skipAssert(assert, 2);
26313      }
26314    });
26315
26316    QUnit.test('should accept falsey arguments', function(assert) {
26317      assert.expect(1);
26318
26319      if (!isNpm) {
26320        var expected = lodashStable.map(falsey, stubTrue);
26321
26322        var actual = lodashStable.map(falsey, function(value, index) {
26323          try {
26324            var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
26325            return lodashStable.eq(result, value);
26326          } catch (e) {}
26327        });
26328
26329        assert.deepEqual(actual, expected);
26330      }
26331      else {
26332        skipAssert(assert);
26333      }
26334    });
26335  }());
26336
26337  /*--------------------------------------------------------------------------*/
26338
26339  QUnit.module('lodash(...).value');
26340
26341  (function() {
26342    QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
26343      assert.expect(4);
26344
26345      if (!isNpm) {
26346        var array = [1],
26347            wrapped = _(array).push(2).push(3);
26348
26349        assert.deepEqual(array, [1]);
26350        assert.deepEqual(wrapped.value(), [1, 2, 3]);
26351        assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
26352        assert.deepEqual(array, [1, 2, 3, 2, 3]);
26353      }
26354      else {
26355        skipAssert(assert, 4);
26356      }
26357    });
26358
26359    QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
26360      assert.expect(1);
26361
26362      if (!isNpm) {
26363        var wrapped = _(123);
26364        assert.strictEqual(Number(wrapped), 123);
26365      }
26366      else {
26367        skipAssert(assert);
26368      }
26369    });
26370
26371    QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
26372      assert.expect(1);
26373
26374      if (!isNpm && JSON) {
26375        var wrapped = _([1, 2, 3]);
26376        assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
26377      }
26378      else {
26379        skipAssert(assert);
26380      }
26381    });
26382
26383    QUnit.test('should be aliased', function(assert) {
26384      assert.expect(2);
26385
26386      if (!isNpm) {
26387        var expected = _.prototype.value;
26388        assert.strictEqual(_.prototype.toJSON, expected);
26389        assert.strictEqual(_.prototype.valueOf, expected);
26390      }
26391      else {
26392        skipAssert(assert, 2);
26393      }
26394    });
26395  }());
26396
26397  /*--------------------------------------------------------------------------*/
26398
26399  QUnit.module('lodash(...) methods that return the wrapped modified array');
26400
26401  (function() {
26402    var funcs = [
26403      'push',
26404      'reverse',
26405      'sort',
26406      'unshift'
26407    ];
26408
26409    lodashStable.each(funcs, function(methodName) {
26410      QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
26411        assert.expect(2);
26412
26413        if (!isNpm) {
26414          var array = [1, 2, 3],
26415              wrapped = _(array),
26416              actual = wrapped[methodName]();
26417
26418          assert.ok(actual instanceof _);
26419          assert.notStrictEqual(actual, wrapped);
26420        }
26421        else {
26422          skipAssert(assert, 2);
26423        }
26424      });
26425    });
26426  }());
26427
26428  /*--------------------------------------------------------------------------*/
26429
26430  QUnit.module('lodash(...) methods that return new wrapped values');
26431
26432  (function() {
26433    var funcs = [
26434      'castArray',
26435      'concat',
26436      'difference',
26437      'differenceBy',
26438      'differenceWith',
26439      'intersection',
26440      'intersectionBy',
26441      'intersectionWith',
26442      'pull',
26443      'pullAll',
26444      'pullAt',
26445      'sampleSize',
26446      'shuffle',
26447      'slice',
26448      'splice',
26449      'split',
26450      'toArray',
26451      'union',
26452      'unionBy',
26453      'unionWith',
26454      'uniq',
26455      'uniqBy',
26456      'uniqWith',
26457      'words',
26458      'xor',
26459      'xorBy',
26460      'xorWith'
26461    ];
26462
26463    lodashStable.each(funcs, function(methodName) {
26464      QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
26465        assert.expect(2);
26466
26467        if (!isNpm) {
26468          var value = methodName == 'split' ? 'abc' : [1, 2, 3],
26469              wrapped = _(value),
26470              actual = wrapped[methodName]();
26471
26472          assert.ok(actual instanceof _);
26473          assert.notStrictEqual(actual, wrapped);
26474        }
26475        else {
26476          skipAssert(assert, 2);
26477        }
26478      });
26479    });
26480  }());
26481
26482  /*--------------------------------------------------------------------------*/
26483
26484  QUnit.module('lodash(...) methods that return unwrapped values');
26485
26486  (function() {
26487    var funcs = [
26488      'add',
26489      'camelCase',
26490      'capitalize',
26491      'ceil',
26492      'clone',
26493      'deburr',
26494      'defaultTo',
26495      'divide',
26496      'endsWith',
26497      'escape',
26498      'escapeRegExp',
26499      'every',
26500      'find',
26501      'floor',
26502      'has',
26503      'hasIn',
26504      'head',
26505      'includes',
26506      'isArguments',
26507      'isArray',
26508      'isArrayBuffer',
26509      'isArrayLike',
26510      'isBoolean',
26511      'isBuffer',
26512      'isDate',
26513      'isElement',
26514      'isEmpty',
26515      'isEqual',
26516      'isError',
26517      'isFinite',
26518      'isFunction',
26519      'isInteger',
26520      'isMap',
26521      'isNaN',
26522      'isNative',
26523      'isNil',
26524      'isNull',
26525      'isNumber',
26526      'isObject',
26527      'isObjectLike',
26528      'isPlainObject',
26529      'isRegExp',
26530      'isSafeInteger',
26531      'isSet',
26532      'isString',
26533      'isUndefined',
26534      'isWeakMap',
26535      'isWeakSet',
26536      'join',
26537      'kebabCase',
26538      'last',
26539      'lowerCase',
26540      'lowerFirst',
26541      'max',
26542      'maxBy',
26543      'min',
26544      'minBy',
26545      'multiply',
26546      'nth',
26547      'pad',
26548      'padEnd',
26549      'padStart',
26550      'parseInt',
26551      'pop',
26552      'random',
26553      'reduce',
26554      'reduceRight',
26555      'repeat',
26556      'replace',
26557      'round',
26558      'sample',
26559      'shift',
26560      'size',
26561      'snakeCase',
26562      'some',
26563      'startCase',
26564      'startsWith',
26565      'subtract',
26566      'sum',
26567      'toFinite',
26568      'toInteger',
26569      'toLower',
26570      'toNumber',
26571      'toSafeInteger',
26572      'toString',
26573      'toUpper',
26574      'trim',
26575      'trimEnd',
26576      'trimStart',
26577      'truncate',
26578      'unescape',
26579      'upperCase',
26580      'upperFirst'
26581    ];
26582
26583    lodashStable.each(funcs, function(methodName) {
26584      QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
26585        assert.expect(1);
26586
26587        if (!isNpm) {
26588          var actual = _()[methodName]();
26589          assert.notOk(actual instanceof _);
26590        }
26591        else {
26592          skipAssert(assert);
26593        }
26594      });
26595
26596      QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
26597        assert.expect(1);
26598
26599        if (!isNpm) {
26600          var actual = _().chain()[methodName]();
26601          assert.ok(actual instanceof _);
26602        }
26603        else {
26604          skipAssert(assert);
26605        }
26606      });
26607    });
26608  }());
26609
26610  /*--------------------------------------------------------------------------*/
26611
26612  QUnit.module('"Arrays" category methods');
26613
26614  (function() {
26615    var args = toArgs([1, null, [3], null, 5]),
26616        sortedArgs = toArgs([1, [3], 5, null, null]),
26617        array = [1, 2, 3, 4, 5, 6];
26618
26619    QUnit.test('should work with `arguments` objects', function(assert) {
26620      assert.expect(30);
26621
26622      function message(methodName) {
26623        return '`_.' + methodName + '` should work with `arguments` objects';
26624      }
26625
26626      assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
26627      assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
26628
26629      assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
26630      assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
26631
26632      assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
26633      assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
26634      assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
26635      assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
26636      assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
26637      assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
26638      assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
26639      assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
26640      assert.deepEqual(_.head(args), 1, message('head'));
26641      assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
26642      assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
26643      assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
26644      assert.deepEqual(_.last(args), 5, message('last'));
26645      assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
26646      assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
26647      assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
26648      assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
26649      assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
26650      assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
26651      assert.deepEqual(_.take(args, 2), [1, null], message('take'));
26652      assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
26653      assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
26654      assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
26655      assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
26656      assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
26657      assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
26658    });
26659
26660    QUnit.test('should accept falsey primary arguments', function(assert) {
26661      assert.expect(4);
26662
26663      function message(methodName) {
26664        return '`_.' + methodName + '` should accept falsey primary arguments';
26665      }
26666
26667      assert.deepEqual(_.difference(null, array), [], message('difference'));
26668      assert.deepEqual(_.intersection(null, array), [], message('intersection'));
26669      assert.deepEqual(_.union(null, array), array, message('union'));
26670      assert.deepEqual(_.xor(null, array), array, message('xor'));
26671    });
26672
26673    QUnit.test('should accept falsey secondary arguments', function(assert) {
26674      assert.expect(3);
26675
26676      function message(methodName) {
26677        return '`_.' + methodName + '` should accept falsey secondary arguments';
26678      }
26679
26680      assert.deepEqual(_.difference(array, null), array, message('difference'));
26681      assert.deepEqual(_.intersection(array, null), [], message('intersection'));
26682      assert.deepEqual(_.union(array, null), array, message('union'));
26683    });
26684  }());
26685
26686  /*--------------------------------------------------------------------------*/
26687
26688  QUnit.module('"Strings" category methods');
26689
26690  (function() {
26691    var stringMethods = [
26692      'camelCase',
26693      'capitalize',
26694      'escape',
26695      'kebabCase',
26696      'lowerCase',
26697      'lowerFirst',
26698      'pad',
26699      'padEnd',
26700      'padStart',
26701      'repeat',
26702      'snakeCase',
26703      'toLower',
26704      'toUpper',
26705      'trim',
26706      'trimEnd',
26707      'trimStart',
26708      'truncate',
26709      'unescape',
26710      'upperCase',
26711      'upperFirst'
26712    ];
26713
26714    lodashStable.each(stringMethods, function(methodName) {
26715      var func = _[methodName];
26716
26717      QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
26718        assert.expect(1);
26719
26720        var values = [, null, undefined, ''],
26721            expected = lodashStable.map(values, stubString);
26722
26723        var actual = lodashStable.map(values, function(value, index) {
26724          return index ? func(value) : func();
26725        });
26726
26727        assert.deepEqual(actual, expected);
26728      });
26729    });
26730  }());
26731
26732  /*--------------------------------------------------------------------------*/
26733
26734  QUnit.module('lodash methods');
26735
26736  (function() {
26737    var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
26738      return lodashStable.startsWith(methodName, '_');
26739    });
26740
26741    var checkFuncs = [
26742      'after',
26743      'ary',
26744      'before',
26745      'bind',
26746      'curry',
26747      'curryRight',
26748      'debounce',
26749      'defer',
26750      'delay',
26751      'flip',
26752      'flow',
26753      'flowRight',
26754      'memoize',
26755      'negate',
26756      'once',
26757      'partial',
26758      'partialRight',
26759      'rearg',
26760      'rest',
26761      'spread',
26762      'throttle',
26763      'unary'
26764    ];
26765
26766    var noBinding = [
26767      'flip',
26768      'memoize',
26769      'negate',
26770      'once',
26771      'overArgs',
26772      'partial',
26773      'partialRight',
26774      'rearg',
26775      'rest',
26776      'spread'
26777    ];
26778
26779    var rejectFalsey = [
26780      'tap',
26781      'thru'
26782    ].concat(checkFuncs);
26783
26784    var returnArrays = [
26785      'at',
26786      'chunk',
26787      'compact',
26788      'difference',
26789      'drop',
26790      'filter',
26791      'flatten',
26792      'functions',
26793      'initial',
26794      'intersection',
26795      'invokeMap',
26796      'keys',
26797      'map',
26798      'orderBy',
26799      'pull',
26800      'pullAll',
26801      'pullAt',
26802      'range',
26803      'rangeRight',
26804      'reject',
26805      'remove',
26806      'shuffle',
26807      'sortBy',
26808      'tail',
26809      'take',
26810      'times',
26811      'toArray',
26812      'toPairs',
26813      'toPairsIn',
26814      'union',
26815      'uniq',
26816      'values',
26817      'without',
26818      'xor',
26819      'zip'
26820    ];
26821
26822    var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
26823
26824    QUnit.test('should accept falsey arguments', function(assert) {
26825      assert.expect(316);
26826
26827      var arrays = lodashStable.map(falsey, stubArray);
26828
26829      lodashStable.each(acceptFalsey, function(methodName) {
26830        var expected = arrays,
26831            func = _[methodName];
26832
26833        var actual = lodashStable.map(falsey, function(value, index) {
26834          return index ? func(value) : func();
26835        });
26836
26837        if (methodName == 'noConflict') {
26838          root._ = oldDash;
26839        }
26840        else if (methodName == 'pull' || methodName == 'pullAll') {
26841          expected = falsey;
26842        }
26843        if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
26844          assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
26845        }
26846        assert.ok(true, '`_.' + methodName + '` accepts falsey arguments');
26847      });
26848
26849      // Skip tests for missing methods of modularized builds.
26850      lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
26851        if (!_[methodName]) {
26852          skipAssert(assert);
26853        }
26854      });
26855    });
26856
26857    QUnit.test('should return an array', function(assert) {
26858      assert.expect(70);
26859
26860      var array = [1, 2, 3];
26861
26862      lodashStable.each(returnArrays, function(methodName) {
26863        var actual,
26864            func = _[methodName];
26865
26866        switch (methodName) {
26867          case 'invokeMap':
26868            actual = func(array, 'toFixed');
26869            break;
26870          case 'sample':
26871            actual = func(array, 1);
26872            break;
26873          default:
26874            actual = func(array);
26875        }
26876        assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
26877
26878        var isPull = methodName == 'pull' || methodName == 'pullAll';
26879        assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
26880      });
26881    });
26882
26883    QUnit.test('should throw an error for falsey arguments', function(assert) {
26884      assert.expect(24);
26885
26886      lodashStable.each(rejectFalsey, function(methodName) {
26887        var expected = lodashStable.map(falsey, stubTrue),
26888            func = _[methodName];
26889
26890        var actual = lodashStable.map(falsey, function(value, index) {
26891          var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
26892
26893          try {
26894            index ? func(value) : func();
26895          } catch (e) {
26896            pass = !pass && (e instanceof TypeError) &&
26897              (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
26898          }
26899          return pass;
26900        });
26901
26902        assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
26903      });
26904    });
26905
26906    QUnit.test('should use `this` binding of function', function(assert) {
26907      assert.expect(30);
26908
26909      lodashStable.each(noBinding, function(methodName) {
26910        var fn = function() { return this.a; },
26911            func = _[methodName],
26912            isNegate = methodName == 'negate',
26913            object = { 'a': 1 },
26914            expected = isNegate ? false : 1;
26915
26916        var wrapper = func(_.bind(fn, object));
26917        assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
26918
26919        wrapper = _.bind(func(fn), object);
26920        assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
26921
26922        object.wrapper = func(fn);
26923        assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
26924      });
26925    });
26926
26927    QUnit.test('should not contain minified method names (test production builds)', function(assert) {
26928      assert.expect(1);
26929
26930      var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
26931      assert.ok(lodashStable.every(_.functions(_), function(methodName) {
26932        return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
26933      }));
26934    });
26935  }());
26936
26937  /*--------------------------------------------------------------------------*/
26938
26939  QUnit.config.asyncRetries = 10;
26940  QUnit.config.hidepassed = true;
26941
26942  if (!document) {
26943    QUnit.config.noglobals = true;
26944    QUnit.load();
26945    QUnit.start();
26946  }
26947}.call(this));
26948