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.