blob: 0df49abb8d949fb28091d93d70fc6e82bb2520d7 [file] [log] [blame]
Matteo Scandolo280dcd32016-05-16 09:59:38 -07001;(function() {
2
3 /** Used as a safe reference for `undefined` in pre-ES5 environments. */
4 var undefined;
5
6 /** Used to detect when a function becomes hot. */
7 var HOT_COUNT = 150;
8
9 /** Used as the size to cover large array optimizations. */
10 var LARGE_ARRAY_SIZE = 200;
11
12 /** Used as the `TypeError` message for "Functions" methods. */
13 var FUNC_ERROR_TEXT = 'Expected a function';
14
15 /** Used as references for various `Number` constants. */
16 var MAX_SAFE_INTEGER = 9007199254740991,
17 MAX_INTEGER = 1.7976931348623157e+308;
18
19 /** Used as references for the maximum length and index of an array. */
20 var MAX_ARRAY_LENGTH = 4294967295,
21 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
22
23 /** `Object#toString` result references. */
24 var funcTag = '[object Function]',
25 numberTag = '[object Number]',
26 objectTag = '[object Object]';
27
28 /** Used as a reference to the global object. */
29 var root = (typeof global == 'object' && global) || this;
30
31 /** Used to store lodash to test for bad extensions/shims. */
32 var lodashBizarro = root.lodashBizarro;
33
34 /** Used for native method references. */
35 var arrayProto = Array.prototype,
36 funcProto = Function.prototype,
37 objectProto = Object.prototype,
38 numberProto = Number.prototype,
39 stringProto = String.prototype;
40
41 /** Method and object shortcuts. */
42 var phantom = root.phantom,
43 process = root.process,
44 amd = root.define && define.amd,
45 argv = process && process.argv,
46 defineProperty = Object.defineProperty,
47 document = !phantom && root.document,
48 body = root.document && root.document.body,
49 create = Object.create,
50 fnToString = funcProto.toString,
51 freeze = Object.freeze,
52 getSymbols = Object.getOwnPropertySymbols,
53 identity = function(value) { return value; },
54 JSON = root.JSON,
55 noop = function() {},
56 objToString = objectProto.toString,
57 params = argv,
58 push = arrayProto.push,
59 realm = {},
60 slice = arrayProto.slice;
61
62 var ArrayBuffer = root.ArrayBuffer,
63 Buffer = root.Buffer,
64 Promise = root.Promise,
65 Map = root.Map,
66 Set = root.Set,
67 Symbol = root.Symbol,
68 Uint8Array = root.Uint8Array,
69 WeakMap = root.WeakMap,
70 WeakSet = root.WeakSet;
71
72 var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
73 map = Map ? new Map : undefined,
74 promise = Promise ? Promise.resolve(1) : undefined,
75 set = Set ? new Set : undefined,
76 symbol = Symbol ? Symbol('a') : undefined,
77 weakMap = WeakMap ? new WeakMap : undefined,
78 weakSet = WeakSet ? new WeakSet : undefined;
79
80 /** Math helpers. */
81 var add = function(x, y) { return x + y; },
82 doubled = function(n) { return n * 2; },
83 isEven = function(n) { return n % 2 == 0; },
84 square = function(n) { return n * n; };
85
86 /** Constant functions. */
87 var alwaysA = function() { return 'a'; },
88 alwaysB = function() { return 'b'; },
89 alwaysC = function() { return 'c'; };
90
91 var alwaysTrue = function() { return true; },
92 alwaysFalse = function() { return false; };
93
94 var alwaysNaN = function() { return NaN; },
95 alwaysNull = function() { return null; };
96
97 var alwaysZero = function() { return 0; },
98 alwaysOne = function() { return 1; },
99 alwaysTwo = function() { return 2; },
100 alwaysThree = function() { return 3; },
101 alwaysFour = function() { return 4; };
102
103 var alwaysEmptyArray = function() { return []; },
104 alwaysEmptyObject = function() { return {}; },
105 alwaysEmptyString = function() { return ''; };
106
107 /** List of latin-1 supplementary letters to basic latin letters. */
108 var burredLetters = [
109 '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce',
110 '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
111 '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
112 '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
113 ];
114
115 /** List of combining diacritical marks. */
116 var comboMarks = [
117 '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
118 '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
119 '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
120 '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
121 '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
122 '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
123 '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
124 '\ufe20', '\ufe21', '\ufe22', '\ufe23'
125 ];
126
127 /** List of `burredLetters` translated to basic latin letters. */
128 var deburredLetters = [
129 'A', 'A', 'A', 'A', 'A', 'A', 'Ae', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I',
130 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
131 'ss', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i',
132 'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y'
133 ];
134
135 /** Used to provide falsey values to methods. */
136 var falsey = [, null, undefined, false, 0, NaN, ''];
137
138 /** Used to specify the emoji style glyph variant of characters. */
139 var emojiVar = '\ufe0f';
140
141 /** Used to provide empty values to methods. */
142 var empties = [[], {}].concat(falsey.slice(1));
143
144 /** Used to test error objects. */
145 var errors = [
146 new Error,
147 new EvalError,
148 new RangeError,
149 new ReferenceError,
150 new SyntaxError,
151 new TypeError,
152 new URIError
153 ];
154
155 /** List of fitzpatrick modifiers. */
156 var fitzModifiers = [
157 '\ud83c\udffb',
158 '\ud83c\udffc',
159 '\ud83c\udffd',
160 '\ud83c\udffe',
161 '\ud83c\udfff'
162 ];
163
164 /** Used to provide primitive values to methods. */
165 var primitives = [null, undefined, false, true, 1, NaN, 'a'];
166
167 /** Used to check whether methods support typed arrays. */
168 var typedArrays = [
169 'Float32Array',
170 'Float64Array',
171 'Int8Array',
172 'Int16Array',
173 'Int32Array',
174 'Uint8Array',
175 'Uint8ClampedArray',
176 'Uint16Array',
177 'Uint32Array'
178 ];
179
180 /** Used to check whether methods support array views. */
181 var arrayViews = typedArrays.concat('DataView');
182
183 /** The file path of the lodash file to test. */
184 var filePath = (function() {
185 var min = 2,
186 result = params || [];
187
188 if (phantom) {
189 min = 0;
190 result = params = phantom.args || require('system').args;
191 }
192 var last = result[result.length - 1];
193 result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
194
195 if (!amd) {
196 try {
197 result = require('fs').realpathSync(result);
198 } catch (e) {}
199
200 try {
201 result = require.resolve(result);
202 } catch (e) {}
203 }
204 return result;
205 }());
206
207 /** The `ui` object. */
208 var ui = root.ui || (root.ui = {
209 'buildPath': filePath,
210 'loaderPath': '',
211 'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath),
212 'isStrict': /\bes\b/.test(filePath),
213 'urlParams': {}
214 });
215
216 /** The basename of the lodash file to test. */
217 var basename = /[\w.-]+$/.exec(filePath)[0];
218
219 /** Used to indicate testing a modularized build. */
220 var isModularize = ui.isModularize;
221
222 /** Detect if testing `npm` modules. */
223 var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
224
225 /** Detect if running in PhantomJS. */
226 var isPhantom = phantom || (typeof callPhantom == 'function');
227
228 /** Detect if lodash is in strict mode. */
229 var isStrict = ui.isStrict;
230
231 /*--------------------------------------------------------------------------*/
232
233 // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
234 root.msWDfn = undefined;
235
236 // Exit early if going to run tests in a PhantomJS web page.
237 if (phantom && isModularize) {
238 var page = require('webpage').create();
239
240 page.onCallback = function(details) {
241 var coverage = details.coverage;
242 if (coverage) {
243 var fs = require('fs'),
244 cwd = fs.workingDirectory,
245 sep = fs.separator;
246
247 fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
248 }
249 phantom.exit(details.failed ? 1 : 0);
250 };
251
252 page.onConsoleMessage = function(message) {
253 console.log(message);
254 };
255
256 page.onInitialized = function() {
257 page.evaluate(function() {
258 document.addEventListener('DOMContentLoaded', function() {
259 QUnit.done(function(details) {
260 details.coverage = window.__coverage__;
261 callPhantom(details);
262 });
263 });
264 });
265 };
266
267 page.open(filePath, function(status) {
268 if (status != 'success') {
269 console.log('PhantomJS failed to load page: ' + filePath);
270 phantom.exit(1);
271 }
272 });
273
274 console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
275 return;
276 }
277
278 /*--------------------------------------------------------------------------*/
279
280 /** Used to test Web Workers. */
281 var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
282 (document && document.origin != 'null') && root.Worker;
283
284 /** Used to test host objects in IE. */
285 try {
286 var xml = new ActiveXObject('Microsoft.XMLDOM');
287 } catch (e) {}
288
289 /** Poison the free variable `root` in Node.js */
290 try {
291 defineProperty(global.root, 'root', {
292 'configurable': false,
293 'enumerable': false,
294 'get': function() { throw new ReferenceError; }
295 });
296 } catch (e) {}
297
298 /** Use a single "load" function. */
299 var load = (!amd && typeof require == 'function')
300 ? require
301 : noop;
302
303 /** The unit testing framework. */
304 var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qunit.js'));
305
306 /** Load stable Lodash and QUnit Extras. */
307 var lodashStable = root.lodashStable;
308 if (!lodashStable) {
309 try {
310 lodashStable = load('../node_modules/lodash/lodash.js');
311 } catch (e) {
312 console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
313 return;
314 }
315 lodashStable = lodashStable.noConflict();
316 }
317 lodashStable = lodashStable.runInContext(root);
318
319 var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
320 if (QUnitExtras) {
321 QUnitExtras.runInContext(root);
322 }
323
324 /** The `lodash` function to test. */
325 var _ = root._ || (root._ = (
326 _ = load(filePath),
327 _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default']) || _,
328 (_.runInContext ? _.runInContext(root) : _)
329 ));
330
331 /** Used to detect instrumented istanbul code coverage runs. */
332 var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
333 return /^(?:\$\$cov_\d+\$\$)$/.test(key);
334 })];
335
336 /** Used to test generator functions. */
337 var generator = lodashStable.attempt(function() {
338 return Function('return function*(){}');
339 });
340
341 /** Used to restore the `_` reference. */
342 var oldDash = root._;
343
344 /**
345 * Used to check for problems removing whitespace. For a whitespace reference,
346 * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
347 */
348 var whitespace = lodashStable.filter([
349 // Basic whitespace characters.
350 ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
351
352 // Line terminators.
353 '\n', '\r', '\u2028', '\u2029',
354
355 // Unicode category "Zs" space separators.
356 '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
357 '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
358 ],
359 function(chr) { return /\s/.exec(chr); })
360 .join('');
361
362 /**
363 * Creates a custom error object.
364 *
365 * @private
366 * @constructor
367 * @param {string} message The error message.
368 */
369 function CustomError(message) {
370 this.name = 'CustomError';
371 this.message = message;
372 }
373
374 CustomError.prototype = lodashStable.create(Error.prototype, {
375 'constructor': CustomError
376 });
377
378 /**
379 * Removes all own enumerable string keyed properties from a given object.
380 *
381 * @private
382 * @param {Object} object The object to empty.
383 */
384 function emptyObject(object) {
385 lodashStable.forOwn(object, function(value, key, object) {
386 delete object[key];
387 });
388 }
389
390 /**
391 * Extracts the unwrapped value from its wrapper.
392 *
393 * @private
394 * @param {Object} wrapper The wrapper to unwrap.
395 * @returns {*} Returns the unwrapped value.
396 */
397 function getUnwrappedValue(wrapper) {
398 var index = -1,
399 actions = wrapper.__actions__,
400 length = actions.length,
401 result = wrapper.__wrapped__;
402
403 while (++index < length) {
404 var args = [result],
405 action = actions[index];
406
407 push.apply(args, action.args);
408 result = action.func.apply(action.thisArg, args);
409 }
410 return result;
411 }
412
413 /**
414 * Sets a non-enumerable property value on `object`.
415 *
416 * Note: This function is used to avoid a bug in older versions of V8 where
417 * overwriting non-enumerable built-ins makes them enumerable.
418 * See https://code.google.com/p/v8/issues/detail?id=1623
419 *
420 * @private
421 * @param {Object} object The object modify.
422 * @param {string} key The name of the property to set.
423 * @param {*} value The property value.
424 */
425 function setProperty(object, key, value) {
426 try {
427 defineProperty(object, key, {
428 'configurable': true,
429 'enumerable': false,
430 'writable': true,
431 'value': value
432 });
433 } catch (e) {
434 object[key] = value;
435 }
436 return object;
437 }
438
439 /**
440 * Skips a given number of tests with a passing result.
441 *
442 * @private
443 * @param {Object} assert The QUnit assert object.
444 * @param {number} [count=1] The number of tests to skip.
445 */
446 function skipAssert(assert, count) {
447 count || (count = 1);
448 while (count--) {
449 assert.ok(true, 'test skipped');
450 }
451 }
452
453 /*--------------------------------------------------------------------------*/
454
455 // Add bizarro values.
456 (function() {
457 if (document || (typeof require != 'function')) {
458 return;
459 }
460 var nativeString = fnToString.call(toString),
461 reToString = /toString/g;
462
463 function createToString(funcName) {
464 return lodashStable.constant(nativeString.replace(reToString, funcName));
465 }
466
467 // Allow bypassing native checks.
468 setProperty(funcProto, 'toString', function wrapper() {
469 setProperty(funcProto, 'toString', fnToString);
470 var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
471 setProperty(funcProto, 'toString', wrapper);
472 return result;
473 });
474
475 // Add prototype extensions.
476 funcProto._method = noop;
477
478 // Set bad shims.
479 setProperty(Object, 'create', (function() {
480 function object() {}
481 return function(prototype) {
482 if (lodashStable.isObject(prototype)) {
483 object.prototype = prototype;
484 var result = new object;
485 object.prototype = undefined;
486 }
487 return result || {};
488 };
489 }()));
490
491 setProperty(Object, 'getOwnPropertySymbols', undefined);
492
493 var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
494 setProperty(objectProto, 'propertyIsEnumerable', function(key) {
495 return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
496 });
497
498 if (Buffer) {
499 defineProperty(root, 'Buffer', {
500 'configurable': true,
501 'enumerable': true,
502 'get': function get() {
503 var caller = get.caller,
504 name = caller ? caller.name : '';
505
506 if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
507 return Buffer;
508 }
509 }
510 });
511 }
512 if (Map) {
513 setProperty(root, 'Map', (function() {
514 var count = 0;
515 return function() {
516 if (count++) {
517 return new Map;
518 }
519 setProperty(root, 'Map', Map);
520 return {};
521 };
522 }()));
523
524 setProperty(root.Map, 'toString', createToString('Map'));
525 }
526 setProperty(root, 'Promise', noop);
527 setProperty(root, 'Set', noop);
528 setProperty(root, 'Symbol', undefined);
529 setProperty(root, 'WeakMap', noop);
530
531 // Fake `WinRTError`.
532 setProperty(root, 'WinRTError', Error);
533
534 // Clear cache so lodash can be reloaded.
535 emptyObject(require.cache);
536
537 // Load lodash and expose it to the bad extensions/shims.
538 lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
539 root._ = oldDash;
540
541 // Restore built-in methods.
542 setProperty(Object, 'create', create);
543 setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
544 setProperty(root, 'Buffer', Buffer);
545
546 if (getSymbols) {
547 Object.getOwnPropertySymbols = getSymbols;
548 } else {
549 delete Object.getOwnPropertySymbols;
550 }
551 if (Map) {
552 setProperty(root, 'Map', Map);
553 } else {
554 delete root.Map;
555 }
556 if (Promise) {
557 setProperty(root, 'Promise', Promise);
558 } else {
559 delete root.Promise;
560 }
561 if (Set) {
562 setProperty(root, 'Set', Set);
563 } else {
564 delete root.Set;
565 }
566 if (Symbol) {
567 setProperty(root, 'Symbol', Symbol);
568 } else {
569 delete root.Symbol;
570 }
571 if (WeakMap) {
572 setProperty(root, 'WeakMap', WeakMap);
573 } else {
574 delete root.WeakMap;
575 }
576 delete root.WinRTError;
577 delete funcProto._method;
578 }());
579
580 // Add other realm values from the `vm` module.
581 lodashStable.attempt(function() {
582 lodashStable.assign(realm, require('vm').runInNewContext([
583 '(function() {',
584 ' var noop = function() {},',
585 ' root = this;',
586 '',
587 ' var object = {',
588 " 'ArrayBuffer': root.ArrayBuffer,",
589 " 'arguments': (function() { return arguments; }(1, 2, 3)),",
590 " 'array': [1],",
591 " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
592 " 'boolean': Object(false),",
593 " 'date': new Date,",
594 " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
595 " 'function': noop,",
596 " 'map': root.Map ? new root.Map : undefined,",
597 " 'nan': NaN,",
598 " 'null': null,",
599 " 'number': Object(0),",
600 " 'object': { 'a': 1 },",
601 " 'promise': root.Promise ? Promise.resolve(1) : undefined,",
602 " 'regexp': /x/,",
603 " 'set': root.Set ? new root.Set : undefined,",
604 " 'string': Object('a'),",
605 " 'symbol': root.Symbol ? root.Symbol() : undefined,",
606 " 'undefined': undefined,",
607 " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
608 " 'weakSet': root.WeakSet ? new root.WeakSet : undefined",
609 ' };',
610 '',
611 " ['" + arrayViews.join("', '") + "'].forEach(function(type) {",
612 ' var Ctor = root[type]',
613 ' object[type] = Ctor;',
614 ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
615 ' });',
616 '',
617 ' return object;',
618 '}())'
619 ].join('\n')));
620 });
621
622 // Add other realm values from an iframe.
623 lodashStable.attempt(function() {
624 _._realm = realm;
625
626 var iframe = document.createElement('iframe');
627 iframe.frameBorder = iframe.height = iframe.width = 0;
628 body.appendChild(iframe);
629
630 var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
631 idoc.write([
632 '<script>',
633 'var _ = parent._;',
634 '',
635 ' var noop = function() {},',
636 ' root = this;',
637 '',
638 'var object = {',
639 " 'ArrayBuffer': root.ArrayBuffer,",
640 " 'arguments': (function() { return arguments; }(1, 2, 3)),",
641 " 'array': [1],",
642 " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
643 " 'boolean': Object(false),",
644 " 'date': new Date,",
645 " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
646 " 'function': noop,",
647 " 'map': root.Map ? new root.Map : undefined,",
648 " 'nan': NaN,",
649 " 'null': null,",
650 " 'number': Object(0),",
651 " 'object': { 'a': 1 },",
652 " 'promise': root.Promise ? Promise.resolve(1) : undefined,",
653 " 'regexp': /x/,",
654 " 'set': root.Set ? new root.Set : undefined,",
655 " 'string': Object('a'),",
656 " 'symbol': root.Symbol ? root.Symbol() : undefined,",
657 " 'undefined': undefined,",
658 " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
659 " 'weakSet': root.WeakSet ? new root.WeakSet : undefined",
660 '};',
661 '',
662 "_.each(['" + arrayViews.join("', '") + "'], function(type) {",
663 ' var Ctor = root[type];',
664 ' object[type] = Ctor;',
665 ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
666 '});',
667 '',
668 '_.assign(_._realm, object);',
669 '<\/script>'
670 ].join('\n'));
671
672 idoc.close();
673 delete _._realm;
674 });
675
676 // Add a web worker.
677 lodashStable.attempt(function() {
678 var worker = new Worker('./asset/worker.js?t=' + (+new Date));
679 worker.addEventListener('message', function(e) {
680 _._VERSION = e.data || '';
681 }, false);
682
683 worker.postMessage(ui.buildPath);
684 });
685
686 // Expose internal modules for better code coverage.
687 lodashStable.attempt(function() {
688 var path = require('path'),
689 basePath = path.dirname(filePath);
690
691 if (isModularize && !(amd || isNpm)) {
692 lodashStable.each([
693 '_baseEach',
694 '_isIndex',
695 '_isIterateeCall'
696 ], function(relPath) {
697 var func = require(path.join(basePath, relPath)),
698 funcName = path.basename(relPath);
699
700 _['_' + funcName] = func[funcName] || func['default'] || func;
701 });
702 }
703 });
704
705 /*--------------------------------------------------------------------------*/
706
707 if (params) {
708 console.log('Running lodash tests.');
709 console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
710 }
711
712 QUnit.module(basename);
713
714 (function() {
715 QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
716 assert.expect(1);
717
718 if (amd) {
719 assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
720 }
721 else {
722 skipAssert(assert);
723 }
724 });
725
726 QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
727 assert.expect(1);
728
729 if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
730 assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
731 } else {
732 skipAssert(assert);
733 }
734 });
735
736 QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
737 assert.expect(1);
738
739 if (amd) {
740 assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
741 }
742 else {
743 skipAssert(assert);
744 }
745 });
746
747 QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
748 assert.expect(1);
749
750 var done = assert.async();
751
752 if (Worker) {
753 var limit = 30000 / QUnit.config.asyncRetries,
754 start = +new Date;
755
756 var attempt = function() {
757 var actual = _._VERSION;
758 if ((new Date - start) < limit && typeof actual != 'string') {
759 setTimeout(attempt, 16);
760 return;
761 }
762 assert.strictEqual(actual, _.VERSION);
763 done();
764 };
765
766 attempt();
767 }
768 else {
769 skipAssert(assert);
770 done();
771 }
772 });
773
774 QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
775 assert.expect(1);
776
777 if (lodashBizarro) {
778 assert.notOk('_method' in lodashBizarro);
779 }
780 else {
781 skipAssert(assert);
782 }
783 });
784
785 QUnit.test('should avoid non-native built-ins', function(assert) {
786 assert.expect(7);
787
788 function message(lodashMethod, nativeMethod) {
789 return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
790 }
791
792 function Foo() {
793 this.a = 1;
794 }
795 Foo.prototype.b = 2;
796
797 var object = { 'a': 1 },
798 otherObject = { 'b': 2 },
799 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
800
801 if (lodashBizarro) {
802 try {
803 var actual = lodashBizarro.keysIn(new Foo).sort();
804 } catch (e) {
805 actual = null;
806 }
807 var label = message('_.keysIn', 'Object#propertyIsEnumerable');
808 assert.deepEqual(actual, ['a', 'b'], label);
809
810 try {
811 var actual = lodashBizarro.isEmpty({});
812 } catch (e) {
813 actual = null;
814 }
815 var label = message('_.isEmpty', 'Object#propertyIsEnumerable');
816 assert.strictEqual(actual, true, label);
817
818 try {
819 actual = [
820 lodashBizarro.difference([object, otherObject], largeArray),
821 lodashBizarro.intersection(largeArray, [object]),
822 lodashBizarro.uniq(largeArray)
823 ];
824 } catch (e) {
825 actual = null;
826 }
827 label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
828 assert.deepEqual(actual, [[otherObject], [object], [object]], label);
829
830 try {
831 if (Symbol) {
832 object[symbol] = {};
833 }
834 actual = [
835 lodashBizarro.clone(object),
836 lodashBizarro.cloneDeep(object)
837 ];
838 } catch (e) {
839 actual = null;
840 }
841 label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
842 assert.deepEqual(actual, [object, object], label);
843
844 try {
845 var symObject = Object(symbol);
846
847 // Avoid symbol detection in Babel's `typeof` helper.
848 symObject.constructor = Object;
849
850 actual = [
851 Symbol ? lodashBizarro.clone(symObject) : { 'constructor': Object },
852 Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
853 Symbol ? lodashBizarro.toString(symObject) : ''
854 ];
855 } catch (e) {
856 actual = null;
857 }
858 label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
859 assert.deepEqual(actual, [{ 'constructor': Object }, false, ''], label);
860
861 try {
862 var map = new lodashBizarro.memoize.Cache;
863 actual = map.set('a', 1).get('a');
864 } catch (e) {
865 actual = null;
866 }
867 label = message('_.memoize.Cache', 'Map');
868 assert.deepEqual(actual, 1, label);
869
870 try {
871 map = new (Map || Object);
872 if (Symbol && Symbol.iterator) {
873 map[Symbol.iterator] = null;
874 }
875 actual = lodashBizarro.toArray(map);
876 } catch (e) {
877 actual = null;
878 }
879 label = message('_.toArray', 'Map');
880 assert.deepEqual(actual, [], label);
881 }
882 else {
883 skipAssert(assert, 7);
884 }
885 });
886 }());
887
888 /*--------------------------------------------------------------------------*/
889
890 QUnit.module('isIndex');
891
892 (function() {
893 var func = _._isIndex;
894
895 QUnit.test('should return `true` for indexes', function(assert) {
896 assert.expect(1);
897
898 if (func) {
899 var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
900 expected = lodashStable.map(values, alwaysTrue);
901
902 var actual = lodashStable.map(values, function(args) {
903 return func.apply(undefined, args);
904 });
905
906 assert.deepEqual(actual, expected);
907 }
908 else {
909 skipAssert(assert);
910 }
911 });
912
913 QUnit.test('should return `false` for non-indexes', function(assert) {
914 assert.expect(1);
915
916 if (func) {
917 var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
918 expected = lodashStable.map(values, alwaysFalse);
919
920 var actual = lodashStable.map(values, function(args) {
921 return func.apply(undefined, args);
922 });
923
924 assert.deepEqual(actual, expected);
925 }
926 else {
927 skipAssert(assert);
928 }
929 });
930 }());
931
932 /*--------------------------------------------------------------------------*/
933
934 QUnit.module('isIterateeCall');
935
936 (function() {
937 var array = [1],
938 func = _._isIterateeCall,
939 object = { 'a': 1 };
940
941 QUnit.test('should return `true` for iteratee calls', function(assert) {
942 assert.expect(3);
943
944 function Foo() {}
945 Foo.prototype.a = 1;
946
947 if (func) {
948 assert.strictEqual(func(1, 0, array), true);
949 assert.strictEqual(func(1, 'a', object), true);
950 assert.strictEqual(func(1, 'a', new Foo), true);
951 }
952 else {
953 skipAssert(assert, 3);
954 }
955 });
956
957 QUnit.test('should return `false` for non-iteratee calls', function(assert) {
958 assert.expect(4);
959
960 if (func) {
961 assert.strictEqual(func(2, 0, array), false);
962 assert.strictEqual(func(1, 1.1, array), false);
963 assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
964 assert.strictEqual(func(1, 'b', object), false);
965 }
966 else {
967 skipAssert(assert, 4);
968 }
969 });
970
971 QUnit.test('should work with `NaN` values', function(assert) {
972 assert.expect(2);
973
974 if (func) {
975 assert.strictEqual(func(NaN, 0, [NaN]), true);
976 assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
977 }
978 else {
979 skipAssert(assert, 2);
980 }
981 });
982
983 QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
984 assert.expect(1);
985
986 if (func) {
987 try {
988 var actual = func(1, { 'toString': null }, [1]);
989 } catch (e) {
990 var message = e.message;
991 }
992 assert.strictEqual(actual, false, message || '');
993 }
994 else {
995 skipAssert(assert);
996 }
997 });
998 }());
999
1000 /*--------------------------------------------------------------------------*/
1001
1002 QUnit.module('lodash constructor');
1003
1004 (function() {
1005 var values = empties.concat(true, 1, 'a'),
1006 expected = lodashStable.map(values, alwaysTrue);
1007
1008 QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
1009 assert.expect(1);
1010
1011 if (!isNpm) {
1012 var actual = lodashStable.map(values, function(value) {
1013 return _(value) instanceof _;
1014 });
1015
1016 assert.deepEqual(actual, expected);
1017 }
1018 else {
1019 skipAssert(assert);
1020 }
1021 });
1022
1023 QUnit.test('should return the given `lodash` instances', function(assert) {
1024 assert.expect(1);
1025
1026 if (!isNpm) {
1027 var actual = lodashStable.map(values, function(value) {
1028 var wrapped = _(value);
1029 return _(wrapped) === wrapped;
1030 });
1031
1032 assert.deepEqual(actual, expected);
1033 }
1034 else {
1035 skipAssert(assert);
1036 }
1037 });
1038
1039 QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
1040 assert.expect(1);
1041
1042 if (!isNpm && lodashBizarro) {
1043 var actual = lodashStable.map(values, function(value) {
1044 var wrapped = _(lodashBizarro(value)),
1045 unwrapped = wrapped.value();
1046
1047 return wrapped instanceof _ &&
1048 ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
1049 });
1050
1051 assert.deepEqual(actual, expected);
1052 }
1053 else {
1054 skipAssert(assert);
1055 }
1056 });
1057 }());
1058
1059 /*--------------------------------------------------------------------------*/
1060
1061 QUnit.module('lodash.add');
1062
1063 (function() {
1064 QUnit.test('should add two numbers', function(assert) {
1065 assert.expect(3);
1066
1067 assert.strictEqual(_.add(6, 4), 10);
1068 assert.strictEqual(_.add(-6, 4), -2);
1069 assert.strictEqual(_.add(-6, -4), -10);
1070 });
1071
1072 QUnit.test('should not coerce arguments to numbers', function(assert) {
1073 assert.expect(2);
1074
1075 assert.strictEqual(_.add('6', '4'), '64');
1076 assert.strictEqual(_.add('x', 'y'), 'xy');
1077 });
1078 }());
1079
1080 /*--------------------------------------------------------------------------*/
1081
1082 QUnit.module('lodash.after');
1083
1084 (function() {
1085 function after(n, times) {
1086 var count = 0;
1087 lodashStable.times(times, _.after(n, function() { count++; }));
1088 return count;
1089 }
1090
1091 QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1092 assert.expect(4);
1093
1094 assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
1095 assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
1096 assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
1097 assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
1098 });
1099
1100 QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1101 assert.expect(1);
1102
1103 assert.strictEqual(after(NaN, 1), 1);
1104 });
1105
1106 QUnit.test('should not set a `this` binding', function(assert) {
1107 assert.expect(2);
1108
1109 var after = _.after(1, function(assert) { return ++this.count; }),
1110 object = { 'after': after, 'count': 0 };
1111
1112 object.after();
1113 assert.strictEqual(object.after(), 2);
1114 assert.strictEqual(object.count, 2);
1115 });
1116 }());
1117
1118 /*--------------------------------------------------------------------------*/
1119
1120 QUnit.module('lodash.ary');
1121
1122 (function() {
1123 function fn(a, b, c) {
1124 return slice.call(arguments);
1125 }
1126
1127 QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
1128 assert.expect(2);
1129
1130 var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
1131 assert.deepEqual(actual, [6, 8, 10]);
1132
1133 var capped = _.ary(fn, 2);
1134 assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
1135 });
1136
1137 QUnit.test('should use `func.length` if `n` is not given', function(assert) {
1138 assert.expect(1);
1139
1140 var capped = _.ary(fn);
1141 assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
1142 });
1143
1144 QUnit.test('should treat a negative `n` as `0`', function(assert) {
1145 assert.expect(1);
1146
1147 var capped = _.ary(fn, -1);
1148
1149 try {
1150 var actual = capped('a');
1151 } catch (e) {}
1152
1153 assert.deepEqual(actual, []);
1154 });
1155
1156 QUnit.test('should coerce `n` to an integer', function(assert) {
1157 assert.expect(1);
1158
1159 var values = ['1', 1.6, 'xyz'],
1160 expected = [['a'], ['a'], []];
1161
1162 var actual = lodashStable.map(values, function(n) {
1163 var capped = _.ary(fn, n);
1164 return capped('a', 'b');
1165 });
1166
1167 assert.deepEqual(actual, expected);
1168 });
1169
1170 QUnit.test('should work when given less than the capped number of arguments', function(assert) {
1171 assert.expect(1);
1172
1173 var capped = _.ary(fn, 3);
1174 assert.deepEqual(capped('a'), ['a']);
1175 });
1176
1177 QUnit.test('should use the existing `ary` if smaller', function(assert) {
1178 assert.expect(1);
1179
1180 var capped = _.ary(_.ary(fn, 1), 2);
1181 assert.deepEqual(capped('a', 'b', 'c'), ['a']);
1182 });
1183
1184 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
1185 assert.expect(1);
1186
1187 var funcs = lodashStable.map([fn], _.ary),
1188 actual = funcs[0]('a', 'b', 'c');
1189
1190 assert.deepEqual(actual, ['a', 'b', 'c']);
1191 });
1192
1193 QUnit.test('should work when combined with other methods that use metadata', function(assert) {
1194 assert.expect(2);
1195
1196 var array = ['a', 'b', 'c'],
1197 includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
1198
1199 assert.strictEqual(includes('b')(array, 2), true);
1200
1201 if (!isNpm) {
1202 includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
1203 assert.strictEqual(includes('b')(array, 2), true);
1204 }
1205 else {
1206 skipAssert(assert);
1207 }
1208 });
1209 }());
1210
1211 /*--------------------------------------------------------------------------*/
1212
1213 QUnit.module('lodash.assignIn');
1214
1215 (function() {
1216 QUnit.test('should be aliased', function(assert) {
1217 assert.expect(1);
1218
1219 assert.strictEqual(_.extend, _.assignIn);
1220 });
1221 }());
1222
1223 /*--------------------------------------------------------------------------*/
1224
1225 QUnit.module('lodash.assign and lodash.assignIn');
1226
1227 lodashStable.each(['assign', 'assignIn'], function(methodName) {
1228 var func = _[methodName];
1229
1230 QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
1231 assert.expect(1);
1232
1233 assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
1234 });
1235
1236 QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
1237 assert.expect(2);
1238
1239 var expected = { 'a': 1, 'b': 2, 'c': 3 };
1240 assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
1241 assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
1242 });
1243
1244 QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
1245 assert.expect(1);
1246
1247 var expected = { 'a': 3, 'b': 2, 'c': 1 };
1248 assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1249 });
1250
1251 QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
1252 assert.expect(1);
1253
1254 var expected = { 'a': null, 'b': undefined, 'c': null };
1255 assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
1256 });
1257
1258 QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
1259 assert.expect(1);
1260
1261 var object = {};
1262
1263 var descriptor = {
1264 'configurable': true,
1265 'enumerable': true,
1266 'set': function() { throw new Error; }
1267 };
1268
1269 var source = {
1270 'a': 1,
1271 'b': undefined,
1272 'c': NaN,
1273 'd': undefined,
1274 'constructor': Object,
1275 'toString': lodashStable.constant('source')
1276 };
1277
1278 defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
1279 'get': alwaysOne
1280 }));
1281
1282 defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
1283 'get': noop
1284 }));
1285
1286 defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
1287 'get': alwaysNaN
1288 }));
1289
1290 defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
1291 'get': lodashStable.constant(Object)
1292 }));
1293
1294 try {
1295 var actual = func(object, source);
1296 } catch (e) {}
1297
1298 assert.deepEqual(actual, source);
1299 });
1300
1301 QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) {
1302 assert.expect(1);
1303
1304 var array = [1];
1305 array[2] = 3;
1306
1307 assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 });
1308 });
1309
1310 QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) {
1311 assert.expect(1);
1312
1313 function Foo() {}
1314 Foo.prototype.a = 1;
1315
1316 assert.deepEqual(func({}, Foo.prototype), { 'a': 1 });
1317 });
1318
1319 QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) {
1320 assert.expect(1);
1321
1322 assert.deepEqual(func({}, 'a'), { '0': 'a' });
1323 });
1324 });
1325
1326 /*--------------------------------------------------------------------------*/
1327
1328 QUnit.module('lodash.assignInWith');
1329
1330 (function() {
1331 QUnit.test('should be aliased', function(assert) {
1332 assert.expect(1);
1333
1334 assert.strictEqual(_.extendWith, _.assignInWith);
1335 });
1336 }());
1337
1338 /*--------------------------------------------------------------------------*/
1339
1340 QUnit.module('lodash.assignWith and lodash.assignInWith');
1341
1342 lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
1343 var func = _[methodName];
1344
1345 QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
1346 assert.expect(1);
1347
1348 var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
1349 return a === undefined ? b : a;
1350 });
1351
1352 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
1353 });
1354
1355 QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
1356 assert.expect(1);
1357
1358 var expected = { 'a': undefined };
1359 assert.deepEqual(func({}, expected, noop), expected);
1360 });
1361 });
1362
1363 /*--------------------------------------------------------------------------*/
1364
1365 QUnit.module('lodash.at');
1366
1367 (function() {
1368 var args = arguments,
1369 array = ['a', 'b', 'c'],
1370 object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
1371
1372 QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
1373 assert.expect(1);
1374
1375 var actual = _.at(array, [0, 2]);
1376 assert.deepEqual(actual, ['a', 'c']);
1377 });
1378
1379 QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
1380 assert.expect(1);
1381
1382 var actual = _.at(array, [2, 4, 0]);
1383 assert.deepEqual(actual, ['c', undefined, 'a']);
1384 });
1385
1386 QUnit.test('should work with non-index keys on array values', function(assert) {
1387 assert.expect(1);
1388
1389 var values = lodashStable.reject(empties, function(value) {
1390 return (value === 0) || lodashStable.isArray(value);
1391 }).concat(-1, 1.1);
1392
1393 var array = lodashStable.transform(values, function(result, value) {
1394 result[value] = 1;
1395 }, []);
1396
1397 var expected = lodashStable.map(values, alwaysOne),
1398 actual = _.at(array, values);
1399
1400 assert.deepEqual(actual, expected);
1401 });
1402
1403 QUnit.test('should return an empty array when no keys are given', function(assert) {
1404 assert.expect(2);
1405
1406 assert.deepEqual(_.at(array), []);
1407 assert.deepEqual(_.at(array, [], []), []);
1408 });
1409
1410 QUnit.test('should accept multiple key arguments', function(assert) {
1411 assert.expect(1);
1412
1413 var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
1414 assert.deepEqual(actual, ['d', 'a', 'c']);
1415 });
1416
1417 QUnit.test('should work with a falsey `object` argument when keys are given', function(assert) {
1418 assert.expect(1);
1419
1420 var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
1421
1422 var actual = lodashStable.map(falsey, function(object) {
1423 try {
1424 return _.at(object, 0, 1, 'pop', 'push');
1425 } catch (e) {}
1426 });
1427
1428 assert.deepEqual(actual, expected);
1429 });
1430
1431 QUnit.test('should work with an `arguments` object for `object`', function(assert) {
1432 assert.expect(1);
1433
1434 var actual = _.at(args, [2, 0]);
1435 assert.deepEqual(actual, [3, 1]);
1436 });
1437
1438 QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
1439 assert.expect(1);
1440
1441 var actual = _.at([1, 2, 3, 4, 5], args);
1442 assert.deepEqual(actual, [2, 3, 4]);
1443 });
1444
1445 QUnit.test('should work with an object for `object`', function(assert) {
1446 assert.expect(1);
1447
1448 var actual = _.at(object, ['a[0].b.c', 'a[1]']);
1449 assert.deepEqual(actual, [3, 4]);
1450 });
1451
1452 QUnit.test('should pluck inherited property values', function(assert) {
1453 assert.expect(1);
1454
1455 function Foo() {
1456 this.a = 1;
1457 }
1458 Foo.prototype.b = 2;
1459
1460 var actual = _.at(new Foo, 'b');
1461 assert.deepEqual(actual, [2]);
1462 });
1463
1464 QUnit.test('should work in a lazy sequence', function(assert) {
1465 assert.expect(6);
1466
1467 if (!isNpm) {
1468 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
1469 smallArray = array;
1470
1471 lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
1472 lodashStable.times(2, function(index) {
1473 var array = index ? largeArray : smallArray,
1474 wrapped = _(array).map(identity).at(paths);
1475
1476 assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
1477 });
1478 });
1479 }
1480 else {
1481 skipAssert(assert, 6);
1482 }
1483 });
1484
1485 QUnit.test('should support shortcut fusion', function(assert) {
1486 assert.expect(8);
1487
1488 if (!isNpm) {
1489 var array = lodashStable.range(LARGE_ARRAY_SIZE),
1490 count = 0,
1491 iteratee = function(value) { count++; return square(value); },
1492 lastIndex = LARGE_ARRAY_SIZE - 1;
1493
1494 lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
1495 count = 0;
1496 var actual = _(array).map(iteratee).at(n).value(),
1497 expected = index < 2 ? 1 : 0;
1498
1499 assert.strictEqual(count, expected);
1500
1501 expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
1502 assert.deepEqual(actual, expected);
1503 });
1504 }
1505 else {
1506 skipAssert(assert, 8);
1507 }
1508 });
1509
1510 QUnit.test('work with an object for `object` when chaining', function(assert) {
1511 assert.expect(2);
1512
1513 if (!isNpm) {
1514 var paths = ['a[0].b.c', 'a[1]'],
1515 actual = _(object).map(identity).at(paths).value();
1516
1517 assert.deepEqual(actual, _.at(_.map(object, identity), paths));
1518
1519 var indexObject = { '0': 1 };
1520 actual = _(indexObject).at(0).value();
1521 assert.deepEqual(actual, _.at(indexObject, 0));
1522 }
1523 else {
1524 skipAssert(assert, 2);
1525 }
1526 });
1527 }(1, 2, 3));
1528
1529 /*--------------------------------------------------------------------------*/
1530
1531 QUnit.module('lodash.attempt');
1532
1533 (function() {
1534 QUnit.test('should return the result of `func`', function(assert) {
1535 assert.expect(1);
1536
1537 assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
1538 });
1539
1540 QUnit.test('should provide additional arguments to `func`', function(assert) {
1541 assert.expect(1);
1542
1543 var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
1544 assert.deepEqual(actual, [1, 2]);
1545 });
1546
1547 QUnit.test('should return the caught error', function(assert) {
1548 assert.expect(1);
1549
1550 var expected = lodashStable.map(errors, alwaysTrue);
1551
1552 var actual = lodashStable.map(errors, function(error) {
1553 return _.attempt(function() { throw error; }) === error;
1554 });
1555
1556 assert.deepEqual(actual, expected);
1557 });
1558
1559 QUnit.test('should coerce errors to error objects', function(assert) {
1560 assert.expect(1);
1561
1562 var actual = _.attempt(function() { throw 'x'; });
1563 assert.ok(lodashStable.isEqual(actual, Error('x')));
1564 });
1565
1566 QUnit.test('should preserve custom errors', function(assert) {
1567 assert.expect(1);
1568
1569 var actual = _.attempt(function() { throw new CustomError('x'); });
1570 assert.ok(actual instanceof CustomError);
1571 });
1572
1573 QUnit.test('should work with an error object from another realm', function(assert) {
1574 assert.expect(1);
1575
1576 if (realm.errors) {
1577 var expected = lodashStable.map(realm.errors, alwaysTrue);
1578
1579 var actual = lodashStable.map(realm.errors, function(error) {
1580 return _.attempt(function() { throw error; }) === error;
1581 });
1582
1583 assert.deepEqual(actual, expected);
1584 }
1585 else {
1586 skipAssert(assert);
1587 }
1588 });
1589
1590 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
1591 assert.expect(1);
1592
1593 if (!isNpm) {
1594 assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
1595 }
1596 else {
1597 skipAssert(assert);
1598 }
1599 });
1600
1601 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
1602 assert.expect(1);
1603
1604 if (!isNpm) {
1605 assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
1606 }
1607 else {
1608 skipAssert(assert);
1609 }
1610 });
1611 }());
1612
1613 /*--------------------------------------------------------------------------*/
1614
1615 QUnit.module('lodash.before');
1616
1617 (function() {
1618 function before(n, times) {
1619 var count = 0;
1620 lodashStable.times(times, _.before(n, function() { count++; }));
1621 return count;
1622 }
1623
1624 QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
1625 assert.expect(4);
1626
1627 assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
1628 assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
1629 assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
1630 assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
1631 });
1632
1633 QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
1634 assert.expect(1);
1635
1636 assert.strictEqual(before(NaN, 1), 0);
1637 });
1638
1639 QUnit.test('should not set a `this` binding', function(assert) {
1640 assert.expect(2);
1641
1642 var before = _.before(2, function(assert) { return ++this.count; }),
1643 object = { 'before': before, 'count': 0 };
1644
1645 object.before();
1646 assert.strictEqual(object.before(), 1);
1647 assert.strictEqual(object.count, 1);
1648 });
1649 }());
1650
1651 /*--------------------------------------------------------------------------*/
1652
1653 QUnit.module('lodash.bind');
1654
1655 (function() {
1656 function fn() {
1657 var result = [this];
1658 push.apply(result, arguments);
1659 return result;
1660 }
1661
1662 QUnit.test('should bind a function to an object', function(assert) {
1663 assert.expect(1);
1664
1665 var object = {},
1666 bound = _.bind(fn, object);
1667
1668 assert.deepEqual(bound('a'), [object, 'a']);
1669 });
1670
1671 QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
1672 assert.expect(1);
1673
1674 var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
1675 expected = lodashStable.map(values, function(value) { return [value]; });
1676
1677 var actual = lodashStable.map(values, function(value) {
1678 try {
1679 var bound = _.bind(fn, value);
1680 return bound();
1681 } catch (e) {}
1682 });
1683
1684 assert.ok(lodashStable.every(actual, function(value, index) {
1685 return lodashStable.isEqual(value, expected[index]);
1686 }));
1687 });
1688
1689 QUnit.test('should bind a function to nullish values', function(assert) {
1690 assert.expect(6);
1691
1692 var bound = _.bind(fn, null),
1693 actual = bound('a');
1694
1695 assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
1696 assert.strictEqual(actual[1], 'a');
1697
1698 lodashStable.times(2, function(index) {
1699 bound = index ? _.bind(fn, undefined) : _.bind(fn);
1700 actual = bound('b');
1701
1702 assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
1703 assert.strictEqual(actual[1], 'b');
1704 });
1705 });
1706
1707 QUnit.test('should partially apply arguments ', function(assert) {
1708 assert.expect(4);
1709
1710 var object = {},
1711 bound = _.bind(fn, object, 'a');
1712
1713 assert.deepEqual(bound(), [object, 'a']);
1714
1715 bound = _.bind(fn, object, 'a');
1716 assert.deepEqual(bound('b'), [object, 'a', 'b']);
1717
1718 bound = _.bind(fn, object, 'a', 'b');
1719 assert.deepEqual(bound(), [object, 'a', 'b']);
1720 assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
1721 });
1722
1723 QUnit.test('should support placeholders', function(assert) {
1724 assert.expect(4);
1725
1726 var object = {},
1727 ph = _.bind.placeholder,
1728 bound = _.bind(fn, object, ph, 'b', ph);
1729
1730 assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
1731 assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
1732 assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
1733 assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
1734 });
1735
1736 QUnit.test('should use `_.placeholder` when set', function(assert) {
1737 assert.expect(1);
1738
1739 if (!isModularize) {
1740 var _ph = _.placeholder = {},
1741 ph = _.bind.placeholder,
1742 object = {},
1743 bound = _.bind(fn, object, _ph, 'b', ph);
1744
1745 assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
1746 delete _.placeholder;
1747 }
1748 else {
1749 skipAssert(assert);
1750 }
1751 });
1752
1753 QUnit.test('should create a function with a `length` of `0`', function(assert) {
1754 assert.expect(2);
1755
1756 var fn = function(a, b, c) {},
1757 bound = _.bind(fn, {});
1758
1759 assert.strictEqual(bound.length, 0);
1760
1761 bound = _.bind(fn, {}, 1);
1762 assert.strictEqual(bound.length, 0);
1763 });
1764
1765 QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
1766 assert.expect(3);
1767
1768 function Foo() {
1769 return this;
1770 }
1771
1772 var bound = _.bind(Foo, { 'a': 1 }),
1773 newBound = new bound;
1774
1775 assert.strictEqual(bound().a, 1);
1776 assert.strictEqual(newBound.a, undefined);
1777 assert.ok(newBound instanceof Foo);
1778 });
1779
1780 QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
1781 assert.expect(1);
1782
1783 function Foo() {
1784 return this;
1785 }
1786
1787 function Bar() {}
1788
1789 var thisArg = { 'a': 1 },
1790 boundFoo = _.bind(Foo, thisArg),
1791 boundBar = _.bind(Bar, thisArg),
1792 count = 9,
1793 expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
1794
1795 var actual = lodashStable.times(count, function(index) {
1796 try {
1797 switch (index) {
1798 case 0: return [new boundFoo().a, new boundBar().a];
1799 case 1: return [new boundFoo(1).a, new boundBar(1).a];
1800 case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
1801 case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
1802 case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
1803 case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
1804 case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
1805 case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
1806 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];
1807 }
1808 } catch (e) {}
1809 });
1810
1811 assert.deepEqual(actual, expected);
1812 });
1813
1814 QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
1815 assert.expect(2);
1816
1817 function Foo(value) {
1818 return value && object;
1819 }
1820
1821 var bound = _.bind(Foo),
1822 object = {};
1823
1824 assert.ok(new bound instanceof Foo);
1825 assert.strictEqual(new bound(true), object);
1826 });
1827
1828 QUnit.test('should append array arguments to partially applied arguments', function(assert) {
1829 assert.expect(1);
1830
1831 var object = {},
1832 bound = _.bind(fn, object, 'a');
1833
1834 assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
1835 });
1836
1837 QUnit.test('should not rebind functions', function(assert) {
1838 assert.expect(3);
1839
1840 var object1 = {},
1841 object2 = {},
1842 object3 = {};
1843
1844 var bound1 = _.bind(fn, object1),
1845 bound2 = _.bind(bound1, object2, 'a'),
1846 bound3 = _.bind(bound1, object3, 'b');
1847
1848 assert.deepEqual(bound1(), [object1]);
1849 assert.deepEqual(bound2(), [object1, 'a']);
1850 assert.deepEqual(bound3(), [object1, 'b']);
1851 });
1852
1853 QUnit.test('should not error when instantiating bound built-ins', function(assert) {
1854 assert.expect(2);
1855
1856 var Ctor = _.bind(Date, null),
1857 expected = new Date(2012, 4, 23, 0, 0, 0, 0);
1858
1859 try {
1860 var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
1861 } catch (e) {}
1862
1863 assert.deepEqual(actual, expected);
1864
1865 Ctor = _.bind(Date, null, 2012, 4, 23);
1866
1867 try {
1868 actual = new Ctor(0, 0, 0, 0);
1869 } catch (e) {}
1870
1871 assert.deepEqual(actual, expected);
1872 });
1873
1874 QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
1875 assert.expect(1);
1876
1877 var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
1878
1879 if (typeof createCtor == 'function') {
1880 var bound = _.bind(createCtor()),
1881 count = 8,
1882 expected = lodashStable.times(count, alwaysTrue);
1883
1884 var actual = lodashStable.times(count, function(index) {
1885 try {
1886 switch (index) {
1887 case 0: return !!(new bound);
1888 case 1: return !!(new bound(1));
1889 case 2: return !!(new bound(1, 2));
1890 case 3: return !!(new bound(1, 2, 3));
1891 case 4: return !!(new bound(1, 2, 3, 4));
1892 case 5: return !!(new bound(1, 2, 3, 4, 5));
1893 case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
1894 case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
1895 }
1896 } catch (e) {}
1897 });
1898
1899 assert.deepEqual(actual, expected);
1900 }
1901 else {
1902 skipAssert(assert);
1903 }
1904 });
1905
1906 QUnit.test('should return a wrapped value when chaining', function(assert) {
1907 assert.expect(2);
1908
1909 if (!isNpm) {
1910 var object = {},
1911 bound = _(fn).bind({}, 'a', 'b');
1912
1913 assert.ok(bound instanceof _);
1914
1915 var actual = bound.value()('c');
1916 assert.deepEqual(actual, [object, 'a', 'b', 'c']);
1917 }
1918 else {
1919 skipAssert(assert, 2);
1920 }
1921 });
1922 }());
1923
1924 /*--------------------------------------------------------------------------*/
1925
1926 QUnit.module('lodash.bindAll');
1927
1928 (function() {
1929 var args = arguments;
1930
1931 var source = {
1932 '_n0': -2,
1933 '_p0': -1,
1934 '_a': 1,
1935 '_b': 2,
1936 '_c': 3,
1937 '_d': 4,
1938 '-0': function() { return this._n0; },
1939 '0': function() { return this._p0; },
1940 'a': function() { return this._a; },
1941 'b': function() { return this._b; },
1942 'c': function() { return this._c; },
1943 'd': function() { return this._d; }
1944 };
1945
1946 QUnit.test('should accept individual method names', function(assert) {
1947 assert.expect(1);
1948
1949 var object = lodashStable.cloneDeep(source);
1950 _.bindAll(object, 'a', 'b');
1951
1952 var actual = lodashStable.map(['a', 'b', 'c'], function(key) {
1953 return object[key].call({});
1954 });
1955
1956 assert.deepEqual(actual, [1, 2, undefined]);
1957 });
1958
1959 QUnit.test('should accept arrays of method names', function(assert) {
1960 assert.expect(1);
1961
1962 var object = lodashStable.cloneDeep(source);
1963 _.bindAll(object, ['a', 'b'], ['c']);
1964
1965 var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) {
1966 return object[key].call({});
1967 });
1968
1969 assert.deepEqual(actual, [1, 2, 3, undefined]);
1970 });
1971
1972 QUnit.test('should preserve the sign of `0`', function(assert) {
1973 assert.expect(1);
1974
1975 var props = [-0, Object(-0), 0, Object(0)];
1976
1977 var actual = lodashStable.map(props, function(key) {
1978 var object = lodashStable.cloneDeep(source);
1979 _.bindAll(object, key);
1980 return object[lodashStable.toString(key)].call({});
1981 });
1982
1983 assert.deepEqual(actual, [-2, -2, -1, -1]);
1984 });
1985
1986 QUnit.test('should work with an array `object` argument', function(assert) {
1987 assert.expect(1);
1988
1989 var array = ['push', 'pop'];
1990 _.bindAll(array);
1991 assert.strictEqual(array.pop, arrayProto.pop);
1992 });
1993
1994 QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
1995 assert.expect(1);
1996
1997 var object = lodashStable.cloneDeep(source);
1998 _.bindAll(object, args);
1999
2000 var actual = lodashStable.map(args, function(key) {
2001 return object[key].call({});
2002 });
2003
2004 assert.deepEqual(actual, [1]);
2005 });
2006 }('a'));
2007
2008 /*--------------------------------------------------------------------------*/
2009
2010 QUnit.module('lodash.bindKey');
2011
2012 (function() {
2013 QUnit.test('should work when the target function is overwritten', function(assert) {
2014 assert.expect(2);
2015
2016 var object = {
2017 'user': 'fred',
2018 'greet': function(greeting) {
2019 return this.user + ' says: ' + greeting;
2020 }
2021 };
2022
2023 var bound = _.bindKey(object, 'greet', 'hi');
2024 assert.strictEqual(bound(), 'fred says: hi');
2025
2026 object.greet = function(greeting) {
2027 return this.user + ' says: ' + greeting + '!';
2028 };
2029
2030 assert.strictEqual(bound(), 'fred says: hi!');
2031 });
2032
2033 QUnit.test('should support placeholders', function(assert) {
2034 assert.expect(4);
2035
2036 var object = {
2037 'fn': function() {
2038 return slice.call(arguments);
2039 }
2040 };
2041
2042 var ph = _.bindKey.placeholder,
2043 bound = _.bindKey(object, 'fn', ph, 'b', ph);
2044
2045 assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
2046 assert.deepEqual(bound('a'), ['a', 'b', undefined]);
2047 assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
2048 assert.deepEqual(bound(), [undefined, 'b', undefined]);
2049 });
2050
2051 QUnit.test('should use `_.placeholder` when set', function(assert) {
2052 assert.expect(1);
2053
2054 if (!isModularize) {
2055 var object = {
2056 'fn': function() {
2057 return slice.call(arguments);
2058 }
2059 };
2060
2061 var _ph = _.placeholder = {},
2062 ph = _.bindKey.placeholder,
2063 bound = _.bindKey(object, 'fn', _ph, 'b', ph);
2064
2065 assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
2066 delete _.placeholder;
2067 }
2068 else {
2069 skipAssert(assert);
2070 }
2071 });
2072
2073 QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
2074 assert.expect(2);
2075
2076 function Foo(value) {
2077 return value && object;
2078 }
2079
2080 var object = { 'Foo': Foo },
2081 bound = _.bindKey(object, 'Foo');
2082
2083 assert.ok(new bound instanceof Foo);
2084 assert.strictEqual(new bound(true), object);
2085 });
2086 }());
2087
2088 /*--------------------------------------------------------------------------*/
2089
2090 QUnit.module('case methods');
2091
2092 lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
2093 var methodName = caseName + 'Case',
2094 func = _[methodName];
2095
2096 var strings = [
2097 'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
2098 'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'
2099 ];
2100
2101 var converted = (function() {
2102 switch (caseName) {
2103 case 'camel': return 'fooBar';
2104 case 'kebab': return 'foo-bar';
2105 case 'lower': return 'foo bar';
2106 case 'snake': return 'foo_bar';
2107 case 'start': return 'Foo Bar';
2108 case 'upper': return 'FOO BAR';
2109 }
2110 }());
2111
2112 QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
2113 assert.expect(1);
2114
2115 var actual = lodashStable.map(strings, function(string) {
2116 var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2117 return func(string) === expected;
2118 });
2119
2120 assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2121 });
2122
2123 QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
2124 assert.expect(1);
2125
2126 var actual = lodashStable.map(strings, function(string) {
2127 var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
2128 return func(func(string)) === expected;
2129 });
2130
2131 assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
2132 });
2133
2134 QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
2135 assert.expect(1);
2136
2137 var actual = lodashStable.map(burredLetters, function(burred, index) {
2138 var letter = deburredLetters[index];
2139 if (caseName == 'start') {
2140 letter = lodashStable.capitalize(letter);
2141 } else if (caseName == 'upper') {
2142 letter = letter.toUpperCase();
2143 } else {
2144 letter = letter.toLowerCase();
2145 }
2146 return func(burred) === letter;
2147 });
2148
2149 assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue));
2150 });
2151
2152 QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) {
2153 assert.expect(2);
2154
2155 var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
2156
2157 lodashStable.each(["'", '\u2019'], function(apos) {
2158 var actual = lodashStable.map(postfixes, function(postfix) {
2159 return func('a b' + apos + postfix + ' c');
2160 });
2161
2162 var expected = lodashStable.map(postfixes, function(postfix) {
2163 switch (caseName) {
2164 case 'camel': return 'aB' + postfix + 'C';
2165 case 'kebab': return 'a-b' + postfix + '-c';
2166 case 'lower': return 'a b' + postfix + ' c';
2167 case 'snake': return 'a_b' + postfix + '_c';
2168 case 'start': return 'A B' + postfix + ' C';
2169 case 'upper': return 'A B' + postfix.toUpperCase() + ' C';
2170 }
2171 });
2172
2173 assert.deepEqual(actual, expected);
2174 });
2175 });
2176
2177 QUnit.test('`_.' + methodName + '` should remove latin-1 mathematical operators', function(assert) {
2178 assert.expect(1);
2179
2180 var actual = lodashStable.map(['\xd7', '\xf7'], func);
2181 assert.deepEqual(actual, ['', '']);
2182 });
2183
2184 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
2185 assert.expect(2);
2186
2187 var string = 'foo bar';
2188 assert.strictEqual(func(Object(string)), converted);
2189 assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
2190 });
2191
2192 QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
2193 assert.expect(1);
2194
2195 if (!isNpm) {
2196 assert.strictEqual(_('foo bar')[methodName](), converted);
2197 }
2198 else {
2199 skipAssert(assert);
2200 }
2201 });
2202
2203 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
2204 assert.expect(1);
2205
2206 if (!isNpm) {
2207 assert.ok(_('foo bar').chain()[methodName]() instanceof _);
2208 }
2209 else {
2210 skipAssert(assert);
2211 }
2212 });
2213 });
2214
2215 (function() {
2216 QUnit.test('should get the original value after cycling through all case methods', function(assert) {
2217 assert.expect(1);
2218
2219 var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase];
2220
2221 var actual = lodashStable.reduce(funcs, function(result, func) {
2222 return func(result);
2223 }, 'enable 6h format');
2224
2225 assert.strictEqual(actual, 'enable6HFormat');
2226 });
2227 }());
2228
2229 /*--------------------------------------------------------------------------*/
2230
2231 QUnit.module('lodash.camelCase');
2232
2233 (function() {
2234 QUnit.test('should work with numbers', function(assert) {
2235 assert.expect(6);
2236
2237 assert.strictEqual(_.camelCase('12 feet'), '12Feet');
2238 assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
2239 assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
2240 assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
2241 assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
2242 assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
2243 });
2244
2245 QUnit.test('should handle acronyms', function(assert) {
2246 assert.expect(6);
2247
2248 lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
2249 assert.strictEqual(_.camelCase(string), 'safeHtml');
2250 });
2251
2252 lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
2253 assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
2254 });
2255
2256 lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
2257 assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
2258 });
2259 });
2260 }());
2261
2262 /*--------------------------------------------------------------------------*/
2263
2264 QUnit.module('lodash.capitalize');
2265
2266 (function() {
2267 QUnit.test('should capitalize the first character of a string', function(assert) {
2268 assert.expect(3);
2269
2270 assert.strictEqual(_.capitalize('fred'), 'Fred');
2271 assert.strictEqual(_.capitalize('Fred'), 'Fred');
2272 assert.strictEqual(_.capitalize(' fred'), ' fred');
2273 });
2274 }());
2275
2276 /*--------------------------------------------------------------------------*/
2277
2278 QUnit.module('lodash.castArray');
2279
2280 (function() {
2281 QUnit.test('should wrap non-array items in an array', function(assert) {
2282 assert.expect(1);
2283
2284 var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
2285 expected = lodashStable.map(values, function(value) { return [value]; }),
2286 actual = lodashStable.map(values, _.castArray);
2287
2288 assert.deepEqual(actual, expected);
2289 });
2290
2291 QUnit.test('should return array values by reference', function(assert) {
2292 assert.expect(1);
2293
2294 var array = [1];
2295 assert.strictEqual(_.castArray(array), array);
2296 });
2297
2298 QUnit.test('should return an empty array when no arguments are given', function(assert) {
2299 assert.expect(1);
2300
2301 assert.deepEqual(_.castArray(), []);
2302 });
2303 }());
2304
2305 /*--------------------------------------------------------------------------*/
2306
2307 QUnit.module('lodash.chain');
2308
2309 (function() {
2310 QUnit.test('should return a wrapped value', function(assert) {
2311 assert.expect(1);
2312
2313 if (!isNpm) {
2314 var actual = _.chain({ 'a': 0 });
2315 assert.ok(actual instanceof _);
2316 }
2317 else {
2318 skipAssert(assert);
2319 }
2320 });
2321
2322 QUnit.test('should return existing wrapped values', function(assert) {
2323 assert.expect(2);
2324
2325 if (!isNpm) {
2326 var wrapped = _({ 'a': 0 });
2327 assert.strictEqual(_.chain(wrapped), wrapped);
2328 assert.strictEqual(wrapped.chain(), wrapped);
2329 }
2330 else {
2331 skipAssert(assert, 2);
2332 }
2333 });
2334
2335 QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
2336 assert.expect(6);
2337
2338 if (!isNpm) {
2339 var array = ['c', 'b', 'a'];
2340
2341 assert.ok(_.chain(array).head() instanceof _);
2342 assert.ok(_(array).chain().head() instanceof _);
2343
2344 assert.ok(_.chain(array).isArray() instanceof _);
2345 assert.ok(_(array).chain().isArray() instanceof _);
2346
2347 assert.ok(_.chain(array).sortBy().head() instanceof _);
2348 assert.ok(_(array).chain().sortBy().head() instanceof _);
2349 }
2350 else {
2351 skipAssert(assert, 6);
2352 }
2353 });
2354
2355 QUnit.test('should chain multiple methods', function(assert) {
2356 assert.expect(6);
2357
2358 if (!isNpm) {
2359 lodashStable.times(2, function(index) {
2360 var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
2361 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 },
2362 wrapped = index ? _(array).chain() : _.chain(array);
2363
2364 var actual = wrapped
2365 .chain()
2366 .map(function(value) { return value.split(''); })
2367 .flatten()
2368 .reduce(function(object, chr) {
2369 object[chr] || (object[chr] = 0);
2370 object[chr]++;
2371 return object;
2372 }, {})
2373 .value();
2374
2375 assert.deepEqual(actual, expected);
2376
2377 array = [1, 2, 3, 4, 5, 6];
2378 wrapped = index ? _(array).chain() : _.chain(array);
2379 actual = wrapped
2380 .chain()
2381 .filter(function(n) { return n % 2 != 0; })
2382 .reject(function(n) { return n % 3 == 0; })
2383 .sortBy(function(n) { return -n; })
2384 .value();
2385
2386 assert.deepEqual(actual, [5, 1]);
2387
2388 array = [3, 4];
2389 wrapped = index ? _(array).chain() : _.chain(array);
2390 actual = wrapped
2391 .reverse()
2392 .concat([2, 1])
2393 .unshift(5)
2394 .tap(function(value) { value.pop(); })
2395 .map(square)
2396 .value();
2397
2398 assert.deepEqual(actual, [25, 16, 9, 4]);
2399 });
2400 }
2401 else {
2402 skipAssert(assert, 6);
2403 }
2404 });
2405 }());
2406
2407 /*--------------------------------------------------------------------------*/
2408
2409 QUnit.module('lodash.chunk');
2410
2411 (function() {
2412 var array = [0, 1, 2, 3, 4, 5];
2413
2414 QUnit.test('should return chunked arrays', function(assert) {
2415 assert.expect(1);
2416
2417 var actual = _.chunk(array, 3);
2418 assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
2419 });
2420
2421 QUnit.test('should return the last chunk as remaining elements', function(assert) {
2422 assert.expect(1);
2423
2424 var actual = _.chunk(array, 4);
2425 assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
2426 });
2427
2428 QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
2429 assert.expect(1);
2430
2431 var expected = lodashStable.map(falsey, function(value) {
2432 return value === undefined ? [[0], [1], [2], [3], [4], [5]] : [];
2433 });
2434
2435 var actual = lodashStable.map(falsey, function(size, index) {
2436 return index ? _.chunk(array, size) : _.chunk(array);
2437 });
2438
2439 assert.deepEqual(actual, expected);
2440 });
2441
2442 QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
2443 assert.expect(1);
2444
2445 var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity),
2446 expected = lodashStable.map(values, alwaysEmptyArray);
2447
2448 var actual = lodashStable.map(values, function(n) {
2449 return _.chunk(array, n);
2450 });
2451
2452 assert.deepEqual(actual, expected);
2453 });
2454
2455 QUnit.test('should coerce `size` to an integer', function(assert) {
2456 assert.expect(1);
2457
2458 assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
2459 });
2460
2461 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
2462 assert.expect(1);
2463
2464 var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk);
2465 assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]);
2466 });
2467 }());
2468
2469 /*--------------------------------------------------------------------------*/
2470
2471 QUnit.module('lodash.clamp');
2472
2473 (function() {
2474 QUnit.test('should work with a `max` argument', function(assert) {
2475 assert.expect(2);
2476
2477 assert.strictEqual(_.clamp(5, 3), 3);
2478 assert.strictEqual(_.clamp(1, 3), 1);
2479 });
2480
2481 QUnit.test('should clamp negative numbers', function(assert) {
2482 assert.expect(3);
2483
2484 assert.strictEqual(_.clamp(-10, -5, 5), -5);
2485 assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
2486 assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
2487 });
2488
2489 QUnit.test('should clamp positive numbers', function(assert) {
2490 assert.expect(3);
2491
2492 assert.strictEqual(_.clamp(10, -5, 5), 5);
2493 assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
2494 assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
2495 });
2496
2497 QUnit.test('should not alter negative numbers in range', function(assert) {
2498 assert.expect(3);
2499
2500 assert.strictEqual(_.clamp(-4, -5, 5), -4);
2501 assert.strictEqual(_.clamp(-5, -5, 5), -5);
2502 assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
2503 });
2504
2505 QUnit.test('should not alter positive numbers in range', function(assert) {
2506 assert.expect(3);
2507
2508 assert.strictEqual(_.clamp(4, -5, 5), 4);
2509 assert.strictEqual(_.clamp(5, -5, 5), 5);
2510 assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
2511 });
2512
2513 QUnit.test('should not alter `0` in range', function(assert) {
2514 assert.expect(1);
2515
2516 assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
2517 });
2518
2519 QUnit.test('should clamp to `0`', function(assert) {
2520 assert.expect(1);
2521
2522 assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
2523 });
2524
2525 QUnit.test('should not alter `-0` in range', function(assert) {
2526 assert.expect(1);
2527
2528 assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
2529 });
2530
2531 QUnit.test('should clamp to `-0`', function(assert) {
2532 assert.expect(1);
2533
2534 assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
2535 });
2536
2537 QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
2538 assert.expect(1);
2539
2540 assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
2541 });
2542
2543 QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
2544 assert.expect(2);
2545
2546 assert.deepEqual(_.clamp(1, -5, NaN), 0);
2547 assert.deepEqual(_.clamp(-1, NaN, 5), 0);
2548 });
2549 }());
2550
2551 /*--------------------------------------------------------------------------*/
2552
2553 QUnit.module('clone methods');
2554
2555 (function() {
2556 function Foo() {
2557 this.a = 1;
2558 }
2559 Foo.prototype.b = 1;
2560 Foo.c = function() {};
2561
2562 if (Map) {
2563 var map = new Map;
2564 map.set('a', 1);
2565 map.set('b', 2);
2566 }
2567 if (Set) {
2568 var set = new Set;
2569 set.add(1);
2570 set.add(2);
2571 }
2572 var objects = {
2573 '`arguments` objects': arguments,
2574 'arrays': ['a', ''],
2575 'array-like-objects': { '0': 'a', '1': '', 'length': 3 },
2576 'booleans': false,
2577 'boolean objects': Object(false),
2578 'date objects': new Date,
2579 'Foo instances': new Foo,
2580 'objects': { 'a': 0, 'b': 1, 'c': 2 },
2581 'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
2582 'objects from another document': realm.object || {},
2583 'maps': map,
2584 'null values': null,
2585 'numbers': 0,
2586 'number objects': Object(0),
2587 'regexes': /a/gim,
2588 'sets': set,
2589 'strings': 'a',
2590 'string objects': Object('a'),
2591 'undefined values': undefined
2592 };
2593
2594 objects.arrays.length = 3;
2595
2596 var uncloneable = {
2597 'DOM elements': body,
2598 'functions': Foo,
2599 'generators': generator
2600 };
2601
2602 lodashStable.each(errors, function(error) {
2603 uncloneable[error.name + 's'] = error;
2604 });
2605
2606 QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
2607 assert.expect(2);
2608
2609 var array = [{ 'a': 0 }, { 'b': 1 }],
2610 actual = _.clone(array);
2611
2612 assert.deepEqual(actual, array);
2613 assert.ok(actual !== array && actual[0] === array[0]);
2614 });
2615
2616 QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
2617 assert.expect(1);
2618
2619 var object = {
2620 'foo': { 'b': { 'c': { 'd': {} } } },
2621 'bar': {}
2622 };
2623
2624 object.foo.b.c.d = object;
2625 object.bar.b = object.foo.b;
2626
2627 var actual = _.cloneDeep(object);
2628 assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
2629 });
2630
2631 QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
2632 assert.expect(2);
2633
2634 var cyclical = {};
2635 lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
2636 cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
2637 });
2638
2639 var clone = _.cloneDeep(cyclical),
2640 actual = clone['v' + LARGE_ARRAY_SIZE][0];
2641
2642 assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
2643 assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
2644 });
2645
2646 QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
2647 assert.expect(164);
2648
2649 var Stack,
2650 keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
2651
2652 var pairs = lodashStable.map(keys, function(key, index) {
2653 var lastIndex = keys.length - 1;
2654 return [key, keys[lastIndex - index]];
2655 });
2656
2657 _.cloneDeepWith({ 'a': 1 }, function() {
2658 if (arguments.length > 1) {
2659 Stack || (Stack = _.last(arguments).constructor);
2660 }
2661 });
2662
2663 var stacks = [new Stack(pairs), new Stack(pairs)];
2664
2665 lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
2666 stacks[1].set({}, {});
2667 });
2668
2669 lodashStable.each(stacks, function(stack) {
2670 lodashStable.each(keys, function(key, index) {
2671 var value = pairs[index][1];
2672
2673 assert.deepEqual(stack.get(key), value);
2674 assert.strictEqual(stack.has(key), true);
2675 assert.strictEqual(stack['delete'](key), true);
2676 assert.strictEqual(stack.has(key), false);
2677 assert.strictEqual(stack.get(key), undefined);
2678 assert.strictEqual(stack['delete'](key), false);
2679 assert.strictEqual(stack.set(key, value), stack);
2680 assert.strictEqual(stack.has(key), true);
2681 });
2682
2683 assert.strictEqual(stack.clear(), undefined);
2684 assert.ok(lodashStable.every(keys, function(key) {
2685 return !stack.has(key);
2686 }));
2687 });
2688 });
2689
2690 lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
2691 var func = _[methodName],
2692 isDeep = methodName == 'cloneDeep';
2693
2694 lodashStable.forOwn(objects, function(object, key) {
2695 QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
2696 assert.expect(2);
2697
2698 var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
2699 actual = func(object);
2700
2701 assert.ok(isEqual(actual, object));
2702
2703 if (lodashStable.isObject(object)) {
2704 assert.notStrictEqual(actual, object);
2705 } else {
2706 assert.strictEqual(actual, object);
2707 }
2708 });
2709 });
2710
2711 QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
2712 assert.expect(2);
2713
2714 if (ArrayBuffer) {
2715 var actual = func(arrayBuffer);
2716 assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
2717 assert.notStrictEqual(actual, arrayBuffer);
2718 }
2719 else {
2720 skipAssert(assert, 2);
2721 }
2722 });
2723
2724 QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
2725 assert.expect(4);
2726
2727 if (Buffer) {
2728 var buffer = new Buffer([1, 2]),
2729 actual = func(buffer);
2730
2731 assert.strictEqual(actual.byteLength, buffer.byteLength);
2732 assert.strictEqual(actual.inspect(), buffer.inspect());
2733 assert.notStrictEqual(actual, buffer);
2734
2735 buffer[0] = 2;
2736 assert.strictEqual(actual[0], isDeep ? 2 : 1);
2737 }
2738 else {
2739 skipAssert(assert, 4);
2740 }
2741 });
2742
2743 QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
2744 assert.expect(2);
2745
2746 var array = /c/.exec('abcde'),
2747 actual = func(array);
2748
2749 assert.strictEqual(actual.index, 2);
2750 assert.strictEqual(actual.input, 'abcde');
2751 });
2752
2753 QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
2754 assert.expect(1);
2755
2756 var regexp = /c/g;
2757 regexp.exec('abcde');
2758
2759 assert.strictEqual(func(regexp).lastIndex, 3);
2760 });
2761
2762 QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
2763 assert.expect(1);
2764
2765 var values = lodashStable.map([false, true, 1, 'a'], function(value) {
2766 var object = Object(value);
2767 object.a = 1;
2768 return object;
2769 });
2770
2771 var expected = lodashStable.map(values, alwaysTrue);
2772
2773 var actual = lodashStable.map(values, function(value) {
2774 return func(value).a === 1;
2775 });
2776
2777 assert.deepEqual(actual, expected);
2778 });
2779
2780 QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
2781 assert.expect(2);
2782
2783 var actual = func(Foo.prototype);
2784
2785 assert.notOk(actual instanceof Foo);
2786 assert.deepEqual(actual, { 'b': 1 });
2787 });
2788
2789 QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
2790 assert.expect(1);
2791
2792 assert.ok(func(new Foo) instanceof Foo);
2793 });
2794
2795 QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
2796 assert.expect(1);
2797
2798 Foo.prototype.constructor = Object;
2799 assert.ok(func(new Foo) instanceof Foo);
2800 Foo.prototype.constructor = Foo;
2801 });
2802
2803 QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
2804 assert.expect(1);
2805
2806 Foo.prototype.constructor = null;
2807 assert.notOk(func(new Foo) instanceof Foo);
2808 Foo.prototype.constructor = Foo;
2809 });
2810
2811 QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
2812 assert.expect(2);
2813
2814 var object = {
2815 'constructor': objectProto.constructor,
2816 'hasOwnProperty': objectProto.hasOwnProperty,
2817 'isPrototypeOf': objectProto.isPrototypeOf,
2818 'propertyIsEnumerable': objectProto.propertyIsEnumerable,
2819 'toLocaleString': objectProto.toLocaleString,
2820 'toString': objectProto.toString,
2821 'valueOf': objectProto.valueOf
2822 };
2823
2824 var actual = func(object);
2825
2826 assert.deepEqual(actual, object);
2827 assert.notStrictEqual(actual, object);
2828 });
2829
2830 QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
2831 assert.expect(3);
2832
2833 function Foo() {
2834 this[symbol] = { 'c': 1 };
2835 }
2836
2837 if (Symbol) {
2838 var symbol2 = Symbol('b');
2839 Foo.prototype[symbol2] = 2;
2840
2841 var object = { 'a': { 'b': new Foo } };
2842 object[symbol] = { 'b': 1 };
2843
2844 var actual = func(object);
2845
2846 assert.deepEqual(getSymbols(actual.a.b), [symbol]);
2847
2848 if (isDeep) {
2849 assert.deepEqual(actual[symbol], object[symbol]);
2850 assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]);
2851 }
2852 else {
2853 assert.strictEqual(actual[symbol], object[symbol]);
2854 assert.strictEqual(actual.a, object.a);
2855 }
2856 }
2857 else {
2858 skipAssert(assert, 3);
2859 }
2860 });
2861
2862 QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
2863 assert.expect(4);
2864
2865 if (Symbol) {
2866 assert.strictEqual(func(symbol), symbol);
2867
2868 var object = Object(symbol),
2869 actual = func(object);
2870
2871 assert.strictEqual(typeof actual, 'object');
2872 assert.strictEqual(typeof actual.valueOf(), 'symbol');
2873 assert.notStrictEqual(actual, object);
2874 }
2875 else {
2876 skipAssert(assert, 4);
2877 }
2878 });
2879
2880 QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
2881 assert.expect(1);
2882
2883 if (Symbol) {
2884 assert.strictEqual(func(symbol), symbol);
2885 }
2886 else {
2887 skipAssert(assert);
2888 }
2889 });
2890
2891 QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
2892 assert.expect(1);
2893
2894 if (document) {
2895 var element = document.createElement('div');
2896
2897 try {
2898 assert.deepEqual(func(element), {});
2899 } catch (e) {
2900 assert.ok(false, e.message);
2901 }
2902 }
2903 else {
2904 skipAssert(assert);
2905 }
2906 });
2907
2908 QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
2909 assert.expect(1);
2910
2911 var props = [];
2912
2913 var objects = lodashStable.transform(_, function(result, value, key) {
2914 if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
2915 !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
2916 !lodashStable.isFunction(value)) {
2917 props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
2918 result.push(value);
2919 }
2920 }, []);
2921
2922 var expected = lodashStable.map(objects, alwaysTrue);
2923
2924 var actual = lodashStable.map(objects, function(object) {
2925 var Ctor = object.constructor,
2926 result = func(object);
2927
2928 return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
2929 });
2930
2931 assert.deepEqual(actual, expected, props.join(', '));
2932 });
2933
2934 QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
2935 assert.expect(2);
2936
2937 var expected = [{ 'a': [0] }, { 'b': [1] }],
2938 actual = lodashStable.map(expected, func);
2939
2940 assert.deepEqual(actual, expected);
2941
2942 if (isDeep) {
2943 assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
2944 } else {
2945 assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
2946 }
2947 });
2948
2949 QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
2950 assert.expect(2);
2951
2952 if (!isNpm) {
2953 var object = objects.objects,
2954 actual = _(object)[methodName]();
2955
2956 assert.deepEqual(actual, object);
2957 assert.notStrictEqual(actual, object);
2958 }
2959 else {
2960 skipAssert(assert, 2);
2961 }
2962 });
2963
2964 lodashStable.each(arrayViews, function(type) {
2965 QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) {
2966 assert.expect(10);
2967
2968 var Ctor = root[type];
2969
2970 lodashStable.times(2, function(index) {
2971 if (Ctor) {
2972 var buffer = new ArrayBuffer(24),
2973 view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
2974 actual = func(view);
2975
2976 assert.deepEqual(actual, view);
2977 assert.notStrictEqual(actual, view);
2978 assert.strictEqual(actual.buffer === view.buffer, !isDeep);
2979 assert.strictEqual(actual.byteOffset, view.byteOffset);
2980 assert.strictEqual(actual.length, view.length);
2981 }
2982 else {
2983 skipAssert(assert, 5);
2984 }
2985 });
2986 });
2987 });
2988
2989 lodashStable.forOwn(uncloneable, function(value, key) {
2990 QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
2991 assert.expect(3);
2992
2993 if (value) {
2994 var object = { 'a': value, 'b': { 'c': value } },
2995 actual = func(object),
2996 expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
2997
2998 assert.deepEqual(actual, object);
2999 assert.notStrictEqual(actual, object);
3000 assert.deepEqual(func(value), expected);
3001 }
3002 else {
3003 skipAssert(assert, 3);
3004 }
3005 });
3006 });
3007 });
3008
3009 lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
3010 var func = _[methodName],
3011 isDeep = methodName == 'cloneDeepWith';
3012
3013 QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
3014 assert.expect(1);
3015
3016 var argsList = [],
3017 object = new Foo;
3018
3019 func(object, function() {
3020 var length = arguments.length,
3021 args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
3022
3023 argsList.push(args);
3024 });
3025
3026 assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]);
3027 });
3028
3029 QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` returns `undefined`', function(assert) {
3030 assert.expect(1);
3031
3032 var actual = func({ 'a': { 'b': 'c' } }, noop);
3033 assert.deepEqual(actual, { 'a': { 'b': 'c' } });
3034 });
3035
3036 lodashStable.forOwn(uncloneable, function(value, key) {
3037 QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
3038 assert.expect(4);
3039
3040 var customizer = function(value) {
3041 return lodashStable.isPlainObject(value) ? undefined : value;
3042 };
3043
3044 var actual = func(value, customizer);
3045
3046 assert.deepEqual(actual, value);
3047 assert.strictEqual(actual, value);
3048
3049 var object = { 'a': value, 'b': { 'c': value } };
3050 actual = func(object, customizer);
3051
3052 assert.deepEqual(actual, object);
3053 assert.notStrictEqual(actual, object);
3054 });
3055 });
3056 });
3057 }(1, 2, 3));
3058
3059 /*--------------------------------------------------------------------------*/
3060
3061 QUnit.module('lodash.compact');
3062
3063 (function() {
3064 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
3065
3066 QUnit.test('should filter falsey values', function(assert) {
3067 assert.expect(1);
3068
3069 var array = ['0', '1', '2'];
3070 assert.deepEqual(_.compact(falsey.concat(array)), array);
3071 });
3072
3073 QUnit.test('should work when in-between lazy operators', function(assert) {
3074 assert.expect(2);
3075
3076 if (!isNpm) {
3077 var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
3078 assert.deepEqual(actual, []);
3079
3080 actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
3081 assert.deepEqual(actual, [true, 1, 'a']);
3082 }
3083 else {
3084 skipAssert(assert, 2);
3085 }
3086 });
3087
3088 QUnit.test('should work in a lazy sequence', function(assert) {
3089 assert.expect(1);
3090
3091 if (!isNpm) {
3092 var actual = _(largeArray).slice(1).compact().reverse().take().value();
3093 assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
3094 }
3095 else {
3096 skipAssert(assert);
3097 }
3098 });
3099
3100 QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
3101 assert.expect(1);
3102
3103 if (!isModularize) {
3104 var iteratee = _.iteratee,
3105 pass = false;
3106
3107 _.iteratee = identity;
3108
3109 try {
3110 var actual = _(largeArray).slice(1).compact().value();
3111 pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
3112 } catch (e) {console.log(e);}
3113
3114 assert.ok(pass);
3115 _.iteratee = iteratee;
3116 }
3117 else {
3118 skipAssert(assert);
3119 }
3120 });
3121 }());
3122
3123 /*--------------------------------------------------------------------------*/
3124
3125 QUnit.module('lodash.concat');
3126
3127 (function() {
3128 QUnit.test('should shallow clone `array`', function(assert) {
3129 assert.expect(2);
3130
3131 var array = [1, 2, 3],
3132 actual = _.concat(array);
3133
3134 assert.deepEqual(actual, array);
3135 assert.notStrictEqual(actual, array);
3136 });
3137
3138 QUnit.test('should concat arrays and values', function(assert) {
3139 assert.expect(2);
3140
3141 var array = [1],
3142 actual = _.concat(array, 2, [3], [[4]]);
3143
3144 assert.deepEqual(actual, [1, 2, 3, [4]]);
3145 assert.deepEqual(array, [1]);
3146 });
3147
3148 QUnit.test('should cast non-array `array` values to arrays', function(assert) {
3149 assert.expect(2);
3150
3151 var values = [, null, undefined, false, true, 1, NaN, 'a'];
3152
3153 var expected = lodashStable.map(values, function(value, index) {
3154 return index ? [value] : [];
3155 });
3156
3157 var actual = lodashStable.map(values, function(value, index) {
3158 return index ? _.concat(value) : _.concat();
3159 });
3160
3161 assert.deepEqual(actual, expected);
3162
3163 expected = lodashStable.map(values, function(value) {
3164 return [value, 2, [3]];
3165 });
3166
3167 actual = lodashStable.map(values, function(value) {
3168 return _.concat(value, [2], [[3]]);
3169 });
3170
3171 assert.deepEqual(actual, expected);
3172 });
3173
3174 QUnit.test('should treat sparse arrays as dense', function(assert) {
3175 assert.expect(3);
3176
3177 var expected = [],
3178 actual = _.concat(Array(1), Array(1));
3179
3180 expected.push(undefined, undefined);
3181
3182 assert.ok('0'in actual);
3183 assert.ok('1' in actual);
3184 assert.deepEqual(actual, expected);
3185 });
3186
3187 QUnit.test('should return a new wrapped array', function(assert) {
3188 assert.expect(2);
3189
3190 if (!isNpm) {
3191 var array = [1],
3192 wrapped = _(array).concat([2, 3]),
3193 actual = wrapped.value();
3194
3195 assert.deepEqual(array, [1]);
3196 assert.deepEqual(actual, [1, 2, 3]);
3197 }
3198 else {
3199 skipAssert(assert, 2);
3200 }
3201 });
3202 }());
3203
3204 /*--------------------------------------------------------------------------*/
3205
3206 QUnit.module('lodash.cond');
3207
3208 (function() {
3209 QUnit.test('should create a conditional function', function(assert) {
3210 assert.expect(3);
3211
3212 var cond = _.cond([
3213 [lodashStable.matches({ 'a': 1 }), alwaysA],
3214 [lodashStable.matchesProperty('b', 1), alwaysB],
3215 [lodashStable.property('c'), alwaysC]
3216 ]);
3217
3218 assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a');
3219 assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b');
3220 assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3221 });
3222
3223 QUnit.test('should provide arguments to functions', function(assert) {
3224 assert.expect(2);
3225
3226 var args1,
3227 args2,
3228 expected = ['a', 'b', 'c'];
3229
3230 var cond = _.cond([[
3231 function() { args1 || (args1 = slice.call(arguments)); return true; },
3232 function() { args2 || (args2 = slice.call(arguments)); }
3233 ]]);
3234
3235 cond('a', 'b', 'c');
3236
3237 assert.deepEqual(args1, expected);
3238 assert.deepEqual(args2, expected);
3239 });
3240
3241 QUnit.test('should work with predicate shorthands', function(assert) {
3242 assert.expect(3);
3243
3244 var cond = _.cond([
3245 [{ 'a': 1 }, alwaysA],
3246 [['b', 1], alwaysB],
3247 ['c', alwaysC]
3248 ]);
3249
3250 assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a');
3251 assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b');
3252 assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
3253 });
3254
3255 QUnit.test('should return `undefined` when no condition is met', function(assert) {
3256 assert.expect(1);
3257
3258 var cond = _.cond([[alwaysFalse, alwaysA]]);
3259 assert.strictEqual(cond({ 'a': 1 }), undefined);
3260 });
3261
3262 QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
3263 assert.expect(2);
3264
3265 lodashStable.each([false, true], function(value) {
3266 assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError);
3267 });
3268 });
3269
3270 QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
3271 assert.expect(1);
3272
3273 var cond = _.cond([
3274 [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
3275 ]);
3276
3277 var object = { 'cond': cond, 'a': 1, 'b': 2 };
3278 assert.strictEqual(object.cond('a', 'b'), 2);
3279 });
3280 }());
3281
3282 /*--------------------------------------------------------------------------*/
3283
3284 QUnit.module('lodash.conforms');
3285
3286 (function() {
3287 var objects = [
3288 { 'a': 1, 'b': 8 },
3289 { 'a': 2, 'b': 4 },
3290 { 'a': 3, 'b': 16 }
3291 ];
3292
3293 QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
3294 assert.expect(2);
3295
3296 var conforms = _.conforms({
3297 'b': function(value) { return value > 4; }
3298 });
3299
3300 var actual = lodashStable.filter(objects, conforms);
3301 assert.deepEqual(actual, [objects[0], objects[2]]);
3302
3303 conforms = _.conforms({
3304 'b': function(value) { return value > 8; },
3305 'a': function(value) { return value > 1; }
3306 });
3307
3308 actual = lodashStable.filter(objects, conforms);
3309 assert.deepEqual(actual, [objects[2]]);
3310 });
3311
3312 QUnit.test('should not match by inherited `source` properties', function(assert) {
3313 assert.expect(1);
3314
3315 function Foo() {
3316 this.a = function(value) {
3317 return value > 1;
3318 };
3319 }
3320 Foo.prototype.b = function(value) {
3321 return value > 8;
3322 };
3323
3324 var conforms = _.conforms(new Foo),
3325 actual = lodashStable.filter(objects, conforms);
3326
3327 assert.deepEqual(actual, [objects[1], objects[2]]);
3328 });
3329
3330 QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
3331 assert.expect(2);
3332
3333 var count = 0;
3334
3335 var conforms = _.conforms({
3336 'a': function() { count++; return true; }
3337 });
3338
3339 assert.strictEqual(conforms({}), false);
3340 assert.strictEqual(count, 0);
3341 });
3342
3343 QUnit.test('should work with a function for `object`', function(assert) {
3344 assert.expect(2);
3345
3346 function Foo() {}
3347 Foo.a = 1;
3348
3349 function Bar() {}
3350 Bar.a = 2;
3351
3352 var conforms = _.conforms({
3353 'a': function(value) { return value > 1; }
3354 });
3355
3356 assert.strictEqual(conforms(Foo), false);
3357 assert.strictEqual(conforms(Bar), true);
3358 });
3359
3360 QUnit.test('should work with a function for `source`', function(assert) {
3361 assert.expect(1);
3362
3363 function Foo() {}
3364 Foo.a = function(value) { return value > 1; };
3365
3366 var objects = [{ 'a': 1 }, { 'a': 2 }],
3367 actual = lodashStable.filter(objects, _.conforms(Foo));
3368
3369 assert.deepEqual(actual, [objects[1]]);
3370 });
3371
3372 QUnit.test('should work with a non-plain `object`', function(assert) {
3373 assert.expect(1);
3374
3375 function Foo() {
3376 this.a = 1;
3377 }
3378 Foo.prototype.b = 2;
3379
3380 var conforms = _.conforms({
3381 'b': function(value) { return value > 1; }
3382 });
3383
3384 assert.strictEqual(conforms(new Foo), true);
3385 });
3386
3387 QUnit.test('should return `false` when `object` is nullish', function(assert) {
3388 assert.expect(1);
3389
3390 var values = [, null, undefined],
3391 expected = lodashStable.map(values, alwaysFalse);
3392
3393 var conforms = _.conforms({
3394 'a': function(value) { return value > 1; }
3395 });
3396
3397 var actual = lodashStable.map(values, function(value, index) {
3398 try {
3399 return index ? conforms(value) : conforms();
3400 } catch (e) {}
3401 });
3402
3403 assert.deepEqual(actual, expected);
3404 });
3405
3406 QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
3407 assert.expect(1);
3408
3409 var values = [, null, undefined],
3410 expected = lodashStable.map(values, alwaysTrue),
3411 conforms = _.conforms({});
3412
3413 var actual = lodashStable.map(values, function(value, index) {
3414 try {
3415 return index ? conforms(value) : conforms();
3416 } catch (e) {}
3417 });
3418
3419 assert.deepEqual(actual, expected);
3420 });
3421
3422 QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
3423 assert.expect(1);
3424
3425 var object = { 'a': 1 },
3426 expected = lodashStable.map(empties, alwaysTrue);
3427
3428 var actual = lodashStable.map(empties, function(value) {
3429 var conforms = _.conforms(value);
3430 return conforms(object);
3431 });
3432
3433 assert.deepEqual(actual, expected);
3434 });
3435
3436 QUnit.test('should not change behavior if `source` is modified', function(assert) {
3437 assert.expect(2);
3438
3439 var source = {
3440 'a': function(value) { return value > 1; }
3441 };
3442
3443 var object = { 'a': 2 },
3444 conforms = _.conforms(source);
3445
3446 assert.strictEqual(conforms(object), true);
3447
3448 source.a = function(value) { return value < 2; };
3449 assert.strictEqual(conforms(object), true);
3450 });
3451 }());
3452
3453 /*--------------------------------------------------------------------------*/
3454
3455 QUnit.module('lodash.constant');
3456
3457 (function() {
3458 QUnit.test('should create a function that returns `value`', function(assert) {
3459 assert.expect(1);
3460
3461 var object = { 'a': 1 },
3462 values = Array(2).concat(empties, true, 1, 'a'),
3463 constant = _.constant(object),
3464 expected = lodashStable.map(values, function() { return true; });
3465
3466 var actual = lodashStable.map(values, function(value, index) {
3467 if (index == 0) {
3468 var result = constant();
3469 } else if (index == 1) {
3470 result = constant.call({});
3471 } else {
3472 result = constant(value);
3473 }
3474 return result === object;
3475 });
3476
3477 assert.deepEqual(actual, expected);
3478 });
3479
3480 QUnit.test('should work with falsey values', function(assert) {
3481 assert.expect(1);
3482
3483 var expected = lodashStable.map(falsey, function() { return true; });
3484
3485 var actual = lodashStable.map(falsey, function(value, index) {
3486 var constant = index ? _.constant(value) : _.constant(),
3487 result = constant();
3488
3489 return (result === value) || (result !== result && value !== value);
3490 });
3491
3492 assert.deepEqual(actual, expected);
3493 });
3494
3495 QUnit.test('should return a wrapped value when chaining', function(assert) {
3496 assert.expect(1);
3497
3498 if (!isNpm) {
3499 var wrapped = _(true).constant();
3500 assert.ok(wrapped instanceof _);
3501 }
3502 else {
3503 skipAssert(assert);
3504 }
3505 });
3506 }());
3507
3508 /*--------------------------------------------------------------------------*/
3509
3510 QUnit.module('lodash.countBy');
3511
3512 (function() {
3513 var array = [6.1, 4.2, 6.3];
3514
3515 QUnit.test('should transform keys by `iteratee`', function(assert) {
3516 assert.expect(1);
3517
3518 var actual = _.countBy(array, Math.floor);
3519 assert.deepEqual(actual, { '4': 1, '6': 2 });
3520 });
3521
3522 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
3523 assert.expect(1);
3524
3525 var array = [4, 6, 6],
3526 values = [, null, undefined],
3527 expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6': 2 }));
3528
3529 var actual = lodashStable.map(values, function(value, index) {
3530 return index ? _.countBy(array, value) : _.countBy(array);
3531 });
3532
3533 assert.deepEqual(actual, expected);
3534 });
3535
3536 QUnit.test('should work with `_.property` shorthands', function(assert) {
3537 assert.expect(1);
3538
3539 var actual = _.countBy(['one', 'two', 'three'], 'length');
3540 assert.deepEqual(actual, { '3': 2, '5': 1 });
3541 });
3542
3543 QUnit.test('should only add values to own, not inherited, properties', function(assert) {
3544 assert.expect(2);
3545
3546 var actual = _.countBy(array, function(n) {
3547 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
3548 });
3549
3550 assert.deepEqual(actual.constructor, 1);
3551 assert.deepEqual(actual.hasOwnProperty, 2);
3552 });
3553
3554 QUnit.test('should work with a number for `iteratee`', function(assert) {
3555 assert.expect(2);
3556
3557 var array = [
3558 [1, 'a'],
3559 [2, 'a'],
3560 [2, 'b']
3561 ];
3562
3563 assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
3564 assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
3565 });
3566
3567 QUnit.test('should work with an object for `collection`', function(assert) {
3568 assert.expect(1);
3569
3570 var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
3571 assert.deepEqual(actual, { '4': 1, '6': 2 });
3572 });
3573
3574 QUnit.test('should work in a lazy sequence', function(assert) {
3575 assert.expect(1);
3576
3577 if (!isNpm) {
3578 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
3579 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
3580 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
3581 );
3582
3583 var actual = _(array).countBy().map(square).filter(isEven).take().value();
3584
3585 assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
3586 }
3587 else {
3588 skipAssert(assert);
3589 }
3590 });
3591 }());
3592
3593 /*--------------------------------------------------------------------------*/
3594
3595 QUnit.module('lodash.create');
3596
3597 (function() {
3598 function Shape() {
3599 this.x = 0;
3600 this.y = 0;
3601 }
3602
3603 function Circle() {
3604 Shape.call(this);
3605 }
3606
3607 QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
3608 assert.expect(3);
3609
3610 Circle.prototype = _.create(Shape.prototype);
3611 Circle.prototype.constructor = Circle;
3612
3613 var actual = new Circle;
3614
3615 assert.ok(actual instanceof Circle);
3616 assert.ok(actual instanceof Shape);
3617 assert.notStrictEqual(Circle.prototype, Shape.prototype);
3618 });
3619
3620 QUnit.test('should assign `properties` to the created object', function(assert) {
3621 assert.expect(3);
3622
3623 var expected = { 'constructor': Circle, 'radius': 0 };
3624 Circle.prototype = _.create(Shape.prototype, expected);
3625
3626 var actual = new Circle;
3627
3628 assert.ok(actual instanceof Circle);
3629 assert.ok(actual instanceof Shape);
3630 assert.deepEqual(Circle.prototype, expected);
3631 });
3632
3633 QUnit.test('should assign own properties', function(assert) {
3634 assert.expect(1);
3635
3636 function Foo() {
3637 this.a = 1;
3638 this.c = 3;
3639 }
3640 Foo.prototype.b = 2;
3641
3642 assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
3643 });
3644
3645 QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
3646 assert.expect(1);
3647
3648 function Foo() {
3649 this.a = 1;
3650 }
3651 var object = _.create(new Foo, { 'a': 1 });
3652 assert.deepEqual(lodashStable.keys(object), ['a']);
3653 });
3654
3655 QUnit.test('should accept a falsey `prototype` argument', function(assert) {
3656 assert.expect(1);
3657
3658 var expected = lodashStable.map(falsey, alwaysEmptyObject);
3659
3660 var actual = lodashStable.map(falsey, function(prototype, index) {
3661 return index ? _.create(prototype) : _.create();
3662 });
3663
3664 assert.deepEqual(actual, expected);
3665 });
3666
3667 QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
3668 assert.expect(1);
3669
3670 var expected = lodashStable.map(primitives, alwaysTrue);
3671
3672 var actual = lodashStable.map(primitives, function(value, index) {
3673 return lodashStable.isPlainObject(index ? _.create(value) : _.create());
3674 });
3675
3676 assert.deepEqual(actual, expected);
3677 });
3678
3679 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
3680 assert.expect(1);
3681
3682 var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
3683 expected = lodashStable.map(array, alwaysTrue),
3684 objects = lodashStable.map(array, _.create);
3685
3686 var actual = lodashStable.map(objects, function(object) {
3687 return object.a === 1 && !_.keys(object).length;
3688 });
3689
3690 assert.deepEqual(actual, expected);
3691 });
3692 }());
3693
3694 /*--------------------------------------------------------------------------*/
3695
3696 QUnit.module('lodash.curry');
3697
3698 (function() {
3699 function fn(a, b, c, d) {
3700 return slice.call(arguments);
3701 }
3702
3703 QUnit.test('should curry based on the number of arguments given', function(assert) {
3704 assert.expect(3);
3705
3706 var curried = _.curry(fn),
3707 expected = [1, 2, 3, 4];
3708
3709 assert.deepEqual(curried(1)(2)(3)(4), expected);
3710 assert.deepEqual(curried(1, 2)(3, 4), expected);
3711 assert.deepEqual(curried(1, 2, 3, 4), expected);
3712 });
3713
3714 QUnit.test('should allow specifying `arity`', function(assert) {
3715 assert.expect(3);
3716
3717 var curried = _.curry(fn, 3),
3718 expected = [1, 2, 3];
3719
3720 assert.deepEqual(curried(1)(2, 3), expected);
3721 assert.deepEqual(curried(1, 2)(3), expected);
3722 assert.deepEqual(curried(1, 2, 3), expected);
3723 });
3724
3725 QUnit.test('should coerce `arity` to an integer', function(assert) {
3726 assert.expect(2);
3727
3728 var values = ['0', 0.6, 'xyz'],
3729 expected = lodashStable.map(values, alwaysEmptyArray);
3730
3731 var actual = lodashStable.map(values, function(arity) {
3732 return _.curry(fn, arity)();
3733 });
3734
3735 assert.deepEqual(actual, expected);
3736 assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
3737 });
3738
3739 QUnit.test('should support placeholders', function(assert) {
3740 assert.expect(4);
3741
3742 var curried = _.curry(fn),
3743 ph = curried.placeholder;
3744
3745 assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
3746 assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
3747 assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
3748 assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
3749 });
3750
3751 QUnit.test('should persist placeholders', function(assert) {
3752 assert.expect(1);
3753
3754 var curried = _.curry(fn),
3755 ph = curried.placeholder,
3756 actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
3757
3758 assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3759 });
3760
3761 QUnit.test('should use `_.placeholder` when set', function(assert) {
3762 assert.expect(1);
3763
3764 if (!isModularize) {
3765 var curried = _.curry(fn),
3766 _ph = _.placeholder = {},
3767 ph = curried.placeholder;
3768
3769 assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
3770 delete _.placeholder;
3771 }
3772 else {
3773 skipAssert(assert);
3774 }
3775 });
3776
3777 QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3778 assert.expect(3);
3779
3780 var curried = _.curry(fn, 3);
3781 assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
3782 assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
3783 assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3784 });
3785
3786 QUnit.test('should create a function with a `length` of `0`', function(assert) {
3787 assert.expect(6);
3788
3789 lodashStable.times(2, function(index) {
3790 var curried = index ? _.curry(fn, 4) : _.curry(fn);
3791 assert.strictEqual(curried.length, 0);
3792 assert.strictEqual(curried(1).length, 0);
3793 assert.strictEqual(curried(1, 2).length, 0);
3794 });
3795 });
3796
3797 QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3798 assert.expect(2);
3799
3800 function Foo(value) {
3801 return value && object;
3802 }
3803
3804 var curried = _.curry(Foo),
3805 object = {};
3806
3807 assert.ok(new curried(false) instanceof Foo);
3808 assert.strictEqual(new curried(true), object);
3809 });
3810
3811 QUnit.test('should not set a `this` binding', function(assert) {
3812 assert.expect(9);
3813
3814 var fn = function(a, b, c) {
3815 var value = this || {};
3816 return [value[a], value[b], value[c]];
3817 };
3818
3819 var object = { 'a': 1, 'b': 2, 'c': 3 },
3820 expected = [1, 2, 3];
3821
3822 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
3823 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
3824 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3825
3826 assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
3827 assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
3828 assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
3829
3830 object.curried = _.curry(fn);
3831 assert.deepEqual(object.curried('a')('b')('c'), Array(3));
3832 assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
3833 assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3834 });
3835
3836 QUnit.test('should work with partialed methods', function(assert) {
3837 assert.expect(2);
3838
3839 var curried = _.curry(fn),
3840 expected = [1, 2, 3, 4];
3841
3842 var a = _.partial(curried, 1),
3843 b = _.bind(a, null, 2),
3844 c = _.partialRight(b, 4),
3845 d = _.partialRight(b(3), 4);
3846
3847 assert.deepEqual(c(3), expected);
3848 assert.deepEqual(d(), expected);
3849 });
3850 }());
3851
3852 /*--------------------------------------------------------------------------*/
3853
3854 QUnit.module('lodash.curryRight');
3855
3856 (function() {
3857 function fn(a, b, c, d) {
3858 return slice.call(arguments);
3859 }
3860
3861 QUnit.test('should curry based on the number of arguments given', function(assert) {
3862 assert.expect(3);
3863
3864 var curried = _.curryRight(fn),
3865 expected = [1, 2, 3, 4];
3866
3867 assert.deepEqual(curried(4)(3)(2)(1), expected);
3868 assert.deepEqual(curried(3, 4)(1, 2), expected);
3869 assert.deepEqual(curried(1, 2, 3, 4), expected);
3870 });
3871
3872 QUnit.test('should allow specifying `arity`', function(assert) {
3873 assert.expect(3);
3874
3875 var curried = _.curryRight(fn, 3),
3876 expected = [1, 2, 3];
3877
3878 assert.deepEqual(curried(3)(1, 2), expected);
3879 assert.deepEqual(curried(2, 3)(1), expected);
3880 assert.deepEqual(curried(1, 2, 3), expected);
3881 });
3882
3883 QUnit.test('should coerce `arity` to an integer', function(assert) {
3884 assert.expect(2);
3885
3886 var values = ['0', 0.6, 'xyz'],
3887 expected = lodashStable.map(values, alwaysEmptyArray);
3888
3889 var actual = lodashStable.map(values, function(arity) {
3890 return _.curryRight(fn, arity)();
3891 });
3892
3893 assert.deepEqual(actual, expected);
3894 assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
3895 });
3896
3897 QUnit.test('should support placeholders', function(assert) {
3898 assert.expect(4);
3899
3900 var curried = _.curryRight(fn),
3901 expected = [1, 2, 3, 4],
3902 ph = curried.placeholder;
3903
3904 assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
3905 assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
3906 assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
3907 assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
3908 });
3909
3910 QUnit.test('should persist placeholders', function(assert) {
3911 assert.expect(1);
3912
3913 var curried = _.curryRight(fn),
3914 ph = curried.placeholder,
3915 actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
3916
3917 assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
3918 });
3919
3920 QUnit.test('should use `_.placeholder` when set', function(assert) {
3921 assert.expect(1);
3922
3923 if (!isModularize) {
3924 var curried = _.curryRight(fn),
3925 _ph = _.placeholder = {},
3926 ph = curried.placeholder;
3927
3928 assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
3929 delete _.placeholder;
3930 }
3931 else {
3932 skipAssert(assert);
3933 }
3934 });
3935
3936 QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
3937 assert.expect(3);
3938
3939 var curried = _.curryRight(fn, 3);
3940 assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
3941 assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
3942 assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
3943 });
3944
3945 QUnit.test('should create a function with a `length` of `0`', function(assert) {
3946 assert.expect(6);
3947
3948 lodashStable.times(2, function(index) {
3949 var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
3950 assert.strictEqual(curried.length, 0);
3951 assert.strictEqual(curried(4).length, 0);
3952 assert.strictEqual(curried(3, 4).length, 0);
3953 });
3954 });
3955
3956 QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
3957 assert.expect(2);
3958
3959 function Foo(value) {
3960 return value && object;
3961 }
3962
3963 var curried = _.curryRight(Foo),
3964 object = {};
3965
3966 assert.ok(new curried(false) instanceof Foo);
3967 assert.strictEqual(new curried(true), object);
3968 });
3969
3970 QUnit.test('should not set a `this` binding', function(assert) {
3971 assert.expect(9);
3972
3973 var fn = function(a, b, c) {
3974 var value = this || {};
3975 return [value[a], value[b], value[c]];
3976 };
3977
3978 var object = { 'a': 1, 'b': 2, 'c': 3 },
3979 expected = [1, 2, 3];
3980
3981 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
3982 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
3983 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
3984
3985 assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
3986 assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
3987 assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
3988
3989 object.curried = _.curryRight(fn);
3990 assert.deepEqual(object.curried('c')('b')('a'), Array(3));
3991 assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
3992 assert.deepEqual(object.curried('a', 'b', 'c'), expected);
3993 });
3994
3995 QUnit.test('should work with partialed methods', function(assert) {
3996 assert.expect(2);
3997
3998 var curried = _.curryRight(fn),
3999 expected = [1, 2, 3, 4];
4000
4001 var a = _.partialRight(curried, 4),
4002 b = _.partialRight(a, 3),
4003 c = _.bind(b, null, 1),
4004 d = _.partial(b(2), 1);
4005
4006 assert.deepEqual(c(2), expected);
4007 assert.deepEqual(d(), expected);
4008 });
4009 }());
4010
4011 /*--------------------------------------------------------------------------*/
4012
4013 QUnit.module('curry methods');
4014
4015 lodashStable.each(['curry', 'curryRight'], function(methodName) {
4016 var func = _[methodName],
4017 fn = function(a, b) { return slice.call(arguments); },
4018 isCurry = methodName == 'curry';
4019
4020 QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
4021 assert.expect(1);
4022
4023 function run(a, b) {
4024 return a + b;
4025 }
4026
4027 var curried = func(run);
4028
4029 try {
4030 var actual = curried(1)(2);
4031 } catch (e) {}
4032
4033 assert.strictEqual(actual, 3);
4034 });
4035
4036 QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
4037 assert.expect(1);
4038
4039 var curried = _.curry(function hasOwnProperty(a, b, c) {
4040 return [a, b, c];
4041 });
4042
4043 var expected = [1, 2, 3];
4044
4045 assert.deepEqual(curried(1)(2)(3), expected);
4046 });
4047
4048 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
4049 assert.expect(2);
4050
4051 var array = [fn, fn, fn],
4052 object = { 'a': fn, 'b': fn, 'c': fn };
4053
4054 lodashStable.each([array, object], function(collection) {
4055 var curries = lodashStable.map(collection, func),
4056 expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
4057
4058 var actual = lodashStable.map(curries, function(curried) {
4059 return curried('a')('b');
4060 });
4061
4062 assert.deepEqual(actual, expected);
4063 });
4064 });
4065 });
4066
4067 /*--------------------------------------------------------------------------*/
4068
4069 QUnit.module('lodash.debounce');
4070
4071 (function() {
4072 QUnit.test('should debounce a function', function(assert) {
4073 assert.expect(6);
4074
4075 var done = assert.async();
4076
4077 var callCount = 0;
4078
4079 var debounced = _.debounce(function(value) {
4080 ++callCount;
4081 return value;
4082 }, 32);
4083
4084 var actual = [debounced(0), debounced(1), debounced(2)];
4085 assert.deepEqual(actual, [undefined, undefined, undefined]);
4086 assert.strictEqual(callCount, 0);
4087
4088 setTimeout(function() {
4089 assert.strictEqual(callCount, 1);
4090
4091 var actual = [debounced(3), debounced(4), debounced(5)];
4092 assert.deepEqual(actual, [2, 2, 2]);
4093 assert.strictEqual(callCount, 1);
4094 }, 128);
4095
4096 setTimeout(function() {
4097 assert.strictEqual(callCount, 2);
4098 done();
4099 }, 256);
4100 });
4101
4102 QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
4103 assert.expect(2);
4104
4105 var done = assert.async();
4106
4107 var debounced = _.debounce(identity, 32);
4108 debounced('x');
4109
4110 setTimeout(function() {
4111 assert.notEqual(debounced('y'), 'y');
4112 }, 64);
4113
4114 setTimeout(function() {
4115 assert.notEqual(debounced('z'), 'z');
4116 done();
4117 }, 128);
4118 });
4119
4120 QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) {
4121 assert.expect(2);
4122
4123 var done = assert.async();
4124
4125 var callCount = 0,
4126 debounced = _.debounce(function() { ++callCount; }, 0);
4127
4128 debounced();
4129 debounced();
4130 assert.strictEqual(callCount, 0);
4131
4132 setTimeout(function() {
4133 assert.strictEqual(callCount, 1);
4134 done();
4135 }, 5);
4136 });
4137
4138 QUnit.test('should apply default options', function(assert) {
4139 assert.expect(2);
4140
4141 var done = assert.async();
4142
4143 var callCount = 0,
4144 debounced = _.debounce(function() { callCount++; }, 32, {});
4145
4146 debounced();
4147 assert.strictEqual(callCount, 0);
4148
4149 setTimeout(function() {
4150 assert.strictEqual(callCount, 1);
4151 done();
4152 }, 64);
4153 });
4154
4155 QUnit.test('should support a `leading` option', function(assert) {
4156 assert.expect(4);
4157
4158 var done = assert.async();
4159
4160 var callCounts = [0, 0];
4161
4162 var withLeading = _.debounce(function() {
4163 callCounts[0]++;
4164 }, 32, { 'leading': true });
4165
4166 var withLeadingAndTrailing = _.debounce(function() {
4167 callCounts[1]++;
4168 }, 32, { 'leading': true });
4169
4170 withLeading();
4171 assert.strictEqual(callCounts[0], 1);
4172
4173 withLeadingAndTrailing();
4174 withLeadingAndTrailing();
4175 assert.strictEqual(callCounts[1], 1);
4176
4177 setTimeout(function() {
4178 assert.deepEqual(callCounts, [1, 2]);
4179
4180 withLeading();
4181 assert.strictEqual(callCounts[0], 2);
4182
4183 done();
4184 }, 64);
4185 });
4186
4187 QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) {
4188 assert.expect(2);
4189
4190 var done = assert.async();
4191
4192 var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
4193 result = [debounced('x'), debounced('y')];
4194
4195 assert.deepEqual(result, ['x', 'x']);
4196
4197 setTimeout(function() {
4198 var result = [debounced('a'), debounced('b')];
4199 assert.deepEqual(result, ['a', 'a']);
4200 done();
4201 }, 64);
4202 });
4203
4204 QUnit.test('should support a `trailing` option', function(assert) {
4205 assert.expect(4);
4206
4207 var done = assert.async();
4208
4209 var withCount = 0,
4210 withoutCount = 0;
4211
4212 var withTrailing = _.debounce(function() {
4213 withCount++;
4214 }, 32, { 'trailing': true });
4215
4216 var withoutTrailing = _.debounce(function() {
4217 withoutCount++;
4218 }, 32, { 'trailing': false });
4219
4220 withTrailing();
4221 assert.strictEqual(withCount, 0);
4222
4223 withoutTrailing();
4224 assert.strictEqual(withoutCount, 0);
4225
4226 setTimeout(function() {
4227 assert.strictEqual(withCount, 1);
4228 assert.strictEqual(withoutCount, 0);
4229 done();
4230 }, 64);
4231 });
4232
4233 QUnit.test('should support a `maxWait` option', function(assert) {
4234 assert.expect(4);
4235
4236 var done = assert.async();
4237
4238 var callCount = 0;
4239
4240 var debounced = _.debounce(function(value) {
4241 ++callCount;
4242 return value;
4243 }, 32, { 'maxWait': 64 });
4244
4245 debounced();
4246 debounced();
4247 assert.strictEqual(callCount, 0);
4248
4249 setTimeout(function() {
4250 assert.strictEqual(callCount, 1);
4251 debounced();
4252 debounced();
4253 assert.strictEqual(callCount, 1);
4254 }, 128);
4255
4256 setTimeout(function() {
4257 assert.strictEqual(callCount, 2);
4258 done();
4259 }, 256);
4260 });
4261
4262 QUnit.test('should support `maxWait` in a tight loop', function(assert) {
4263 assert.expect(1);
4264
4265 var done = assert.async();
4266
4267 var limit = (argv || isPhantom) ? 1000 : 320,
4268 withCount = 0,
4269 withoutCount = 0;
4270
4271 var withMaxWait = _.debounce(function() {
4272 withCount++;
4273 }, 64, { 'maxWait': 128 });
4274
4275 var withoutMaxWait = _.debounce(function() {
4276 withoutCount++;
4277 }, 96);
4278
4279 var start = +new Date;
4280 while ((new Date - start) < limit) {
4281 withMaxWait();
4282 withoutMaxWait();
4283 }
4284 var actual = [Boolean(withoutCount), Boolean(withCount)];
4285 setTimeout(function() {
4286 assert.deepEqual(actual, [false, true]);
4287 done();
4288 }, 1);
4289 });
4290
4291 QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) {
4292 assert.expect(1);
4293
4294 var done = assert.async();
4295
4296 var callCount = 0;
4297
4298 var debounced = _.debounce(function() {
4299 ++callCount;
4300 }, 64, { 'maxWait': 64 });
4301
4302 debounced();
4303
4304 lodashStable.times(20, function(index) {
4305 setTimeout(debounced, 54 + index);
4306 });
4307
4308 setTimeout(function() {
4309 assert.strictEqual(callCount, 2);
4310 done();
4311 }, 160);
4312 });
4313
4314 QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
4315 assert.expect(2);
4316
4317 var done = assert.async();
4318
4319 var callCount = 0;
4320
4321 var debounced = _.debounce(function() {
4322 callCount++;
4323 }, 32, { 'maxWait': 64 });
4324
4325 debounced();
4326
4327 setTimeout(function() {
4328 debounced();
4329 assert.strictEqual(callCount, 1);
4330 }, 128);
4331
4332 setTimeout(function() {
4333 assert.strictEqual(callCount, 2);
4334 done();
4335 }, 192);
4336 });
4337
4338 QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) {
4339 assert.expect(2);
4340
4341 var done = assert.async();
4342
4343 var actual,
4344 callCount = 0,
4345 object = {};
4346
4347 var debounced = _.debounce(function(value) {
4348 actual = [this];
4349 push.apply(actual, arguments);
4350 return ++callCount != 2;
4351 }, 32, { 'leading': true, 'maxWait': 64 });
4352
4353 while (true) {
4354 if (!debounced.call(object, 'a')) {
4355 break;
4356 }
4357 }
4358 setTimeout(function() {
4359 assert.strictEqual(callCount, 2);
4360 assert.deepEqual(actual, [object, 'a']);
4361 done();
4362 }, 64);
4363 });
4364 }());
4365
4366 /*--------------------------------------------------------------------------*/
4367
4368 QUnit.module('lodash.deburr');
4369
4370 (function() {
4371 QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
4372 assert.expect(1);
4373
4374 var actual = lodashStable.map(burredLetters, _.deburr);
4375 assert.deepEqual(actual, deburredLetters);
4376 });
4377
4378 QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
4379 assert.expect(1);
4380
4381 var operators = ['\xd7', '\xf7'],
4382 actual = lodashStable.map(operators, _.deburr);
4383
4384 assert.deepEqual(actual, operators);
4385 });
4386
4387 QUnit.test('should deburr combining diacritical marks', function(assert) {
4388 assert.expect(1);
4389
4390 var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
4391
4392 var actual = lodashStable.map(comboMarks, function(chr) {
4393 return _.deburr('e' + chr + 'i');
4394 });
4395
4396 assert.deepEqual(actual, expected);
4397 });
4398 }());
4399
4400 /*--------------------------------------------------------------------------*/
4401
4402 QUnit.module('lodash.defaults');
4403
4404 (function() {
4405 QUnit.test('should assign source properties if missing on `object`', function(assert) {
4406 assert.expect(1);
4407
4408 assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
4409 });
4410
4411 QUnit.test('should accept multiple sources', function(assert) {
4412 assert.expect(2);
4413
4414 var expected = { 'a': 1, 'b': 2, 'c': 3 };
4415 assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
4416 assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
4417 });
4418
4419 QUnit.test('should not overwrite `null` values', function(assert) {
4420 assert.expect(1);
4421
4422 var actual = _.defaults({ 'a': null }, { 'a': 1 });
4423 assert.strictEqual(actual.a, null);
4424 });
4425
4426 QUnit.test('should overwrite `undefined` values', function(assert) {
4427 assert.expect(1);
4428
4429 var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
4430 assert.strictEqual(actual.a, 1);
4431 });
4432
4433 QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
4434 assert.expect(2);
4435
4436 var object = {
4437 'constructor': objectProto.constructor,
4438 'hasOwnProperty': objectProto.hasOwnProperty,
4439 'isPrototypeOf': objectProto.isPrototypeOf,
4440 'propertyIsEnumerable': objectProto.propertyIsEnumerable,
4441 'toLocaleString': objectProto.toLocaleString,
4442 'toString': objectProto.toString,
4443 'valueOf': objectProto.valueOf
4444 };
4445
4446 var source = {
4447 'constructor': 1,
4448 'hasOwnProperty': 2,
4449 'isPrototypeOf': 3,
4450 'propertyIsEnumerable': 4,
4451 'toLocaleString': 5,
4452 'toString': 6,
4453 'valueOf': 7
4454 };
4455
4456 assert.deepEqual(_.defaults({}, source), source);
4457 assert.deepEqual(_.defaults({}, object, source), object);
4458 });
4459 }());
4460
4461 /*--------------------------------------------------------------------------*/
4462
4463 QUnit.module('lodash.defaultsDeep');
4464
4465 (function() {
4466 QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
4467 assert.expect(1);
4468
4469 var object = { 'a': { 'b': 2 }, 'd': 4 },
4470 source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 },
4471 expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
4472
4473 assert.deepEqual(_.defaultsDeep(object, source), expected);
4474 });
4475
4476 QUnit.test('should accept multiple sources', function(assert) {
4477 assert.expect(2);
4478
4479 var source1 = { 'a': { 'b': 3 } },
4480 source2 = { 'a': { 'c': 3 } },
4481 source3 = { 'a': { 'b': 3, 'c': 3 } },
4482 source4 = { 'a': { 'c': 4 } },
4483 expected = { 'a': { 'b': 2, 'c': 3 } };
4484
4485 assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
4486 assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
4487 });
4488
4489 QUnit.test('should not overwrite `null` values', function(assert) {
4490 assert.expect(1);
4491
4492 var object = { 'a': { 'b': null } },
4493 source = { 'a': { 'b': 2 } },
4494 actual = _.defaultsDeep(object, source);
4495
4496 assert.strictEqual(actual.a.b, null);
4497 });
4498
4499 QUnit.test('should not overwrite regexp values', function(assert) {
4500 assert.expect(1);
4501
4502 var object = { 'a': { 'b': /x/ } },
4503 source = { 'a': { 'b': /y/ } },
4504 actual = _.defaultsDeep(object, source);
4505
4506 assert.deepEqual(actual.a.b, /x/);
4507 });
4508
4509 QUnit.test('should not convert function properties to objects', function(assert) {
4510 assert.expect(2);
4511
4512 var actual = _.defaultsDeep({}, { 'a': noop });
4513 assert.strictEqual(actual.a, noop);
4514
4515 actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
4516 assert.strictEqual(actual.a.b, noop);
4517 });
4518
4519 QUnit.test('should overwrite `undefined` values', function(assert) {
4520 assert.expect(1);
4521
4522 var object = { 'a': { 'b': undefined } },
4523 source = { 'a': { 'b': 2 } },
4524 actual = _.defaultsDeep(object, source);
4525
4526 assert.strictEqual(actual.a.b, 2);
4527 });
4528
4529 QUnit.test('should merge sources containing circular references', function(assert) {
4530 assert.expect(2);
4531
4532 var object = {
4533 'foo': { 'b': { 'c': { 'd': {} } } },
4534 'bar': { 'a': 2 }
4535 };
4536
4537 var source = {
4538 'foo': { 'b': { 'c': { 'd': {} } } },
4539 'bar': {}
4540 };
4541
4542 object.foo.b.c.d = object;
4543 source.foo.b.c.d = source;
4544 source.bar.b = source.foo.b;
4545
4546 var actual = _.defaultsDeep(object, source);
4547
4548 assert.strictEqual(actual.bar.b, actual.foo.b);
4549 assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
4550 });
4551
4552 QUnit.test('should not modify sources', function(assert) {
4553 assert.expect(3);
4554
4555 var source1 = { 'a': 1, 'b': { 'c': 2 } },
4556 source2 = { 'b': { 'c': 3, 'd': 3 } },
4557 actual = _.defaultsDeep({}, source1, source2);
4558
4559 assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
4560 assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
4561 assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
4562 });
4563
4564 QUnit.test('should not attempt a merge of a string into an array', function(assert) {
4565 assert.expect(1);
4566
4567 var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
4568 assert.deepEqual(actual, { 'a': ['abc'] });
4569 });
4570 }());
4571
4572 /*--------------------------------------------------------------------------*/
4573
4574 QUnit.module('lodash.defer');
4575
4576 (function() {
4577 QUnit.test('should defer `func` execution', function(assert) {
4578 assert.expect(1);
4579
4580 var done = assert.async();
4581
4582 var pass = false;
4583 _.defer(function() { pass = true; });
4584
4585 setTimeout(function() {
4586 assert.ok(pass);
4587 done();
4588 }, 32);
4589 });
4590
4591 QUnit.test('should provide additional arguments to `func`', function(assert) {
4592 assert.expect(1);
4593
4594 var done = assert.async();
4595
4596 var args;
4597
4598 _.defer(function() {
4599 args = slice.call(arguments);
4600 }, 1, 2);
4601
4602 setTimeout(function() {
4603 assert.deepEqual(args, [1, 2]);
4604 done();
4605 }, 32);
4606 });
4607
4608 QUnit.test('should be cancelable', function(assert) {
4609 assert.expect(1);
4610
4611 var done = assert.async();
4612
4613 var pass = true;
4614
4615 var timerId = _.defer(function() {
4616 pass = false;
4617 });
4618
4619 clearTimeout(timerId);
4620
4621 setTimeout(function() {
4622 assert.ok(pass);
4623 done();
4624 }, 32);
4625 });
4626 }());
4627
4628 /*--------------------------------------------------------------------------*/
4629
4630 QUnit.module('lodash.delay');
4631
4632 (function() {
4633 QUnit.test('should delay `func` execution', function(assert) {
4634 assert.expect(2);
4635
4636 var done = assert.async();
4637
4638 var pass = false;
4639 _.delay(function() { pass = true; }, 32);
4640
4641 setTimeout(function() {
4642 assert.notOk(pass);
4643 }, 1);
4644
4645 setTimeout(function() {
4646 assert.ok(pass);
4647 done();
4648 }, 64);
4649 });
4650
4651 QUnit.test('should provide additional arguments to `func`', function(assert) {
4652 assert.expect(1);
4653
4654 var done = assert.async();
4655
4656 var args;
4657
4658 _.delay(function() {
4659 args = slice.call(arguments);
4660 }, 32, 1, 2);
4661
4662 setTimeout(function() {
4663 assert.deepEqual(args, [1, 2]);
4664 done();
4665 }, 64);
4666 });
4667
4668 QUnit.test('should use a default `wait` of `0`', function(assert) {
4669 assert.expect(2);
4670
4671 var done = assert.async();
4672
4673 var pass = false;
4674
4675 _.delay(function() {
4676 pass = true;
4677 });
4678
4679 assert.notOk(pass);
4680
4681 setTimeout(function() {
4682 assert.ok(pass);
4683 done();
4684 }, 0);
4685 });
4686
4687 QUnit.test('should be cancelable', function(assert) {
4688 assert.expect(1);
4689
4690 var done = assert.async();
4691
4692 var pass = true;
4693
4694 var timerId = _.delay(function() {
4695 pass = false;
4696 }, 32);
4697
4698 clearTimeout(timerId);
4699
4700 setTimeout(function() {
4701 assert.ok(pass);
4702 done();
4703 }, 64);
4704 });
4705 }());
4706
4707 /*--------------------------------------------------------------------------*/
4708
4709 QUnit.module('difference methods');
4710
4711 lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
4712 var args = (function() { return arguments; }(1, 2, 3)),
4713 func = _[methodName];
4714
4715 QUnit.test('`_.' + methodName + '` should return the difference of the given arrays', function(assert) {
4716 assert.expect(2);
4717
4718 var actual = func([1, 2, 3, 4, 5], [5, 2, 10]);
4719 assert.deepEqual(actual, [1, 3, 4]);
4720
4721 actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]);
4722 assert.deepEqual(actual, [1, 3]);
4723 });
4724
4725 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
4726 assert.expect(2);
4727
4728 var array = [-0, 0];
4729
4730 var actual = lodashStable.map(array, function(value) {
4731 return func(array, [value]);
4732 });
4733
4734 assert.deepEqual(actual, [[], []]);
4735
4736 actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
4737 assert.deepEqual(actual, ['0']);
4738 });
4739
4740 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
4741 assert.expect(1);
4742
4743 assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
4744 });
4745
4746 QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
4747 assert.expect(1);
4748
4749 var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
4750 array2 = lodashStable.range(LARGE_ARRAY_SIZE),
4751 a = {},
4752 b = {},
4753 c = {};
4754
4755 array1.push(a, b, c);
4756 array2.push(b, c, a);
4757
4758 assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
4759 });
4760
4761 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
4762 assert.expect(2);
4763
4764 var array = [-0, 0];
4765
4766 var actual = lodashStable.map(array, function(value) {
4767 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
4768 return func(array, largeArray);
4769 });
4770
4771 assert.deepEqual(actual, [[], []]);
4772
4773 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne);
4774 actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
4775 assert.deepEqual(actual, ['0']);
4776 });
4777
4778 QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
4779 assert.expect(1);
4780
4781 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
4782 assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
4783 });
4784
4785 QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
4786 assert.expect(1);
4787
4788 var object1 = {},
4789 object2 = {},
4790 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
4791
4792 assert.deepEqual(func([object1, object2], largeArray), [object2]);
4793 });
4794
4795 QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
4796 assert.expect(3);
4797
4798 var array = [1, null, 3];
4799
4800 assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
4801 assert.deepEqual(func(null, array, 1), []);
4802 assert.deepEqual(func(array, args, null), [null]);
4803 });
4804 });
4805
4806 /*--------------------------------------------------------------------------*/
4807
4808 QUnit.module('lodash.differenceBy');
4809
4810 (function() {
4811 QUnit.test('should accept an `iteratee` argument', function(assert) {
4812 assert.expect(2);
4813
4814 var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
4815 assert.deepEqual(actual, [3.1, 1.3]);
4816
4817 actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
4818 assert.deepEqual(actual, [{ 'x': 2 }]);
4819 });
4820
4821 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
4822 assert.expect(1);
4823
4824 var args;
4825
4826 _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() {
4827 args || (args = slice.call(arguments));
4828 });
4829
4830 assert.deepEqual(args, [4.4]);
4831 });
4832 }());
4833
4834 /*--------------------------------------------------------------------------*/
4835
4836 QUnit.module('lodash.differenceWith');
4837
4838 (function() {
4839 QUnit.test('should work with a `comparator` argument', function(assert) {
4840 assert.expect(1);
4841
4842 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
4843 actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
4844
4845 assert.deepEqual(actual, [objects[1]]);
4846 });
4847
4848 QUnit.test('should preserve the sign of `0`', function(assert) {
4849 assert.expect(1);
4850
4851 var array = [-0, 1],
4852 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne),
4853 others = [[1], largeArray],
4854 expected = lodashStable.map(others, lodashStable.constant(['-0']));
4855
4856 var actual = lodashStable.map(others, function(other) {
4857 return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
4858 });
4859
4860 assert.deepEqual(actual, expected);
4861 });
4862 }());
4863
4864 /*--------------------------------------------------------------------------*/
4865
4866 QUnit.module('lodash.divide');
4867
4868 (function() {
4869 QUnit.test('should divide two numbers', function(assert) {
4870 assert.expect(3);
4871
4872 assert.strictEqual(_.divide(6, 4), 1.5);
4873 assert.strictEqual(_.divide(-6, 4), -1.5);
4874 assert.strictEqual(_.divide(-6, -4), 1.5);
4875 });
4876
4877 QUnit.test('should coerce arguments to numbers', function(assert) {
4878 assert.expect(2);
4879
4880 assert.strictEqual(_.divide('6', '4'), 1.5);
4881 assert.deepEqual(_.divide('x', 'y'), NaN);
4882 });
4883 }());
4884
4885 /*--------------------------------------------------------------------------*/
4886
4887 QUnit.module('lodash.drop');
4888
4889 (function() {
4890 var array = [1, 2, 3];
4891
4892 QUnit.test('should drop the first two elements', function(assert) {
4893 assert.expect(1);
4894
4895 assert.deepEqual(_.drop(array, 2), [3]);
4896 });
4897
4898 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4899 assert.expect(1);
4900
4901 var expected = lodashStable.map(falsey, function(value) {
4902 return value === undefined ? [2, 3] : array;
4903 });
4904
4905 var actual = lodashStable.map(falsey, function(n) {
4906 return _.drop(array, n);
4907 });
4908
4909 assert.deepEqual(actual, expected);
4910 });
4911
4912 QUnit.test('should return all elements when `n` < `1`', function(assert) {
4913 assert.expect(3);
4914
4915 lodashStable.each([0, -1, -Infinity], function(n) {
4916 assert.deepEqual(_.drop(array, n), array);
4917 });
4918 });
4919
4920 QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
4921 assert.expect(4);
4922
4923 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
4924 assert.deepEqual(_.drop(array, n), []);
4925 });
4926 });
4927
4928 QUnit.test('should coerce `n` to an integer', function(assert) {
4929 assert.expect(1);
4930
4931 assert.deepEqual(_.drop(array, 1.6), [2, 3]);
4932 });
4933
4934 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
4935 assert.expect(1);
4936
4937 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
4938 actual = lodashStable.map(array, _.drop);
4939
4940 assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
4941 });
4942
4943 QUnit.test('should work in a lazy sequence', function(assert) {
4944 assert.expect(6);
4945
4946 if (!isNpm) {
4947 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
4948 predicate = function(value) { values.push(value); return isEven(value); },
4949 values = [],
4950 actual = _(array).drop(2).drop().value();
4951
4952 assert.deepEqual(actual, array.slice(3));
4953
4954 actual = _(array).filter(predicate).drop(2).drop().value();
4955 assert.deepEqual(values, array);
4956 assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
4957
4958 actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
4959 assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
4960
4961 values = [];
4962
4963 actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
4964 assert.deepEqual(values, array.slice(1));
4965 assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
4966 }
4967 else {
4968 skipAssert(assert, 6);
4969 }
4970 });
4971 }());
4972
4973 /*--------------------------------------------------------------------------*/
4974
4975 QUnit.module('lodash.dropRight');
4976
4977 (function() {
4978 var array = [1, 2, 3];
4979
4980 QUnit.test('should drop the last two elements', function(assert) {
4981 assert.expect(1);
4982
4983 assert.deepEqual(_.dropRight(array, 2), [1]);
4984 });
4985
4986 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
4987 assert.expect(1);
4988
4989 var expected = lodashStable.map(falsey, function(value) {
4990 return value === undefined ? [1, 2] : array;
4991 });
4992
4993 var actual = lodashStable.map(falsey, function(n) {
4994 return _.dropRight(array, n);
4995 });
4996
4997 assert.deepEqual(actual, expected);
4998 });
4999
5000 QUnit.test('should return all elements when `n` < `1`', function(assert) {
5001 assert.expect(3);
5002
5003 lodashStable.each([0, -1, -Infinity], function(n) {
5004 assert.deepEqual(_.dropRight(array, n), array);
5005 });
5006 });
5007
5008 QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
5009 assert.expect(4);
5010
5011 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
5012 assert.deepEqual(_.dropRight(array, n), []);
5013 });
5014 });
5015
5016 QUnit.test('should coerce `n` to an integer', function(assert) {
5017 assert.expect(1);
5018
5019 assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
5020 });
5021
5022 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5023 assert.expect(1);
5024
5025 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
5026 actual = lodashStable.map(array, _.dropRight);
5027
5028 assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
5029 });
5030
5031 QUnit.test('should work in a lazy sequence', function(assert) {
5032 assert.expect(6);
5033
5034 if (!isNpm) {
5035 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5036 predicate = function(value) { values.push(value); return isEven(value); },
5037 values = [],
5038 actual = _(array).dropRight(2).dropRight().value();
5039
5040 assert.deepEqual(actual, array.slice(0, -3));
5041
5042 actual = _(array).filter(predicate).dropRight(2).dropRight().value();
5043 assert.deepEqual(values, array);
5044 assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
5045
5046 actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
5047 assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
5048
5049 values = [];
5050
5051 actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
5052 assert.deepEqual(values, array.slice(0, -1));
5053 assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
5054 }
5055 else {
5056 skipAssert(assert, 6);
5057 }
5058 });
5059 }());
5060
5061 /*--------------------------------------------------------------------------*/
5062
5063 QUnit.module('lodash.dropRightWhile');
5064
5065 (function() {
5066 var array = [1, 2, 3, 4];
5067
5068 var objects = [
5069 { 'a': 0, 'b': 0 },
5070 { 'a': 1, 'b': 1 },
5071 { 'a': 2, 'b': 2 }
5072 ];
5073
5074 QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5075 assert.expect(1);
5076
5077 var actual = _.dropRightWhile(array, function(n) {
5078 return n > 2;
5079 });
5080
5081 assert.deepEqual(actual, [1, 2]);
5082 });
5083
5084 QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5085 assert.expect(1);
5086
5087 var args;
5088
5089 _.dropRightWhile(array, function() {
5090 args = slice.call(arguments);
5091 });
5092
5093 assert.deepEqual(args, [4, 3, array]);
5094 });
5095
5096 QUnit.test('should work with `_.matches` shorthands', function(assert) {
5097 assert.expect(1);
5098
5099 assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
5100 });
5101
5102 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5103 assert.expect(1);
5104
5105 assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
5106 });
5107
5108 QUnit.test('should work with `_.property` shorthands', function(assert) {
5109 assert.expect(1);
5110
5111 assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
5112 });
5113
5114 QUnit.test('should return a wrapped value when chaining', function(assert) {
5115 assert.expect(2);
5116
5117 if (!isNpm) {
5118 var wrapped = _(array).dropRightWhile(function(n) {
5119 return n > 2;
5120 });
5121
5122 assert.ok(wrapped instanceof _);
5123 assert.deepEqual(wrapped.value(), [1, 2]);
5124 }
5125 else {
5126 skipAssert(assert, 2);
5127 }
5128 });
5129 }());
5130
5131 /*--------------------------------------------------------------------------*/
5132
5133 QUnit.module('lodash.dropWhile');
5134
5135 (function() {
5136 var array = [1, 2, 3, 4];
5137
5138 var objects = [
5139 { 'a': 2, 'b': 2 },
5140 { 'a': 1, 'b': 1 },
5141 { 'a': 0, 'b': 0 }
5142 ];
5143
5144 QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
5145 assert.expect(1);
5146
5147 var actual = _.dropWhile(array, function(n) {
5148 return n < 3;
5149 });
5150
5151 assert.deepEqual(actual, [3, 4]);
5152 });
5153
5154 QUnit.test('should provide the correct `predicate` arguments', function(assert) {
5155 assert.expect(1);
5156
5157 var args;
5158
5159 _.dropWhile(array, function() {
5160 args = slice.call(arguments);
5161 });
5162
5163 assert.deepEqual(args, [1, 0, array]);
5164 });
5165
5166 QUnit.test('should work with `_.matches` shorthands', function(assert) {
5167 assert.expect(1);
5168
5169 assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
5170 });
5171
5172 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
5173 assert.expect(1);
5174
5175 assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
5176 });
5177
5178 QUnit.test('should work with `_.property` shorthands', function(assert) {
5179 assert.expect(1);
5180
5181 assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
5182 });
5183
5184 QUnit.test('should work in a lazy sequence', function(assert) {
5185 assert.expect(3);
5186
5187 if (!isNpm) {
5188 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
5189 predicate = function(n) { return n < 3; },
5190 expected = _.dropWhile(array, predicate),
5191 wrapped = _(array).dropWhile(predicate);
5192
5193 assert.deepEqual(wrapped.value(), expected);
5194 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
5195 assert.strictEqual(wrapped.last(), _.last(expected));
5196 }
5197 else {
5198 skipAssert(assert, 3);
5199 }
5200 });
5201
5202 QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
5203 assert.expect(1);
5204
5205 if (!isNpm) {
5206 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
5207
5208 var actual = _(array)
5209 .dropWhile(function(n) { return n == 1; })
5210 .drop()
5211 .dropWhile(function(n) { return n == 3; })
5212 .value();
5213
5214 assert.deepEqual(actual, array.slice(3));
5215 }
5216 else {
5217 skipAssert(assert);
5218 }
5219 });
5220 }());
5221
5222 /*--------------------------------------------------------------------------*/
5223
5224 QUnit.module('lodash.endsWith');
5225
5226 (function() {
5227 var string = 'abc';
5228
5229 QUnit.test('should return `true` if a string ends with `target`', function(assert) {
5230 assert.expect(1);
5231
5232 assert.strictEqual(_.endsWith(string, 'c'), true);
5233 });
5234
5235 QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
5236 assert.expect(1);
5237
5238 assert.strictEqual(_.endsWith(string, 'b'), false);
5239 });
5240
5241 QUnit.test('should work with a `position` argument', function(assert) {
5242 assert.expect(1);
5243
5244 assert.strictEqual(_.endsWith(string, 'b', 2), true);
5245 });
5246
5247 QUnit.test('should work with `position` >= `string.length`', function(assert) {
5248 assert.expect(4);
5249
5250 lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5251 assert.strictEqual(_.endsWith(string, 'c', position), true);
5252 });
5253 });
5254
5255 QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
5256 assert.expect(1);
5257
5258 var expected = lodashStable.map(falsey, alwaysTrue);
5259
5260 var actual = lodashStable.map(falsey, function(position) {
5261 return _.endsWith(string, position === undefined ? 'c' : '', position);
5262 });
5263
5264 assert.deepEqual(actual, expected);
5265 });
5266
5267 QUnit.test('should treat a negative `position` as `0`', function(assert) {
5268 assert.expect(6);
5269
5270 lodashStable.each([-1, -3, -Infinity], function(position) {
5271 assert.ok(lodashStable.every(string, function(chr) {
5272 return _.endsWith(string, chr, position) === false;
5273 }));
5274 assert.strictEqual(_.endsWith(string, '', position), true);
5275 });
5276 });
5277
5278 QUnit.test('should coerce `position` to an integer', function(assert) {
5279 assert.expect(1);
5280
5281 assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
5282 });
5283
5284 QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
5285 assert.expect(1);
5286
5287 assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
5288 return _.endsWith(string, '', position, true);
5289 }));
5290 });
5291 }());
5292
5293 /*--------------------------------------------------------------------------*/
5294
5295 QUnit.module('lodash.eq');
5296
5297 (function() {
5298 QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
5299 assert.expect(11);
5300
5301 assert.strictEqual(_.eq(), true);
5302 assert.strictEqual(_.eq(undefined), true);
5303 assert.strictEqual(_.eq(0, -0), true);
5304 assert.strictEqual(_.eq(NaN, NaN), true);
5305 assert.strictEqual(_.eq(1, 1), true);
5306
5307 assert.strictEqual(_.eq(null, undefined), false);
5308 assert.strictEqual(_.eq(1, Object(1)), false);
5309 assert.strictEqual(_.eq(1, '1'), false);
5310 assert.strictEqual(_.eq(1, '1'), false);
5311
5312 var object = { 'a': 1 };
5313 assert.strictEqual(_.eq(object, object), true);
5314 assert.strictEqual(_.eq(object, { 'a': 1 }), false);
5315 });
5316 }());
5317
5318 /*--------------------------------------------------------------------------*/
5319
5320 QUnit.module('lodash.escape');
5321
5322 (function() {
5323 var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
5324 unescaped = '&<>"\'`\/';
5325
5326 escaped += escaped;
5327 unescaped += unescaped;
5328
5329 QUnit.test('should escape values', function(assert) {
5330 assert.expect(1);
5331
5332 assert.strictEqual(_.escape(unescaped), escaped);
5333 });
5334
5335 QUnit.test('should not escape the "/" character', function(assert) {
5336 assert.expect(1);
5337
5338 assert.strictEqual(_.escape('/'), '/');
5339 });
5340
5341 QUnit.test('should handle strings with nothing to escape', function(assert) {
5342 assert.expect(1);
5343
5344 assert.strictEqual(_.escape('abc'), 'abc');
5345 });
5346
5347 QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
5348 assert.expect(1);
5349
5350 assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
5351 });
5352 }());
5353
5354 /*--------------------------------------------------------------------------*/
5355
5356 QUnit.module('lodash.escapeRegExp');
5357
5358 (function() {
5359 var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
5360 unescaped = '^$.*+?()[]{}|\\';
5361
5362 QUnit.test('should escape values', function(assert) {
5363 assert.expect(1);
5364
5365 assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
5366 });
5367
5368 QUnit.test('should handle strings with nothing to escape', function(assert) {
5369 assert.expect(1);
5370
5371 assert.strictEqual(_.escapeRegExp('abc'), 'abc');
5372 });
5373
5374 QUnit.test('should return an empty string for empty values', function(assert) {
5375 assert.expect(1);
5376
5377 var values = [, null, undefined, ''],
5378 expected = lodashStable.map(values, alwaysEmptyString);
5379
5380 var actual = lodashStable.map(values, function(value, index) {
5381 return index ? _.escapeRegExp(value) : _.escapeRegExp();
5382 });
5383
5384 assert.deepEqual(actual, expected);
5385 });
5386 }());
5387
5388 /*--------------------------------------------------------------------------*/
5389
5390 QUnit.module('lodash.every');
5391
5392 (function() {
5393 QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
5394 assert.expect(1);
5395
5396 assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
5397 });
5398
5399 QUnit.test('should return `true` for empty collections', function(assert) {
5400 assert.expect(1);
5401
5402 var expected = lodashStable.map(empties, alwaysTrue);
5403
5404 var actual = lodashStable.map(empties, function(value) {
5405 try {
5406 return _.every(value, identity);
5407 } catch (e) {}
5408 });
5409
5410 assert.deepEqual(actual, expected);
5411 });
5412
5413 QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
5414 assert.expect(2);
5415
5416 var count = 0;
5417
5418 assert.strictEqual(_.every([true, null, true], function(value) {
5419 count++;
5420 return value;
5421 }), false);
5422
5423 assert.strictEqual(count, 2);
5424 });
5425
5426 QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
5427 assert.expect(1);
5428
5429 assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
5430 });
5431
5432 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
5433 assert.expect(2);
5434
5435 var values = [, null, undefined],
5436 expected = lodashStable.map(values, alwaysFalse);
5437
5438 var actual = lodashStable.map(values, function(value, index) {
5439 var array = [0];
5440 return index ? _.every(array, value) : _.every(array);
5441 });
5442
5443 assert.deepEqual(actual, expected);
5444
5445 expected = lodashStable.map(values, alwaysTrue);
5446 actual = lodashStable.map(values, function(value, index) {
5447 var array = [1];
5448 return index ? _.every(array, value) : _.every(array);
5449 });
5450
5451 assert.deepEqual(actual, expected);
5452 });
5453
5454 QUnit.test('should work with `_.property` shorthands', function(assert) {
5455 assert.expect(2);
5456
5457 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
5458 assert.strictEqual(_.every(objects, 'a'), false);
5459 assert.strictEqual(_.every(objects, 'b'), true);
5460 });
5461
5462 QUnit.test('should work with `_.matches` shorthands', function(assert) {
5463 assert.expect(2);
5464
5465 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
5466 assert.strictEqual(_.every(objects, { 'a': 0 }), true);
5467 assert.strictEqual(_.every(objects, { 'b': 1 }), false);
5468 });
5469
5470 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5471 assert.expect(1);
5472
5473 var actual = lodashStable.map([[1]], _.every);
5474 assert.deepEqual(actual, [true]);
5475 });
5476 }());
5477
5478 /*--------------------------------------------------------------------------*/
5479
5480 QUnit.module('strict mode checks');
5481
5482 lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
5483 var func = _[methodName],
5484 isBindAll = methodName == 'bindAll';
5485
5486 QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
5487 assert.expect(1);
5488
5489 if (freeze) {
5490 var object = freeze({ 'a': undefined, 'b': function() {} }),
5491 pass = !isStrict;
5492
5493 try {
5494 func(object, isBindAll ? 'b' : { 'a': 1 });
5495 } catch (e) {
5496 pass = !pass;
5497 }
5498 assert.ok(pass);
5499 }
5500 else {
5501 skipAssert(assert);
5502 }
5503 });
5504 });
5505
5506 /*--------------------------------------------------------------------------*/
5507
5508 QUnit.module('lodash.fill');
5509
5510 (function() {
5511 QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
5512 assert.expect(1);
5513
5514 var array = [1, 2, 3];
5515 assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
5516 });
5517
5518 QUnit.test('should use `undefined` for `value` if not given', function(assert) {
5519 assert.expect(2);
5520
5521 var array = [1, 2, 3],
5522 actual = _.fill(array);
5523
5524 assert.deepEqual(actual, Array(3));
5525 assert.ok(lodashStable.every(actual, function(value, index) {
5526 return index in actual;
5527 }));
5528 });
5529
5530 QUnit.test('should work with a positive `start`', function(assert) {
5531 assert.expect(1);
5532
5533 var array = [1, 2, 3];
5534 assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
5535 });
5536
5537 QUnit.test('should work with a `start` >= `array.length`', function(assert) {
5538 assert.expect(4);
5539
5540 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
5541 var array = [1, 2, 3];
5542 assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
5543 });
5544 });
5545
5546 QUnit.test('should treat falsey `start` values as `0`', function(assert) {
5547 assert.expect(1);
5548
5549 var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
5550
5551 var actual = lodashStable.map(falsey, function(start) {
5552 var array = [1, 2, 3];
5553 return _.fill(array, 'a', start);
5554 });
5555
5556 assert.deepEqual(actual, expected);
5557 });
5558
5559 QUnit.test('should work with a negative `start`', function(assert) {
5560 assert.expect(1);
5561
5562 var array = [1, 2, 3];
5563 assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
5564 });
5565
5566 QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
5567 assert.expect(3);
5568
5569 lodashStable.each([-3, -4, -Infinity], function(start) {
5570 var array = [1, 2, 3];
5571 assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
5572 });
5573 });
5574
5575 QUnit.test('should work with `start` >= `end`', function(assert) {
5576 assert.expect(2);
5577
5578 lodashStable.each([2, 3], function(start) {
5579 var array = [1, 2, 3];
5580 assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
5581 });
5582 });
5583
5584 QUnit.test('should work with a positive `end`', function(assert) {
5585 assert.expect(1);
5586
5587 var array = [1, 2, 3];
5588 assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
5589 });
5590
5591 QUnit.test('should work with a `end` >= `array.length`', function(assert) {
5592 assert.expect(4);
5593
5594 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
5595 var array = [1, 2, 3];
5596 assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
5597 });
5598 });
5599
5600 QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
5601 assert.expect(1);
5602
5603 var expected = lodashStable.map(falsey, function(value) {
5604 return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
5605 });
5606
5607 var actual = lodashStable.map(falsey, function(end) {
5608 var array = [1, 2, 3];
5609 return _.fill(array, 'a', 0, end);
5610 });
5611
5612 assert.deepEqual(actual, expected);
5613 });
5614
5615 QUnit.test('should work with a negative `end`', function(assert) {
5616 assert.expect(1);
5617
5618 var array = [1, 2, 3];
5619 assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
5620 });
5621
5622 QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
5623 assert.expect(3);
5624
5625 lodashStable.each([-3, -4, -Infinity], function(end) {
5626 var array = [1, 2, 3];
5627 assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
5628 });
5629 });
5630
5631 QUnit.test('should coerce `start` and `end` to integers', function(assert) {
5632 assert.expect(1);
5633
5634 var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
5635
5636 var actual = lodashStable.map(positions, function(pos) {
5637 var array = [1, 2, 3];
5638 return _.fill.apply(_, [array, 'a'].concat(pos));
5639 });
5640
5641 assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
5642 });
5643
5644 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
5645 assert.expect(1);
5646
5647 var array = [[1, 2], [3, 4]],
5648 actual = lodashStable.map(array, _.fill);
5649
5650 assert.deepEqual(actual, [[0, 0], [1, 1]]);
5651 });
5652
5653 QUnit.test('should return a wrapped value when chaining', function(assert) {
5654 assert.expect(3);
5655
5656 if (!isNpm) {
5657 var array = [1, 2, 3],
5658 wrapped = _(array).fill('a'),
5659 actual = wrapped.value();
5660
5661 assert.ok(wrapped instanceof _);
5662 assert.deepEqual(actual, ['a', 'a', 'a']);
5663 assert.strictEqual(actual, array);
5664 }
5665 else {
5666 skipAssert(assert, 3);
5667 }
5668 });
5669 }());
5670
5671 /*--------------------------------------------------------------------------*/
5672
5673 QUnit.module('lodash.filter');
5674
5675 (function() {
5676 var array = [1, 2, 3];
5677
5678 QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
5679 assert.expect(1);
5680
5681 assert.deepEqual(_.filter(array, isEven), [2]);
5682 });
5683
5684 QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
5685 assert.expect(1);
5686
5687 // Trigger a mobile Safari 8 JIT bug.
5688 // See https://github.com/lodash/lodash/issues/799.
5689 var counter = 0,
5690 object = { '1': 'foo', '8': 'bar', '50': 'baz' };
5691
5692 lodashStable.times(1000, function(assert) {
5693 _.filter([], alwaysTrue);
5694 });
5695
5696 _.filter(object, function() {
5697 counter++;
5698 return true;
5699 });
5700
5701 assert.strictEqual(counter, 3);
5702 });
5703 }());
5704
5705 /*--------------------------------------------------------------------------*/
5706
5707 lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
5708 QUnit.module('lodash.' + methodName);
5709
5710 var func = _[methodName];
5711
5712 (function() {
5713 var objects = [
5714 { 'a': 0, 'b': 0 },
5715 { 'a': 1, 'b': 1 },
5716 { 'a': 2, 'b': 2 }
5717 ];
5718
5719 var expected = ({
5720 'find': [objects[1], undefined, objects[2], objects[1]],
5721 'findLast': [objects[2], undefined, objects[2], objects[2]],
5722 'findIndex': [1, -1, 2, 1],
5723 'findLastIndex': [2, -1, 2, 2],
5724 'findKey': ['1', undefined, '2', '1'],
5725 'findLastKey': ['2', undefined, '2', '2']
5726 })[methodName];
5727
5728 QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
5729 assert.expect(1);
5730
5731 assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
5732 });
5733
5734 QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
5735 assert.expect(1);
5736
5737 assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
5738 });
5739
5740 QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
5741 assert.expect(1);
5742
5743 assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
5744 });
5745
5746 QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
5747 assert.expect(1);
5748
5749 assert.strictEqual(func(objects, ['b', 2]), expected[2]);
5750 });
5751
5752 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5753 assert.expect(1);
5754
5755 assert.strictEqual(func(objects, 'b'), expected[3]);
5756 });
5757
5758 QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
5759 assert.expect(1);
5760
5761 var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
5762 expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
5763
5764 var actual = lodashStable.map(emptyValues, function(value) {
5765 try {
5766 return func(value, { 'a': 3 });
5767 } catch (e) {}
5768 });
5769
5770 assert.deepEqual(actual, expecting);
5771 });
5772 }());
5773
5774 (function() {
5775 var array = [1, 2, 3, 4];
5776
5777 var expected = ({
5778 'find': 1,
5779 'findLast': 4,
5780 'findIndex': 0,
5781 'findLastIndex': 3,
5782 'findKey': '0',
5783 'findLastKey': '3'
5784 })[methodName];
5785
5786 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
5787 assert.expect(1);
5788
5789 if (!isNpm) {
5790 assert.strictEqual(_(array)[methodName](), expected);
5791 }
5792 else {
5793 skipAssert(assert);
5794 }
5795 });
5796
5797 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
5798 assert.expect(1);
5799
5800 if (!isNpm) {
5801 assert.ok(_(array).chain()[methodName]() instanceof _);
5802 }
5803 else {
5804 skipAssert(assert);
5805 }
5806 });
5807
5808 QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
5809 assert.expect(1);
5810
5811 if (!isNpm) {
5812 var wrapped = _(array).chain()[methodName]();
5813 assert.strictEqual(wrapped.__wrapped__, array);
5814 }
5815 else {
5816 skipAssert(assert);
5817 }
5818 });
5819
5820 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
5821 assert.expect(2);
5822
5823 if (!isNpm) {
5824 var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5825 smallArray = array;
5826
5827 lodashStable.times(2, function(index) {
5828 var array = index ? largeArray : smallArray,
5829 wrapped = _(array).filter(isEven);
5830
5831 assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
5832 });
5833 }
5834 else {
5835 skipAssert(assert, 2);
5836 }
5837 });
5838 }());
5839
5840 (function() {
5841 var expected = ({
5842 'find': 1,
5843 'findLast': 2,
5844 'findKey': 'a',
5845 'findLastKey': 'b'
5846 })[methodName];
5847
5848 if (expected != null) {
5849 QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
5850 assert.expect(1);
5851
5852 var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
5853 return n < 3;
5854 });
5855
5856 assert.strictEqual(actual, expected);
5857 });
5858 }
5859 }());
5860 });
5861
5862 /*--------------------------------------------------------------------------*/
5863
5864 QUnit.module('lodash.find and lodash.findLast');
5865
5866 lodashStable.each(['find', 'findLast'], function(methodName) {
5867 var isFind = methodName == 'find';
5868
5869 QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
5870 assert.expect(3);
5871
5872 if (!isNpm) {
5873 var findCount = 0,
5874 mapCount = 0,
5875 array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
5876 iteratee = function(value) { mapCount++; return square(value); },
5877 predicate = function(value) { findCount++; return isEven(value); },
5878 actual = _(array).map(iteratee)[methodName](predicate);
5879
5880 assert.strictEqual(findCount, isFind ? 2 : 1);
5881 assert.strictEqual(mapCount, isFind ? 2 : 1);
5882 assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
5883 }
5884 else {
5885 skipAssert(assert, 3);
5886 }
5887 });
5888 });
5889
5890 /*--------------------------------------------------------------------------*/
5891
5892 QUnit.module('lodash.flip');
5893
5894 (function() {
5895 function fn() {
5896 return slice.call(arguments);
5897 }
5898
5899 QUnit.test('should flip arguments provided to `func`', function(assert) {
5900 assert.expect(1);
5901
5902 var flipped = _.flip(fn);
5903 assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
5904 });
5905 }());
5906
5907 /*--------------------------------------------------------------------------*/
5908
5909 QUnit.module('lodash.flatMapDepth');
5910
5911 (function() {
5912 var array = [1, [2, [3, [4]], 5]];
5913
5914 QUnit.test('should use a default `depth` of `1`', function(assert) {
5915 assert.expect(1);
5916
5917 assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
5918 });
5919
5920 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
5921 assert.expect(1);
5922
5923 var values = [, null, undefined],
5924 expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
5925
5926 var actual = lodashStable.map(values, function(value, index) {
5927 return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
5928 });
5929
5930 assert.deepEqual(actual, expected);
5931 });
5932
5933 QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
5934 assert.expect(2);
5935
5936 lodashStable.each([-1, 0], function(depth) {
5937 assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
5938 });
5939 });
5940
5941 QUnit.test('should coerce `depth` to an integer', function(assert) {
5942 assert.expect(1);
5943
5944 assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
5945 });
5946 }());
5947
5948 /*--------------------------------------------------------------------------*/
5949
5950 QUnit.module('flatMap methods');
5951
5952 lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
5953 var func = _[methodName],
5954 array = [1, 2, 3, 4];
5955
5956 function duplicate(n) {
5957 return [n, n];
5958 }
5959
5960 QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
5961 assert.expect(1);
5962
5963 var actual = func(array, duplicate),
5964 expected = lodashStable.flatten(lodashStable.map(array, duplicate));
5965
5966 assert.deepEqual(actual, expected);
5967 });
5968
5969 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
5970 assert.expect(1);
5971
5972 var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
5973 assert.deepEqual(func(objects, 'a'), array);
5974 });
5975
5976 QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
5977 assert.expect(1);
5978
5979 function Foo() {
5980 this.a = [1, 2];
5981 }
5982 Foo.prototype.b = [3, 4];
5983
5984 var actual = func(new Foo, identity);
5985 assert.deepEqual(actual, [1, 2]);
5986 });
5987
5988 QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
5989 assert.expect(2);
5990
5991 var array = [[1, 2], [3, 4]],
5992 object = { 'a': [1, 2], 'b': [3, 4] },
5993 values = [, null, undefined],
5994 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
5995
5996 lodashStable.each([array, object], function(collection) {
5997 var actual = lodashStable.map(values, function(value, index) {
5998 return index ? func(collection, value) : func(collection);
5999 });
6000
6001 assert.deepEqual(actual, expected);
6002 });
6003 });
6004
6005 QUnit.test('`_.' + methodName + '` should accept a falsey `collection` argument', function(assert) {
6006 assert.expect(1);
6007
6008 var expected = lodashStable.map(falsey, alwaysEmptyArray);
6009
6010 var actual = lodashStable.map(falsey, function(collection, index) {
6011 try {
6012 return index ? func(collection) : func();
6013 } catch (e) {}
6014 });
6015
6016 assert.deepEqual(actual, expected);
6017 });
6018
6019 QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
6020 assert.expect(1);
6021
6022 assert.deepEqual(func(1), []);
6023 });
6024
6025 QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
6026 assert.expect(1);
6027
6028 var object = { 'length': [1, 2] };
6029 assert.deepEqual(func(object, identity), [1, 2]);
6030 });
6031 });
6032
6033 /*--------------------------------------------------------------------------*/
6034
6035 QUnit.module('lodash.flattenDepth');
6036
6037 (function() {
6038 var array = [1, [2, [3, [4]], 5]];
6039
6040 QUnit.test('should use a default `depth` of `1`', function(assert) {
6041 assert.expect(1);
6042
6043 assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
6044 });
6045
6046 QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
6047 assert.expect(2);
6048
6049 lodashStable.each([-1, 0], function(depth) {
6050 assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
6051 });
6052 });
6053
6054 QUnit.test('should coerce `depth` to an integer', function(assert) {
6055 assert.expect(1);
6056
6057 assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
6058 });
6059 }());
6060
6061 /*--------------------------------------------------------------------------*/
6062
6063 QUnit.module('flatten methods');
6064
6065 (function() {
6066 var args = arguments,
6067 array = [1, [2, [3, [4]], 5]];
6068
6069 QUnit.test('should flatten `arguments` objects', function(assert) {
6070 assert.expect(3);
6071
6072 var array = [args, [args]];
6073
6074 assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
6075 assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
6076 assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
6077 });
6078
6079 QUnit.test('should treat sparse arrays as dense', function(assert) {
6080 assert.expect(6);
6081
6082 var array = [[1, 2, 3], Array(3)],
6083 expected = [1, 2, 3];
6084
6085 expected.push(undefined, undefined, undefined);
6086
6087 lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) {
6088 assert.deepEqual(actual, expected);
6089 assert.ok('4' in actual);
6090 });
6091 });
6092
6093 QUnit.test('should work with extremely large arrays', function(assert) {
6094 assert.expect(3);
6095
6096 lodashStable.times(3, function(index) {
6097 var expected = Array(5e5);
6098 try {
6099 var func = _.flatten;
6100 if (index == 1) {
6101 func = _.flattenDeep;
6102 } else if (index == 2) {
6103 func = _.flattenDepth;
6104 }
6105 assert.deepEqual(func([expected]), expected);
6106 } catch (e) {
6107 assert.ok(false, e.message);
6108 }
6109 });
6110 });
6111
6112 QUnit.test('should work with empty arrays', function(assert) {
6113 assert.expect(3);
6114
6115 var array = [[], [[]], [[], [[[]]]]];
6116
6117 assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
6118 assert.deepEqual(_.flattenDeep(array), []);
6119 assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
6120 });
6121
6122 QUnit.test('should support flattening of nested arrays', function(assert) {
6123 assert.expect(3);
6124
6125 assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
6126 assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
6127 assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
6128 });
6129
6130 QUnit.test('should return an empty array for non array-like objects', function(assert) {
6131 assert.expect(3);
6132
6133 var expected = [],
6134 nonArray = { 'a': 1 };
6135
6136 assert.deepEqual(_.flatten(nonArray), expected);
6137 assert.deepEqual(_.flattenDeep(nonArray), expected);
6138 assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
6139 });
6140
6141 QUnit.test('should return a wrapped value when chaining', function(assert) {
6142 assert.expect(6);
6143
6144 if (!isNpm) {
6145 var wrapped = _(array),
6146 actual = wrapped.flatten();
6147
6148 assert.ok(actual instanceof _);
6149 assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
6150
6151 actual = wrapped.flattenDeep();
6152
6153 assert.ok(actual instanceof _);
6154 assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
6155
6156 actual = wrapped.flattenDepth(2);
6157
6158 assert.ok(actual instanceof _);
6159 assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
6160 }
6161 else {
6162 skipAssert(assert, 6);
6163 }
6164 });
6165 }(1, 2, 3));
6166
6167 /*--------------------------------------------------------------------------*/
6168
6169 QUnit.module('flow methods');
6170
6171 lodashStable.each(['flow', 'flowRight'], function(methodName) {
6172 var func = _[methodName],
6173 isFlow = methodName == 'flow';
6174
6175 QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
6176 assert.expect(1);
6177
6178 var fixed = function(n) { return n.toFixed(1); },
6179 combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
6180
6181 assert.strictEqual(combined(1, 2), '9.0');
6182 });
6183
6184 QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
6185 assert.expect(1);
6186
6187 assert.notStrictEqual(func(noop), noop);
6188 });
6189
6190 QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
6191 assert.expect(6);
6192
6193 _.times(2, function(index) {
6194 try {
6195 var combined = index ? func([]) : func();
6196 assert.strictEqual(combined('a'), 'a');
6197 } catch (e) {
6198 assert.ok(false, e.message);
6199 }
6200 assert.strictEqual(combined.length, 0);
6201 assert.notStrictEqual(combined, identity);
6202 });
6203 });
6204
6205 QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
6206 assert.expect(1);
6207
6208 var curried = _.curry(identity);
6209
6210 var combined = isFlow
6211 ? func(_.head, curried)
6212 : func(curried, _.head);
6213
6214 assert.strictEqual(combined([1]), 1);
6215 });
6216
6217 QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
6218 assert.expect(6);
6219
6220 var filterCount,
6221 mapCount,
6222 array = lodashStable.range(LARGE_ARRAY_SIZE),
6223 iteratee = function(value) { mapCount++; return square(value); },
6224 predicate = function(value) { filterCount++; return isEven(value); };
6225
6226 lodashStable.times(2, function(index) {
6227 var filter1 = _.filter,
6228 filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
6229 filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
6230
6231 var map1 = _.map,
6232 map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
6233 map3 = (_.map = index ? map2 : map1, map2(iteratee));
6234
6235 var take1 = _.take,
6236 take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
6237 take3 = (_.take = index ? take2 : take1, take2(2));
6238
6239 var combined = isFlow
6240 ? func(map3, filter3, _.compact, take3)
6241 : func(take3, _.compact, filter3, map3);
6242
6243 filterCount = mapCount = 0;
6244 assert.deepEqual(combined(array), [4, 16]);
6245
6246 if (!isNpm && WeakMap && WeakMap.name) {
6247 assert.strictEqual(filterCount, 5, 'filterCount');
6248 assert.strictEqual(mapCount, 5, 'mapCount');
6249 }
6250 else {
6251 skipAssert(assert, 2);
6252 }
6253 _.filter = filter1;
6254 _.map = map1;
6255 _.take = take1;
6256 });
6257 });
6258
6259 QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
6260 assert.expect(1);
6261
6262 var curried = _.curry(_.ary(_.map, 2), 2),
6263 getProp = curried(curried.placeholder, 'a'),
6264 objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
6265
6266 var combined = isFlow
6267 ? func(getProp, _.uniq)
6268 : func(_.uniq, getProp);
6269
6270 assert.deepEqual(combined(objects), [1, 2]);
6271 });
6272
6273 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
6274 assert.expect(1);
6275
6276 if (!isNpm) {
6277 var wrapped = _(noop)[methodName]();
6278 assert.ok(wrapped instanceof _);
6279 }
6280 else {
6281 skipAssert(assert);
6282 }
6283 });
6284 });
6285
6286 /*--------------------------------------------------------------------------*/
6287
6288 QUnit.module('lodash.forEach');
6289
6290 (function() {
6291 QUnit.test('should be aliased', function(assert) {
6292 assert.expect(1);
6293
6294 assert.strictEqual(_.each, _.forEach);
6295 });
6296 }());
6297
6298 /*--------------------------------------------------------------------------*/
6299
6300 QUnit.module('lodash.forEachRight');
6301
6302 (function() {
6303 QUnit.test('should be aliased', function(assert) {
6304 assert.expect(1);
6305
6306 assert.strictEqual(_.eachRight, _.forEachRight);
6307 });
6308 }());
6309
6310 /*--------------------------------------------------------------------------*/
6311
6312 QUnit.module('forIn methods');
6313
6314 lodashStable.each(['forIn', 'forInRight'], function(methodName) {
6315 var func = _[methodName];
6316
6317 QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
6318 assert.expect(1);
6319
6320 function Foo() {
6321 this.a = 1;
6322 }
6323 Foo.prototype.b = 2;
6324
6325 var keys = [];
6326 func(new Foo, function(value, key) { keys.push(key); });
6327 assert.deepEqual(keys.sort(), ['a', 'b']);
6328 });
6329 });
6330
6331 /*--------------------------------------------------------------------------*/
6332
6333 QUnit.module('forOwn methods');
6334
6335 lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
6336 var func = _[methodName];
6337
6338 QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
6339 assert.expect(1);
6340
6341 var object = { '0': 'zero', '1': 'one', 'length': 2 },
6342 props = [];
6343
6344 func(object, function(value, prop) { props.push(prop); });
6345 assert.deepEqual(props.sort(), ['0', '1', 'length']);
6346 });
6347 });
6348
6349 /*--------------------------------------------------------------------------*/
6350
6351 QUnit.module('iteration methods');
6352
6353 (function() {
6354 var methods = [
6355 '_baseEach',
6356 'countBy',
6357 'every',
6358 'filter',
6359 'find',
6360 'findIndex',
6361 'findKey',
6362 'findLast',
6363 'findLastIndex',
6364 'findLastKey',
6365 'forEach',
6366 'forEachRight',
6367 'forIn',
6368 'forInRight',
6369 'forOwn',
6370 'forOwnRight',
6371 'groupBy',
6372 'keyBy',
6373 'map',
6374 'mapKeys',
6375 'mapValues',
6376 'maxBy',
6377 'minBy',
6378 'omitBy',
6379 'partition',
6380 'pickBy',
6381 'reject',
6382 'some'
6383 ];
6384
6385 var arrayMethods = [
6386 'findIndex',
6387 'findLastIndex',
6388 'maxBy',
6389 'minBy'
6390 ];
6391
6392 var collectionMethods = [
6393 '_baseEach',
6394 'countBy',
6395 'every',
6396 'filter',
6397 'find',
6398 'findLast',
6399 'forEach',
6400 'forEachRight',
6401 'groupBy',
6402 'keyBy',
6403 'map',
6404 'partition',
6405 'reduce',
6406 'reduceRight',
6407 'reject',
6408 'some'
6409 ];
6410
6411 var forInMethods = [
6412 'forIn',
6413 'forInRight',
6414 'omitBy',
6415 'pickBy'
6416 ];
6417
6418 var iterationMethods = [
6419 '_baseEach',
6420 'forEach',
6421 'forEachRight',
6422 'forIn',
6423 'forInRight',
6424 'forOwn',
6425 'forOwnRight'
6426 ];
6427
6428 var objectMethods = [
6429 'findKey',
6430 'findLastKey',
6431 'forIn',
6432 'forInRight',
6433 'forOwn',
6434 'forOwnRight',
6435 'mapKeys',
6436 'mapValues',
6437 'omitBy',
6438 'pickBy'
6439 ];
6440
6441 var rightMethods = [
6442 'findLast',
6443 'findLastIndex',
6444 'findLastKey',
6445 'forEachRight',
6446 'forInRight',
6447 'forOwnRight'
6448 ];
6449
6450 var unwrappedMethods = [
6451 'each',
6452 'eachRight',
6453 'every',
6454 'find',
6455 'findIndex',
6456 'findKey',
6457 'findLast',
6458 'findLastIndex',
6459 'findLastKey',
6460 'forEach',
6461 'forEachRight',
6462 'forIn',
6463 'forInRight',
6464 'forOwn',
6465 'forOwnRight',
6466 'max',
6467 'maxBy',
6468 'min',
6469 'minBy',
6470 'some'
6471 ];
6472
6473 lodashStable.each(methods, function(methodName) {
6474 var array = [1, 2, 3],
6475 func = _[methodName],
6476 isBy = /(^partition|By)$/.test(methodName),
6477 isFind = /^find/.test(methodName),
6478 isOmitPick = /^(?:omit|pick)By$/.test(methodName),
6479 isSome = methodName == 'some';
6480
6481 QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
6482 assert.expect(1);
6483
6484 if (func) {
6485 var args,
6486 expected = [1, 0, array];
6487
6488 func(array, function() {
6489 args || (args = slice.call(arguments));
6490 });
6491
6492 if (lodashStable.includes(rightMethods, methodName)) {
6493 expected[0] = 3;
6494 expected[1] = 2;
6495 }
6496 if (lodashStable.includes(objectMethods, methodName)) {
6497 expected[1] += '';
6498 }
6499 if (isBy) {
6500 expected.length = isOmitPick ? 2 : 1;
6501 }
6502 assert.deepEqual(args, expected);
6503 }
6504 else {
6505 skipAssert(assert);
6506 }
6507 });
6508
6509 QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
6510 assert.expect(1);
6511
6512 if (func) {
6513 var array = [1];
6514 array[2] = 3;
6515
6516 var expected = lodashStable.includes(objectMethods, methodName)
6517 ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
6518 : [[1, 0, array], [undefined, 1, array], [3, 2, array]];
6519
6520 if (isBy) {
6521 expected = lodashStable.map(expected, function(args) {
6522 return args.slice(0, isOmitPick ? 2 : 1);
6523 });
6524 }
6525 else if (lodashStable.includes(objectMethods, methodName)) {
6526 expected = lodashStable.map(expected, function(args) {
6527 args[1] += '';
6528 return args;
6529 });
6530 }
6531 if (lodashStable.includes(rightMethods, methodName)) {
6532 expected.reverse();
6533 }
6534 var argsList = [];
6535 func(array, function() {
6536 argsList.push(slice.call(arguments));
6537 return !(isFind || isSome);
6538 });
6539
6540 assert.deepEqual(argsList, expected);
6541 }
6542 else {
6543 skipAssert(assert);
6544 }
6545 });
6546 });
6547
6548 lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
6549 var array = [1, 2, 3],
6550 func = _[methodName],
6551 isEvery = methodName == 'every';
6552
6553 array.a = 1;
6554
6555 QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
6556 assert.expect(1);
6557
6558 if (func) {
6559 var keys = [];
6560 func(array, function(value, key) {
6561 keys.push(key);
6562 return isEvery;
6563 });
6564
6565 assert.notOk(lodashStable.includes(keys, 'a'));
6566 }
6567 else {
6568 skipAssert(assert);
6569 }
6570 });
6571 });
6572
6573 lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
6574 var array = [1, 2, 3],
6575 isBaseEach = methodName == '_baseEach';
6576
6577 QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
6578 assert.expect(1);
6579
6580 if (!(isBaseEach || isNpm)) {
6581 var wrapped = _(array)[methodName](noop);
6582 assert.ok(wrapped instanceof _);
6583 }
6584 else {
6585 skipAssert(assert);
6586 }
6587 });
6588 });
6589
6590 lodashStable.each(unwrappedMethods, function(methodName) {
6591 var array = [1, 2, 3];
6592
6593 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
6594 assert.expect(1);
6595
6596 if (!isNpm) {
6597 var actual = _(array)[methodName](noop);
6598 assert.notOk(actual instanceof _);
6599 }
6600 else {
6601 skipAssert(assert);
6602 }
6603 });
6604
6605 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
6606 assert.expect(2);
6607
6608 if (!isNpm) {
6609 var wrapped = _(array).chain(),
6610 actual = wrapped[methodName](noop);
6611
6612 assert.ok(actual instanceof _);
6613 assert.notStrictEqual(actual, wrapped);
6614 }
6615 else {
6616 skipAssert(assert, 2);
6617 }
6618 });
6619 });
6620
6621 lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
6622 var func = _[methodName];
6623
6624 QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
6625 assert.expect(1);
6626
6627 function Foo() {
6628 this.a = 1;
6629 }
6630 Foo.prototype.b = 2;
6631
6632 if (func) {
6633 var values = [];
6634 func(new Foo, function(value) { values.push(value); });
6635 assert.deepEqual(values, [1]);
6636 }
6637 else {
6638 skipAssert(assert);
6639 }
6640 });
6641 });
6642
6643 lodashStable.each(iterationMethods, function(methodName) {
6644 var array = [1, 2, 3],
6645 func = _[methodName];
6646
6647 QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
6648 assert.expect(1);
6649
6650 if (func) {
6651 assert.strictEqual(func(array, Boolean), array);
6652 }
6653 else {
6654 skipAssert(assert);
6655 }
6656 });
6657 });
6658
6659 lodashStable.each(collectionMethods, function(methodName) {
6660 var func = _[methodName];
6661
6662 QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
6663 assert.expect(3);
6664
6665 if (func) {
6666 var isIteratedAsObject = function(object) {
6667 var result = false;
6668 func(object, function() { result = true; }, 0);
6669 return result;
6670 };
6671
6672 var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
6673 expected = lodashStable.map(values, alwaysTrue);
6674
6675 var actual = lodashStable.map(values, function(length) {
6676 return isIteratedAsObject({ 'length': length });
6677 });
6678
6679 var Foo = function(a) {};
6680 Foo.a = 1;
6681
6682 assert.deepEqual(actual, expected);
6683 assert.ok(isIteratedAsObject(Foo));
6684 assert.notOk(isIteratedAsObject({ 'length': 0 }));
6685 }
6686 else {
6687 skipAssert(assert, 3);
6688 }
6689 });
6690 });
6691
6692 lodashStable.each(methods, function(methodName) {
6693 var func = _[methodName],
6694 isFind = /^find/.test(methodName),
6695 isSome = methodName == 'some',
6696 isReduce = /^reduce/.test(methodName);
6697
6698 QUnit.test('`_.' + methodName + '` should ignore changes to `array.length`', function(assert) {
6699 assert.expect(1);
6700
6701 if (func) {
6702 var count = 0,
6703 array = [1];
6704
6705 func(array, function() {
6706 if (++count == 1) {
6707 array.push(2);
6708 }
6709 return !(isFind || isSome);
6710 }, isReduce ? array : null);
6711
6712 assert.strictEqual(count, 1);
6713 }
6714 else {
6715 skipAssert(assert);
6716 }
6717 });
6718 });
6719
6720 lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
6721 var func = _[methodName],
6722 isFind = /^find/.test(methodName),
6723 isSome = methodName == 'some',
6724 isReduce = /^reduce/.test(methodName);
6725
6726 QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
6727 assert.expect(1);
6728
6729 if (func) {
6730 var count = 0,
6731 object = { 'a': 1 };
6732
6733 func(object, function() {
6734 if (++count == 1) {
6735 object.b = 2;
6736 }
6737 return !(isFind || isSome);
6738 }, isReduce ? object : null);
6739
6740 assert.strictEqual(count, 1);
6741 }
6742 else {
6743 skipAssert(assert);
6744 }
6745 });
6746 });
6747 }());
6748
6749 /*--------------------------------------------------------------------------*/
6750
6751 QUnit.module('object assignments');
6752
6753 lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
6754 var func = _[methodName],
6755 isAssign = methodName == 'assign',
6756 isDefaults = methodName == 'defaults';
6757
6758 QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
6759 assert.expect(1);
6760
6761 var expected = lodashStable.map(primitives, function(value) {
6762 var object = Object(value);
6763 object.a = 1;
6764 return object;
6765 });
6766
6767 var actual = lodashStable.map(primitives, function(value) {
6768 return func(value, { 'a': 1 });
6769 });
6770
6771 assert.deepEqual(actual, expected);
6772 });
6773
6774 QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
6775 assert.expect(1);
6776
6777 function Foo() {
6778 this.a = 1;
6779 }
6780 Foo.prototype.b = 2;
6781
6782 var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
6783 assert.deepEqual(func({}, new Foo), expected);
6784 });
6785
6786 QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
6787 assert.expect(1);
6788
6789 try {
6790 assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
6791 } catch (e) {
6792 assert.ok(false, e.message);
6793 }
6794 });
6795
6796 QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
6797 assert.expect(2);
6798
6799 var source = { 'a': 1 },
6800 values = [null, undefined],
6801 expected = lodashStable.map(values, alwaysTrue);
6802
6803 var actual = lodashStable.map(values, function(value) {
6804 var object = func(value, source);
6805 return object !== source && lodashStable.isEqual(object, source);
6806 });
6807
6808 assert.deepEqual(actual, expected);
6809
6810 actual = lodashStable.map(values, function(value) {
6811 return lodashStable.isEqual(func(value), {});
6812 });
6813
6814 assert.deepEqual(actual, expected);
6815 });
6816
6817 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
6818 assert.expect(2);
6819
6820 var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
6821 expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
6822
6823 assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
6824
6825 var fn = function() {};
6826 fn.a = array[0];
6827 fn.b = array[1];
6828 fn.c = array[2];
6829
6830 assert.deepEqual(_.reduce(fn, func, { 'a': 0 }), expected);
6831 });
6832
6833 QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
6834 assert.expect(1);
6835
6836 if (!isNpm) {
6837 var wrapped = _({ 'a': 1 }),
6838 actual = wrapped[methodName]({ 'b': 2 });
6839
6840 assert.notStrictEqual(actual, wrapped);
6841 }
6842 else {
6843 skipAssert(assert);
6844 }
6845 });
6846 });
6847
6848 lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
6849 var func = _[methodName];
6850
6851 QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
6852 assert.expect(1);
6853
6854 function Foo() {}
6855 Foo.prototype.a = 1;
6856
6857 var actual = func(new Foo, { 'b': 2 });
6858 assert.notOk(_.has(actual, 'a'));
6859 });
6860 });
6861
6862 lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
6863 var func = _[methodName];
6864
6865 QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
6866 assert.expect(4);
6867
6868 lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
6869 if (defineProperty) {
6870 var object = {},
6871 pass = true;
6872
6873 defineProperty(object, 'a', {
6874 'enumerable': true,
6875 'configurable': true,
6876 'get': lodashStable.constant(value),
6877 'set': function() { pass = false; }
6878 });
6879
6880 func(object, { 'a': value });
6881 assert.ok(pass);
6882 }
6883 else {
6884 skipAssert(assert);
6885 }
6886 });
6887 });
6888 });
6889
6890 lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
6891 var func = _[methodName],
6892 isMergeWith = methodName == 'mergeWith';
6893
6894 QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
6895 assert.expect(3);
6896
6897 var args,
6898 object = { 'a': 1 },
6899 source = { 'a': 2 },
6900 expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
6901
6902 func(object, source, function() {
6903 args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6904 });
6905
6906 assert.deepEqual(args, expected, 'primitive property values');
6907
6908 args = undefined;
6909 object = { 'a': 1 };
6910 source = { 'b': 2 };
6911 expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
6912
6913 func(object, source, function() {
6914 args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6915 });
6916
6917 assert.deepEqual(args, expected, 'missing destination property');
6918
6919 var argsList = [],
6920 objectValue = [1, 2],
6921 sourceValue = { 'b': 2 };
6922
6923 object = { 'a': objectValue };
6924 source = { 'a': sourceValue };
6925 expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
6926
6927 if (isMergeWith) {
6928 expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
6929 }
6930 func(object, source, function() {
6931 argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
6932 });
6933
6934 assert.deepEqual(argsList, expected, 'object property values');
6935 });
6936
6937 QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
6938 assert.expect(2);
6939
6940 function callback() {}
6941 callback.b = 2;
6942
6943 var actual = func({ 'a': 1 }, callback);
6944 assert.deepEqual(actual, { 'a': 1, 'b': 2 });
6945
6946 actual = func({ 'a': 1 }, callback, { 'c': 3 });
6947 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
6948 });
6949 });
6950
6951 /*--------------------------------------------------------------------------*/
6952
6953 QUnit.module('exit early');
6954
6955 lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
6956 var func = _[methodName];
6957
6958 QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
6959 assert.expect(1);
6960
6961 if (func) {
6962 var array = [1, 2, 3],
6963 values = [];
6964
6965 func(array, function(value, other) {
6966 values.push(lodashStable.isArray(value) ? other : value);
6967 return false;
6968 });
6969
6970 assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
6971 }
6972 else {
6973 skipAssert(assert);
6974 }
6975 });
6976
6977 QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
6978 assert.expect(1);
6979
6980 if (func) {
6981 var object = { 'a': 1, 'b': 2, 'c': 3 },
6982 values = [];
6983
6984 func(object, function(value, other) {
6985 values.push(lodashStable.isArray(value) ? other : value);
6986 return false;
6987 });
6988
6989 assert.strictEqual(values.length, 1);
6990 }
6991 else {
6992 skipAssert(assert);
6993 }
6994 });
6995 });
6996
6997 /*--------------------------------------------------------------------------*/
6998
6999 QUnit.module('`__proto__` property bugs');
7000
7001 (function() {
7002 QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
7003 assert.expect(4);
7004
7005 var stringLiteral = '__proto__',
7006 stringObject = Object(stringLiteral),
7007 expected = [stringLiteral, stringObject];
7008
7009 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
7010 return isEven(count) ? stringLiteral : stringObject;
7011 });
7012
7013 assert.deepEqual(_.difference(largeArray, largeArray), []);
7014 assert.deepEqual(_.intersection(largeArray, largeArray), expected);
7015 assert.deepEqual(_.uniq(largeArray), expected);
7016 assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
7017 });
7018 }());
7019
7020 /*--------------------------------------------------------------------------*/
7021
7022 QUnit.module('lodash.fromPairs');
7023
7024 (function() {
7025 QUnit.test('should accept a two dimensional array', function(assert) {
7026 assert.expect(1);
7027
7028 var array = [['a', 1], ['b', 2]],
7029 object = { 'a': 1, 'b': 2 },
7030 actual = _.fromPairs(array);
7031
7032 assert.deepEqual(actual, object);
7033 });
7034
7035 QUnit.test('should accept a falsey `array` argument', function(assert) {
7036 assert.expect(1);
7037
7038 var expected = lodashStable.map(falsey, alwaysEmptyObject);
7039
7040 var actual = lodashStable.map(falsey, function(array, index) {
7041 try {
7042 return index ? _.fromPairs(array) : _.fromPairs();
7043 } catch (e) {}
7044 });
7045
7046 assert.deepEqual(actual, expected);
7047 });
7048
7049 QUnit.test('should not support deep paths', function(assert) {
7050 assert.expect(1);
7051
7052 var actual = _.fromPairs([['a.b', 1]]);
7053 assert.deepEqual(actual, { 'a.b': 1 });
7054 });
7055
7056 QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
7057 assert.expect(1);
7058
7059 var object = { 'a.b': 1 };
7060 assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
7061 });
7062
7063 QUnit.test('should work in a lazy sequence', function(assert) {
7064 assert.expect(1);
7065
7066 if (!isNpm) {
7067 var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
7068 return ['key' + index, index];
7069 });
7070
7071 var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
7072
7073 assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
7074 }
7075 else {
7076 skipAssert(assert);
7077 }
7078 });
7079 }());
7080
7081 /*--------------------------------------------------------------------------*/
7082
7083 QUnit.module('lodash.functions');
7084
7085 (function() {
7086 QUnit.test('should return the function names of an object', function(assert) {
7087 assert.expect(1);
7088
7089 var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
7090 actual = _.functions(object).sort();
7091
7092 assert.deepEqual(actual, ['b', 'd']);
7093 });
7094
7095 QUnit.test('should not include inherited functions', function(assert) {
7096 assert.expect(1);
7097
7098 function Foo() {
7099 this.a = identity;
7100 this.b = 'b';
7101 }
7102 Foo.prototype.c = noop;
7103
7104 assert.deepEqual(_.functions(new Foo), ['a']);
7105 });
7106 }());
7107
7108 /*--------------------------------------------------------------------------*/
7109
7110 QUnit.module('lodash.groupBy');
7111
7112 (function() {
7113 var array = [6.1, 4.2, 6.3];
7114
7115 QUnit.test('should transform keys by `iteratee`', function(assert) {
7116 assert.expect(1);
7117
7118 var actual = _.groupBy(array, Math.floor);
7119 assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7120 });
7121
7122 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
7123 assert.expect(1);
7124
7125 var array = [6, 4, 6],
7126 values = [, null, undefined],
7127 expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6': [6, 6] }));
7128
7129 var actual = lodashStable.map(values, function(value, index) {
7130 return index ? _.groupBy(array, value) : _.groupBy(array);
7131 });
7132
7133 assert.deepEqual(actual, expected);
7134 });
7135
7136 QUnit.test('should work with `_.property` shorthands', function(assert) {
7137 assert.expect(1);
7138
7139 var actual = _.groupBy(['one', 'two', 'three'], 'length');
7140 assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
7141 });
7142
7143 QUnit.test('should only add values to own, not inherited, properties', function(assert) {
7144 assert.expect(2);
7145
7146 var actual = _.groupBy(array, function(n) {
7147 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
7148 });
7149
7150 assert.deepEqual(actual.constructor, [4.2]);
7151 assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
7152 });
7153
7154 QUnit.test('should work with a number for `iteratee`', function(assert) {
7155 assert.expect(2);
7156
7157 var array = [
7158 [1, 'a'],
7159 [2, 'a'],
7160 [2, 'b']
7161 ];
7162
7163 assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
7164 assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
7165 });
7166
7167 QUnit.test('should work with an object for `collection`', function(assert) {
7168 assert.expect(1);
7169
7170 var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
7171 assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
7172 });
7173
7174 QUnit.test('should work in a lazy sequence', function(assert) {
7175 assert.expect(1);
7176
7177 if (!isNpm) {
7178 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
7179 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
7180 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
7181 );
7182
7183 var iteratee = function(value) { value.push(value[0]); return value; },
7184 predicate = function(value) { return isEven(value[0]); },
7185 actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
7186
7187 assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
7188 }
7189 else {
7190 skipAssert(assert);
7191 }
7192 });
7193 }());
7194
7195 /*--------------------------------------------------------------------------*/
7196
7197 QUnit.module('lodash.gt');
7198
7199 (function() {
7200 QUnit.test('should return `true` if `value` > `other`', function(assert) {
7201 assert.expect(2);
7202
7203 assert.strictEqual(_.gt(3, 1), true);
7204 assert.strictEqual(_.gt('def', 'abc'), true);
7205 });
7206
7207 QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
7208 assert.expect(4);
7209
7210 assert.strictEqual(_.gt(1, 3), false);
7211 assert.strictEqual(_.gt(3, 3), false);
7212 assert.strictEqual(_.gt('abc', 'def'), false);
7213 assert.strictEqual(_.gt('def', 'def'), false);
7214 });
7215 }());
7216
7217 /*--------------------------------------------------------------------------*/
7218
7219 QUnit.module('lodash.gte');
7220
7221 (function() {
7222 QUnit.test('should return `true` if `value` >= `other`', function(assert) {
7223 assert.expect(4);
7224
7225 assert.strictEqual(_.gte(3, 1), true);
7226 assert.strictEqual(_.gte(3, 3), true);
7227 assert.strictEqual(_.gte('def', 'abc'), true);
7228 assert.strictEqual(_.gte('def', 'def'), true);
7229 });
7230
7231 QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
7232 assert.expect(2);
7233
7234 assert.strictEqual(_.gte(1, 3), false);
7235 assert.strictEqual(_.gte('abc', 'def'), false);
7236 });
7237 }());
7238
7239 /*--------------------------------------------------------------------------*/
7240
7241 QUnit.module('has methods');
7242
7243 lodashStable.each(['has', 'hasIn'], function(methodName) {
7244 var args = (function() { return arguments; }(1, 2, 3)),
7245 func = _[methodName],
7246 isHas = methodName == 'has';
7247
7248 QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
7249 assert.expect(2);
7250
7251 var object = { 'a': 1 };
7252
7253 lodashStable.each(['a', ['a']], function(path) {
7254 assert.strictEqual(func(object, path), true);
7255 });
7256 });
7257
7258 QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
7259 assert.expect(1);
7260
7261 var object = { 'hasOwnProperty': null, 'a': 1 };
7262 assert.strictEqual(func(object, 'a'), true);
7263 });
7264
7265 QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
7266 assert.expect(4);
7267
7268 var object = { 'a': { 'b': 2 } };
7269
7270 lodashStable.each(['a.b', ['a', 'b']], function(path) {
7271 assert.strictEqual(func(object, path), true);
7272 });
7273
7274 lodashStable.each(['a.a', ['a', 'a']], function(path) {
7275 assert.strictEqual(func(object, path), false);
7276 });
7277 });
7278
7279 QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
7280 assert.expect(1);
7281
7282 function fn() {}
7283 fn.toString = lodashStable.constant('fn');
7284
7285 var expected = [1, 1, 2, 2, 3, 3, 4, 4],
7286 objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
7287 values = [null, undefined, fn, {}];
7288
7289 var actual = lodashStable.transform(objects, function(result, object, index) {
7290 var key = values[index];
7291 lodashStable.each([key, [key]], function(path) {
7292 var prop = _.property(key);
7293 result.push(prop(object));
7294 });
7295 });
7296
7297 assert.deepEqual(actual, expected);
7298 });
7299
7300 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7301 assert.expect(1);
7302
7303 assert.strictEqual(func(args, 1), true);
7304 });
7305
7306 QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
7307 assert.expect(2);
7308
7309 var array = [1, 2, 3];
7310
7311 lodashStable.each([1, [1]], function(path) {
7312 assert.strictEqual(func(array, path), true);
7313 });
7314 });
7315
7316 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
7317 assert.expect(1);
7318
7319 var object = { '-0': 'a', '0': 'b' },
7320 props = [-0, Object(-0), 0, Object(0)],
7321 expected = lodashStable.map(props, alwaysTrue);
7322
7323 var actual = lodashStable.map(props, function(key) {
7324 return func(object, key);
7325 });
7326
7327 assert.deepEqual(actual, expected);
7328 });
7329
7330 QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
7331 assert.expect(1);
7332
7333 function Foo() {
7334 this[symbol] = 1;
7335 }
7336
7337 if (Symbol) {
7338 var symbol2 = Symbol('b');
7339 Foo.prototype[symbol2] = 2;
7340 var path = isHas ? symbol : symbol2;
7341
7342 assert.strictEqual(func(new Foo, path), true);
7343 }
7344 else {
7345 skipAssert(assert);
7346 }
7347 });
7348
7349 QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
7350 assert.expect(1);
7351
7352 if (create) {
7353 var object = create(null);
7354 object[1] = 'a';
7355 assert.strictEqual(func(object, 1), true);
7356 }
7357 else {
7358 skipAssert(assert);
7359 }
7360 });
7361
7362 QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
7363 assert.expect(2);
7364
7365 var object = { 'a.b': 1 };
7366
7367 lodashStable.each(['a.b', ['a.b']], function(path) {
7368 assert.strictEqual(func(object, path), true);
7369 });
7370 });
7371
7372 QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
7373 assert.expect(2);
7374
7375 function Foo() {}
7376 Foo.prototype.a = 1;
7377
7378 lodashStable.each(['a', ['a']], function(path) {
7379 assert.strictEqual(func(new Foo, path), !isHas);
7380 });
7381 });
7382
7383 QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
7384 assert.expect(2);
7385
7386 function Foo() {}
7387 Foo.prototype.a = { 'b': 1 };
7388
7389 lodashStable.each(['a.b', ['a', 'b']], function(path) {
7390 assert.strictEqual(func(new Foo, path), !isHas);
7391 });
7392 });
7393
7394 QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
7395 assert.expect(2);
7396
7397 var string = Object('abc');
7398 delete args[0];
7399 delete string[0];
7400
7401 var values = [Array(3), args, string],
7402 expected = lodashStable.map(values, alwaysTrue);
7403
7404 var actual = lodashStable.map(values, function(value) {
7405 return func(value, 0);
7406 });
7407
7408 assert.deepEqual(actual, expected);
7409
7410 expected = lodashStable.map(values, lodashStable.constant([true, true]));
7411
7412 actual = lodashStable.map(values, function(value) {
7413 return lodashStable.map(['a[0]', ['a', '0']], function(path) {
7414 return func({ 'a': value }, path);
7415 });
7416 });
7417
7418 assert.deepEqual(actual, expected);
7419 args[0] = 1;
7420 });
7421
7422 QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
7423 assert.expect(2);
7424
7425 var values = [null, undefined],
7426 expected = lodashStable.map(values, alwaysFalse);
7427
7428 lodashStable.each(['constructor', ['constructor']], function(path) {
7429 var actual = lodashStable.map(values, function(value) {
7430 return func(value, path);
7431 });
7432
7433 assert.deepEqual(actual, expected);
7434 });
7435 });
7436
7437 QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
7438 assert.expect(2);
7439
7440 var values = [null, undefined],
7441 expected = lodashStable.map(values, alwaysFalse);
7442
7443 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
7444 var actual = lodashStable.map(values, function(value) {
7445 return func(value, path);
7446 });
7447
7448 assert.deepEqual(actual, expected);
7449 });
7450 });
7451
7452 QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
7453 assert.expect(2);
7454
7455 var values = [, null, undefined],
7456 expected = lodashStable.map(values, alwaysFalse);
7457
7458 lodashStable.each(['a.b', ['a', 'b']], function(path) {
7459 var actual = lodashStable.map(values, function(value, index) {
7460 var object = index ? { 'a': value } : {};
7461 return func(object, path);
7462 });
7463
7464 assert.deepEqual(actual, expected);
7465 });
7466 });
7467 });
7468
7469 /*--------------------------------------------------------------------------*/
7470
7471 QUnit.module('lodash.head');
7472
7473 (function() {
7474 var array = [1, 2, 3, 4];
7475
7476 QUnit.test('should return the first element', function(assert) {
7477 assert.expect(1);
7478
7479 assert.strictEqual(_.head(array), 1);
7480 });
7481
7482 QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
7483 assert.expect(1);
7484
7485 arrayProto[0] = 1;
7486 assert.strictEqual(_.head([]), undefined);
7487 arrayProto.length = 0;
7488 });
7489
7490 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7491 assert.expect(1);
7492
7493 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7494 actual = lodashStable.map(array, _.head);
7495
7496 assert.deepEqual(actual, [1, 4, 7]);
7497 });
7498
7499 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
7500 assert.expect(1);
7501
7502 if (!isNpm) {
7503 assert.strictEqual(_(array).head(), 1);
7504 }
7505 else {
7506 skipAssert(assert);
7507 }
7508 });
7509
7510 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
7511 assert.expect(1);
7512
7513 if (!isNpm) {
7514 assert.ok(_(array).chain().head() instanceof _);
7515 }
7516 else {
7517 skipAssert(assert);
7518 }
7519 });
7520
7521 QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
7522 assert.expect(1);
7523
7524 if (!isNpm) {
7525 var wrapped = _(array).chain().head();
7526 assert.strictEqual(wrapped.__wrapped__, array);
7527 }
7528 else {
7529 skipAssert(assert);
7530 }
7531 });
7532
7533 QUnit.test('should work in a lazy sequence', function(assert) {
7534 assert.expect(2);
7535
7536 if (!isNpm) {
7537 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
7538 smallArray = array;
7539
7540 lodashStable.times(2, function(index) {
7541 var array = index ? largeArray : smallArray,
7542 wrapped = _(array).filter(isEven);
7543
7544 assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
7545 });
7546 }
7547 else {
7548 skipAssert(assert, 2);
7549 }
7550 });
7551
7552 QUnit.test('should be aliased', function(assert) {
7553 assert.expect(1);
7554
7555 assert.strictEqual(_.first, _.head);
7556 });
7557 }());
7558
7559 /*--------------------------------------------------------------------------*/
7560
7561 QUnit.module('lodash.identity');
7562
7563 (function() {
7564 QUnit.test('should return the first argument given', function(assert) {
7565 assert.expect(1);
7566
7567 var object = { 'name': 'fred' };
7568 assert.strictEqual(_.identity(object), object);
7569 });
7570 }());
7571
7572 /*--------------------------------------------------------------------------*/
7573
7574 QUnit.module('lodash.includes');
7575
7576 (function() {
7577 lodashStable.each({
7578 'an `arguments` object': arguments,
7579 'an array': [1, 2, 3, 4],
7580 'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
7581 'a string': '1234'
7582 },
7583 function(collection, key) {
7584 var isStr = typeof collection == 'string',
7585 values = _.toArray(collection),
7586 length = values.length;
7587
7588 QUnit.test('should work with ' + key + ' and return `true` for matched values', function(assert) {
7589 assert.expect(1);
7590
7591 assert.strictEqual(_.includes(collection, 3), true);
7592 });
7593
7594 QUnit.test('should work with ' + key + ' and return `false` for unmatched values', function(assert) {
7595 assert.expect(1);
7596
7597 assert.strictEqual(_.includes(collection, 5), false);
7598 });
7599
7600 QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
7601 assert.expect(2);
7602
7603 assert.strictEqual(_.includes(collection, values[2], 2), true);
7604 assert.strictEqual(_.includes(collection, values[1], 2), false);
7605 });
7606
7607 QUnit.test('should work with ' + key + ' and a `fromIndex` >= `collection.length`', function(assert) {
7608 assert.expect(12);
7609
7610 lodashStable.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) {
7611 assert.strictEqual(_.includes(collection, 1, fromIndex), false);
7612 assert.strictEqual(_.includes(collection, undefined, fromIndex), false);
7613 assert.strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length));
7614 });
7615 });
7616
7617 QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
7618 assert.expect(1);
7619
7620 var expected = lodashStable.map(falsey, alwaysTrue);
7621
7622 var actual = lodashStable.map(falsey, function(fromIndex) {
7623 return _.includes(collection, values[0], fromIndex);
7624 });
7625
7626 assert.deepEqual(actual, expected);
7627 });
7628
7629 QUnit.test('should work with ' + key + ' and coerce non-integer `fromIndex` values to integers', function(assert) {
7630 assert.expect(3);
7631
7632 assert.strictEqual(_.includes(collection, values[0], '1'), false);
7633 assert.strictEqual(_.includes(collection, values[0], 0.1), true);
7634 assert.strictEqual(_.includes(collection, values[0], NaN), true);
7635 });
7636
7637 QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
7638 assert.expect(2);
7639
7640 assert.strictEqual(_.includes(collection, values[2], -2), true);
7641 assert.strictEqual(_.includes(collection, values[1], -2), false);
7642 });
7643
7644 QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= negative `collection.length`', function(assert) {
7645 assert.expect(3);
7646
7647 lodashStable.each([-4, -6, -Infinity], function(fromIndex) {
7648 assert.strictEqual(_.includes(collection, values[0], fromIndex), true);
7649 });
7650 });
7651
7652 QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
7653 assert.expect(1);
7654
7655 assert.strictEqual(_.includes(collection, 2, 1.2), true);
7656 });
7657
7658 QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
7659 assert.expect(1);
7660
7661 if (!isNpm) {
7662 assert.strictEqual(_(collection).includes(3), true);
7663 }
7664 else {
7665 skipAssert(assert);
7666 }
7667 });
7668
7669 QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
7670 assert.expect(1);
7671
7672 if (!isNpm) {
7673 assert.ok(_(collection).chain().includes(3) instanceof _);
7674 }
7675 else {
7676 skipAssert(assert);
7677 }
7678 });
7679 });
7680
7681 lodashStable.each({
7682 'literal': 'abc',
7683 'object': Object('abc')
7684 },
7685 function(collection, key) {
7686 QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
7687 assert.expect(2);
7688
7689 assert.strictEqual(_.includes(collection, 'bc'), true);
7690 assert.strictEqual(_.includes(collection, 'd'), false);
7691 });
7692 });
7693
7694 QUnit.test('should return `false` for empty collections', function(assert) {
7695 assert.expect(1);
7696
7697 var expected = lodashStable.map(empties, alwaysFalse);
7698
7699 var actual = lodashStable.map(empties, function(value) {
7700 try {
7701 return _.includes(value);
7702 } catch (e) {}
7703 });
7704
7705 assert.deepEqual(actual, expected);
7706 });
7707
7708 QUnit.test('should match `NaN`', function(assert) {
7709 assert.expect(1);
7710
7711 assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
7712 });
7713
7714 QUnit.test('should match `-0` as `0`', function(assert) {
7715 assert.expect(2);
7716
7717 assert.strictEqual(_.includes([-0], 0), true);
7718 assert.strictEqual(_.includes([0], -0), true);
7719 });
7720
7721 QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
7722 assert.expect(1);
7723
7724 var array1 = [1, 2, 3],
7725 array2 = [2, 3, 1];
7726
7727 assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
7728 });
7729 }(1, 2, 3, 4));
7730
7731 /*--------------------------------------------------------------------------*/
7732
7733 QUnit.module('lodash.indexOf');
7734
7735 (function() {
7736 var array = [1, 2, 3, 1, 2, 3];
7737
7738 QUnit.test('should return the index of the first matched value', function(assert) {
7739 assert.expect(1);
7740
7741 assert.strictEqual(_.indexOf(array, 3), 2);
7742 });
7743
7744 QUnit.test('should work with a positive `fromIndex`', function(assert) {
7745 assert.expect(1);
7746
7747 assert.strictEqual(_.indexOf(array, 1, 2), 3);
7748 });
7749
7750 QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
7751 assert.expect(1);
7752
7753 var values = [6, 8, Math.pow(2, 32), Infinity],
7754 expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
7755
7756 var actual = lodashStable.map(values, function(fromIndex) {
7757 return [
7758 _.indexOf(array, undefined, fromIndex),
7759 _.indexOf(array, 1, fromIndex),
7760 _.indexOf(array, '', fromIndex)
7761 ];
7762 });
7763
7764 assert.deepEqual(actual, expected);
7765 });
7766
7767 QUnit.test('should work with a negative `fromIndex`', function(assert) {
7768 assert.expect(1);
7769
7770 assert.strictEqual(_.indexOf(array, 2, -3), 4);
7771 });
7772
7773 QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
7774 assert.expect(1);
7775
7776 var values = [-6, -8, -Infinity],
7777 expected = lodashStable.map(values, alwaysZero);
7778
7779 var actual = lodashStable.map(values, function(fromIndex) {
7780 return _.indexOf(array, 1, fromIndex);
7781 });
7782
7783 assert.deepEqual(actual, expected);
7784 });
7785
7786 QUnit.test('should treat falsey `fromIndex` values as `0`', function(assert) {
7787 assert.expect(1);
7788
7789 var expected = lodashStable.map(falsey, alwaysZero);
7790
7791 var actual = lodashStable.map(falsey, function(fromIndex) {
7792 return _.indexOf(array, 1, fromIndex);
7793 });
7794
7795 assert.deepEqual(actual, expected);
7796 });
7797
7798 QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
7799 assert.expect(1);
7800
7801 assert.strictEqual(_.indexOf(array, 2, 1.2), 1);
7802 });
7803 }());
7804
7805 /*--------------------------------------------------------------------------*/
7806
7807 QUnit.module('lodash.initial');
7808
7809 (function() {
7810 var array = [1, 2, 3];
7811
7812 QUnit.test('should accept a falsey `array` argument', function(assert) {
7813 assert.expect(1);
7814
7815 var expected = lodashStable.map(falsey, alwaysEmptyArray);
7816
7817 var actual = lodashStable.map(falsey, function(array, index) {
7818 try {
7819 return index ? _.initial(array) : _.initial();
7820 } catch (e) {}
7821 });
7822
7823 assert.deepEqual(actual, expected);
7824 });
7825
7826 QUnit.test('should exclude last element', function(assert) {
7827 assert.expect(1);
7828
7829 assert.deepEqual(_.initial(array), [1, 2]);
7830 });
7831
7832 QUnit.test('should return an empty when querying empty arrays', function(assert) {
7833 assert.expect(1);
7834
7835 assert.deepEqual(_.initial([]), []);
7836 });
7837
7838 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
7839 assert.expect(1);
7840
7841 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
7842 actual = lodashStable.map(array, _.initial);
7843
7844 assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
7845 });
7846
7847 QUnit.test('should work in a lazy sequence', function(assert) {
7848 assert.expect(4);
7849
7850 if (!isNpm) {
7851 var array = lodashStable.range(LARGE_ARRAY_SIZE),
7852 values = [];
7853
7854 var actual = _(array).initial().filter(function(value) {
7855 values.push(value);
7856 return false;
7857 })
7858 .value();
7859
7860 assert.deepEqual(actual, []);
7861 assert.deepEqual(values, _.initial(array));
7862
7863 values = [];
7864
7865 actual = _(array).filter(function(value) {
7866 values.push(value);
7867 return isEven(value);
7868 })
7869 .initial()
7870 .value();
7871
7872 assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
7873 assert.deepEqual(values, array);
7874 }
7875 else {
7876 skipAssert(assert, 4);
7877 }
7878 });
7879 }());
7880
7881 /*--------------------------------------------------------------------------*/
7882
7883 QUnit.module('lodash.inRange');
7884
7885 (function() {
7886 QUnit.test('should work with an `end` argument', function(assert) {
7887 assert.expect(3);
7888
7889 assert.strictEqual(_.inRange(3, 5), true);
7890 assert.strictEqual(_.inRange(5, 5), false);
7891 assert.strictEqual(_.inRange(6, 5), false);
7892 });
7893
7894 QUnit.test('should work with `start` and `end` arguments', function(assert) {
7895 assert.expect(4);
7896
7897 assert.strictEqual(_.inRange(1, 1, 5), true);
7898 assert.strictEqual(_.inRange(3, 1, 5), true);
7899 assert.strictEqual(_.inRange(0, 1, 5), false);
7900 assert.strictEqual(_.inRange(5, 1, 5), false);
7901 });
7902
7903 QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
7904 assert.expect(13);
7905
7906 lodashStable.each(falsey, function(value, index) {
7907 if (index) {
7908 assert.strictEqual(_.inRange(0, value), false);
7909 assert.strictEqual(_.inRange(0, value, 1), true);
7910 } else {
7911 assert.strictEqual(_.inRange(0), false);
7912 }
7913 });
7914 });
7915
7916 QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
7917 assert.expect(2);
7918
7919 assert.strictEqual(_.inRange(2, 5, 1), true);
7920 assert.strictEqual(_.inRange(-3, -2, -6), true);
7921 });
7922
7923 QUnit.test('should work with a floating point `n` value', function(assert) {
7924 assert.expect(4);
7925
7926 assert.strictEqual(_.inRange(0.5, 5), true);
7927 assert.strictEqual(_.inRange(1.2, 1, 5), true);
7928 assert.strictEqual(_.inRange(5.2, 5), false);
7929 assert.strictEqual(_.inRange(0.5, 1, 5), false);
7930 });
7931
7932 QUnit.test('should coerce arguments to finite numbers', function(assert) {
7933 assert.expect(1);
7934
7935 var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
7936 expected = lodashStable.map(actual, alwaysTrue);
7937
7938 assert.deepEqual(actual, expected);
7939 });
7940 }());
7941
7942 /*--------------------------------------------------------------------------*/
7943
7944 QUnit.module('intersection methods');
7945
7946 lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
7947 var args = (function() { return arguments; }(1, 2, 3)),
7948 func = _[methodName];
7949
7950 QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
7951 assert.expect(2);
7952
7953 var actual = func([1, 3, 2], [5, 2, 1, 4]);
7954 assert.deepEqual(actual, [1, 2]);
7955
7956 actual = func([5, 2, 1, 4], [1, 3, 2]);
7957 assert.deepEqual(actual, [2, 1]);
7958 });
7959
7960 QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
7961 assert.expect(2);
7962
7963 var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
7964 assert.deepEqual(actual, [1, 2]);
7965
7966 actual = func([5, 2, 1, 4], [2, 1], [1, 3, 2]);
7967 assert.deepEqual(actual, [2, 1]);
7968 });
7969
7970 QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
7971 assert.expect(1);
7972
7973 var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
7974 assert.deepEqual(actual, [1, 2]);
7975 });
7976
7977 QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
7978 assert.expect(1);
7979
7980 var actual = func([1, 1, 3, 2, 2]);
7981 assert.deepEqual(actual, [1, 3, 2]);
7982 });
7983
7984 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
7985 assert.expect(2);
7986
7987 var array = [0, 1, null, 3],
7988 expected = [1, 3];
7989
7990 assert.deepEqual(func(array, args), expected);
7991 assert.deepEqual(func(args, array), expected);
7992 });
7993
7994 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
7995 assert.expect(1);
7996
7997 var values = [-0, 0],
7998 expected = lodashStable.map(values, lodashStable.constant(['0']));
7999
8000 var actual = lodashStable.map(values, function(value) {
8001 return lodashStable.map(func(values, [value]), lodashStable.toString);
8002 });
8003
8004 assert.deepEqual(actual, expected);
8005 });
8006
8007 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
8008 assert.expect(1);
8009
8010 var actual = func([1, NaN, 3], [NaN, 5, NaN]);
8011 assert.deepEqual(actual, [NaN]);
8012 });
8013
8014 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
8015 assert.expect(1);
8016
8017 var values = [-0, 0],
8018 expected = lodashStable.map(values, lodashStable.constant(['0']));
8019
8020 var actual = lodashStable.map(values, function(value) {
8021 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
8022 return lodashStable.map(func(values, largeArray), lodashStable.toString);
8023 });
8024
8025 assert.deepEqual(actual, expected);
8026 });
8027
8028 QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
8029 assert.expect(1);
8030
8031 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
8032 assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
8033 });
8034
8035 QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
8036 assert.expect(2);
8037
8038 var object = {},
8039 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
8040
8041 assert.deepEqual(func([object], largeArray), [object]);
8042 assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
8043 });
8044
8045 QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
8046 assert.expect(3);
8047
8048 var array = [0, 1, null, 3];
8049 assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
8050 assert.deepEqual(func(null, array, null, [2, 3]), []);
8051 assert.deepEqual(func(array, null, args, null), []);
8052 });
8053
8054 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
8055 assert.expect(2);
8056
8057 if (!isNpm) {
8058 var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
8059 assert.ok(wrapped instanceof _);
8060 assert.deepEqual(wrapped.value(), [1, 2]);
8061 }
8062 else {
8063 skipAssert(assert, 2);
8064 }
8065 });
8066 });
8067
8068 /*--------------------------------------------------------------------------*/
8069
8070 QUnit.module('lodash.intersectionBy');
8071
8072 (function() {
8073 QUnit.test('should accept an `iteratee` argument', function(assert) {
8074 assert.expect(2);
8075
8076 var actual = _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
8077 assert.deepEqual(actual, [2.1]);
8078
8079 actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8080 assert.deepEqual(actual, [{ 'x': 1 }]);
8081 });
8082
8083 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
8084 assert.expect(1);
8085
8086 var args;
8087
8088 _.intersectionBy([2.1, 1.2], [4.3, 2.4], function() {
8089 args || (args = slice.call(arguments));
8090 });
8091
8092 assert.deepEqual(args, [4.3]);
8093 });
8094 }());
8095
8096 /*--------------------------------------------------------------------------*/
8097
8098 QUnit.module('lodash.intersectionWith');
8099
8100 (function() {
8101 QUnit.test('should work with a `comparator` argument', function(assert) {
8102 assert.expect(1);
8103
8104 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
8105 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
8106 actual = _.intersectionWith(objects, others, lodashStable.isEqual);
8107
8108 assert.deepEqual(actual, [objects[0]]);
8109 });
8110
8111 QUnit.test('should preserve the sign of `0`', function(assert) {
8112 assert.expect(1);
8113
8114 var array = [-0],
8115 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysZero),
8116 others = [[0], largeArray],
8117 expected = lodashStable.map(others, lodashStable.constant(['-0']));
8118
8119 var actual = lodashStable.map(others, function(other) {
8120 return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
8121 });
8122
8123 assert.deepEqual(actual, expected);
8124 });
8125 }());
8126
8127 /*--------------------------------------------------------------------------*/
8128
8129 QUnit.module('lodash.invert');
8130
8131 (function() {
8132 QUnit.test('should invert an object', function(assert) {
8133 assert.expect(2);
8134
8135 var object = { 'a': 1, 'b': 2 },
8136 actual = _.invert(object);
8137
8138 assert.deepEqual(actual, { '1': 'a', '2': 'b' });
8139 assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
8140 });
8141
8142 QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
8143 assert.expect(1);
8144
8145 var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
8146 assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
8147 });
8148
8149 QUnit.test('should work with an object that has a `length` property', function(assert) {
8150 assert.expect(1);
8151
8152 var object = { '0': 'a', '1': 'b', 'length': 2 };
8153 assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
8154 });
8155
8156 QUnit.test('should return a wrapped value when chaining', function(assert) {
8157 assert.expect(2);
8158
8159 if (!isNpm) {
8160 var object = { 'a': 1, 'b': 2 },
8161 wrapped = _(object).invert();
8162
8163 assert.ok(wrapped instanceof _);
8164 assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
8165 }
8166 else {
8167 skipAssert(assert, 2);
8168 }
8169 });
8170 }());
8171
8172 /*--------------------------------------------------------------------------*/
8173
8174 QUnit.module('lodash.invertBy');
8175
8176 (function() {
8177 var object = { 'a': 1, 'b': 2, 'c': 1 };
8178
8179 QUnit.test('should transform keys by `iteratee`', function(assert) {
8180 assert.expect(1);
8181
8182 var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
8183
8184 var actual = _.invertBy(object, function(value) {
8185 return 'group' + value;
8186 });
8187
8188 assert.deepEqual(actual, expected);
8189 });
8190
8191 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
8192 assert.expect(1);
8193
8194 var values = [, null, undefined],
8195 expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
8196
8197 var actual = lodashStable.map(values, function(value, index) {
8198 return index ? _.invertBy(object, value) : _.invertBy(object);
8199 });
8200
8201 assert.deepEqual(actual, expected);
8202 });
8203
8204 QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
8205 assert.expect(1);
8206
8207 var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
8208 expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
8209
8210 assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
8211 });
8212
8213 QUnit.test('should return a wrapped value when chaining', function(assert) {
8214 assert.expect(2);
8215
8216 if (!isNpm) {
8217 var wrapped = _(object).invertBy();
8218
8219 assert.ok(wrapped instanceof _);
8220 assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
8221 }
8222 else {
8223 skipAssert(assert, 2);
8224 }
8225 });
8226 }());
8227
8228 /*--------------------------------------------------------------------------*/
8229
8230 QUnit.module('lodash.invoke');
8231
8232 (function() {
8233 QUnit.test('should invoke a method on `object`', function(assert) {
8234 assert.expect(1);
8235
8236 var object = { 'a': lodashStable.constant('A') },
8237 actual = _.invoke(object, 'a');
8238
8239 assert.strictEqual(actual, 'A');
8240 });
8241
8242 QUnit.test('should support invoking with arguments', function(assert) {
8243 assert.expect(1);
8244
8245 var object = { 'a': function(a, b) { return [a, b]; } },
8246 actual = _.invoke(object, 'a', 1, 2);
8247
8248 assert.deepEqual(actual, [1, 2]);
8249 });
8250
8251 QUnit.test('should not error on nullish elements', function(assert) {
8252 assert.expect(1);
8253
8254 var values = [null, undefined],
8255 expected = lodashStable.map(values, noop);
8256
8257 var actual = lodashStable.map(values, function(value) {
8258 try {
8259 return _.invoke(value, 'a.b', 1, 2);
8260 } catch (e) {}
8261 });
8262
8263 assert.deepEqual(actual, expected);
8264 });
8265
8266 QUnit.test('should preserve the sign of `0`', function(assert) {
8267 assert.expect(1);
8268
8269 var object = { '-0': alwaysA, '0': alwaysB },
8270 props = [-0, Object(-0), 0, Object(0)];
8271
8272 var actual = lodashStable.map(props, function(key) {
8273 return _.invoke(object, key);
8274 });
8275
8276 assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
8277 });
8278
8279 QUnit.test('should support deep paths', function(assert) {
8280 assert.expect(2);
8281
8282 var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
8283
8284 lodashStable.each(['a.b', ['a', 'b']], function(path) {
8285 var actual = _.invoke(object, path, 1, 2);
8286 assert.deepEqual(actual, [1, 2]);
8287 });
8288 });
8289
8290 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8291 assert.expect(2);
8292
8293 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8294
8295 lodashStable.each(['a.b', ['a', 'b']], function(path) {
8296 assert.deepEqual(_.invoke(object, path), 1);
8297 });
8298 });
8299
8300 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
8301 assert.expect(1);
8302
8303 if (!isNpm) {
8304 var object = { 'a': alwaysOne };
8305 assert.strictEqual(_(object).invoke('a'), 1);
8306 }
8307 else {
8308 skipAssert(assert);
8309 }
8310 });
8311
8312 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
8313 assert.expect(1);
8314
8315 if (!isNpm) {
8316 var object = { 'a': alwaysOne };
8317 assert.ok(_(object).chain().invoke('a') instanceof _);
8318 }
8319 else {
8320 skipAssert(assert);
8321 }
8322 });
8323 }());
8324
8325 /*--------------------------------------------------------------------------*/
8326
8327 QUnit.module('lodash.invokeMap');
8328
8329 (function() {
8330 QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
8331 assert.expect(1);
8332
8333 var array = ['a', 'b', 'c'],
8334 actual = _.invokeMap(array, 'toUpperCase');
8335
8336 assert.deepEqual(actual, ['A', 'B', 'C']);
8337 });
8338
8339 QUnit.test('should support invoking with arguments', function(assert) {
8340 assert.expect(1);
8341
8342 var array = [function() { return slice.call(arguments); }],
8343 actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
8344
8345 assert.deepEqual(actual, [['a', 'b', 'c']]);
8346 });
8347
8348 QUnit.test('should work with a function for `methodName`', function(assert) {
8349 assert.expect(1);
8350
8351 var array = ['a', 'b', 'c'];
8352
8353 var actual = _.invokeMap(array, function(left, right) {
8354 return left + this.toUpperCase() + right;
8355 }, '(', ')');
8356
8357 assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
8358 });
8359
8360 QUnit.test('should work with an object for `collection`', function(assert) {
8361 assert.expect(1);
8362
8363 var object = { 'a': 1, 'b': 2, 'c': 3 },
8364 actual = _.invokeMap(object, 'toFixed', 1);
8365
8366 assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
8367 });
8368
8369 QUnit.test('should treat number values for `collection` as empty', function(assert) {
8370 assert.expect(1);
8371
8372 assert.deepEqual(_.invokeMap(1), []);
8373 });
8374
8375 QUnit.test('should not error on nullish elements', function(assert) {
8376 assert.expect(1);
8377
8378 var array = ['a', null, undefined, 'd'];
8379
8380 try {
8381 var actual = _.invokeMap(array, 'toUpperCase');
8382 } catch (e) {}
8383
8384 assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
8385 });
8386
8387 QUnit.test('should not error on elements with missing properties', function(assert) {
8388 assert.expect(1);
8389
8390 var objects = lodashStable.map([null, undefined, alwaysOne], function(value) {
8391 return { 'a': value };
8392 });
8393
8394 var expected = lodashStable.map(objects, function(object) {
8395 return object.a ? object.a() : undefined;
8396 });
8397
8398 try {
8399 var actual = _.invokeMap(objects, 'a');
8400 } catch (e) {}
8401
8402 assert.deepEqual(actual, expected);
8403 });
8404
8405 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
8406 assert.expect(2);
8407
8408 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
8409
8410 lodashStable.each(['a.b', ['a', 'b']], function(path) {
8411 assert.deepEqual(_.invokeMap([object], path), [1]);
8412 });
8413 });
8414
8415 QUnit.test('should return a wrapped value when chaining', function(assert) {
8416 assert.expect(4);
8417
8418 if (!isNpm) {
8419 var array = ['a', 'b', 'c'],
8420 wrapped = _(array),
8421 actual = wrapped.invokeMap('toUpperCase');
8422
8423 assert.ok(actual instanceof _);
8424 assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
8425
8426 actual = wrapped.invokeMap(function(left, right) {
8427 return left + this.toUpperCase() + right;
8428 }, '(', ')');
8429
8430 assert.ok(actual instanceof _);
8431 assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
8432 }
8433 else {
8434 skipAssert(assert, 4);
8435 }
8436 });
8437
8438 QUnit.test('should support shortcut fusion', function(assert) {
8439 assert.expect(2);
8440
8441 if (!isNpm) {
8442 var count = 0,
8443 method = function() { count++; return this.index; };
8444
8445 var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
8446 return { 'index': index, 'method': method };
8447 });
8448
8449 var actual = _(array).invokeMap('method').take(1).value();
8450
8451 assert.strictEqual(count, 1);
8452 assert.deepEqual(actual, [0]);
8453 }
8454 else {
8455 skipAssert(assert, 2);
8456 }
8457 });
8458 }());
8459
8460 /*--------------------------------------------------------------------------*/
8461
8462 QUnit.module('lodash.isArguments');
8463
8464 (function() {
8465 var args = (function() { return arguments; }(1, 2, 3)),
8466 strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
8467
8468 QUnit.test('should return `true` for `arguments` objects', function(assert) {
8469 assert.expect(2);
8470
8471 assert.strictEqual(_.isArguments(args), true);
8472 assert.strictEqual(_.isArguments(strictArgs), true);
8473 });
8474
8475 QUnit.test('should return `false` for non `arguments` objects', function(assert) {
8476 assert.expect(12);
8477
8478 var expected = lodashStable.map(falsey, alwaysFalse);
8479
8480 var actual = lodashStable.map(falsey, function(value, index) {
8481 return index ? _.isArguments(value) : _.isArguments();
8482 });
8483
8484 assert.deepEqual(actual, expected);
8485
8486 assert.strictEqual(_.isArguments([1, 2, 3]), false);
8487 assert.strictEqual(_.isArguments(true), false);
8488 assert.strictEqual(_.isArguments(new Date), false);
8489 assert.strictEqual(_.isArguments(new Error), false);
8490 assert.strictEqual(_.isArguments(_), false);
8491 assert.strictEqual(_.isArguments(slice), false);
8492 assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
8493 assert.strictEqual(_.isArguments(1), false);
8494 assert.strictEqual(_.isArguments(/x/), false);
8495 assert.strictEqual(_.isArguments('a'), false);
8496 assert.strictEqual(_.isArguments(symbol), false);
8497 });
8498
8499 QUnit.test('should work with an `arguments` object from another realm', function(assert) {
8500 assert.expect(1);
8501
8502 if (realm.arguments) {
8503 assert.strictEqual(_.isArguments(realm.arguments), true);
8504 }
8505 else {
8506 skipAssert(assert);
8507 }
8508 });
8509 }());
8510
8511 /*--------------------------------------------------------------------------*/
8512
8513 QUnit.module('lodash.isArray');
8514
8515 (function() {
8516 var args = arguments;
8517
8518 QUnit.test('should return `true` for arrays', function(assert) {
8519 assert.expect(1);
8520
8521 assert.strictEqual(_.isArray([1, 2, 3]), true);
8522 });
8523
8524 QUnit.test('should return `false` for non-arrays', function(assert) {
8525 assert.expect(12);
8526
8527 var expected = lodashStable.map(falsey, alwaysFalse);
8528
8529 var actual = lodashStable.map(falsey, function(value, index) {
8530 return index ? _.isArray(value) : _.isArray();
8531 });
8532
8533 assert.deepEqual(actual, expected);
8534
8535 assert.strictEqual(_.isArray(args), false);
8536 assert.strictEqual(_.isArray(true), false);
8537 assert.strictEqual(_.isArray(new Date), false);
8538 assert.strictEqual(_.isArray(new Error), false);
8539 assert.strictEqual(_.isArray(_), false);
8540 assert.strictEqual(_.isArray(slice), false);
8541 assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
8542 assert.strictEqual(_.isArray(1), false);
8543 assert.strictEqual(_.isArray(/x/), false);
8544 assert.strictEqual(_.isArray('a'), false);
8545 assert.strictEqual(_.isArray(symbol), false);
8546 });
8547
8548 QUnit.test('should work with an array from another realm', function(assert) {
8549 assert.expect(1);
8550
8551 if (realm.array) {
8552 assert.strictEqual(_.isArray(realm.array), true);
8553 }
8554 else {
8555 skipAssert(assert);
8556 }
8557 });
8558 }(1, 2, 3));
8559
8560 /*--------------------------------------------------------------------------*/
8561
8562 QUnit.module('lodash.isArrayBuffer');
8563
8564 (function() {
8565 var args = arguments;
8566
8567 QUnit.test('should return `true` for array buffers', function(assert) {
8568 assert.expect(1);
8569
8570 if (ArrayBuffer) {
8571 assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
8572 }
8573 else {
8574 skipAssert(assert);
8575 }
8576 });
8577
8578 QUnit.test('should return `false` for non array buffers', function(assert) {
8579 assert.expect(13);
8580
8581 var expected = lodashStable.map(falsey, alwaysFalse);
8582
8583 var actual = lodashStable.map(falsey, function(value, index) {
8584 return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
8585 });
8586
8587 assert.deepEqual(actual, expected);
8588
8589 assert.strictEqual(_.isArrayBuffer(args), false);
8590 assert.strictEqual(_.isArrayBuffer([1, 2, 3]), false);
8591 assert.strictEqual(_.isArrayBuffer(true), false);
8592 assert.strictEqual(_.isArrayBuffer(new Date), false);
8593 assert.strictEqual(_.isArrayBuffer(new Error), false);
8594 assert.strictEqual(_.isArrayBuffer(_), false);
8595 assert.strictEqual(_.isArrayBuffer(slice), false);
8596 assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
8597 assert.strictEqual(_.isArrayBuffer(1), false);
8598 assert.strictEqual(_.isArrayBuffer(/x/), false);
8599 assert.strictEqual(_.isArrayBuffer('a'), false);
8600 assert.strictEqual(_.isArrayBuffer(symbol), false);
8601 });
8602
8603 QUnit.test('should work with array buffers from another realm', function(assert) {
8604 assert.expect(1);
8605
8606 if (realm.arrayBuffer) {
8607 assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
8608 }
8609 else {
8610 skipAssert(assert);
8611 }
8612 });
8613 }(1, 2, 3));
8614
8615 /*--------------------------------------------------------------------------*/
8616
8617 QUnit.module('lodash.isArrayLike');
8618
8619 (function() {
8620 var args = arguments;
8621
8622 QUnit.test('should return `true` for array-like values', function(assert) {
8623 assert.expect(1);
8624
8625 var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
8626 expected = lodashStable.map(values, alwaysTrue),
8627 actual = lodashStable.map(values, _.isArrayLike);
8628
8629 assert.deepEqual(actual, expected);
8630 });
8631
8632 QUnit.test('should return `false` for non-arrays', function(assert) {
8633 assert.expect(11);
8634
8635 var expected = lodashStable.map(falsey, function(value) {
8636 return value === '';
8637 });
8638
8639 var actual = lodashStable.map(falsey, function(value, index) {
8640 return index ? _.isArrayLike(value) : _.isArrayLike();
8641 });
8642
8643 assert.deepEqual(actual, expected);
8644
8645 assert.strictEqual(_.isArrayLike(true), false);
8646 assert.strictEqual(_.isArrayLike(new Date), false);
8647 assert.strictEqual(_.isArrayLike(new Error), false);
8648 assert.strictEqual(_.isArrayLike(_), false);
8649 assert.strictEqual(_.isArrayLike(generator), false);
8650 assert.strictEqual(_.isArrayLike(slice), false);
8651 assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
8652 assert.strictEqual(_.isArrayLike(1), false);
8653 assert.strictEqual(_.isArrayLike(/x/), false);
8654 assert.strictEqual(_.isArrayLike(symbol), false);
8655 });
8656
8657 QUnit.test('should work with an array from another realm', function(assert) {
8658 assert.expect(1);
8659
8660 if (realm.object) {
8661 var values = [realm.arguments, realm.array, realm.string],
8662 expected = lodashStable.map(values, alwaysTrue),
8663 actual = lodashStable.map(values, _.isArrayLike);
8664
8665 assert.deepEqual(actual, expected);
8666 }
8667 else {
8668 skipAssert(assert);
8669 }
8670 });
8671 }(1, 2, 3));
8672
8673 /*--------------------------------------------------------------------------*/
8674
8675 QUnit.module('lodash.isBoolean');
8676
8677 (function() {
8678 var args = arguments;
8679
8680 QUnit.test('should return `true` for booleans', function(assert) {
8681 assert.expect(4);
8682
8683 assert.strictEqual(_.isBoolean(true), true);
8684 assert.strictEqual(_.isBoolean(false), true);
8685 assert.strictEqual(_.isBoolean(Object(true)), true);
8686 assert.strictEqual(_.isBoolean(Object(false)), true);
8687 });
8688
8689 QUnit.test('should return `false` for non-booleans', function(assert) {
8690 assert.expect(12);
8691
8692 var expected = lodashStable.map(falsey, function(value) {
8693 return value === false;
8694 });
8695
8696 var actual = lodashStable.map(falsey, function(value, index) {
8697 return index ? _.isBoolean(value) : _.isBoolean();
8698 });
8699
8700 assert.deepEqual(actual, expected);
8701
8702 assert.strictEqual(_.isBoolean(args), false);
8703 assert.strictEqual(_.isBoolean([1, 2, 3]), false);
8704 assert.strictEqual(_.isBoolean(new Date), false);
8705 assert.strictEqual(_.isBoolean(new Error), false);
8706 assert.strictEqual(_.isBoolean(_), false);
8707 assert.strictEqual(_.isBoolean(slice), false);
8708 assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
8709 assert.strictEqual(_.isBoolean(1), false);
8710 assert.strictEqual(_.isBoolean(/x/), false);
8711 assert.strictEqual(_.isBoolean('a'), false);
8712 assert.strictEqual(_.isBoolean(symbol), false);
8713 });
8714
8715 QUnit.test('should work with a boolean from another realm', function(assert) {
8716 assert.expect(1);
8717
8718 if (realm.boolean) {
8719 assert.strictEqual(_.isBoolean(realm.boolean), true);
8720 }
8721 else {
8722 skipAssert(assert);
8723 }
8724 });
8725 }(1, 2, 3));
8726
8727 /*--------------------------------------------------------------------------*/
8728
8729 QUnit.module('lodash.isBuffer');
8730
8731 (function() {
8732 var args = arguments;
8733
8734 QUnit.test('should return `true` for buffers', function(assert) {
8735 assert.expect(1);
8736
8737 if (Buffer) {
8738 assert.strictEqual(_.isBuffer(new Buffer(2)), true);
8739 }
8740 else {
8741 skipAssert(assert);
8742 }
8743 });
8744
8745 QUnit.test('should return `false` for non-buffers', function(assert) {
8746 assert.expect(13);
8747
8748 var expected = lodashStable.map(falsey, alwaysFalse);
8749
8750 var actual = lodashStable.map(falsey, function(value, index) {
8751 return index ? _.isBuffer(value) : _.isBuffer();
8752 });
8753
8754 assert.deepEqual(actual, expected);
8755
8756 assert.strictEqual(_.isBuffer(args), false);
8757 assert.strictEqual(_.isBuffer([1, 2, 3]), false);
8758 assert.strictEqual(_.isBuffer(true), false);
8759 assert.strictEqual(_.isBuffer(new Date), false);
8760 assert.strictEqual(_.isBuffer(new Error), false);
8761 assert.strictEqual(_.isBuffer(_), false);
8762 assert.strictEqual(_.isBuffer(slice), false);
8763 assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
8764 assert.strictEqual(_.isBuffer(1), false);
8765 assert.strictEqual(_.isBuffer(/x/), false);
8766 assert.strictEqual(_.isBuffer('a'), false);
8767 assert.strictEqual(_.isBuffer(symbol), false);
8768 });
8769
8770 QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
8771 assert.expect(1);
8772
8773 if (!isStrict && Buffer && lodashBizarro) {
8774 assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
8775 }
8776 else {
8777 skipAssert(assert);
8778 }
8779 });
8780 }(1, 2, 3));
8781
8782 /*--------------------------------------------------------------------------*/
8783
8784 QUnit.module('lodash.isDate');
8785
8786 (function() {
8787 var args = arguments;
8788
8789 QUnit.test('should return `true` for dates', function(assert) {
8790 assert.expect(1);
8791
8792 assert.strictEqual(_.isDate(new Date), true);
8793 });
8794
8795 QUnit.test('should return `false` for non-dates', function(assert) {
8796 assert.expect(12);
8797
8798 var expected = lodashStable.map(falsey, alwaysFalse);
8799
8800 var actual = lodashStable.map(falsey, function(value, index) {
8801 return index ? _.isDate(value) : _.isDate();
8802 });
8803
8804 assert.deepEqual(actual, expected);
8805
8806 assert.strictEqual(_.isDate(args), false);
8807 assert.strictEqual(_.isDate([1, 2, 3]), false);
8808 assert.strictEqual(_.isDate(true), false);
8809 assert.strictEqual(_.isDate(new Error), false);
8810 assert.strictEqual(_.isDate(_), false);
8811 assert.strictEqual(_.isDate(slice), false);
8812 assert.strictEqual(_.isDate({ 'a': 1 }), false);
8813 assert.strictEqual(_.isDate(1), false);
8814 assert.strictEqual(_.isDate(/x/), false);
8815 assert.strictEqual(_.isDate('a'), false);
8816 assert.strictEqual(_.isDate(symbol), false);
8817 });
8818
8819 QUnit.test('should work with a date object from another realm', function(assert) {
8820 assert.expect(1);
8821
8822 if (realm.date) {
8823 assert.strictEqual(_.isDate(realm.date), true);
8824 }
8825 else {
8826 skipAssert(assert);
8827 }
8828 });
8829 }(1, 2, 3));
8830
8831 /*--------------------------------------------------------------------------*/
8832
8833 QUnit.module('lodash.isElement');
8834
8835 (function() {
8836 var args = arguments;
8837
8838 function Element() {
8839 this.nodeType = 1;
8840 }
8841
8842 QUnit.test('should return `false` for plain objects', function(assert) {
8843 assert.expect(7);
8844
8845 var element = body || new Element;
8846
8847 assert.strictEqual(_.isElement(element), true);
8848 assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
8849 assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
8850 assert.strictEqual(_.isElement({ 'nodeType': true }), false);
8851 assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
8852 assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
8853 assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
8854 });
8855
8856 QUnit.test('should return `false` for non DOM elements', function(assert) {
8857 assert.expect(13);
8858
8859 var expected = lodashStable.map(falsey, alwaysFalse);
8860
8861 var actual = lodashStable.map(falsey, function(value, index) {
8862 return index ? _.isElement(value) : _.isElement();
8863 });
8864
8865 assert.deepEqual(actual, expected);
8866
8867 assert.strictEqual(_.isElement(args), false);
8868 assert.strictEqual(_.isElement([1, 2, 3]), false);
8869 assert.strictEqual(_.isElement(true), false);
8870 assert.strictEqual(_.isElement(new Date), false);
8871 assert.strictEqual(_.isElement(new Error), false);
8872 assert.strictEqual(_.isElement(_), false);
8873 assert.strictEqual(_.isElement(slice), false);
8874 assert.strictEqual(_.isElement({ 'a': 1 }), false);
8875 assert.strictEqual(_.isElement(1), false);
8876 assert.strictEqual(_.isElement(/x/), false);
8877 assert.strictEqual(_.isElement('a'), false);
8878 assert.strictEqual(_.isElement(symbol), false);
8879 });
8880
8881 QUnit.test('should work with a DOM element from another realm', function(assert) {
8882 assert.expect(1);
8883
8884 if (realm.element) {
8885 assert.strictEqual(_.isElement(realm.element), true);
8886 }
8887 else {
8888 skipAssert(assert);
8889 }
8890 });
8891 }(1, 2, 3));
8892
8893 /*--------------------------------------------------------------------------*/
8894
8895 QUnit.module('lodash.isEmpty');
8896
8897 (function() {
8898 var args = arguments;
8899
8900 QUnit.test('should return `true` for empty values', function(assert) {
8901 assert.expect(10);
8902
8903 var expected = lodashStable.map(empties, alwaysTrue),
8904 actual = lodashStable.map(empties, _.isEmpty);
8905
8906 assert.deepEqual(actual, expected);
8907
8908 assert.strictEqual(_.isEmpty(true), true);
8909 assert.strictEqual(_.isEmpty(slice), true);
8910 assert.strictEqual(_.isEmpty(1), true);
8911 assert.strictEqual(_.isEmpty(NaN), true);
8912 assert.strictEqual(_.isEmpty(/x/), true);
8913 assert.strictEqual(_.isEmpty(symbol), true);
8914 assert.strictEqual(_.isEmpty(), true);
8915
8916 if (Buffer) {
8917 assert.strictEqual(_.isEmpty(new Buffer(0)), true);
8918 assert.strictEqual(_.isEmpty(new Buffer(1)), false);
8919 }
8920 else {
8921 skipAssert(assert, 2);
8922 }
8923 });
8924
8925 QUnit.test('should return `false` for non-empty values', function(assert) {
8926 assert.expect(3);
8927
8928 assert.strictEqual(_.isEmpty([0]), false);
8929 assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
8930 assert.strictEqual(_.isEmpty('a'), false);
8931 });
8932
8933 QUnit.test('should work with an object that has a `length` property', function(assert) {
8934 assert.expect(1);
8935
8936 assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
8937 });
8938
8939 QUnit.test('should work with `arguments` objects', function(assert) {
8940 assert.expect(1);
8941
8942 assert.strictEqual(_.isEmpty(args), false);
8943 });
8944
8945 QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
8946 assert.expect(1);
8947
8948 function Foo(elements) {
8949 push.apply(this, elements);
8950 }
8951 Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
8952
8953 assert.strictEqual(_.isEmpty(new Foo([])), true);
8954 });
8955
8956 QUnit.test('should work with maps', function(assert) {
8957 assert.expect(4);
8958
8959 if (Map) {
8960 lodashStable.each([new Map, realm.map], function(map) {
8961 assert.strictEqual(_.isEmpty(map), true);
8962 map.set('a', 1);
8963 assert.strictEqual(_.isEmpty(map), false);
8964 map.clear();
8965 });
8966 }
8967 else {
8968 skipAssert(assert, 4);
8969 }
8970 });
8971
8972 QUnit.test('should work with sets', function(assert) {
8973 assert.expect(4);
8974
8975 if (Set) {
8976 lodashStable.each([new Set, realm.set], function(set) {
8977 assert.strictEqual(_.isEmpty(set), true);
8978 set.add(1);
8979 assert.strictEqual(_.isEmpty(set), false);
8980 set.clear();
8981 });
8982 }
8983 else {
8984 skipAssert(assert, 4);
8985 }
8986 });
8987
8988 QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
8989 assert.expect(1);
8990
8991 function Foo() {}
8992 Foo.prototype.length = -1;
8993
8994 assert.strictEqual(_.isEmpty(new Foo), true);
8995 });
8996
8997 QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
8998 assert.expect(1);
8999
9000 function Foo() {}
9001 Foo.prototype.length = MAX_SAFE_INTEGER + 1;
9002
9003 assert.strictEqual(_.isEmpty(new Foo), true);
9004 });
9005
9006 QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
9007 assert.expect(1);
9008
9009 assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
9010 });
9011
9012 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9013 assert.expect(1);
9014
9015 if (!isNpm) {
9016 assert.strictEqual(_({}).isEmpty(), true);
9017 }
9018 else {
9019 skipAssert(assert);
9020 }
9021 });
9022
9023 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9024 assert.expect(1);
9025
9026 if (!isNpm) {
9027 assert.ok(_({}).chain().isEmpty() instanceof _);
9028 }
9029 else {
9030 skipAssert(assert);
9031 }
9032 });
9033 }(1, 2, 3));
9034
9035 /*--------------------------------------------------------------------------*/
9036
9037 QUnit.module('lodash.isEqual');
9038
9039 (function() {
9040 var symbol1 = Symbol ? Symbol('a') : true,
9041 symbol2 = Symbol ? Symbol('b') : false;
9042
9043 QUnit.test('should compare primitives', function(assert) {
9044 assert.expect(1);
9045
9046 var pairs = [
9047 [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
9048 [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
9049 [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
9050 ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
9051 [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
9052 [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
9053 [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
9054 [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
9055 [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
9056 ];
9057
9058 var expected = lodashStable.map(pairs, function(pair) {
9059 return pair[2];
9060 });
9061
9062 var actual = lodashStable.map(pairs, function(pair) {
9063 return _.isEqual(pair[0], pair[1]);
9064 });
9065
9066 assert.deepEqual(actual, expected);
9067 });
9068
9069 QUnit.test('should compare arrays', function(assert) {
9070 assert.expect(6);
9071
9072 var array1 = [true, null, 1, 'a', undefined],
9073 array2 = [true, null, 1, 'a', undefined];
9074
9075 assert.strictEqual(_.isEqual(array1, array2), true);
9076
9077 array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9078 array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
9079
9080 assert.strictEqual(_.isEqual(array1, array2), true);
9081
9082 array1 = [1];
9083 array1[2] = 3;
9084
9085 array2 = [1];
9086 array2[1] = undefined;
9087 array2[2] = 3;
9088
9089 assert.strictEqual(_.isEqual(array1, array2), true);
9090
9091 array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
9092 array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
9093
9094 assert.strictEqual(_.isEqual(array1, array2), true);
9095
9096 array1 = [1, 2, 3];
9097 array2 = [3, 2, 1];
9098
9099 assert.strictEqual(_.isEqual(array1, array2), false);
9100
9101 array1 = [1, 2];
9102 array2 = [1, 2, 3];
9103
9104 assert.strictEqual(_.isEqual(array1, array2), false);
9105 });
9106
9107 QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
9108 assert.expect(3);
9109
9110 var array1 = [1, 2, 3],
9111 array2 = [1, 2, 3];
9112
9113 array1.every = array1.filter = array1.forEach =
9114 array1.indexOf = array1.lastIndexOf = array1.map =
9115 array1.some = array1.reduce = array1.reduceRight = null;
9116
9117 array2.concat = array2.join = array2.pop =
9118 array2.reverse = array2.shift = array2.slice =
9119 array2.sort = array2.splice = array2.unshift = null;
9120
9121 assert.strictEqual(_.isEqual(array1, array2), true);
9122
9123 array1 = [1, 2, 3];
9124 array1.a = 1;
9125
9126 array2 = [1, 2, 3];
9127 array2.b = 1;
9128
9129 assert.strictEqual(_.isEqual(array1, array2), true);
9130
9131 array1 = /c/.exec('abcde');
9132 array2 = ['c'];
9133
9134 assert.strictEqual(_.isEqual(array1, array2), true);
9135 });
9136
9137 QUnit.test('should compare sparse arrays', function(assert) {
9138 assert.expect(3);
9139
9140 var array = Array(1);
9141
9142 assert.strictEqual(_.isEqual(array, Array(1)), true);
9143 assert.strictEqual(_.isEqual(array, [undefined]), true);
9144 assert.strictEqual(_.isEqual(array, Array(2)), false);
9145 });
9146
9147 QUnit.test('should compare plain objects', function(assert) {
9148 assert.expect(5);
9149
9150 var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
9151 object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
9152
9153 assert.strictEqual(_.isEqual(object1, object2), true);
9154
9155 object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9156 object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
9157
9158 assert.strictEqual(_.isEqual(object1, object2), true);
9159
9160 object1 = { 'a': 1, 'b': 2, 'c': 3 };
9161 object2 = { 'a': 3, 'b': 2, 'c': 1 };
9162
9163 assert.strictEqual(_.isEqual(object1, object2), false);
9164
9165 object1 = { 'a': 1, 'b': 2, 'c': 3 };
9166 object2 = { 'd': 1, 'e': 2, 'f': 3 };
9167
9168 assert.strictEqual(_.isEqual(object1, object2), false);
9169
9170 object1 = { 'a': 1, 'b': 2 };
9171 object2 = { 'a': 1, 'b': 2, 'c': 3 };
9172
9173 assert.strictEqual(_.isEqual(object1, object2), false);
9174 });
9175
9176 QUnit.test('should compare objects regardless of key order', function(assert) {
9177 assert.expect(1);
9178
9179 var object1 = { 'a': 1, 'b': 2, 'c': 3 },
9180 object2 = { 'c': 3, 'a': 1, 'b': 2 };
9181
9182 assert.strictEqual(_.isEqual(object1, object2), true);
9183 });
9184
9185 QUnit.test('should compare nested objects', function(assert) {
9186 assert.expect(1);
9187
9188 var object1 = {
9189 'a': [1, 2, 3],
9190 'b': true,
9191 'c': Object(1),
9192 'd': 'a',
9193 'e': {
9194 'f': ['a', Object('b'), 'c'],
9195 'g': Object(false),
9196 'h': new Date(2012, 4, 23),
9197 'i': noop,
9198 'j': 'a'
9199 }
9200 };
9201
9202 var object2 = {
9203 'a': [1, Object(2), 3],
9204 'b': Object(true),
9205 'c': 1,
9206 'd': Object('a'),
9207 'e': {
9208 'f': ['a', 'b', 'c'],
9209 'g': false,
9210 'h': new Date(2012, 4, 23),
9211 'i': noop,
9212 'j': 'a'
9213 }
9214 };
9215
9216 assert.strictEqual(_.isEqual(object1, object2), true);
9217 });
9218
9219 QUnit.test('should compare object instances', function(assert) {
9220 assert.expect(4);
9221
9222 function Foo() {
9223 this.a = 1;
9224 }
9225 Foo.prototype.a = 1;
9226
9227 function Bar() {
9228 this.a = 1;
9229 }
9230 Bar.prototype.a = 2;
9231
9232 assert.strictEqual(_.isEqual(new Foo, new Foo), true);
9233 assert.strictEqual(_.isEqual(new Foo, new Bar), false);
9234 assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
9235 assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
9236 });
9237
9238 QUnit.test('should compare objects with constructor properties', function(assert) {
9239 assert.expect(5);
9240
9241 assert.strictEqual(_.isEqual({ 'constructor': 1 }, { 'constructor': 1 }), true);
9242 assert.strictEqual(_.isEqual({ 'constructor': 1 }, { 'constructor': '1' }), false);
9243 assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
9244 assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
9245 assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
9246 });
9247
9248 QUnit.test('should compare arrays with circular references', function(assert) {
9249 assert.expect(4);
9250
9251 var array1 = [],
9252 array2 = [];
9253
9254 array1.push(array1);
9255 array2.push(array2);
9256
9257 assert.strictEqual(_.isEqual(array1, array2), true);
9258
9259 array1.push('b');
9260 array2.push('b');
9261
9262 assert.strictEqual(_.isEqual(array1, array2), true);
9263
9264 array1.push('c');
9265 array2.push('d');
9266
9267 assert.strictEqual(_.isEqual(array1, array2), false);
9268
9269 array1 = ['a', 'b', 'c'];
9270 array1[1] = array1;
9271 array2 = ['a', ['a', 'b', 'c'], 'c'];
9272
9273 assert.strictEqual(_.isEqual(array1, array2), false);
9274 });
9275
9276 QUnit.test('should compare objects with circular references', function(assert) {
9277 assert.expect(4);
9278
9279 var object1 = {},
9280 object2 = {};
9281
9282 object1.a = object1;
9283 object2.a = object2;
9284
9285 assert.strictEqual(_.isEqual(object1, object2), true);
9286
9287 object1.b = 0;
9288 object2.b = Object(0);
9289
9290 assert.strictEqual(_.isEqual(object1, object2), true);
9291
9292 object1.c = Object(1);
9293 object2.c = Object(2);
9294
9295 assert.strictEqual(_.isEqual(object1, object2), false);
9296
9297 object1 = { 'a': 1, 'b': 2, 'c': 3 };
9298 object1.b = object1;
9299 object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
9300
9301 assert.strictEqual(_.isEqual(object1, object2), false);
9302 });
9303
9304 QUnit.test('should compare objects with multiple circular references', function(assert) {
9305 assert.expect(3);
9306
9307 var array1 = [{}],
9308 array2 = [{}];
9309
9310 (array1[0].a = array1).push(array1);
9311 (array2[0].a = array2).push(array2);
9312
9313 assert.strictEqual(_.isEqual(array1, array2), true);
9314
9315 array1[0].b = 0;
9316 array2[0].b = Object(0);
9317
9318 assert.strictEqual(_.isEqual(array1, array2), true);
9319
9320 array1[0].c = Object(1);
9321 array2[0].c = Object(2);
9322
9323 assert.strictEqual(_.isEqual(array1, array2), false);
9324 });
9325
9326 QUnit.test('should compare objects with complex circular references', function(assert) {
9327 assert.expect(1);
9328
9329 var object1 = {
9330 'foo': { 'b': { 'c': { 'd': {} } } },
9331 'bar': { 'a': 2 }
9332 };
9333
9334 var object2 = {
9335 'foo': { 'b': { 'c': { 'd': {} } } },
9336 'bar': { 'a': 2 }
9337 };
9338
9339 object1.foo.b.c.d = object1;
9340 object1.bar.b = object1.foo.b;
9341
9342 object2.foo.b.c.d = object2;
9343 object2.bar.b = object2.foo.b;
9344
9345 assert.strictEqual(_.isEqual(object1, object2), true);
9346 });
9347
9348 QUnit.test('should compare objects with shared property values', function(assert) {
9349 assert.expect(1);
9350
9351 var object1 = {
9352 'a': [1, 2]
9353 };
9354
9355 var object2 = {
9356 'a': [1, 2],
9357 'b': [1, 2]
9358 };
9359
9360 object1.b = object1.a;
9361
9362 assert.strictEqual(_.isEqual(object1, object2), true);
9363 });
9364
9365 QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
9366 assert.expect(2);
9367
9368 function Foo() {
9369 this.a = 1;
9370 }
9371 Foo.prototype.constructor = null;
9372
9373 var object2 = { 'a': 1 };
9374 assert.strictEqual(_.isEqual(new Foo, object2), false);
9375
9376 if (create) {
9377 var object1 = create(null);
9378 object1.a = 1;
9379 assert.strictEqual(_.isEqual(object1, object2), true);
9380 }
9381 else {
9382 skipAssert(assert);
9383 }
9384 });
9385
9386 QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
9387 assert.expect(1);
9388
9389 var primitive,
9390 object = { 'toString': function() { return primitive; } },
9391 values = [true, null, 1, 'a', undefined],
9392 expected = lodashStable.map(values, alwaysFalse);
9393
9394 var actual = lodashStable.map(values, function(value) {
9395 primitive = value;
9396 return _.isEqual(object, value);
9397 });
9398
9399 assert.deepEqual(actual, expected);
9400 });
9401
9402 QUnit.test('should avoid common type coercions', function(assert) {
9403 assert.expect(9);
9404
9405 assert.strictEqual(_.isEqual(true, Object(false)), false);
9406 assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
9407 assert.strictEqual(_.isEqual(false, Object('')), false);
9408 assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
9409 assert.strictEqual(_.isEqual(0, ''), false);
9410 assert.strictEqual(_.isEqual(1, true), false);
9411 assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
9412 assert.strictEqual(_.isEqual('36', 36), false);
9413 assert.strictEqual(_.isEqual(36, '36'), false);
9414 });
9415
9416 QUnit.test('should compare `arguments` objects', function(assert) {
9417 assert.expect(2);
9418
9419 var args1 = (function() { return arguments; }(1, 2, 3)),
9420 args2 = (function() { return arguments; }(1, 2, 3)),
9421 args3 = (function() { return arguments; }(1, 2));
9422
9423 assert.strictEqual(_.isEqual(args1, args2), true);
9424 assert.strictEqual(_.isEqual(args1, args3), false);
9425 });
9426
9427 QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
9428 assert.expect(4);
9429
9430 var args = (function() { return arguments; }(1, 2, 3)),
9431 object = { '0': 1, '1': 2, '2': 3 };
9432
9433 function Foo() {}
9434 Foo.prototype = object;
9435
9436 assert.strictEqual(_.isEqual(args, object), true);
9437 assert.strictEqual(_.isEqual(object, args), true);
9438
9439 assert.strictEqual(_.isEqual(args, new Foo), false);
9440 assert.strictEqual(_.isEqual(new Foo, args), false);
9441 });
9442
9443 QUnit.test('should compare array buffers', function(assert) {
9444 assert.expect(2);
9445
9446 if (ArrayBuffer) {
9447 var buffer1 = new ArrayBuffer(4),
9448 buffer2 = new ArrayBuffer(8);
9449
9450 assert.strictEqual(_.isEqual(buffer1, buffer2), false);
9451
9452 buffer1 = new Int8Array([-1]).buffer;
9453 buffer2 = new Uint8Array([255]).buffer;
9454
9455 assert.strictEqual(_.isEqual(buffer1, buffer2), true);
9456 }
9457 else {
9458 skipAssert(assert, 2);
9459 }
9460 });
9461
9462 QUnit.test('should compare array views', function(assert) {
9463 assert.expect(2);
9464
9465 lodashStable.times(2, function(index) {
9466 var ns = index ? realm : root;
9467
9468 var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
9469 var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
9470 CtorA = ns[type] || function(n) { this.n = n; },
9471 CtorB = ns[otherType] || function(n) { this.n = n; },
9472 bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
9473 bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
9474 bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
9475
9476 return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
9477 });
9478
9479 var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9480
9481 var actual = lodashStable.map(pairs, function(pair) {
9482 return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9483 });
9484
9485 assert.deepEqual(actual, expected);
9486 });
9487 });
9488
9489 QUnit.test('should compare date objects', function(assert) {
9490 assert.expect(4);
9491
9492 var date = new Date(2012, 4, 23);
9493
9494 assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
9495 assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
9496 assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
9497 assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
9498 });
9499
9500 QUnit.test('should compare error objects', function(assert) {
9501 assert.expect(1);
9502
9503 var pairs = lodashStable.map([
9504 'Error',
9505 'EvalError',
9506 'RangeError',
9507 'ReferenceError',
9508 'SyntaxError',
9509 'TypeError',
9510 'URIError'
9511 ], function(type, index, errorTypes) {
9512 var otherType = errorTypes[++index % errorTypes.length],
9513 CtorA = root[type],
9514 CtorB = root[otherType];
9515
9516 return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
9517 });
9518
9519 var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
9520
9521 var actual = lodashStable.map(pairs, function(pair) {
9522 return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
9523 });
9524
9525 assert.deepEqual(actual, expected);
9526 });
9527
9528 QUnit.test('should compare functions', function(assert) {
9529 assert.expect(2);
9530
9531 function a() { return 1 + 2; }
9532 function b() { return 1 + 2; }
9533
9534 assert.strictEqual(_.isEqual(a, a), true);
9535 assert.strictEqual(_.isEqual(a, b), false);
9536 });
9537
9538 QUnit.test('should compare maps', function(assert) {
9539 assert.expect(8);
9540
9541 if (Map) {
9542 lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
9543 var map1 = maps[0],
9544 map2 = maps[1];
9545
9546 map1.set('a', 1);
9547 map2.set('b', 2);
9548 assert.strictEqual(_.isEqual(map1, map2), false);
9549
9550 map1.set('b', 2);
9551 map2.set('a', 1);
9552 assert.strictEqual(_.isEqual(map1, map2), true);
9553
9554 map1['delete']('a');
9555 map1.set('a', 1);
9556 assert.strictEqual(_.isEqual(map1, map2), true);
9557
9558 map2['delete']('a');
9559 assert.strictEqual(_.isEqual(map1, map2), false);
9560
9561 map1.clear();
9562 map2.clear();
9563 });
9564 }
9565 else {
9566 skipAssert(assert, 8);
9567 }
9568 });
9569
9570 QUnit.test('should compare maps with circular references', function(assert) {
9571 assert.expect(2);
9572
9573 if (Map) {
9574 var map1 = new Map,
9575 map2 = new Map;
9576
9577 map1.set('a', map1);
9578 map2.set('a', map2);
9579 assert.strictEqual(_.isEqual(map1, map2), true);
9580
9581 map1.set('b', 1);
9582 map2.set('b', 2);
9583 assert.strictEqual(_.isEqual(map1, map2), false);
9584 }
9585 else {
9586 skipAssert(assert, 2);
9587 }
9588 });
9589
9590 QUnit.test('should compare promises by reference', function(assert) {
9591 assert.expect(4);
9592
9593 if (promise) {
9594 lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
9595 var promise1 = promises[0],
9596 promise2 = promises[1];
9597
9598 assert.strictEqual(_.isEqual(promise1, promise2), false);
9599 assert.strictEqual(_.isEqual(promise1, promise1), true);
9600 });
9601 }
9602 else {
9603 skipAssert(assert, 4);
9604 }
9605 });
9606
9607 QUnit.test('should compare regexes', function(assert) {
9608 assert.expect(5);
9609
9610 assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
9611 assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
9612 assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
9613 assert.strictEqual(_.isEqual(/x/, /y/), false);
9614 assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
9615 });
9616
9617 QUnit.test('should compare sets', function(assert) {
9618 assert.expect(8);
9619
9620 if (Set) {
9621 lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
9622 var set1 = sets[0],
9623 set2 = sets[1];
9624
9625 set1.add(1);
9626 set2.add(2);
9627 assert.strictEqual(_.isEqual(set1, set2), false);
9628
9629 set1.add(2);
9630 set2.add(1);
9631 assert.strictEqual(_.isEqual(set1, set2), true);
9632
9633 set1['delete'](1);
9634 set1.add(1);
9635 assert.strictEqual(_.isEqual(set1, set2), true);
9636
9637 set2['delete'](1);
9638 assert.strictEqual(_.isEqual(set1, set2), false);
9639
9640 set1.clear();
9641 set2.clear();
9642 });
9643 }
9644 else {
9645 skipAssert(assert, 8);
9646 }
9647 });
9648
9649 QUnit.test('should compare sets with circular references', function(assert) {
9650 assert.expect(2);
9651
9652 if (Set) {
9653 var set1 = new Set,
9654 set2 = new Set;
9655
9656 set1.add(set1);
9657 set2.add(set2);
9658 assert.strictEqual(_.isEqual(set1, set2), true);
9659
9660 set1.add(1);
9661 set2.add(2);
9662 assert.strictEqual(_.isEqual(set1, set2), false);
9663 }
9664 else {
9665 skipAssert(assert, 2);
9666 }
9667 });
9668
9669 QUnit.test('should work as an iteratee for `_.every`', function(assert) {
9670 assert.expect(1);
9671
9672 var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
9673 assert.ok(actual);
9674 });
9675
9676 QUnit.test('should return `true` for like-objects from different documents', function(assert) {
9677 assert.expect(4);
9678
9679 if (realm.object) {
9680 assert.strictEqual(_.isEqual([1], realm.array), true);
9681 assert.strictEqual(_.isEqual([2], realm.array), false);
9682 assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
9683 assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
9684 }
9685 else {
9686 skipAssert(assert, 4);
9687 }
9688 });
9689
9690 QUnit.test('should not error on DOM elements', function(assert) {
9691 assert.expect(1);
9692
9693 if (document) {
9694 var element1 = document.createElement('div'),
9695 element2 = element1.cloneNode(true);
9696
9697 try {
9698 assert.strictEqual(_.isEqual(element1, element2), false);
9699 } catch (e) {
9700 assert.ok(false, e.message);
9701 }
9702 }
9703 else {
9704 skipAssert(assert);
9705 }
9706 });
9707
9708 QUnit.test('should compare wrapped values', function(assert) {
9709 assert.expect(32);
9710
9711 var stamp = +new Date;
9712
9713 var values = [
9714 [[1, 2], [1, 2], [1, 2, 3]],
9715 [true, true, false],
9716 [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
9717 [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
9718 [1, 1, 2],
9719 [NaN, NaN, Infinity],
9720 [/x/, /x/, /x/i],
9721 ['a', 'a', 'A']
9722 ];
9723
9724 lodashStable.each(values, function(vals) {
9725 if (!isNpm) {
9726 var wrapped1 = _(vals[0]),
9727 wrapped2 = _(vals[1]),
9728 actual = wrapped1.isEqual(wrapped2);
9729
9730 assert.strictEqual(actual, true);
9731 assert.strictEqual(_.isEqual(_(actual), _(true)), true);
9732
9733 wrapped1 = _(vals[0]);
9734 wrapped2 = _(vals[2]);
9735
9736 actual = wrapped1.isEqual(wrapped2);
9737 assert.strictEqual(actual, false);
9738 assert.strictEqual(_.isEqual(_(actual), _(false)), true);
9739 }
9740 else {
9741 skipAssert(assert, 4);
9742 }
9743 });
9744 });
9745
9746 QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
9747 assert.expect(4);
9748
9749 if (!isNpm) {
9750 var object1 = _({ 'a': 1, 'b': 2 }),
9751 object2 = { 'a': 1, 'b': 2 };
9752
9753 assert.strictEqual(object1.isEqual(object2), true);
9754 assert.strictEqual(_.isEqual(object1, object2), true);
9755
9756 object1 = _({ 'a': 1, 'b': 2 });
9757 object2 = { 'a': 1, 'b': 1 };
9758
9759 assert.strictEqual(object1.isEqual(object2), false);
9760 assert.strictEqual(_.isEqual(object1, object2), false);
9761 }
9762 else {
9763 skipAssert(assert, 4);
9764 }
9765 });
9766
9767 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
9768 assert.expect(1);
9769
9770 if (!isNpm) {
9771 assert.strictEqual(_('a').isEqual('a'), true);
9772 }
9773 else {
9774 skipAssert(assert);
9775 }
9776 });
9777
9778 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
9779 assert.expect(1);
9780
9781 if (!isNpm) {
9782 assert.ok(_('a').chain().isEqual('a') instanceof _);
9783 }
9784 else {
9785 skipAssert(assert);
9786 }
9787 });
9788 }());
9789
9790 /*--------------------------------------------------------------------------*/
9791
9792 QUnit.module('lodash.isEqualWith');
9793
9794 (function() {
9795 QUnit.test('should provide the correct `customizer` arguments', function(assert) {
9796 assert.expect(1);
9797
9798 var argsList = [],
9799 object1 = { 'a': [1, 2], 'b': null },
9800 object2 = { 'a': [1, 2], 'b': null };
9801
9802 object1.b = object2;
9803 object2.b = object1;
9804
9805 var expected = [
9806 [object1, object2],
9807 [object1.a, object2.a, 'a', object1, object2],
9808 [object1.a[0], object2.a[0], 0, object1.a, object2.a],
9809 [object1.a[1], object2.a[1], 1, object1.a, object2.a],
9810 [object1.b, object2.b, 'b', object1.b, object2.b],
9811 [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
9812 [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
9813 [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
9814 [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
9815 ];
9816
9817 _.isEqualWith(object1, object2, function(assert) {
9818 var length = arguments.length,
9819 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9820
9821 argsList.push(args);
9822 });
9823
9824 assert.deepEqual(argsList, expected);
9825 });
9826
9827 QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
9828 assert.expect(3);
9829
9830 assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
9831 assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
9832 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
9833 });
9834
9835 QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
9836 assert.expect(3);
9837
9838 var customizer = function(value) {
9839 return _.isString(value) || undefined;
9840 };
9841
9842 assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
9843 assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
9844 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
9845 });
9846
9847 QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
9848 assert.expect(3);
9849
9850 var customizer = function(value) {
9851 return _.isString(value) ? false : undefined;
9852 };
9853
9854 assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
9855 assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
9856 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
9857 });
9858
9859 QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
9860 assert.expect(2);
9861
9862 var actual = _.isEqualWith('a', 'b', alwaysC);
9863 assert.strictEqual(actual, true);
9864
9865 var values = _.without(falsey, undefined),
9866 expected = lodashStable.map(values, alwaysFalse);
9867
9868 actual = [];
9869 lodashStable.each(values, function(value) {
9870 actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
9871 });
9872
9873 assert.deepEqual(actual, expected);
9874 });
9875
9876 QUnit.test('should ensure `customizer` is a function', function(assert) {
9877 assert.expect(1);
9878
9879 var array = [1, 2, 3],
9880 eq = _.partial(_.isEqualWith, array),
9881 actual = lodashStable.map([array, [1, 0, 3]], eq);
9882
9883 assert.deepEqual(actual, [true, false]);
9884 });
9885
9886 QUnit.test('should call `customizer` for values maps and sets', function(assert) {
9887 assert.expect(2);
9888
9889 var value = { 'a': { 'b': 2 } };
9890
9891 if (Map) {
9892 var map1 = new Map;
9893 map1.set('a', value);
9894
9895 var map2 = new Map;
9896 map2.set('a', value);
9897 }
9898 if (Set) {
9899 var set1 = new Set;
9900 set1.add(value);
9901
9902 var set2 = new Set;
9903 set2.add(value);
9904 }
9905 lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
9906 if (pair[0]) {
9907 var argsList = [],
9908 array = _.toArray(pair[0]);
9909
9910 var expected = [
9911 [pair[0], pair[1]],
9912 [array[0], array[0], 0, array, array],
9913 [array[0][0], array[0][0], 0, array[0], array[0]],
9914 [array[0][1], array[0][1], 1, array[0], array[0]]
9915 ];
9916
9917 if (index) {
9918 expected.length = 2;
9919 }
9920 _.isEqualWith(pair[0], pair[1], function() {
9921 var length = arguments.length,
9922 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
9923
9924 argsList.push(args);
9925 });
9926
9927 assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
9928 }
9929 else {
9930 skipAssert(assert);
9931 }
9932 });
9933 });
9934 }());
9935
9936 /*--------------------------------------------------------------------------*/
9937
9938 QUnit.module('lodash.isError');
9939
9940 (function() {
9941 var args = arguments;
9942
9943 QUnit.test('should return `true` for error objects', function(assert) {
9944 assert.expect(1);
9945
9946 var expected = lodashStable.map(errors, alwaysTrue);
9947
9948 var actual = lodashStable.map(errors, function(error) {
9949 return _.isError(error) === true;
9950 });
9951
9952 assert.deepEqual(actual, expected);
9953 });
9954
9955 QUnit.test('should return `true` for subclassed values', function(assert) {
9956 assert.expect(1);
9957
9958 assert.strictEqual(_.isError(new CustomError('x')), true);
9959 });
9960
9961 QUnit.test('should return `false` for non error objects', function(assert) {
9962 assert.expect(12);
9963
9964 var expected = lodashStable.map(falsey, alwaysFalse);
9965
9966 var actual = lodashStable.map(falsey, function(value, index) {
9967 return index ? _.isError(value) : _.isError();
9968 });
9969
9970 assert.deepEqual(actual, expected);
9971
9972 assert.strictEqual(_.isError(args), false);
9973 assert.strictEqual(_.isError([1, 2, 3]), false);
9974 assert.strictEqual(_.isError(true), false);
9975 assert.strictEqual(_.isError(new Date), false);
9976 assert.strictEqual(_.isError(_), false);
9977 assert.strictEqual(_.isError(slice), false);
9978 assert.strictEqual(_.isError({ 'a': 1 }), false);
9979 assert.strictEqual(_.isError(1), false);
9980 assert.strictEqual(_.isError(/x/), false);
9981 assert.strictEqual(_.isError('a'), false);
9982 assert.strictEqual(_.isError(symbol), false);
9983 });
9984
9985 QUnit.test('should work with an error object from another realm', function(assert) {
9986 assert.expect(1);
9987
9988 if (realm.errors) {
9989 var expected = lodashStable.map(realm.errors, alwaysTrue);
9990
9991 var actual = lodashStable.map(realm.errors, function(error) {
9992 return _.isError(error) === true;
9993 });
9994
9995 assert.deepEqual(actual, expected);
9996 }
9997 else {
9998 skipAssert(assert);
9999 }
10000 });
10001 }(1, 2, 3));
10002
10003 /*--------------------------------------------------------------------------*/
10004
10005 QUnit.module('lodash.isFinite');
10006
10007 (function() {
10008 var args = arguments;
10009
10010 QUnit.test('should return `true` for finite values', function(assert) {
10011 assert.expect(1);
10012
10013 var values = [0, 1, 3.14, -1],
10014 expected = lodashStable.map(values, alwaysTrue),
10015 actual = lodashStable.map(values, _.isFinite);
10016
10017 assert.deepEqual(actual, expected);
10018 });
10019
10020 QUnit.test('should return `false` for non-finite values', function(assert) {
10021 assert.expect(1);
10022
10023 var values = [NaN, Infinity, -Infinity, Object(1)],
10024 expected = lodashStable.map(values, alwaysFalse),
10025 actual = lodashStable.map(values, _.isFinite);
10026
10027 assert.deepEqual(actual, expected);
10028 });
10029
10030 QUnit.test('should return `false` for non-numeric values', function(assert) {
10031 assert.expect(10);
10032
10033 var values = [undefined, [], true, '', ' ', '2px'],
10034 expected = lodashStable.map(values, alwaysFalse),
10035 actual = lodashStable.map(values, _.isFinite);
10036
10037 assert.deepEqual(actual, expected);
10038
10039 assert.strictEqual(_.isFinite(args), false);
10040 assert.strictEqual(_.isFinite([1, 2, 3]), false);
10041 assert.strictEqual(_.isFinite(true), false);
10042 assert.strictEqual(_.isFinite(new Date), false);
10043 assert.strictEqual(_.isFinite(new Error), false);
10044 assert.strictEqual(_.isFinite({ 'a': 1 }), false);
10045 assert.strictEqual(_.isFinite(/x/), false);
10046 assert.strictEqual(_.isFinite('a'), false);
10047 assert.strictEqual(_.isFinite(symbol), false);
10048 });
10049
10050 QUnit.test('should return `false` for numeric string values', function(assert) {
10051 assert.expect(1);
10052
10053 var values = ['2', '0', '08'],
10054 expected = lodashStable.map(values, alwaysFalse),
10055 actual = lodashStable.map(values, _.isFinite);
10056
10057 assert.deepEqual(actual, expected);
10058 });
10059 }(1, 2, 3));
10060
10061 /*--------------------------------------------------------------------------*/
10062
10063 QUnit.module('lodash.isFunction');
10064
10065 (function() {
10066 var args = arguments;
10067
10068 QUnit.test('should return `true` for functions', function(assert) {
10069 assert.expect(2);
10070
10071 assert.strictEqual(_.isFunction(_), true);
10072 assert.strictEqual(_.isFunction(slice), true);
10073 });
10074
10075 QUnit.test('should return `true` for generator functions', function(assert) {
10076 assert.expect(1);
10077
10078 assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
10079 });
10080
10081 QUnit.test('should return `true` for array view constructors', function(assert) {
10082 assert.expect(1);
10083
10084 var expected = lodashStable.map(arrayViews, function(type) {
10085 return objToString.call(root[type]) == funcTag;
10086 });
10087
10088 var actual = lodashStable.map(arrayViews, function(type) {
10089 return _.isFunction(root[type]);
10090 });
10091
10092 assert.deepEqual(actual, expected);
10093 });
10094
10095 QUnit.test('should return `false` for non-functions', function(assert) {
10096 assert.expect(12);
10097
10098 var expected = lodashStable.map(falsey, alwaysFalse);
10099
10100 var actual = lodashStable.map(falsey, function(value, index) {
10101 return index ? _.isFunction(value) : _.isFunction();
10102 });
10103
10104 assert.deepEqual(actual, expected);
10105
10106 assert.strictEqual(_.isFunction(args), false);
10107 assert.strictEqual(_.isFunction([1, 2, 3]), false);
10108 assert.strictEqual(_.isFunction(true), false);
10109 assert.strictEqual(_.isFunction(new Date), false);
10110 assert.strictEqual(_.isFunction(new Error), false);
10111 assert.strictEqual(_.isFunction({ 'a': 1 }), false);
10112 assert.strictEqual(_.isFunction(1), false);
10113 assert.strictEqual(_.isFunction(/x/), false);
10114 assert.strictEqual(_.isFunction('a'), false);
10115 assert.strictEqual(_.isFunction(symbol), false);
10116
10117 if (document) {
10118 assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
10119 } else {
10120 skipAssert(assert);
10121 }
10122 });
10123
10124 QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
10125 assert.expect(2);
10126
10127 // Trigger a Chakra JIT bug.
10128 // See https://github.com/jashkenas/underscore/issues/1621.
10129 lodashStable.each([body, xml], function(object) {
10130 if (object) {
10131 lodashStable.times(100, _.isFunction);
10132 assert.strictEqual(_.isFunction(object), false);
10133 }
10134 else {
10135 skipAssert(assert);
10136 }
10137 });
10138 });
10139
10140 QUnit.test('should work with a function from another realm', function(assert) {
10141 assert.expect(1);
10142
10143 if (realm.function) {
10144 assert.strictEqual(_.isFunction(realm.function), true);
10145 }
10146 else {
10147 skipAssert(assert);
10148 }
10149 });
10150 }(1, 2, 3));
10151
10152 /*--------------------------------------------------------------------------*/
10153
10154 QUnit.module('isInteger methods');
10155
10156 lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
10157 var args = arguments,
10158 func = _[methodName],
10159 isSafe = methodName == 'isSafeInteger';
10160
10161 QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
10162 assert.expect(2);
10163
10164 var values = [-1, 0, 1],
10165 expected = lodashStable.map(values, alwaysTrue);
10166
10167 var actual = lodashStable.map(values, function(value) {
10168 return func(value);
10169 });
10170
10171 assert.deepEqual(actual, expected);
10172 assert.strictEqual(func(MAX_INTEGER), !isSafe);
10173 });
10174
10175 QUnit.test('should return `false` for non-integer number values', function(assert) {
10176 assert.expect(1);
10177
10178 var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
10179 expected = lodashStable.map(values, alwaysFalse);
10180
10181 var actual = lodashStable.map(values, function(value) {
10182 return func(value);
10183 });
10184
10185 assert.deepEqual(actual, expected);
10186 });
10187
10188 QUnit.test('should return `false` for non-numeric values', function(assert) {
10189 assert.expect(10);
10190
10191 var expected = lodashStable.map(falsey, function(value) {
10192 return value === 0;
10193 });
10194
10195 var actual = lodashStable.map(falsey, function(value, index) {
10196 return index ? func(value) : func();
10197 });
10198
10199 assert.deepEqual(actual, expected);
10200
10201 assert.strictEqual(func(args), false);
10202 assert.strictEqual(func([1, 2, 3]), false);
10203 assert.strictEqual(func(true), false);
10204 assert.strictEqual(func(new Date), false);
10205 assert.strictEqual(func(new Error), false);
10206 assert.strictEqual(func({ 'a': 1 }), false);
10207 assert.strictEqual(func(/x/), false);
10208 assert.strictEqual(func('a'), false);
10209 assert.strictEqual(func(symbol), false);
10210 });
10211 });
10212
10213 /*--------------------------------------------------------------------------*/
10214
10215 QUnit.module('lodash.isLength');
10216
10217 (function() {
10218 QUnit.test('should return `true` for lengths', function(assert) {
10219 assert.expect(1);
10220
10221 var values = [0, 3, MAX_SAFE_INTEGER],
10222 expected = lodashStable.map(values, alwaysTrue),
10223 actual = lodashStable.map(values, _.isLength);
10224
10225 assert.deepEqual(actual, expected);
10226 });
10227
10228 QUnit.test('should return `false` for non-lengths', function(assert) {
10229 assert.expect(1);
10230
10231 var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
10232 expected = lodashStable.map(values, alwaysFalse),
10233 actual = lodashStable.map(values, _.isLength);
10234
10235 assert.deepEqual(actual, expected);
10236 });
10237 }());
10238
10239 /*--------------------------------------------------------------------------*/
10240
10241 QUnit.module('lodash.isMap');
10242
10243 (function() {
10244 var args = arguments;
10245
10246 QUnit.test('should return `true` for maps', function(assert) {
10247 assert.expect(1);
10248
10249 if (Map) {
10250 assert.strictEqual(_.isMap(map), true);
10251 }
10252 else {
10253 skipAssert(assert);
10254 }
10255 });
10256
10257 QUnit.test('should return `false` for non-maps', function(assert) {
10258 assert.expect(14);
10259
10260 var expected = lodashStable.map(falsey, alwaysFalse);
10261
10262 var actual = lodashStable.map(falsey, function(value, index) {
10263 return index ? _.isMap(value) : _.isMap();
10264 });
10265
10266 assert.deepEqual(actual, expected);
10267
10268 assert.strictEqual(_.isMap(args), false);
10269 assert.strictEqual(_.isMap([1, 2, 3]), false);
10270 assert.strictEqual(_.isMap(true), false);
10271 assert.strictEqual(_.isMap(new Date), false);
10272 assert.strictEqual(_.isMap(new Error), false);
10273 assert.strictEqual(_.isMap(_), false);
10274 assert.strictEqual(_.isMap(slice), false);
10275 assert.strictEqual(_.isMap({ 'a': 1 }), false);
10276 assert.strictEqual(_.isMap(1), false);
10277 assert.strictEqual(_.isMap(/x/), false);
10278 assert.strictEqual(_.isMap('a'), false);
10279 assert.strictEqual(_.isMap(symbol), false);
10280 assert.strictEqual(_.isMap(weakMap), false);
10281 });
10282
10283 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
10284 assert.expect(1);
10285
10286 var values = [false, true],
10287 expected = lodashStable.map(values, alwaysFalse);
10288
10289 var actual = lodashStable.map(values, function(value) {
10290 return _.isMap({ 'constructor': value });
10291 });
10292
10293 assert.deepEqual(actual, expected);
10294 });
10295
10296 QUnit.test('should work with maps from another realm', function(assert) {
10297 assert.expect(1);
10298
10299 if (realm.map) {
10300 assert.strictEqual(_.isMap(realm.map), true);
10301 }
10302 else {
10303 skipAssert(assert);
10304 }
10305 });
10306 }(1, 2, 3));
10307
10308 /*--------------------------------------------------------------------------*/
10309
10310 QUnit.module('lodash.isMatch');
10311
10312 (function() {
10313 QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
10314 assert.expect(5);
10315
10316 var object = { 'a': 1, 'b': 2, 'c': 3 };
10317 assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
10318 assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
10319 assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
10320 assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
10321
10322 object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
10323 assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
10324 });
10325
10326 QUnit.test('should match inherited string keyed `object` properties', function(assert) {
10327 assert.expect(1);
10328
10329 function Foo() {
10330 this.a = 1;
10331 }
10332 Foo.prototype.b = 2;
10333
10334 assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
10335 });
10336
10337 QUnit.test('should not match by inherited `source` properties', function(assert) {
10338 assert.expect(1);
10339
10340 function Foo() {
10341 this.a = 1;
10342 }
10343 Foo.prototype.b = 2;
10344
10345 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
10346 source = new Foo,
10347 expected = lodashStable.map(objects, alwaysTrue);
10348
10349 var actual = lodashStable.map(objects, function(object) {
10350 return _.isMatch(object, source);
10351 });
10352
10353 assert.deepEqual(actual, expected);
10354 });
10355
10356 QUnit.test('should compare a variety of `source` property values', function(assert) {
10357 assert.expect(2);
10358
10359 var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
10360 object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
10361
10362 assert.strictEqual(_.isMatch(object1, object1), true);
10363 assert.strictEqual(_.isMatch(object1, object2), false);
10364 });
10365
10366 QUnit.test('should match `-0` as `0`', function(assert) {
10367 assert.expect(2);
10368
10369 var object1 = { 'a': -0 },
10370 object2 = { 'a': 0 };
10371
10372 assert.strictEqual(_.isMatch(object1, object2), true);
10373 assert.strictEqual(_.isMatch(object2, object1), true);
10374 });
10375
10376 QUnit.test('should compare functions by reference', function(assert) {
10377 assert.expect(3);
10378
10379 var object1 = { 'a': lodashStable.noop },
10380 object2 = { 'a': noop },
10381 object3 = { 'a': {} };
10382
10383 assert.strictEqual(_.isMatch(object1, object1), true);
10384 assert.strictEqual(_.isMatch(object2, object1), false);
10385 assert.strictEqual(_.isMatch(object3, object1), false);
10386 });
10387
10388 QUnit.test('should work with a function for `object`', function(assert) {
10389 assert.expect(1);
10390
10391 function Foo() {}
10392 Foo.a = { 'b': 1, 'c': 2 };
10393
10394 assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 1 } }), true);
10395 });
10396
10397 QUnit.test('should work with a function for `source`', function(assert) {
10398 assert.expect(1);
10399
10400 function Foo() {}
10401 Foo.a = 1;
10402 Foo.b = function() {};
10403 Foo.c = 3;
10404
10405 var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
10406
10407 var actual = lodashStable.map(objects, function(object) {
10408 return _.isMatch(object, Foo);
10409 });
10410
10411 assert.deepEqual(actual, [false, true]);
10412 });
10413
10414 QUnit.test('should work with a non-plain `object`', function(assert) {
10415 assert.expect(1);
10416
10417 function Foo(object) { lodashStable.assign(this, object); }
10418
10419 var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) });
10420 assert.strictEqual(_.isMatch(object, { 'a': { 'b': 1 } }), true);
10421 });
10422
10423 QUnit.test('should partial match arrays', function(assert) {
10424 assert.expect(3);
10425
10426 var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
10427 source = { 'a': ['d'] },
10428 predicate = function(object) { return _.isMatch(object, source); },
10429 actual = lodashStable.filter(objects, predicate);
10430
10431 assert.deepEqual(actual, [objects[1]]);
10432
10433 source = { 'a': ['b', 'd'] };
10434 actual = lodashStable.filter(objects, predicate);
10435
10436 assert.deepEqual(actual, []);
10437
10438 source = { 'a': ['d', 'b'] };
10439 actual = lodashStable.filter(objects, predicate);
10440 assert.deepEqual(actual, []);
10441 });
10442
10443 QUnit.test('should partial match arrays of objects', function(assert) {
10444 assert.expect(1);
10445
10446 var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
10447
10448 var objects = [
10449 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
10450 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
10451 ];
10452
10453 var actual = lodashStable.filter(objects, function(object) {
10454 return _.isMatch(object, source);
10455 });
10456
10457 assert.deepEqual(actual, [objects[0]]);
10458 });
10459
10460 QUnit.test('should partial match maps', function(assert) {
10461 assert.expect(3);
10462
10463 if (Map) {
10464 var objects = [{ 'a': new Map }, { 'a': new Map }];
10465 objects[0].a.set('a', 1);
10466 objects[1].a.set('a', 1);
10467 objects[1].a.set('b', 2);
10468
10469 var map = new Map;
10470 map.set('b', 2);
10471
10472 var source = { 'a': map },
10473 predicate = function(object) { return _.isMatch(object, source); },
10474 actual = lodashStable.filter(objects, predicate);
10475
10476 assert.deepEqual(actual, [objects[1]]);
10477
10478 map['delete']('b');
10479 actual = lodashStable.filter(objects, predicate);
10480
10481 assert.deepEqual(actual, objects);
10482
10483 map.set('c', 3);
10484 actual = lodashStable.filter(objects, predicate);
10485
10486 assert.deepEqual(actual, []);
10487 }
10488 else {
10489 skipAssert(assert, 3);
10490 }
10491 });
10492
10493 QUnit.test('should partial match sets', function(assert) {
10494 assert.expect(3);
10495
10496 if (Set) {
10497 var objects = [{ 'a': new Set }, { 'a': new Set }];
10498 objects[0].a.add(1);
10499 objects[1].a.add(1);
10500 objects[1].a.add(2);
10501
10502 var set = new Set;
10503 set.add(2);
10504
10505 var source = { 'a': set },
10506 predicate = function(object) { return _.isMatch(object, source); },
10507 actual = lodashStable.filter(objects, predicate);
10508
10509 assert.deepEqual(actual, [objects[1]]);
10510
10511 set['delete'](2);
10512 actual = lodashStable.filter(objects, predicate);
10513
10514 assert.deepEqual(actual, objects);
10515
10516 set.add(3);
10517 actual = lodashStable.filter(objects, predicate);
10518
10519 assert.deepEqual(actual, []);
10520 }
10521 else {
10522 skipAssert(assert, 3);
10523 }
10524 });
10525
10526 QUnit.test('should match `undefined` values', function(assert) {
10527 assert.expect(3);
10528
10529 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
10530 source = { 'b': undefined },
10531 predicate = function(object) { return _.isMatch(object, source); },
10532 actual = lodashStable.map(objects, predicate),
10533 expected = [false, false, true];
10534
10535 assert.deepEqual(actual, expected);
10536
10537 source = { 'a': 1, 'b': undefined };
10538 actual = lodashStable.map(objects, predicate);
10539
10540 assert.deepEqual(actual, expected);
10541
10542 objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
10543 source = { 'a': { 'c': undefined } };
10544 actual = lodashStable.map(objects, predicate);
10545
10546 assert.deepEqual(actual, expected);
10547 });
10548
10549 QUnit.test('should match `undefined` values on primitives', function(assert) {
10550 assert.expect(3);
10551
10552 numberProto.a = 1;
10553 numberProto.b = undefined;
10554
10555 try {
10556 assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
10557 } catch (e) {
10558 assert.ok(false, e.message);
10559 }
10560 try {
10561 assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
10562 } catch (e) {
10563 assert.ok(false, e.message);
10564 }
10565 numberProto.a = { 'b': 1, 'c': undefined };
10566 try {
10567 assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
10568 } catch (e) {
10569 assert.ok(false, e.message);
10570 }
10571 delete numberProto.a;
10572 delete numberProto.b;
10573 });
10574
10575 QUnit.test('should return `false` when `object` is nullish', function(assert) {
10576 assert.expect(1);
10577
10578 var values = [null, undefined],
10579 expected = lodashStable.map(values, alwaysFalse),
10580 source = { 'a': 1 };
10581
10582 var actual = lodashStable.map(values, function(value) {
10583 try {
10584 return _.isMatch(value, source);
10585 } catch (e) {}
10586 });
10587
10588 assert.deepEqual(actual, expected);
10589 });
10590
10591 QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
10592 assert.expect(1);
10593
10594 var values = [null, undefined],
10595 expected = lodashStable.map(values, alwaysTrue),
10596 source = {};
10597
10598 var actual = lodashStable.map(values, function(value) {
10599 try {
10600 return _.isMatch(value, source);
10601 } catch (e) {}
10602 });
10603
10604 assert.deepEqual(actual, expected);
10605 });
10606
10607 QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
10608 assert.expect(1);
10609
10610 var object = { 'a': 1 },
10611 expected = lodashStable.map(empties, alwaysTrue);
10612
10613 var actual = lodashStable.map(empties, function(value) {
10614 return _.isMatch(object, value);
10615 });
10616
10617 assert.deepEqual(actual, expected);
10618 });
10619
10620 QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
10621 assert.expect(1);
10622
10623 var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
10624 source = { 'a': [], 'b': {} };
10625
10626 var actual = lodashStable.filter(objects, function(object) {
10627 return _.isMatch(object, source);
10628 });
10629
10630 assert.deepEqual(actual, objects);
10631 });
10632 }());
10633
10634 /*--------------------------------------------------------------------------*/
10635
10636 QUnit.module('lodash.isMatchWith');
10637
10638 (function() {
10639 QUnit.test('should provide the correct `customizer` arguments', function(assert) {
10640 assert.expect(1);
10641
10642 var argsList = [],
10643 object1 = { 'a': [1, 2], 'b': null },
10644 object2 = { 'a': [1, 2], 'b': null };
10645
10646 object1.b = object2;
10647 object2.b = object1;
10648
10649 var expected = [
10650 [object1.a, object2.a, 'a', object1, object2],
10651 [object1.a[0], object2.a[0], 0, object1.a, object2.a],
10652 [object1.a[1], object2.a[1], 1, object1.a, object2.a],
10653 [object1.b, object2.b, 'b', object1, object2],
10654 [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
10655 [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
10656 [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
10657 [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
10658 [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
10659 [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
10660 [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
10661 [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
10662 ];
10663
10664 _.isMatchWith(object1, object2, function(assert) {
10665 argsList.push(slice.call(arguments, 0, -1));
10666 });
10667
10668 assert.deepEqual(argsList, expected);
10669 });
10670
10671 QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
10672 assert.expect(1);
10673
10674 assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
10675 });
10676
10677 QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
10678 assert.expect(2);
10679
10680 var customizer = function(value) {
10681 return _.isString(value) || undefined;
10682 };
10683
10684 assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
10685 assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
10686 });
10687
10688 QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
10689 assert.expect(2);
10690
10691 var customizer = function(value) {
10692 return _.isString(value) ? false : undefined;
10693 };
10694
10695 assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
10696 assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
10697 });
10698
10699 QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
10700 assert.expect(2);
10701
10702 var object = { 'a': 1 },
10703 actual = _.isMatchWith(object, { 'a': 1 }, alwaysA);
10704
10705 assert.strictEqual(actual, true);
10706
10707 var expected = lodashStable.map(falsey, alwaysFalse);
10708
10709 actual = [];
10710 lodashStable.each(falsey, function(value) {
10711 actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
10712 });
10713
10714 assert.deepEqual(actual, expected);
10715 });
10716
10717 QUnit.test('should ensure `customizer` is a function', function(assert) {
10718 assert.expect(1);
10719
10720 var object = { 'a': 1 },
10721 matches = _.partial(_.isMatchWith, object),
10722 actual = lodashStable.map([object, { 'a': 2 }], matches);
10723
10724 assert.deepEqual(actual, [true, false]);
10725 });
10726
10727 QUnit.test('should call `customizer` for values maps and sets', function(assert) {
10728 assert.expect(2);
10729
10730 var value = { 'a': { 'b': 2 } };
10731
10732 if (Map) {
10733 var map1 = new Map;
10734 map1.set('a', value);
10735
10736 var map2 = new Map;
10737 map2.set('a', value);
10738 }
10739 if (Set) {
10740 var set1 = new Set;
10741 set1.add(value);
10742
10743 var set2 = new Set;
10744 set2.add(value);
10745 }
10746 lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
10747 if (pair[0]) {
10748 var argsList = [],
10749 array = _.toArray(pair[0]),
10750 object1 = { 'a': pair[0] },
10751 object2 = { 'a': pair[1] };
10752
10753 var expected = [
10754 [pair[0], pair[1], 'a', object1, object2],
10755 [array[0], array[0], 0, array, array],
10756 [array[0][0], array[0][0], 0, array[0], array[0]],
10757 [array[0][1], array[0][1], 1, array[0], array[0]]
10758 ];
10759
10760 if (index) {
10761 expected.length = 2;
10762 }
10763 _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
10764 argsList.push(slice.call(arguments, 0, -1));
10765 });
10766
10767 assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
10768 }
10769 else {
10770 skipAssert(assert);
10771 }
10772 });
10773 });
10774 }());
10775
10776 /*--------------------------------------------------------------------------*/
10777
10778 QUnit.module('lodash.isNaN');
10779
10780 (function() {
10781 var args = arguments;
10782
10783 QUnit.test('should return `true` for NaNs', function(assert) {
10784 assert.expect(2);
10785
10786 assert.strictEqual(_.isNaN(NaN), true);
10787 assert.strictEqual(_.isNaN(Object(NaN)), true);
10788 });
10789
10790 QUnit.test('should return `false` for non-NaNs', function(assert) {
10791 assert.expect(14);
10792
10793 var expected = lodashStable.map(falsey, function(value) {
10794 return value !== value;
10795 });
10796
10797 var actual = lodashStable.map(falsey, function(value, index) {
10798 return index ? _.isNaN(value) : _.isNaN();
10799 });
10800
10801 assert.deepEqual(actual, expected);
10802
10803 assert.strictEqual(_.isNaN(args), false);
10804 assert.strictEqual(_.isNaN([1, 2, 3]), false);
10805 assert.strictEqual(_.isNaN(true), false);
10806 assert.strictEqual(_.isNaN(new Date), false);
10807 assert.strictEqual(_.isNaN(new Error), false);
10808 assert.strictEqual(_.isNaN(_), false);
10809 assert.strictEqual(_.isNaN(slice), false);
10810 assert.strictEqual(_.isNaN({ 'a': 1 }), false);
10811 assert.strictEqual(_.isNaN(1), false);
10812 assert.strictEqual(_.isNaN(Object(1)), false);
10813 assert.strictEqual(_.isNaN(/x/), false);
10814 assert.strictEqual(_.isNaN('a'), false);
10815 assert.strictEqual(_.isNaN(symbol), false);
10816 });
10817
10818 QUnit.test('should work with `NaN` from another realm', function(assert) {
10819 assert.expect(1);
10820
10821 if (realm.object) {
10822 assert.strictEqual(_.isNaN(realm.nan), true);
10823 }
10824 else {
10825 skipAssert(assert);
10826 }
10827 });
10828 }(1, 2, 3));
10829
10830 /*--------------------------------------------------------------------------*/
10831
10832 QUnit.module('lodash.isNative');
10833
10834 (function() {
10835 var args = arguments;
10836
10837 QUnit.test('should return `true` for native methods', function(assert) {
10838 assert.expect(1);
10839
10840 var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
10841 expected = lodashStable.map(values, Boolean),
10842 actual = lodashStable.map(values, _.isNative);
10843
10844 assert.deepEqual(actual, expected);
10845 });
10846
10847 QUnit.test('should return `false` for non-native methods', function(assert) {
10848 assert.expect(12);
10849
10850 var expected = lodashStable.map(falsey, alwaysFalse);
10851
10852 var actual = lodashStable.map(falsey, function(value, index) {
10853 return index ? _.isNative(value) : _.isNative();
10854 });
10855
10856 assert.deepEqual(actual, expected);
10857
10858 assert.strictEqual(_.isNative(args), false);
10859 assert.strictEqual(_.isNative([1, 2, 3]), false);
10860 assert.strictEqual(_.isNative(true), false);
10861 assert.strictEqual(_.isNative(new Date), false);
10862 assert.strictEqual(_.isNative(new Error), false);
10863 assert.strictEqual(_.isNative(_), false);
10864 assert.strictEqual(_.isNative({ 'a': 1 }), false);
10865 assert.strictEqual(_.isNative(1), false);
10866 assert.strictEqual(_.isNative(/x/), false);
10867 assert.strictEqual(_.isNative('a'), false);
10868 assert.strictEqual(_.isNative(symbol), false);
10869 });
10870
10871 QUnit.test('should work with native functions from another realm', function(assert) {
10872 assert.expect(2);
10873
10874 if (realm.element) {
10875 assert.strictEqual(_.isNative(realm.element.cloneNode), true);
10876 }
10877 else {
10878 skipAssert(assert);
10879 }
10880 if (realm.object) {
10881 assert.strictEqual(_.isNative(realm.object.valueOf), true);
10882 }
10883 else {
10884 skipAssert(assert);
10885 }
10886 });
10887 }(1, 2, 3));
10888
10889 /*--------------------------------------------------------------------------*/
10890
10891 QUnit.module('lodash.isNil');
10892
10893 (function() {
10894 var args = arguments;
10895
10896 QUnit.test('should return `true` for nullish values', function(assert) {
10897 assert.expect(3);
10898
10899 assert.strictEqual(_.isNil(null), true);
10900 assert.strictEqual(_.isNil(), true);
10901 assert.strictEqual(_.isNil(undefined), true);
10902 });
10903
10904 QUnit.test('should return `false` for non-nullish values', function(assert) {
10905 assert.expect(13);
10906
10907 var expected = lodashStable.map(falsey, function(value) {
10908 return value == null;
10909 });
10910
10911 var actual = lodashStable.map(falsey, function(value, index) {
10912 return index ? _.isNil(value) : _.isNil();
10913 });
10914
10915 assert.deepEqual(actual, expected);
10916
10917 assert.strictEqual(_.isNil(args), false);
10918 assert.strictEqual(_.isNil([1, 2, 3]), false);
10919 assert.strictEqual(_.isNil(true), false);
10920 assert.strictEqual(_.isNil(new Date), false);
10921 assert.strictEqual(_.isNil(new Error), false);
10922 assert.strictEqual(_.isNil(_), false);
10923 assert.strictEqual(_.isNil(slice), false);
10924 assert.strictEqual(_.isNil({ 'a': 1 }), false);
10925 assert.strictEqual(_.isNil(1), false);
10926 assert.strictEqual(_.isNil(/x/), false);
10927 assert.strictEqual(_.isNil('a'), false);
10928
10929 if (Symbol) {
10930 assert.strictEqual(_.isNil(symbol), false);
10931 }
10932 else {
10933 skipAssert(assert);
10934 }
10935 });
10936
10937 QUnit.test('should work with nulls from another realm', function(assert) {
10938 assert.expect(2);
10939
10940 if (realm.object) {
10941 assert.strictEqual(_.isNil(realm.null), true);
10942 assert.strictEqual(_.isNil(realm.undefined), true);
10943 }
10944 else {
10945 skipAssert(assert, 2);
10946 }
10947 });
10948 }(1, 2, 3));
10949
10950 /*--------------------------------------------------------------------------*/
10951
10952 QUnit.module('lodash.isNull');
10953
10954 (function() {
10955 var args = arguments;
10956
10957 QUnit.test('should return `true` for `null` values', function(assert) {
10958 assert.expect(1);
10959
10960 assert.strictEqual(_.isNull(null), true);
10961 });
10962
10963 QUnit.test('should return `false` for non `null` values', function(assert) {
10964 assert.expect(13);
10965
10966 var expected = lodashStable.map(falsey, function(value) {
10967 return value === null;
10968 });
10969
10970 var actual = lodashStable.map(falsey, function(value, index) {
10971 return index ? _.isNull(value) : _.isNull();
10972 });
10973
10974 assert.deepEqual(actual, expected);
10975
10976 assert.strictEqual(_.isNull(args), false);
10977 assert.strictEqual(_.isNull([1, 2, 3]), false);
10978 assert.strictEqual(_.isNull(true), false);
10979 assert.strictEqual(_.isNull(new Date), false);
10980 assert.strictEqual(_.isNull(new Error), false);
10981 assert.strictEqual(_.isNull(_), false);
10982 assert.strictEqual(_.isNull(slice), false);
10983 assert.strictEqual(_.isNull({ 'a': 1 }), false);
10984 assert.strictEqual(_.isNull(1), false);
10985 assert.strictEqual(_.isNull(/x/), false);
10986 assert.strictEqual(_.isNull('a'), false);
10987 assert.strictEqual(_.isNull(symbol), false);
10988 });
10989
10990 QUnit.test('should work with nulls from another realm', function(assert) {
10991 assert.expect(1);
10992
10993 if (realm.object) {
10994 assert.strictEqual(_.isNull(realm.null), true);
10995 }
10996 else {
10997 skipAssert(assert);
10998 }
10999 });
11000 }(1, 2, 3));
11001
11002 /*--------------------------------------------------------------------------*/
11003
11004 QUnit.module('lodash.isNumber');
11005
11006 (function() {
11007 var args = arguments;
11008
11009 QUnit.test('should return `true` for numbers', function(assert) {
11010 assert.expect(3);
11011
11012 assert.strictEqual(_.isNumber(0), true);
11013 assert.strictEqual(_.isNumber(Object(0)), true);
11014 assert.strictEqual(_.isNumber(NaN), true);
11015 });
11016
11017 QUnit.test('should return `false` for non-numbers', function(assert) {
11018 assert.expect(12);
11019
11020 var expected = lodashStable.map(falsey, function(value) {
11021 return typeof value == 'number';
11022 });
11023
11024 var actual = lodashStable.map(falsey, function(value, index) {
11025 return index ? _.isNumber(value) : _.isNumber();
11026 });
11027
11028 assert.deepEqual(actual, expected);
11029
11030 assert.strictEqual(_.isNumber(args), false);
11031 assert.strictEqual(_.isNumber([1, 2, 3]), false);
11032 assert.strictEqual(_.isNumber(true), false);
11033 assert.strictEqual(_.isNumber(new Date), false);
11034 assert.strictEqual(_.isNumber(new Error), false);
11035 assert.strictEqual(_.isNumber(_), false);
11036 assert.strictEqual(_.isNumber(slice), false);
11037 assert.strictEqual(_.isNumber({ 'a': 1 }), false);
11038 assert.strictEqual(_.isNumber(/x/), false);
11039 assert.strictEqual(_.isNumber('a'), false);
11040 assert.strictEqual(_.isNumber(symbol), false);
11041 });
11042
11043 QUnit.test('should work with numbers from another realm', function(assert) {
11044 assert.expect(1);
11045
11046 if (realm.number) {
11047 assert.strictEqual(_.isNumber(realm.number), true);
11048 }
11049 else {
11050 skipAssert(assert);
11051 }
11052 });
11053
11054 QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
11055 assert.expect(1);
11056
11057 assert.strictEqual(_.isNumber(+'2'), true);
11058 });
11059 }(1, 2, 3));
11060
11061 /*--------------------------------------------------------------------------*/
11062
11063 QUnit.module('lodash.isObject');
11064
11065 (function() {
11066 var args = arguments;
11067
11068 QUnit.test('should return `true` for objects', function(assert) {
11069 assert.expect(13);
11070
11071 assert.strictEqual(_.isObject(args), true);
11072 assert.strictEqual(_.isObject([1, 2, 3]), true);
11073 assert.strictEqual(_.isObject(Object(false)), true);
11074 assert.strictEqual(_.isObject(new Date), true);
11075 assert.strictEqual(_.isObject(new Error), true);
11076 assert.strictEqual(_.isObject(_), true);
11077 assert.strictEqual(_.isObject(slice), true);
11078 assert.strictEqual(_.isObject({ 'a': 1 }), true);
11079 assert.strictEqual(_.isObject(Object(0)), true);
11080 assert.strictEqual(_.isObject(/x/), true);
11081 assert.strictEqual(_.isObject(Object('a')), true);
11082
11083 if (document) {
11084 assert.strictEqual(_.isObject(body), true);
11085 }
11086 else {
11087 skipAssert(assert);
11088 }
11089 if (Symbol) {
11090 assert.strictEqual(_.isObject(Object(symbol)), true);
11091 }
11092 else {
11093 skipAssert(assert);
11094 }
11095 });
11096
11097 QUnit.test('should return `false` for non-objects', function(assert) {
11098 assert.expect(1);
11099
11100 var values = falsey.concat(true, 1, 'a', symbol),
11101 expected = lodashStable.map(values, alwaysFalse);
11102
11103 var actual = lodashStable.map(values, function(value, index) {
11104 return index ? _.isObject(value) : _.isObject();
11105 });
11106
11107 assert.deepEqual(actual, expected);
11108 });
11109
11110 QUnit.test('should work with objects from another realm', function(assert) {
11111 assert.expect(8);
11112
11113 if (realm.element) {
11114 assert.strictEqual(_.isObject(realm.element), true);
11115 }
11116 else {
11117 skipAssert(assert);
11118 }
11119 if (realm.object) {
11120 assert.strictEqual(_.isObject(realm.boolean), true);
11121 assert.strictEqual(_.isObject(realm.date), true);
11122 assert.strictEqual(_.isObject(realm.function), true);
11123 assert.strictEqual(_.isObject(realm.number), true);
11124 assert.strictEqual(_.isObject(realm.object), true);
11125 assert.strictEqual(_.isObject(realm.regexp), true);
11126 assert.strictEqual(_.isObject(realm.string), true);
11127 }
11128 else {
11129 skipAssert(assert, 7);
11130 }
11131 });
11132
11133 QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
11134 assert.expect(1);
11135
11136 // Trigger a V8 JIT bug.
11137 // See https://code.google.com/p/v8/issues/detail?id=2291.
11138 var object = {};
11139
11140 // First, have a comparison statement.
11141 object == object;
11142
11143 // Then perform the check with `object`.
11144 _.isObject(object);
11145
11146 assert.strictEqual(_.isObject('a'), false);
11147 });
11148 }(1, 2, 3));
11149
11150 /*--------------------------------------------------------------------------*/
11151
11152 QUnit.module('lodash.isObjectLike');
11153
11154 (function() {
11155 var args = arguments;
11156
11157 QUnit.test('should return `true` for objects', function(assert) {
11158 assert.expect(9);
11159
11160 assert.strictEqual(_.isObjectLike(args), true);
11161 assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
11162 assert.strictEqual(_.isObjectLike(Object(false)), true);
11163 assert.strictEqual(_.isObjectLike(new Date), true);
11164 assert.strictEqual(_.isObjectLike(new Error), true);
11165 assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
11166 assert.strictEqual(_.isObjectLike(Object(0)), true);
11167 assert.strictEqual(_.isObjectLike(/x/), true);
11168 assert.strictEqual(_.isObjectLike(Object('a')), true);
11169 });
11170
11171 QUnit.test('should return `false` for non-objects', function(assert) {
11172 assert.expect(1);
11173
11174 var values = falsey.concat(true, _, slice, 1, 'a', symbol),
11175 expected = lodashStable.map(values, alwaysFalse);
11176
11177 var actual = lodashStable.map(values, function(value, index) {
11178 return index ? _.isObjectLike(value) : _.isObjectLike();
11179 });
11180
11181 assert.deepEqual(actual, expected);
11182 });
11183
11184 QUnit.test('should work with objects from another realm', function(assert) {
11185 assert.expect(6);
11186
11187 if (realm.object) {
11188 assert.strictEqual(_.isObjectLike(realm.boolean), true);
11189 assert.strictEqual(_.isObjectLike(realm.date), true);
11190 assert.strictEqual(_.isObjectLike(realm.number), true);
11191 assert.strictEqual(_.isObjectLike(realm.object), true);
11192 assert.strictEqual(_.isObjectLike(realm.regexp), true);
11193 assert.strictEqual(_.isObjectLike(realm.string), true);
11194 }
11195 else {
11196 skipAssert(assert, 6);
11197 }
11198 });
11199 }(1, 2, 3));
11200
11201 /*--------------------------------------------------------------------------*/
11202
11203 QUnit.module('lodash.isPlainObject');
11204
11205 (function() {
11206 var element = document && document.createElement('div');
11207
11208 QUnit.test('should detect plain objects', function(assert) {
11209 assert.expect(5);
11210
11211 function Foo(a) {
11212 this.a = 1;
11213 }
11214
11215 assert.strictEqual(_.isPlainObject({}), true);
11216 assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
11217 assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
11218 assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
11219 assert.strictEqual(_.isPlainObject(new Foo(1)), false);
11220 });
11221
11222 QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
11223 assert.expect(2);
11224
11225 if (create) {
11226 var object = create(null);
11227 assert.strictEqual(_.isPlainObject(object), true);
11228
11229 object.constructor = objectProto.constructor;
11230 assert.strictEqual(_.isPlainObject(object), true);
11231 }
11232 else {
11233 skipAssert(assert, 2);
11234 }
11235 });
11236
11237 QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
11238 assert.expect(2);
11239
11240 assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
11241
11242 if (element) {
11243 var valueOf = element.valueOf;
11244 element.valueOf = 0;
11245
11246 assert.strictEqual(_.isPlainObject(element), false);
11247 element.valueOf = valueOf;
11248 }
11249 else {
11250 skipAssert(assert);
11251 }
11252 });
11253
11254 QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
11255 assert.expect(1);
11256
11257 if (create) {
11258 var object = create({ 'a': 1 });
11259 assert.strictEqual(_.isPlainObject(object), false);
11260 }
11261 else {
11262 skipAssert(assert);
11263 }
11264 });
11265
11266 QUnit.test('should return `false` for DOM elements', function(assert) {
11267 assert.expect(1);
11268
11269 if (element) {
11270 assert.strictEqual(_.isPlainObject(element), false);
11271 } else {
11272 skipAssert(assert);
11273 }
11274 });
11275
11276 QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
11277 assert.expect(3);
11278
11279 assert.strictEqual(_.isPlainObject(arguments), false);
11280 assert.strictEqual(_.isPlainObject(Error), false);
11281 assert.strictEqual(_.isPlainObject(Math), false);
11282 });
11283
11284 QUnit.test('should return `false` for non-objects', function(assert) {
11285 assert.expect(4);
11286
11287 var expected = lodashStable.map(falsey, alwaysFalse);
11288
11289 var actual = lodashStable.map(falsey, function(value, index) {
11290 return index ? _.isPlainObject(value) : _.isPlainObject();
11291 });
11292
11293 assert.deepEqual(actual, expected);
11294
11295 assert.strictEqual(_.isPlainObject(true), false);
11296 assert.strictEqual(_.isPlainObject('a'), false);
11297 assert.strictEqual(_.isPlainObject(symbol), false);
11298 });
11299
11300 QUnit.test('should work with objects from another realm', function(assert) {
11301 assert.expect(1);
11302
11303 if (realm.object) {
11304 assert.strictEqual(_.isPlainObject(realm.object), true);
11305 }
11306 else {
11307 skipAssert(assert);
11308 }
11309 });
11310 }());
11311
11312 /*--------------------------------------------------------------------------*/
11313
11314 QUnit.module('lodash.isRegExp');
11315
11316 (function() {
11317 var args = arguments;
11318
11319 QUnit.test('should return `true` for regexes', function(assert) {
11320 assert.expect(2);
11321
11322 assert.strictEqual(_.isRegExp(/x/), true);
11323 assert.strictEqual(_.isRegExp(RegExp('x')), true);
11324 });
11325
11326 QUnit.test('should return `false` for non-regexes', function(assert) {
11327 assert.expect(12);
11328
11329 var expected = lodashStable.map(falsey, alwaysFalse);
11330
11331 var actual = lodashStable.map(falsey, function(value, index) {
11332 return index ? _.isRegExp(value) : _.isRegExp();
11333 });
11334
11335 assert.deepEqual(actual, expected);
11336
11337 assert.strictEqual(_.isRegExp(args), false);
11338 assert.strictEqual(_.isRegExp([1, 2, 3]), false);
11339 assert.strictEqual(_.isRegExp(true), false);
11340 assert.strictEqual(_.isRegExp(new Date), false);
11341 assert.strictEqual(_.isRegExp(new Error), false);
11342 assert.strictEqual(_.isRegExp(_), false);
11343 assert.strictEqual(_.isRegExp(slice), false);
11344 assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
11345 assert.strictEqual(_.isRegExp(1), false);
11346 assert.strictEqual(_.isRegExp('a'), false);
11347 assert.strictEqual(_.isRegExp(symbol), false);
11348 });
11349
11350 QUnit.test('should work with regexes from another realm', function(assert) {
11351 assert.expect(1);
11352
11353 if (realm.regexp) {
11354 assert.strictEqual(_.isRegExp(realm.regexp), true);
11355 }
11356 else {
11357 skipAssert(assert);
11358 }
11359 });
11360 }(1, 2, 3));
11361
11362 /*--------------------------------------------------------------------------*/
11363
11364 QUnit.module('lodash.isSet');
11365
11366 (function() {
11367 var args = arguments;
11368
11369 QUnit.test('should return `true` for sets', function(assert) {
11370 assert.expect(1);
11371
11372 if (Set) {
11373 assert.strictEqual(_.isSet(set), true);
11374 }
11375 else {
11376 skipAssert(assert);
11377 }
11378 });
11379
11380 QUnit.test('should return `false` for non-sets', function(assert) {
11381 assert.expect(14);
11382
11383 var expected = lodashStable.map(falsey, alwaysFalse);
11384
11385 var actual = lodashStable.map(falsey, function(value, index) {
11386 return index ? _.isSet(value) : _.isSet();
11387 });
11388
11389 assert.deepEqual(actual, expected);
11390
11391 assert.strictEqual(_.isSet(args), false);
11392 assert.strictEqual(_.isSet([1, 2, 3]), false);
11393 assert.strictEqual(_.isSet(true), false);
11394 assert.strictEqual(_.isSet(new Date), false);
11395 assert.strictEqual(_.isSet(new Error), false);
11396 assert.strictEqual(_.isSet(_), false);
11397 assert.strictEqual(_.isSet(slice), false);
11398 assert.strictEqual(_.isSet({ 'a': 1 }), false);
11399 assert.strictEqual(_.isSet(1), false);
11400 assert.strictEqual(_.isSet(/x/), false);
11401 assert.strictEqual(_.isSet('a'), false);
11402 assert.strictEqual(_.isSet(symbol), false);
11403 assert.strictEqual(_.isSet(weakSet), false);
11404 });
11405
11406 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11407 assert.expect(1);
11408
11409 var values = [false, true],
11410 expected = lodashStable.map(values, alwaysFalse);
11411
11412 var actual = lodashStable.map(values, function(value) {
11413 return _.isSet({ 'constructor': value });
11414 });
11415
11416 assert.deepEqual(actual, expected);
11417 });
11418
11419 QUnit.test('should work with weak sets from another realm', function(assert) {
11420 assert.expect(1);
11421
11422 if (realm.set) {
11423 assert.strictEqual(_.isSet(realm.set), true);
11424 }
11425 else {
11426 skipAssert(assert);
11427 }
11428 });
11429 }(1, 2, 3));
11430
11431 /*--------------------------------------------------------------------------*/
11432
11433 QUnit.module('lodash.isString');
11434
11435 (function() {
11436 var args = arguments;
11437
11438 QUnit.test('should return `true` for strings', function(assert) {
11439 assert.expect(2);
11440
11441 assert.strictEqual(_.isString('a'), true);
11442 assert.strictEqual(_.isString(Object('a')), true);
11443 });
11444
11445 QUnit.test('should return `false` for non-strings', function(assert) {
11446 assert.expect(12);
11447
11448 var expected = lodashStable.map(falsey, function(value) {
11449 return value === '';
11450 });
11451
11452 var actual = lodashStable.map(falsey, function(value, index) {
11453 return index ? _.isString(value) : _.isString();
11454 });
11455
11456 assert.deepEqual(actual, expected);
11457
11458 assert.strictEqual(_.isString(args), false);
11459 assert.strictEqual(_.isString([1, 2, 3]), false);
11460 assert.strictEqual(_.isString(true), false);
11461 assert.strictEqual(_.isString(new Date), false);
11462 assert.strictEqual(_.isString(new Error), false);
11463 assert.strictEqual(_.isString(_), false);
11464 assert.strictEqual(_.isString(slice), false);
11465 assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
11466 assert.strictEqual(_.isString(1), false);
11467 assert.strictEqual(_.isString(/x/), false);
11468 assert.strictEqual(_.isString(symbol), false);
11469 });
11470
11471 QUnit.test('should work with strings from another realm', function(assert) {
11472 assert.expect(1);
11473
11474 if (realm.string) {
11475 assert.strictEqual(_.isString(realm.string), true);
11476 }
11477 else {
11478 skipAssert(assert);
11479 }
11480 });
11481 }(1, 2, 3));
11482
11483 /*--------------------------------------------------------------------------*/
11484
11485 QUnit.module('lodash.isSymbol');
11486
11487 (function() {
11488 var args = arguments;
11489
11490 QUnit.test('should return `true` for symbols', function(assert) {
11491 assert.expect(2);
11492
11493 if (Symbol) {
11494 assert.strictEqual(_.isSymbol(symbol), true);
11495 assert.strictEqual(_.isSymbol(Object(symbol)), true);
11496 }
11497 else {
11498 skipAssert(assert, 2);
11499 }
11500 });
11501
11502 QUnit.test('should return `false` for non-symbols', function(assert) {
11503 assert.expect(12);
11504
11505 var expected = lodashStable.map(falsey, alwaysFalse);
11506
11507 var actual = lodashStable.map(falsey, function(value, index) {
11508 return index ? _.isSymbol(value) : _.isSymbol();
11509 });
11510
11511 assert.deepEqual(actual, expected);
11512
11513 assert.strictEqual(_.isSymbol(args), false);
11514 assert.strictEqual(_.isSymbol([1, 2, 3]), false);
11515 assert.strictEqual(_.isSymbol(true), false);
11516 assert.strictEqual(_.isSymbol(new Date), false);
11517 assert.strictEqual(_.isSymbol(new Error), false);
11518 assert.strictEqual(_.isSymbol(_), false);
11519 assert.strictEqual(_.isSymbol(slice), false);
11520 assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
11521 assert.strictEqual(_.isSymbol(1), false);
11522 assert.strictEqual(_.isSymbol(/x/), false);
11523 assert.strictEqual(_.isSymbol('a'), false);
11524 });
11525
11526 QUnit.test('should work with symbols from another realm', function(assert) {
11527 assert.expect(1);
11528
11529 if (Symbol && realm.symbol) {
11530 assert.strictEqual(_.isSymbol(realm.symbol), true);
11531 }
11532 else {
11533 skipAssert(assert);
11534 }
11535 });
11536 }(1, 2, 3));
11537
11538 /*--------------------------------------------------------------------------*/
11539
11540 QUnit.module('lodash.isTypedArray');
11541
11542 (function() {
11543 var args = arguments;
11544
11545 QUnit.test('should return `true` for typed arrays', function(assert) {
11546 assert.expect(1);
11547
11548 var expected = lodashStable.map(typedArrays, function(type) {
11549 return type in root;
11550 });
11551
11552 var actual = lodashStable.map(typedArrays, function(type) {
11553 var Ctor = root[type];
11554 return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
11555 });
11556
11557 assert.deepEqual(actual, expected);
11558 });
11559
11560 QUnit.test('should return `false` for non typed arrays', function(assert) {
11561 assert.expect(13);
11562
11563 var expected = lodashStable.map(falsey, alwaysFalse);
11564
11565 var actual = lodashStable.map(falsey, function(value, index) {
11566 return index ? _.isTypedArray(value) : _.isTypedArray();
11567 });
11568
11569 assert.deepEqual(actual, expected);
11570
11571 assert.strictEqual(_.isTypedArray(args), false);
11572 assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
11573 assert.strictEqual(_.isTypedArray(true), false);
11574 assert.strictEqual(_.isTypedArray(new Date), false);
11575 assert.strictEqual(_.isTypedArray(new Error), false);
11576 assert.strictEqual(_.isTypedArray(_), false);
11577 assert.strictEqual(_.isTypedArray(slice), false);
11578 assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
11579 assert.strictEqual(_.isTypedArray(1), false);
11580 assert.strictEqual(_.isTypedArray(/x/), false);
11581 assert.strictEqual(_.isTypedArray('a'), false);
11582 assert.strictEqual(_.isTypedArray(symbol), false);
11583 });
11584
11585 QUnit.test('should work with typed arrays from another realm', function(assert) {
11586 assert.expect(1);
11587
11588 if (realm.object) {
11589 var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
11590
11591 var expected = lodashStable.map(props, function(key) {
11592 return realm[key] !== undefined;
11593 });
11594
11595 var actual = lodashStable.map(props, function(key) {
11596 var value = realm[key];
11597 return value ? _.isTypedArray(value) : false;
11598 });
11599
11600 assert.deepEqual(actual, expected);
11601 }
11602 else {
11603 skipAssert(assert);
11604 }
11605 });
11606 }(1, 2, 3));
11607
11608 /*--------------------------------------------------------------------------*/
11609
11610 QUnit.module('lodash.isUndefined');
11611
11612 (function() {
11613 var args = arguments;
11614
11615 QUnit.test('should return `true` for `undefined` values', function(assert) {
11616 assert.expect(2);
11617
11618 assert.strictEqual(_.isUndefined(), true);
11619 assert.strictEqual(_.isUndefined(undefined), true);
11620 });
11621
11622 QUnit.test('should return `false` for non `undefined` values', function(assert) {
11623 assert.expect(13);
11624
11625 var expected = lodashStable.map(falsey, function(value) {
11626 return value === undefined;
11627 });
11628
11629 var actual = lodashStable.map(falsey, function(value, index) {
11630 return index ? _.isUndefined(value) : _.isUndefined();
11631 });
11632
11633 assert.deepEqual(actual, expected);
11634
11635 assert.strictEqual(_.isUndefined(args), false);
11636 assert.strictEqual(_.isUndefined([1, 2, 3]), false);
11637 assert.strictEqual(_.isUndefined(true), false);
11638 assert.strictEqual(_.isUndefined(new Date), false);
11639 assert.strictEqual(_.isUndefined(new Error), false);
11640 assert.strictEqual(_.isUndefined(_), false);
11641 assert.strictEqual(_.isUndefined(slice), false);
11642 assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
11643 assert.strictEqual(_.isUndefined(1), false);
11644 assert.strictEqual(_.isUndefined(/x/), false);
11645 assert.strictEqual(_.isUndefined('a'), false);
11646
11647 if (Symbol) {
11648 assert.strictEqual(_.isUndefined(symbol), false);
11649 }
11650 else {
11651 skipAssert(assert);
11652 }
11653 });
11654
11655 QUnit.test('should work with `undefined` from another realm', function(assert) {
11656 assert.expect(1);
11657
11658 if (realm.object) {
11659 assert.strictEqual(_.isUndefined(realm.undefined), true);
11660 }
11661 else {
11662 skipAssert(assert);
11663 }
11664 });
11665 }(1, 2, 3));
11666
11667 /*--------------------------------------------------------------------------*/
11668
11669 QUnit.module('lodash.isWeakMap');
11670
11671 (function() {
11672 var args = arguments;
11673
11674 QUnit.test('should return `true` for weak maps', function(assert) {
11675 assert.expect(1);
11676
11677 if (WeakMap) {
11678 assert.strictEqual(_.isWeakMap(weakMap), true);
11679 }
11680 else {
11681 skipAssert(assert);
11682 }
11683 });
11684
11685 QUnit.test('should return `false` for non weak maps', function(assert) {
11686 assert.expect(14);
11687
11688 var expected = lodashStable.map(falsey, alwaysFalse);
11689
11690 var actual = lodashStable.map(falsey, function(value, index) {
11691 return index ? _.isWeakMap(value) : _.isWeakMap();
11692 });
11693
11694 assert.deepEqual(actual, expected);
11695
11696 assert.strictEqual(_.isWeakMap(args), false);
11697 assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
11698 assert.strictEqual(_.isWeakMap(true), false);
11699 assert.strictEqual(_.isWeakMap(new Date), false);
11700 assert.strictEqual(_.isWeakMap(new Error), false);
11701 assert.strictEqual(_.isWeakMap(_), false);
11702 assert.strictEqual(_.isWeakMap(slice), false);
11703 assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
11704 assert.strictEqual(_.isWeakMap(map), false);
11705 assert.strictEqual(_.isWeakMap(1), false);
11706 assert.strictEqual(_.isWeakMap(/x/), false);
11707 assert.strictEqual(_.isWeakMap('a'), false);
11708 assert.strictEqual(_.isWeakMap(symbol), false);
11709 });
11710
11711 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
11712 assert.expect(1);
11713
11714 var values = [false, true],
11715 expected = lodashStable.map(values, alwaysFalse);
11716
11717 var actual = lodashStable.map(values, function(value) {
11718 return _.isWeakMap({ 'constructor': value });
11719 });
11720
11721 assert.deepEqual(actual, expected);
11722 });
11723
11724 QUnit.test('should work with weak maps from another realm', function(assert) {
11725 assert.expect(1);
11726
11727 if (realm.weakMap) {
11728 assert.strictEqual(_.isWeakMap(realm.weakMap), true);
11729 }
11730 else {
11731 skipAssert(assert);
11732 }
11733 });
11734 }(1, 2, 3));
11735
11736 /*--------------------------------------------------------------------------*/
11737
11738 QUnit.module('lodash.isWeakSet');
11739
11740 (function() {
11741 var args = arguments;
11742
11743 QUnit.test('should return `true` for weak sets', function(assert) {
11744 assert.expect(1);
11745
11746 if (WeakSet) {
11747 assert.strictEqual(_.isWeakSet(weakSet), true);
11748 }
11749 else {
11750 skipAssert(assert);
11751 }
11752 });
11753
11754 QUnit.test('should return `false` for non weak sets', function(assert) {
11755 assert.expect(14);
11756
11757 var expected = lodashStable.map(falsey, alwaysFalse);
11758
11759 var actual = lodashStable.map(falsey, function(value, index) {
11760 return index ? _.isWeakSet(value) : _.isWeakSet();
11761 });
11762
11763 assert.deepEqual(actual, expected);
11764
11765 assert.strictEqual(_.isWeakSet(args), false);
11766 assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
11767 assert.strictEqual(_.isWeakSet(true), false);
11768 assert.strictEqual(_.isWeakSet(new Date), false);
11769 assert.strictEqual(_.isWeakSet(new Error), false);
11770 assert.strictEqual(_.isWeakSet(_), false);
11771 assert.strictEqual(_.isWeakSet(slice), false);
11772 assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
11773 assert.strictEqual(_.isWeakSet(1), false);
11774 assert.strictEqual(_.isWeakSet(/x/), false);
11775 assert.strictEqual(_.isWeakSet('a'), false);
11776 assert.strictEqual(_.isWeakSet(set), false);
11777 assert.strictEqual(_.isWeakSet(symbol), false);
11778 });
11779
11780 QUnit.test('should work with weak sets from another realm', function(assert) {
11781 assert.expect(1);
11782
11783 if (realm.weakSet) {
11784 assert.strictEqual(_.isWeakSet(realm.weakSet), true);
11785 }
11786 else {
11787 skipAssert(assert);
11788 }
11789 });
11790 }(1, 2, 3));
11791
11792 /*--------------------------------------------------------------------------*/
11793
11794 QUnit.module('isType checks');
11795
11796 (function() {
11797 QUnit.test('should return `false` for subclassed values', function(assert) {
11798 assert.expect(7);
11799
11800 var funcs = [
11801 'isArray', 'isBoolean', 'isDate', 'isFunction',
11802 'isNumber', 'isRegExp', 'isString'
11803 ];
11804
11805 lodashStable.each(funcs, function(methodName) {
11806 function Foo() {}
11807 Foo.prototype = root[methodName.slice(2)].prototype;
11808
11809 var object = new Foo;
11810 if (objToString.call(object) == objectTag) {
11811 assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
11812 }
11813 else {
11814 skipAssert(assert);
11815 }
11816 });
11817 });
11818
11819 QUnit.test('should not error on host objects (test in IE)', function(assert) {
11820 assert.expect(26);
11821
11822 var funcs = [
11823 'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
11824 'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
11825 'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
11826 'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
11827 'isUndefined', 'isWeakMap', 'isWeakSet'
11828 ];
11829
11830 lodashStable.each(funcs, function(methodName) {
11831 if (xml) {
11832 var pass = true;
11833
11834 try {
11835 _[methodName](xml);
11836 } catch (e) {
11837 pass = false;
11838 }
11839 assert.ok(pass, '`_.' + methodName + '` should not error');
11840 }
11841 else {
11842 skipAssert(assert);
11843 }
11844 });
11845 });
11846 }());
11847
11848 /*--------------------------------------------------------------------------*/
11849
11850 QUnit.module('lodash.iteratee');
11851
11852 (function() {
11853 QUnit.test('should provide arguments to `func`', function(assert) {
11854 assert.expect(1);
11855
11856 var fn = function() { return slice.call(arguments); },
11857 iteratee = _.iteratee(fn),
11858 actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
11859
11860 assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
11861 });
11862
11863 QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
11864 assert.expect(1);
11865
11866 var object = {},
11867 values = [, null, undefined],
11868 expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
11869
11870 var actual = lodashStable.map(values, function(value, index) {
11871 var identity = index ? _.iteratee(value) : _.iteratee();
11872 return [!isNpm && identity, identity(object)];
11873 });
11874
11875 assert.deepEqual(actual, expected);
11876 });
11877
11878 QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
11879 assert.expect(2);
11880
11881 var matches = _.iteratee({ 'a': 1, 'b': 2 });
11882 assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
11883 assert.strictEqual(matches({ 'b': 2 }), false);
11884 });
11885
11886 QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
11887 assert.expect(9);
11888
11889 var sources = [
11890 { 'a': { 'b': 2, 'c': 3 } },
11891 { 'a': 1, 'b': 2 },
11892 { 'a': 1 }
11893 ];
11894
11895 lodashStable.each(sources, function(source, index) {
11896 var object = lodashStable.cloneDeep(source),
11897 matches = _.iteratee(source);
11898
11899 assert.strictEqual(matches(object), true);
11900
11901 if (index) {
11902 source.a = 2;
11903 source.b = 1;
11904 source.c = 3;
11905 } else {
11906 source.a.b = 1;
11907 source.a.c = 2;
11908 source.a.d = 3;
11909 }
11910 assert.strictEqual(matches(object), true);
11911 assert.strictEqual(matches(source), false);
11912 });
11913 });
11914
11915 QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
11916 assert.expect(3);
11917
11918 var array = ['a', undefined],
11919 matches = _.iteratee([0, 'a']);
11920
11921 assert.strictEqual(matches(array), true);
11922
11923 matches = _.iteratee(['0', 'a']);
11924 assert.strictEqual(matches(array), true);
11925
11926 matches = _.iteratee([1, undefined]);
11927 assert.strictEqual(matches(array), true);
11928 });
11929
11930 QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
11931 assert.expect(1);
11932
11933 var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
11934 matches = _.iteratee(['a.b', { 'c': 1 }]);
11935
11936 assert.strictEqual(matches(object), true);
11937 });
11938
11939 QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
11940 assert.expect(9);
11941
11942 var sources = [
11943 { 'a': { 'b': 2, 'c': 3 } },
11944 { 'a': 1, 'b': 2 },
11945 { 'a': 1 }
11946 ];
11947
11948 lodashStable.each(sources, function(source, index) {
11949 var object = { 'a': lodashStable.cloneDeep(source) },
11950 matches = _.iteratee(['a', source]);
11951
11952 assert.strictEqual(matches(object), true);
11953
11954 if (index) {
11955 source.a = 2;
11956 source.b = 1;
11957 source.c = 3;
11958 } else {
11959 source.a.b = 1;
11960 source.a.c = 2;
11961 source.a.d = 3;
11962 }
11963 assert.strictEqual(matches(object), true);
11964 assert.strictEqual(matches({ 'a': source }), false);
11965 });
11966 });
11967
11968 QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
11969 assert.expect(2);
11970
11971 var array = ['a'],
11972 prop = _.iteratee(0);
11973
11974 assert.strictEqual(prop(array), 'a');
11975
11976 prop = _.iteratee('0');
11977 assert.strictEqual(prop(array), 'a');
11978 });
11979
11980 QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
11981 assert.expect(1);
11982
11983 var object = { 'a': { 'b': 2 } },
11984 prop = _.iteratee('a.b');
11985
11986 assert.strictEqual(prop(object), 2);
11987 });
11988
11989 QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
11990 assert.expect(2);
11991
11992 var fn = function() {
11993 var result = [this.a];
11994 push.apply(result, arguments);
11995 return result;
11996 };
11997
11998 var expected = [1, 2, 3],
11999 object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
12000
12001 assert.deepEqual(object.iteratee(3), expected);
12002
12003 object.iteratee = _.iteratee(_.partialRight(fn, 3));
12004 assert.deepEqual(object.iteratee(2), expected);
12005 });
12006
12007 QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
12008 assert.expect(1);
12009
12010 var iteratee = _.iteratee;
12011 delete _.iteratee;
12012
12013 assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
12014
12015 _.iteratee = iteratee;
12016 });
12017
12018 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12019 assert.expect(1);
12020
12021 var fn = function() { return this instanceof Number; },
12022 array = [fn, fn, fn],
12023 iteratees = lodashStable.map(array, _.iteratee),
12024 expected = lodashStable.map(array, alwaysFalse);
12025
12026 var actual = lodashStable.map(iteratees, function(iteratee) {
12027 return iteratee();
12028 });
12029
12030 assert.deepEqual(actual, expected);
12031 });
12032 }());
12033
12034 /*--------------------------------------------------------------------------*/
12035
12036 QUnit.module('custom `_.iteratee` methods');
12037
12038 (function() {
12039 var array = ['one', 'two', 'three'],
12040 getPropA = _.partial(_.property, 'a'),
12041 getPropB = _.partial(_.property, 'b'),
12042 getLength = _.partial(_.property, 'length'),
12043 iteratee = _.iteratee;
12044
12045 var getSum = function() {
12046 return function(result, object) {
12047 return result + object.a;
12048 };
12049 };
12050
12051 var objects = [
12052 { 'a': 0, 'b': 0 },
12053 { 'a': 1, 'b': 0 },
12054 { 'a': 1, 'b': 1 }
12055 ];
12056
12057 QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
12058 assert.expect(1);
12059
12060 if (!isModularize) {
12061 _.iteratee = getLength;
12062 assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
12063 _.iteratee = iteratee;
12064 }
12065 else {
12066 skipAssert(assert);
12067 }
12068 });
12069
12070 QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
12071 assert.expect(1);
12072
12073 if (!isModularize) {
12074 _.iteratee = getPropA;
12075 assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
12076 _.iteratee = iteratee;
12077 }
12078 else {
12079 skipAssert(assert);
12080 }
12081 });
12082
12083 QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
12084 assert.expect(1);
12085
12086 if (!isModularize) {
12087 _.iteratee = getPropB;
12088 assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
12089 _.iteratee = iteratee;
12090 }
12091 else {
12092 skipAssert(assert);
12093 }
12094 });
12095
12096 QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
12097 assert.expect(1);
12098
12099 if (!isModularize) {
12100 _.iteratee = getPropB;
12101 assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
12102 _.iteratee = iteratee;
12103 }
12104 else {
12105 skipAssert(assert);
12106 }
12107 });
12108
12109 QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
12110 assert.expect(1);
12111
12112 if (!isModularize) {
12113 _.iteratee = getPropA;
12114 assert.strictEqual(_.every(objects.slice(1)), true);
12115 _.iteratee = iteratee;
12116 }
12117 else {
12118 skipAssert(assert);
12119 }
12120 });
12121
12122 QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
12123 assert.expect(1);
12124
12125 if (!isModularize) {
12126 var objects = [{ 'a': 0 }, { 'a': 1 }];
12127
12128 _.iteratee = getPropA;
12129 assert.deepEqual(_.filter(objects), [objects[1]]);
12130 _.iteratee = iteratee;
12131 }
12132 else {
12133 skipAssert(assert);
12134 }
12135 });
12136
12137 QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
12138 assert.expect(1);
12139
12140 if (!isModularize) {
12141 _.iteratee = getPropA;
12142 assert.strictEqual(_.find(objects), objects[1]);
12143 _.iteratee = iteratee;
12144 }
12145 else {
12146 skipAssert(assert);
12147 }
12148 });
12149
12150 QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
12151 assert.expect(1);
12152
12153 if (!isModularize) {
12154 _.iteratee = getPropA;
12155 assert.strictEqual(_.findIndex(objects), 1);
12156 _.iteratee = iteratee;
12157 }
12158 else {
12159 skipAssert(assert);
12160 }
12161 });
12162
12163 QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
12164 assert.expect(1);
12165
12166 if (!isModularize) {
12167 _.iteratee = getPropA;
12168 assert.strictEqual(_.findLast(objects), objects[2]);
12169 _.iteratee = iteratee;
12170 }
12171 else {
12172 skipAssert(assert);
12173 }
12174 });
12175
12176 QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
12177 assert.expect(1);
12178
12179 if (!isModularize) {
12180 _.iteratee = getPropA;
12181 assert.strictEqual(_.findLastIndex(objects), 2);
12182 _.iteratee = iteratee;
12183 }
12184 else {
12185 skipAssert(assert);
12186 }
12187 });
12188
12189 QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
12190 assert.expect(1);
12191
12192 if (!isModularize) {
12193 _.iteratee = getPropB;
12194 assert.strictEqual(_.findKey(objects), '2');
12195 _.iteratee = iteratee;
12196 }
12197 else {
12198 skipAssert(assert);
12199 }
12200 });
12201
12202 QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
12203 assert.expect(1);
12204
12205 if (!isModularize) {
12206 _.iteratee = getPropB;
12207 assert.strictEqual(_.findLastKey(objects), '2');
12208 _.iteratee = iteratee;
12209 }
12210 else {
12211 skipAssert(assert);
12212 }
12213 });
12214
12215 QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
12216 assert.expect(1);
12217
12218 if (!isModularize) {
12219 _.iteratee = getLength;
12220 assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
12221 _.iteratee = iteratee;
12222 }
12223 else {
12224 skipAssert(assert);
12225 }
12226 });
12227
12228 QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
12229 assert.expect(1);
12230
12231 if (!isModularize) {
12232 _.iteratee = getPropA;
12233 assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
12234 _.iteratee = iteratee;
12235 }
12236 else {
12237 skipAssert(assert);
12238 }
12239 });
12240
12241 QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
12242 assert.expect(1);
12243
12244 if (!isModularize) {
12245 _.iteratee = getLength;
12246 assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
12247 _.iteratee = iteratee;
12248 }
12249 else {
12250 skipAssert(assert);
12251 }
12252 });
12253
12254 QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
12255 assert.expect(1);
12256
12257 if (!isModularize) {
12258 _.iteratee = getPropA;
12259 assert.deepEqual(_.map(objects), [0, 1, 1]);
12260 _.iteratee = iteratee;
12261 }
12262 else {
12263 skipAssert(assert);
12264 }
12265 });
12266
12267 QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
12268 assert.expect(1);
12269
12270 if (!isModularize) {
12271 _.iteratee = getPropB;
12272 assert.deepEqual(_.mapKeys({ 'a': { 'b': 1 } }), { '1': { 'b': 1 } });
12273 _.iteratee = iteratee;
12274 }
12275 else {
12276 skipAssert(assert);
12277 }
12278 });
12279
12280 QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
12281 assert.expect(1);
12282
12283 if (!isModularize) {
12284 _.iteratee = getPropB;
12285 assert.deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 });
12286 _.iteratee = iteratee;
12287 }
12288 else {
12289 skipAssert(assert);
12290 }
12291 });
12292
12293 QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
12294 assert.expect(1);
12295
12296 if (!isModularize) {
12297 _.iteratee = getPropB;
12298 assert.deepEqual(_.maxBy(objects), objects[2]);
12299 _.iteratee = iteratee;
12300 }
12301 else {
12302 skipAssert(assert);
12303 }
12304 });
12305
12306 QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
12307 assert.expect(1);
12308
12309 if (!isModularize) {
12310 _.iteratee = getPropA;
12311 assert.strictEqual(_.meanBy(objects), 2 / 3);
12312 _.iteratee = iteratee;
12313 }
12314 else {
12315 skipAssert(assert);
12316 }
12317 });
12318
12319 QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
12320 assert.expect(1);
12321
12322 if (!isModularize) {
12323 _.iteratee = getPropB;
12324 assert.deepEqual(_.minBy(objects), objects[0]);
12325 _.iteratee = iteratee;
12326 }
12327 else {
12328 skipAssert(assert);
12329 }
12330 });
12331
12332 QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
12333 assert.expect(1);
12334
12335 if (!isModularize) {
12336 var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
12337
12338 _.iteratee = getPropA;
12339 assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
12340 _.iteratee = iteratee;
12341 }
12342 else {
12343 skipAssert(assert);
12344 }
12345 });
12346
12347 QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
12348 assert.expect(1);
12349
12350 if (!isModularize) {
12351 _.iteratee = getPropA;
12352 assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
12353 _.iteratee = iteratee;
12354 }
12355 else {
12356 skipAssert(assert);
12357 }
12358 });
12359
12360 QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
12361 assert.expect(1);
12362
12363 if (!isModularize) {
12364 _.iteratee = getSum;
12365 assert.strictEqual(_.reduce(objects, undefined, 0), 2);
12366 _.iteratee = iteratee;
12367 }
12368 else {
12369 skipAssert(assert);
12370 }
12371 });
12372
12373 QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
12374 assert.expect(1);
12375
12376 if (!isModularize) {
12377 _.iteratee = getSum;
12378 assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
12379 _.iteratee = iteratee;
12380 }
12381 else {
12382 skipAssert(assert);
12383 }
12384 });
12385
12386 QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
12387 assert.expect(1);
12388
12389 if (!isModularize) {
12390 var objects = [{ 'a': 0 }, { 'a': 1 }];
12391
12392 _.iteratee = getPropA;
12393 assert.deepEqual(_.reject(objects), [objects[0]]);
12394 _.iteratee = iteratee;
12395 }
12396 else {
12397 skipAssert(assert);
12398 }
12399 });
12400
12401 QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
12402 assert.expect(1);
12403
12404 if (!isModularize) {
12405 var objects = [{ 'a': 0 }, { 'a': 1 }];
12406
12407 _.iteratee = getPropA;
12408 _.remove(objects);
12409 assert.deepEqual(objects, [{ 'a': 0 }]);
12410 _.iteratee = iteratee;
12411 }
12412 else {
12413 skipAssert(assert);
12414 }
12415 });
12416
12417 QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
12418 assert.expect(1);
12419
12420 if (!isModularize) {
12421 _.iteratee = getPropB;
12422 assert.strictEqual(_.some(objects), true);
12423 _.iteratee = iteratee;
12424 }
12425 else {
12426 skipAssert(assert);
12427 }
12428 });
12429
12430 QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
12431 assert.expect(1);
12432
12433 if (!isModularize) {
12434 _.iteratee = getPropA;
12435 assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
12436 _.iteratee = iteratee;
12437 }
12438 else {
12439 skipAssert(assert);
12440 }
12441 });
12442
12443 QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
12444 assert.expect(1);
12445
12446 if (!isModularize) {
12447 var objects = [{ 'a': 30 }, { 'a': 50 }];
12448
12449 _.iteratee = getPropA;
12450 assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
12451 _.iteratee = iteratee;
12452 }
12453 else {
12454 skipAssert(assert);
12455 }
12456 });
12457
12458 QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
12459 assert.expect(1);
12460
12461 if (!isModularize) {
12462 var objects = [{ 'a': 30 }, { 'a': 50 }];
12463
12464 _.iteratee = getPropA;
12465 assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
12466 _.iteratee = iteratee;
12467 }
12468 else {
12469 skipAssert(assert);
12470 }
12471 });
12472
12473 QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
12474 assert.expect(1);
12475
12476 if (!isModularize) {
12477 _.iteratee = getPropB;
12478 assert.strictEqual(_.sumBy(objects), 1);
12479 _.iteratee = iteratee;
12480 }
12481 else {
12482 skipAssert(assert);
12483 }
12484 });
12485
12486 QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
12487 assert.expect(1);
12488
12489 if (!isModularize) {
12490 _.iteratee = getPropB;
12491 assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
12492 _.iteratee = iteratee;
12493 }
12494 else {
12495 skipAssert(assert);
12496 }
12497 });
12498
12499 QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
12500 assert.expect(1);
12501
12502 if (!isModularize) {
12503 _.iteratee = getPropB;
12504 assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
12505 _.iteratee = iteratee;
12506 }
12507 else {
12508 skipAssert(assert);
12509 }
12510 });
12511
12512 QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
12513 assert.expect(1);
12514
12515 if (!isModularize) {
12516 _.iteratee = function() {
12517 return function(result, object) {
12518 result.sum += object.a;
12519 };
12520 };
12521
12522 assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
12523 _.iteratee = iteratee;
12524 }
12525 else {
12526 skipAssert(assert);
12527 }
12528 });
12529
12530 QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
12531 assert.expect(1);
12532
12533 if (!isModularize) {
12534 _.iteratee = getPropB;
12535 assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
12536 _.iteratee = iteratee;
12537 }
12538 else {
12539 skipAssert(assert);
12540 }
12541 });
12542
12543 QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
12544 assert.expect(1);
12545
12546 if (!isModularize) {
12547 _.iteratee = getPropB;
12548 assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
12549 _.iteratee = iteratee;
12550 }
12551 else {
12552 skipAssert(assert);
12553 }
12554 });
12555
12556 QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
12557 assert.expect(1);
12558
12559 if (!isModularize) {
12560 _.iteratee = getPropA;
12561 assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
12562 _.iteratee = iteratee;
12563 }
12564 else {
12565 skipAssert(assert);
12566 }
12567 });
12568 }());
12569
12570 /*--------------------------------------------------------------------------*/
12571
12572 QUnit.module('lodash.join');
12573
12574 (function() {
12575 var array = ['a', 'b', 'c'];
12576
12577 QUnit.test('should return join all array elements into a string', function(assert) {
12578 assert.expect(1);
12579
12580 assert.strictEqual(_.join(array, '~'), 'a~b~c');
12581 });
12582
12583 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12584 assert.expect(2);
12585
12586 if (!isNpm) {
12587 var wrapped = _(array);
12588 assert.strictEqual(wrapped.join('~'), 'a~b~c');
12589 assert.strictEqual(wrapped.value(), array);
12590 }
12591 else {
12592 skipAssert(assert, 2);
12593 }
12594 });
12595
12596 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12597 assert.expect(1);
12598
12599 if (!isNpm) {
12600 assert.ok(_(array).chain().join('~') instanceof _);
12601 }
12602 else {
12603 skipAssert(assert);
12604 }
12605 });
12606 }());
12607
12608 /*--------------------------------------------------------------------------*/
12609
12610 QUnit.module('lodash.keyBy');
12611
12612 (function() {
12613 var array = [
12614 { 'dir': 'left', 'code': 97 },
12615 { 'dir': 'right', 'code': 100 }
12616 ];
12617
12618 QUnit.test('should transform keys by `iteratee`', function(assert) {
12619 assert.expect(1);
12620
12621 var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
12622
12623 var actual = _.keyBy(array, function(object) {
12624 return String.fromCharCode(object.code);
12625 });
12626
12627 assert.deepEqual(actual, expected);
12628 });
12629
12630 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
12631 assert.expect(1);
12632
12633 var array = [4, 6, 6],
12634 values = [, null, undefined],
12635 expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
12636
12637 var actual = lodashStable.map(values, function(value, index) {
12638 return index ? _.keyBy(array, value) : _.keyBy(array);
12639 });
12640
12641 assert.deepEqual(actual, expected);
12642 });
12643
12644 QUnit.test('should work with `_.property` shorthands', function(assert) {
12645 assert.expect(1);
12646
12647 var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
12648 actual = _.keyBy(array, 'dir');
12649
12650 assert.deepEqual(actual, expected);
12651 });
12652
12653 QUnit.test('should only add values to own, not inherited, properties', function(assert) {
12654 assert.expect(2);
12655
12656 var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
12657 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
12658 });
12659
12660 assert.deepEqual(actual.constructor, 4.2);
12661 assert.deepEqual(actual.hasOwnProperty, 6.3);
12662 });
12663
12664 QUnit.test('should work with a number for `iteratee`', function(assert) {
12665 assert.expect(2);
12666
12667 var array = [
12668 [1, 'a'],
12669 [2, 'a'],
12670 [2, 'b']
12671 ];
12672
12673 assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
12674 assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
12675 });
12676
12677 QUnit.test('should work with an object for `collection`', function(assert) {
12678 assert.expect(1);
12679
12680 var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
12681 assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
12682 });
12683
12684 QUnit.test('should work in a lazy sequence', function(assert) {
12685 assert.expect(1);
12686
12687 if (!isNpm) {
12688 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
12689 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
12690 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
12691 );
12692
12693 var actual = _(array).keyBy().map(square).filter(isEven).take().value();
12694
12695 assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
12696 }
12697 else {
12698 skipAssert(assert);
12699 }
12700 });
12701 }());
12702
12703 /*--------------------------------------------------------------------------*/
12704
12705 QUnit.module('keys methods');
12706
12707 lodashStable.each(['keys', 'keysIn'], function(methodName) {
12708 var args = (function() { return arguments; }(1, 2, 3)),
12709 strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
12710 func = _[methodName],
12711 isKeys = methodName == 'keys';
12712
12713 QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
12714 assert.expect(1);
12715
12716 var actual = func({ 'a': 1, 'b': 1 }).sort();
12717
12718 assert.deepEqual(actual, ['a', 'b']);
12719 });
12720
12721 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
12722 assert.expect(1);
12723
12724 function Foo() {
12725 this.a = 1;
12726 }
12727 Foo.prototype.b = 2;
12728
12729 var expected = isKeys ? ['a'] : ['a', 'b'],
12730 actual = func(new Foo).sort();
12731
12732 assert.deepEqual(actual, expected);
12733 });
12734
12735 QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
12736 assert.expect(2);
12737
12738 var expected = lodashStable.map(primitives, function(value) {
12739 return typeof value == 'string' ? ['0'] : [];
12740 });
12741
12742 var actual = lodashStable.map(primitives, func);
12743 assert.deepEqual(actual, expected);
12744
12745 // IE 9 doesn't box numbers in for-in loops.
12746 numberProto.a = 1;
12747 assert.deepEqual(func(0), isKeys ? [] : ['a']);
12748 delete numberProto.a;
12749 });
12750
12751 QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
12752 assert.expect(1);
12753
12754 var array = [1];
12755 array[2] = 3;
12756
12757 var actual = func(array).sort();
12758
12759 assert.deepEqual(actual, ['0', '1', '2']);
12760 });
12761
12762 QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
12763 assert.expect(2);
12764
12765 objectProto.a = 1;
12766 lodashStable.each([null, undefined], function(value) {
12767 assert.deepEqual(func(value), []);
12768 });
12769 delete objectProto.a;
12770 });
12771
12772 QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
12773 assert.expect(1);
12774
12775 var array = [1];
12776 array.a = 1;
12777
12778 var actual = func(array).sort();
12779
12780 assert.deepEqual(actual, ['0', 'a']);
12781 });
12782
12783 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
12784 assert.expect(1);
12785
12786 arrayProto.a = 1;
12787
12788 var expected = isKeys ? ['0'] : ['0', 'a'],
12789 actual = func([1]).sort();
12790
12791 assert.deepEqual(actual, expected);
12792
12793 delete arrayProto.a;
12794 });
12795
12796 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
12797 assert.expect(1);
12798
12799 var values = [args, strictArgs],
12800 expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
12801
12802 var actual = lodashStable.map(values, function(value) {
12803 return func(value).sort();
12804 });
12805
12806 assert.deepEqual(actual, expected);
12807 });
12808
12809 QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
12810 assert.expect(1);
12811
12812 var values = [args, strictArgs],
12813 expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
12814
12815 var actual = lodashStable.map(values, function(value) {
12816 value.a = 1;
12817 var result = func(value).sort();
12818 delete value.a;
12819 return result;
12820 });
12821
12822 assert.deepEqual(actual, expected);
12823 });
12824
12825 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
12826 assert.expect(1);
12827
12828 var values = [args, strictArgs],
12829 expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
12830
12831 var actual = lodashStable.map(values, function(value) {
12832 objectProto.a = 1;
12833 var result = func(value).sort();
12834 delete objectProto.a;
12835 return result;
12836 });
12837
12838 assert.deepEqual(actual, expected);
12839 });
12840
12841 QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
12842 assert.expect(1);
12843
12844 var actual = func(Object('abc')).sort();
12845
12846 assert.deepEqual(actual, ['0', '1', '2']);
12847 });
12848
12849 QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
12850 assert.expect(1);
12851
12852 var object = Object('a');
12853 object.a = 1;
12854
12855 var actual = func(object).sort();
12856
12857 assert.deepEqual(actual, ['0', 'a']);
12858 });
12859
12860 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
12861 assert.expect(1);
12862
12863 stringProto.a = 1;
12864
12865 var expected = isKeys ? ['0'] : ['0', 'a'],
12866 actual = func(Object('a')).sort();
12867
12868 assert.deepEqual(actual, expected);
12869
12870 delete stringProto.a;
12871 });
12872
12873 QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
12874 assert.expect(3);
12875
12876 function Foo() {}
12877 Foo.prototype.a = 1;
12878
12879 var expected = ['a'];
12880 assert.deepEqual(func(Foo.prototype), expected);
12881
12882 Foo.prototype = { 'constructor': Foo, 'a': 1 };
12883 assert.deepEqual(func(Foo.prototype), expected);
12884
12885 var Fake = { 'prototype': {} };
12886 Fake.prototype.constructor = Fake;
12887 assert.deepEqual(func(Fake.prototype), ['constructor']);
12888 });
12889 });
12890
12891 /*--------------------------------------------------------------------------*/
12892
12893 QUnit.module('lodash.last');
12894
12895 (function() {
12896 var array = [1, 2, 3, 4];
12897
12898 QUnit.test('should return the last element', function(assert) {
12899 assert.expect(1);
12900
12901 assert.strictEqual(_.last(array), 4);
12902 });
12903
12904 QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
12905 assert.expect(1);
12906
12907 var array = [];
12908 array['-1'] = 1;
12909
12910 assert.strictEqual(_.last([]), undefined);
12911 });
12912
12913 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
12914 assert.expect(1);
12915
12916 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
12917 actual = lodashStable.map(array, _.last);
12918
12919 assert.deepEqual(actual, [3, 6, 9]);
12920 });
12921
12922 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
12923 assert.expect(1);
12924
12925 if (!isNpm) {
12926 assert.strictEqual(_(array).last(), 4);
12927 }
12928 else {
12929 skipAssert(assert);
12930 }
12931 });
12932
12933 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
12934 assert.expect(1);
12935
12936 if (!isNpm) {
12937 assert.ok(_(array).chain().last() instanceof _);
12938 }
12939 else {
12940 skipAssert(assert);
12941 }
12942 });
12943
12944 QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
12945 assert.expect(1);
12946
12947 if (!isNpm) {
12948 var wrapped = _(array).chain().last();
12949 assert.strictEqual(wrapped.__wrapped__, array);
12950 }
12951 else {
12952 skipAssert(assert);
12953 }
12954 });
12955
12956 QUnit.test('should work in a lazy sequence', function(assert) {
12957 assert.expect(2);
12958
12959 if (!isNpm) {
12960 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
12961 smallArray = array;
12962
12963 lodashStable.times(2, function(index) {
12964 var array = index ? largeArray : smallArray,
12965 wrapped = _(array).filter(isEven);
12966
12967 assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
12968 });
12969 }
12970 else {
12971 skipAssert(assert, 2);
12972 }
12973 });
12974 }());
12975
12976 /*--------------------------------------------------------------------------*/
12977
12978 QUnit.module('lodash.lowerCase');
12979
12980 (function() {
12981 QUnit.test('should lowercase as space-separated words', function(assert) {
12982 assert.expect(3);
12983
12984 assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
12985 assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
12986 assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
12987 });
12988 }());
12989
12990 /*--------------------------------------------------------------------------*/
12991
12992 QUnit.module('lodash.lowerFirst');
12993
12994 (function() {
12995 QUnit.test('should lowercase only the first character', function(assert) {
12996 assert.expect(3);
12997
12998 assert.strictEqual(_.lowerFirst('fred'), 'fred');
12999 assert.strictEqual(_.lowerFirst('Fred'), 'fred');
13000 assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
13001 });
13002 }());
13003
13004 /*--------------------------------------------------------------------------*/
13005
13006 QUnit.module('lodash.lt');
13007
13008 (function() {
13009 QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
13010 assert.expect(2);
13011
13012 assert.strictEqual(_.lt(1, 3), true);
13013 assert.strictEqual(_.lt('abc', 'def'), true);
13014 });
13015
13016 QUnit.test('should return `false` if `value` >= `other`', function(assert) {
13017 assert.expect(4);
13018
13019 assert.strictEqual(_.lt(3, 1), false);
13020 assert.strictEqual(_.lt(3, 3), false);
13021 assert.strictEqual(_.lt('def', 'abc'), false);
13022 assert.strictEqual(_.lt('def', 'def'), false);
13023 });
13024 }());
13025
13026 /*--------------------------------------------------------------------------*/
13027
13028 QUnit.module('lodash.lte');
13029
13030 (function() {
13031 QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
13032 assert.expect(4);
13033
13034 assert.strictEqual(_.lte(1, 3), true);
13035 assert.strictEqual(_.lte(3, 3), true);
13036 assert.strictEqual(_.lte('abc', 'def'), true);
13037 assert.strictEqual(_.lte('def', 'def'), true);
13038 });
13039
13040 QUnit.test('should return `false` if `value` > `other`', function(assert) {
13041 assert.expect(2);
13042
13043 assert.strictEqual(_.lt(3, 1), false);
13044 assert.strictEqual(_.lt('def', 'abc'), false);
13045 });
13046 }());
13047
13048 /*--------------------------------------------------------------------------*/
13049
13050 QUnit.module('lodash.lastIndexOf');
13051
13052 (function() {
13053 var array = [1, 2, 3, 1, 2, 3];
13054
13055 QUnit.test('should return the index of the last matched value', function(assert) {
13056 assert.expect(1);
13057
13058 assert.strictEqual(_.lastIndexOf(array, 3), 5);
13059 });
13060
13061 QUnit.test('should work with a positive `fromIndex`', function(assert) {
13062 assert.expect(1);
13063
13064 assert.strictEqual(_.lastIndexOf(array, 1, 2), 0);
13065 });
13066
13067 QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
13068 assert.expect(1);
13069
13070 var values = [6, 8, Math.pow(2, 32), Infinity],
13071 expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
13072
13073 var actual = lodashStable.map(values, function(fromIndex) {
13074 return [
13075 _.lastIndexOf(array, undefined, fromIndex),
13076 _.lastIndexOf(array, 1, fromIndex),
13077 _.lastIndexOf(array, '', fromIndex)
13078 ];
13079 });
13080
13081 assert.deepEqual(actual, expected);
13082 });
13083
13084 QUnit.test('should work with a negative `fromIndex`', function(assert) {
13085 assert.expect(1);
13086
13087 assert.strictEqual(_.lastIndexOf(array, 2, -3), 1);
13088 });
13089
13090 QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
13091 assert.expect(1);
13092
13093 var values = [-6, -8, -Infinity],
13094 expected = lodashStable.map(values, alwaysZero);
13095
13096 var actual = lodashStable.map(values, function(fromIndex) {
13097 return _.lastIndexOf(array, 1, fromIndex);
13098 });
13099
13100 assert.deepEqual(actual, expected);
13101 });
13102
13103 QUnit.test('should treat falsey `fromIndex` values correctly', function(assert) {
13104 assert.expect(1);
13105
13106 var expected = lodashStable.map(falsey, function(value) {
13107 return value === undefined ? 5 : -1;
13108 });
13109
13110 var actual = lodashStable.map(falsey, function(fromIndex) {
13111 return _.lastIndexOf(array, 3, fromIndex);
13112 });
13113
13114 assert.deepEqual(actual, expected);
13115 });
13116
13117 QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
13118 assert.expect(1);
13119
13120 assert.strictEqual(_.lastIndexOf(array, 2, 4.2), 4);
13121 });
13122 }());
13123
13124 /*--------------------------------------------------------------------------*/
13125
13126 QUnit.module('indexOf methods');
13127
13128 lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
13129 var func = _[methodName],
13130 isIndexOf = !/last/i.test(methodName),
13131 isSorted = /^sorted/.test(methodName);
13132
13133 QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
13134 assert.expect(1);
13135
13136 var expected = lodashStable.map(falsey, lodashStable.constant(-1));
13137
13138 var actual = lodashStable.map(falsey, function(array, index) {
13139 try {
13140 return index ? func(array) : func();
13141 } catch (e) {}
13142 });
13143
13144 assert.deepEqual(actual, expected);
13145 });
13146
13147 QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
13148 assert.expect(5);
13149
13150 var array = [1, 2, 3],
13151 empty = [];
13152
13153 assert.strictEqual(func(array, 4), -1);
13154 assert.strictEqual(func(array, 4, true), -1);
13155 assert.strictEqual(func(array, undefined, true), -1);
13156
13157 assert.strictEqual(func(empty, undefined), -1);
13158 assert.strictEqual(func(empty, undefined, true), -1);
13159 });
13160
13161 QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
13162 assert.expect(2);
13163
13164 var array = [];
13165 array[-1] = 0;
13166
13167 assert.strictEqual(func(array, undefined), -1);
13168 assert.strictEqual(func(array, 0, true), -1);
13169 });
13170
13171 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
13172 assert.expect(3);
13173
13174 var array = isSorted
13175 ? [1, 2, NaN, NaN]
13176 : [1, NaN, 3, NaN, 5, NaN];
13177
13178 if (isSorted) {
13179 assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
13180 skipAssert(assert, 2);
13181 }
13182 else {
13183 assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
13184 assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
13185 assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
13186 }
13187 });
13188
13189 QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
13190 assert.expect(2);
13191
13192 assert.strictEqual(func([-0], 0), 0);
13193 assert.strictEqual(func([0], -0), 0);
13194 });
13195 });
13196
13197 /*--------------------------------------------------------------------------*/
13198
13199 QUnit.module('lodash.map');
13200
13201 (function() {
13202 var array = [1, 2];
13203
13204 QUnit.test('should map values in `collection` to a new array', function(assert) {
13205 assert.expect(2);
13206
13207 var object = { 'a': 1, 'b': 2 },
13208 expected = ['1', '2'];
13209
13210 assert.deepEqual(_.map(array, String), expected);
13211 assert.deepEqual(_.map(object, String), expected);
13212 });
13213
13214 QUnit.test('should work with `_.property` shorthands', function(assert) {
13215 assert.expect(1);
13216
13217 var objects = [{ 'a': 'x' }, { 'a': 'y' }];
13218 assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
13219 });
13220
13221 QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
13222 assert.expect(1);
13223
13224 function Foo() {
13225 this.a = 1;
13226 }
13227 Foo.prototype.b = 2;
13228
13229 var actual = _.map(new Foo, identity);
13230 assert.deepEqual(actual, [1]);
13231 });
13232
13233 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13234 assert.expect(2);
13235
13236 var object = { 'a': 1, 'b': 2 },
13237 values = [, null, undefined],
13238 expected = lodashStable.map(values, lodashStable.constant([1, 2]));
13239
13240 lodashStable.each([array, object], function(collection) {
13241 var actual = lodashStable.map(values, function(value, index) {
13242 return index ? _.map(collection, value) : _.map(collection);
13243 });
13244
13245 assert.deepEqual(actual, expected);
13246 });
13247 });
13248
13249 QUnit.test('should accept a falsey `collection` argument', function(assert) {
13250 assert.expect(1);
13251
13252 var expected = lodashStable.map(falsey, alwaysEmptyArray);
13253
13254 var actual = lodashStable.map(falsey, function(collection, index) {
13255 try {
13256 return index ? _.map(collection) : _.map();
13257 } catch (e) {}
13258 });
13259
13260 assert.deepEqual(actual, expected);
13261 });
13262
13263 QUnit.test('should treat number values for `collection` as empty', function(assert) {
13264 assert.expect(1);
13265
13266 assert.deepEqual(_.map(1), []);
13267 });
13268
13269 QUnit.test('should treat a nodelist as an array-like object', function(assert) {
13270 assert.expect(1);
13271
13272 if (document) {
13273 var actual = _.map(document.getElementsByTagName('body'), function(element) {
13274 return element.nodeName.toLowerCase();
13275 });
13276
13277 assert.deepEqual(actual, ['body']);
13278 }
13279 else {
13280 skipAssert(assert);
13281 }
13282 });
13283
13284 QUnit.test('should work with objects with non-number length properties', function(assert) {
13285 assert.expect(1);
13286
13287 var value = { 'value': 'x' },
13288 object = { 'length': { 'value': 'x' } };
13289
13290 assert.deepEqual(_.map(object, identity), [value]);
13291 });
13292
13293 QUnit.test('should return a wrapped value when chaining', function(assert) {
13294 assert.expect(1);
13295
13296 if (!isNpm) {
13297 assert.ok(_(array).map(noop) instanceof _);
13298 }
13299 else {
13300 skipAssert(assert);
13301 }
13302 });
13303
13304 QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
13305 assert.expect(5);
13306
13307 if (!isNpm) {
13308 var args,
13309 array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
13310 expected = [1, 0, _.map(array.slice(1), square)];
13311
13312 _(array).slice(1).map(function(value, index, array) {
13313 args || (args = slice.call(arguments));
13314 }).value();
13315
13316 assert.deepEqual(args, [1, 0, array.slice(1)]);
13317
13318 args = undefined;
13319 _(array).slice(1).map(square).map(function(value, index, array) {
13320 args || (args = slice.call(arguments));
13321 }).value();
13322
13323 assert.deepEqual(args, expected);
13324
13325 args = undefined;
13326 _(array).slice(1).map(square).map(function(value, index) {
13327 args || (args = slice.call(arguments));
13328 }).value();
13329
13330 assert.deepEqual(args, expected);
13331
13332 args = undefined;
13333 _(array).slice(1).map(square).map(function(value) {
13334 args || (args = slice.call(arguments));
13335 }).value();
13336
13337 assert.deepEqual(args, [1]);
13338
13339 args = undefined;
13340 _(array).slice(1).map(square).map(function() {
13341 args || (args = slice.call(arguments));
13342 }).value();
13343
13344 assert.deepEqual(args, expected);
13345 }
13346 else {
13347 skipAssert(assert, 5);
13348 }
13349 });
13350 }());
13351
13352 /*--------------------------------------------------------------------------*/
13353
13354 QUnit.module('lodash.mapKeys');
13355
13356 (function() {
13357 var array = [1, 2],
13358 object = { 'a': 1, 'b': 2 };
13359
13360 QUnit.test('should map keys in `object` to a new object', function(assert) {
13361 assert.expect(1);
13362
13363 var actual = _.mapKeys(object, String);
13364 assert.deepEqual(actual, { '1': 1, '2': 2 });
13365 });
13366
13367 QUnit.test('should treat arrays like objects', function(assert) {
13368 assert.expect(1);
13369
13370 var actual = _.mapKeys(array, String);
13371 assert.deepEqual(actual, { '1': 1, '2': 2 });
13372 });
13373
13374 QUnit.test('should work with `_.property` shorthands', function(assert) {
13375 assert.expect(1);
13376
13377 var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
13378 assert.deepEqual(actual, { 'c': { 'b': 'c' } });
13379 });
13380
13381 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13382 assert.expect(1);
13383
13384 var object = { 'a': 1, 'b': 2 },
13385 values = [, null, undefined],
13386 expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
13387
13388 var actual = lodashStable.map(values, function(value, index) {
13389 return index ? _.mapKeys(object, value) : _.mapKeys(object);
13390 });
13391
13392 assert.deepEqual(actual, expected);
13393 });
13394 }());
13395
13396 /*--------------------------------------------------------------------------*/
13397
13398 QUnit.module('lodash.mapValues');
13399
13400 (function() {
13401 var array = [1, 2],
13402 object = { 'a': 1, 'b': 2 };
13403
13404 QUnit.test('should map values in `object` to a new object', function(assert) {
13405 assert.expect(1);
13406
13407 var actual = _.mapValues(object, String);
13408 assert.deepEqual(actual, { 'a': '1', 'b': '2' });
13409 });
13410
13411 QUnit.test('should treat arrays like objects', function(assert) {
13412 assert.expect(1);
13413
13414 var actual = _.mapValues(array, String);
13415 assert.deepEqual(actual, { '0': '1', '1': '2' });
13416 });
13417
13418 QUnit.test('should work with `_.property` shorthands', function(assert) {
13419 assert.expect(1);
13420
13421 var actual = _.mapValues({ 'a': { 'b': 1 } }, 'b');
13422 assert.deepEqual(actual, { 'a': 1 });
13423 });
13424
13425 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
13426 assert.expect(1);
13427
13428 var object = { 'a': 1, 'b': 2 },
13429 values = [, null, undefined],
13430 expected = lodashStable.map(values, lodashStable.constant([true, false]));
13431
13432 var actual = lodashStable.map(values, function(value, index) {
13433 var result = index ? _.mapValues(object, value) : _.mapValues(object);
13434 return [lodashStable.isEqual(result, object), result === object];
13435 });
13436
13437 assert.deepEqual(actual, expected);
13438 });
13439 }());
13440
13441 /*--------------------------------------------------------------------------*/
13442
13443 QUnit.module('lodash.mapKeys and lodash.mapValues');
13444
13445 lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
13446 var func = _[methodName],
13447 object = { 'a': 1, 'b': 2 };
13448
13449 QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
13450 assert.expect(1);
13451
13452 function Foo() {
13453 this.a = 'a';
13454 }
13455 Foo.prototype.b = 'b';
13456
13457 var actual = func(new Foo, function(value, key) { return key; });
13458 assert.deepEqual(actual, { 'a': 'a' });
13459 });
13460
13461 QUnit.test('`_.' + methodName + '` should accept a falsey `object` argument', function(assert) {
13462 assert.expect(1);
13463
13464 var expected = lodashStable.map(falsey, alwaysEmptyObject);
13465
13466 var actual = lodashStable.map(falsey, function(object, index) {
13467 try {
13468 return index ? func(object) : func();
13469 } catch (e) {}
13470 });
13471
13472 assert.deepEqual(actual, expected);
13473 });
13474
13475 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
13476 assert.expect(1);
13477
13478 if (!isNpm) {
13479 assert.ok(_(object)[methodName](noop) instanceof _);
13480 }
13481 else {
13482 skipAssert(assert);
13483 }
13484 });
13485 });
13486
13487 /*--------------------------------------------------------------------------*/
13488
13489 QUnit.module('lodash.matches');
13490
13491 (function() {
13492 QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
13493 assert.expect(6);
13494
13495 var object = { 'a': 1, 'b': 2, 'c': 3 },
13496 matches = _.matches({ 'a': 1 });
13497
13498 assert.strictEqual(matches.length, 1);
13499 assert.strictEqual(matches(object), true);
13500
13501 matches = _.matches({ 'b': 1 });
13502 assert.strictEqual(matches(object), false);
13503
13504 matches = _.matches({ 'a': 1, 'c': 3 });
13505 assert.strictEqual(matches(object), true);
13506
13507 matches = _.matches({ 'c': 3, 'd': 4 });
13508 assert.strictEqual(matches(object), false);
13509
13510 object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13511 matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
13512
13513 assert.strictEqual(matches(object), true);
13514 });
13515
13516 QUnit.test('should match inherited string keyed `object` properties', function(assert) {
13517 assert.expect(1);
13518
13519 function Foo() {
13520 this.a = 1;
13521 }
13522 Foo.prototype.b = 2;
13523
13524 var object = { 'a': new Foo },
13525 matches = _.matches({ 'a': { 'b': 2 } });
13526
13527 assert.strictEqual(matches(object), true);
13528 });
13529
13530 QUnit.test('should not match by inherited `source` properties', function(assert) {
13531 assert.expect(1);
13532
13533 function Foo() {
13534 this.a = 1;
13535 }
13536 Foo.prototype.b = 2;
13537
13538 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
13539 source = new Foo,
13540 actual = lodashStable.map(objects, _.matches(source)),
13541 expected = lodashStable.map(objects, alwaysTrue);
13542
13543 assert.deepEqual(actual, expected);
13544 });
13545
13546 QUnit.test('should compare a variety of `source` property values', function(assert) {
13547 assert.expect(2);
13548
13549 var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
13550 object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
13551 matches = _.matches(object1);
13552
13553 assert.strictEqual(matches(object1), true);
13554 assert.strictEqual(matches(object2), false);
13555 });
13556
13557 QUnit.test('should match `-0` as `0`', function(assert) {
13558 assert.expect(2);
13559
13560 var object1 = { 'a': -0 },
13561 object2 = { 'a': 0 },
13562 matches = _.matches(object1);
13563
13564 assert.strictEqual(matches(object2), true);
13565
13566 matches = _.matches(object2);
13567 assert.strictEqual(matches(object1), true);
13568 });
13569
13570 QUnit.test('should compare functions by reference', function(assert) {
13571 assert.expect(3);
13572
13573 var object1 = { 'a': lodashStable.noop },
13574 object2 = { 'a': noop },
13575 object3 = { 'a': {} },
13576 matches = _.matches(object1);
13577
13578 assert.strictEqual(matches(object1), true);
13579 assert.strictEqual(matches(object2), false);
13580 assert.strictEqual(matches(object3), false);
13581 });
13582
13583 QUnit.test('should work with a function for `object`', function(assert) {
13584 assert.expect(1);
13585
13586 function Foo() {}
13587 Foo.a = { 'b': 1, 'c': 2 };
13588
13589 var matches = _.matches({ 'a': { 'b': 1 } });
13590 assert.strictEqual(matches(Foo), true);
13591 });
13592
13593 QUnit.test('should work with a function for `source`', function(assert) {
13594 assert.expect(1);
13595
13596 function Foo() {}
13597 Foo.a = 1;
13598 Foo.b = function() {};
13599 Foo.c = 3;
13600
13601 var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
13602 actual = lodashStable.map(objects, _.matches(Foo));
13603
13604 assert.deepEqual(actual, [false, true]);
13605 });
13606
13607 QUnit.test('should work with a non-plain `object`', function(assert) {
13608 assert.expect(1);
13609
13610 function Foo(object) { lodashStable.assign(this, object); }
13611
13612 var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
13613 matches = _.matches({ 'a': { 'b': 1 } });
13614
13615 assert.strictEqual(matches(object), true);
13616 });
13617
13618 QUnit.test('should partial match arrays', function(assert) {
13619 assert.expect(3);
13620
13621 var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
13622 actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
13623
13624 assert.deepEqual(actual, [objects[1]]);
13625
13626 actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
13627 assert.deepEqual(actual, []);
13628
13629 actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
13630 assert.deepEqual(actual, []);
13631 });
13632
13633 QUnit.test('should partial match arrays of objects', function(assert) {
13634 assert.expect(1);
13635
13636 var objects = [
13637 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
13638 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
13639 ];
13640
13641 var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
13642 assert.deepEqual(actual, [objects[0]]);
13643 });
13644
13645 QUnit.test('should partial match maps', function(assert) {
13646 assert.expect(3);
13647
13648 if (Map) {
13649 var objects = [{ 'a': new Map }, { 'a': new Map }];
13650 objects[0].a.set('a', 1);
13651 objects[1].a.set('a', 1);
13652 objects[1].a.set('b', 2);
13653
13654 var map = new Map;
13655 map.set('b', 2);
13656 var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13657
13658 assert.deepEqual(actual, [objects[1]]);
13659
13660 map['delete']('b');
13661 actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13662
13663 assert.deepEqual(actual, objects);
13664
13665 map.set('c', 3);
13666 actual = lodashStable.filter(objects, _.matches({ 'a': map }));
13667
13668 assert.deepEqual(actual, []);
13669 }
13670 else {
13671 skipAssert(assert, 3);
13672 }
13673 });
13674
13675 QUnit.test('should partial match sets', function(assert) {
13676 assert.expect(3);
13677
13678 if (Set) {
13679 var objects = [{ 'a': new Set }, { 'a': new Set }];
13680 objects[0].a.add(1);
13681 objects[1].a.add(1);
13682 objects[1].a.add(2);
13683
13684 var set = new Set;
13685 set.add(2);
13686 var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13687
13688 assert.deepEqual(actual, [objects[1]]);
13689
13690 set['delete'](2);
13691 actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13692
13693 assert.deepEqual(actual, objects);
13694
13695 set.add(3);
13696 actual = lodashStable.filter(objects, _.matches({ 'a': set }));
13697
13698 assert.deepEqual(actual, []);
13699 }
13700 else {
13701 skipAssert(assert, 3);
13702 }
13703 });
13704
13705 QUnit.test('should match `undefined` values', function(assert) {
13706 assert.expect(3);
13707
13708 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
13709 actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
13710 expected = [false, false, true];
13711
13712 assert.deepEqual(actual, expected);
13713
13714 actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
13715
13716 assert.deepEqual(actual, expected);
13717
13718 objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
13719 actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
13720
13721 assert.deepEqual(actual, expected);
13722 });
13723
13724 QUnit.test('should match `undefined` values on primitives', function(assert) {
13725 assert.expect(3);
13726
13727 numberProto.a = 1;
13728 numberProto.b = undefined;
13729
13730 try {
13731 var matches = _.matches({ 'b': undefined });
13732 assert.strictEqual(matches(1), true);
13733 } catch (e) {
13734 assert.ok(false, e.message);
13735 }
13736 try {
13737 matches = _.matches({ 'a': 1, 'b': undefined });
13738 assert.strictEqual(matches(1), true);
13739 } catch (e) {
13740 assert.ok(false, e.message);
13741 }
13742 numberProto.a = { 'b': 1, 'c': undefined };
13743 try {
13744 matches = _.matches({ 'a': { 'c': undefined } });
13745 assert.strictEqual(matches(1), true);
13746 } catch (e) {
13747 assert.ok(false, e.message);
13748 }
13749 delete numberProto.a;
13750 delete numberProto.b;
13751 });
13752
13753 QUnit.test('should return `false` when `object` is nullish', function(assert) {
13754 assert.expect(1);
13755
13756 var values = [, null, undefined],
13757 expected = lodashStable.map(values, alwaysFalse),
13758 matches = _.matches({ 'a': 1 });
13759
13760 var actual = lodashStable.map(values, function(value, index) {
13761 try {
13762 return index ? matches(value) : matches();
13763 } catch (e) {}
13764 });
13765
13766 assert.deepEqual(actual, expected);
13767 });
13768
13769 QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
13770 assert.expect(1);
13771
13772 var values = [, null, undefined],
13773 expected = lodashStable.map(values, alwaysTrue),
13774 matches = _.matches({});
13775
13776 var actual = lodashStable.map(values, function(value, index) {
13777 try {
13778 return index ? matches(value) : matches();
13779 } catch (e) {}
13780 });
13781
13782 assert.deepEqual(actual, expected);
13783 });
13784
13785 QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
13786 assert.expect(1);
13787
13788 var object = { 'a': 1 },
13789 expected = lodashStable.map(empties, alwaysTrue);
13790
13791 var actual = lodashStable.map(empties, function(value) {
13792 var matches = _.matches(value);
13793 return matches(object);
13794 });
13795
13796 assert.deepEqual(actual, expected);
13797 });
13798
13799 QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
13800 assert.expect(1);
13801
13802 var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
13803 actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
13804
13805 assert.deepEqual(actual, objects);
13806 });
13807
13808 QUnit.test('should not change behavior if `source` is modified', function(assert) {
13809 assert.expect(9);
13810
13811 var sources = [
13812 { 'a': { 'b': 2, 'c': 3 } },
13813 { 'a': 1, 'b': 2 },
13814 { 'a': 1 }
13815 ];
13816
13817 lodashStable.each(sources, function(source, index) {
13818 var object = lodashStable.cloneDeep(source),
13819 matches = _.matches(source);
13820
13821 assert.strictEqual(matches(object), true);
13822
13823 if (index) {
13824 source.a = 2;
13825 source.b = 1;
13826 source.c = 3;
13827 } else {
13828 source.a.b = 1;
13829 source.a.c = 2;
13830 source.a.d = 3;
13831 }
13832 assert.strictEqual(matches(object), true);
13833 assert.strictEqual(matches(source), false);
13834 });
13835 });
13836 }());
13837
13838 /*--------------------------------------------------------------------------*/
13839
13840 QUnit.module('lodash.matchesProperty');
13841
13842 (function() {
13843 QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
13844 assert.expect(6);
13845
13846 var object = { 'a': 1, 'b': 2, 'c': 3 },
13847 matches = _.matchesProperty('a', 1);
13848
13849 assert.strictEqual(matches.length, 1);
13850 assert.strictEqual(matches(object), true);
13851
13852 matches = _.matchesProperty('b', 3);
13853 assert.strictEqual(matches(object), false);
13854
13855 matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
13856 assert.strictEqual(matches({ 'a': object }), true);
13857
13858 matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
13859 assert.strictEqual(matches(object), false);
13860
13861 object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
13862 matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
13863
13864 assert.strictEqual(matches(object), true);
13865 });
13866
13867 QUnit.test('should support deep paths', function(assert) {
13868 assert.expect(2);
13869
13870 var object = { 'a': { 'b': 2 } };
13871
13872 lodashStable.each(['a.b', ['a', 'b']], function(path) {
13873 var matches = _.matchesProperty(path, 2);
13874 assert.strictEqual(matches(object), true);
13875 });
13876 });
13877
13878 QUnit.test('should work with a non-string `path`', function(assert) {
13879 assert.expect(2);
13880
13881 var array = [1, 2, 3];
13882
13883 lodashStable.each([1, [1]], function(path) {
13884 var matches = _.matchesProperty(path, 2);
13885 assert.strictEqual(matches(array), true);
13886 });
13887 });
13888
13889 QUnit.test('should preserve the sign of `0`', function(assert) {
13890 assert.expect(1);
13891
13892 var object1 = { '-0': 'a' },
13893 object2 = { '0': 'b' },
13894 pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
13895 props = [-0, Object(-0), 0, Object(0)],
13896 values = ['a', 'a', 'b', 'b'],
13897 expected = lodashStable.map(props, lodashStable.constant([true, false]));
13898
13899 var actual = lodashStable.map(props, function(key, index) {
13900 var matches = _.matchesProperty(key, values[index]),
13901 pair = pairs[index];
13902
13903 return [matches(pair[0]), matches(pair[1])];
13904 });
13905
13906 assert.deepEqual(actual, expected);
13907 });
13908
13909 QUnit.test('should coerce key to a string', function(assert) {
13910 assert.expect(1);
13911
13912 function fn() {}
13913 fn.toString = lodashStable.constant('fn');
13914
13915 var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
13916 values = [null, undefined, fn, {}];
13917
13918 var expected = lodashStable.transform(values, function(result) {
13919 result.push(true, true);
13920 });
13921
13922 var actual = lodashStable.transform(objects, function(result, object, index) {
13923 var key = values[index];
13924 lodashStable.each([key, [key]], function(path) {
13925 var matches = _.matchesProperty(path, object[key]);
13926 result.push(matches(object));
13927 });
13928 });
13929
13930 assert.deepEqual(actual, expected);
13931 });
13932
13933 QUnit.test('should match a key over a path', function(assert) {
13934 assert.expect(2);
13935
13936 var object = { 'a.b': 1, 'a': { 'b': 2 } };
13937
13938 lodashStable.each(['a.b', ['a.b']], function(path) {
13939 var matches = _.matchesProperty(path, 1);
13940 assert.strictEqual(matches(object), true);
13941 });
13942 });
13943
13944 QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
13945 assert.expect(4);
13946
13947 var object = {};
13948
13949 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
13950 var matches = _.matchesProperty(path, 1);
13951 assert.strictEqual(matches(object), false);
13952 });
13953 });
13954
13955 QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
13956 assert.expect(2);
13957
13958 var values = [, null, undefined],
13959 expected = lodashStable.map(values, alwaysFalse);
13960
13961 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
13962 var matches = _.matchesProperty(path, 1);
13963
13964 var actual = lodashStable.map(values, function(value, index) {
13965 try {
13966 return index ? matches(value) : matches();
13967 } catch (e) {}
13968 });
13969
13970 assert.deepEqual(actual, expected);
13971 });
13972 });
13973
13974 QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
13975 assert.expect(2);
13976
13977 function Foo() {}
13978 Foo.prototype.b = 2;
13979
13980 var object = { 'a': new Foo };
13981
13982 lodashStable.each(['a', ['a']], function(path) {
13983 var matches = _.matchesProperty(path, { 'b': 2 });
13984 assert.strictEqual(matches(object), true);
13985 });
13986 });
13987
13988 QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
13989 assert.expect(2);
13990
13991 function Foo() {
13992 this.a = 1;
13993 }
13994 Foo.prototype.b = 2;
13995
13996 var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
13997 expected = lodashStable.map(objects, alwaysTrue);
13998
13999 lodashStable.each(['a', ['a']], function(path) {
14000 assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
14001 });
14002 });
14003
14004 QUnit.test('should compare a variety of values', function(assert) {
14005 assert.expect(2);
14006
14007 var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
14008 object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
14009 matches = _.matchesProperty('a', object1);
14010
14011 assert.strictEqual(matches({ 'a': object1 }), true);
14012 assert.strictEqual(matches({ 'a': object2 }), false);
14013 });
14014
14015 QUnit.test('should match `-0` as `0`', function(assert) {
14016 assert.expect(2);
14017
14018 var matches = _.matchesProperty('a', -0);
14019 assert.strictEqual(matches({ 'a': 0 }), true);
14020
14021 matches = _.matchesProperty('a', 0);
14022 assert.strictEqual(matches({ 'a': -0 }), true);
14023 });
14024
14025 QUnit.test('should compare functions by reference', function(assert) {
14026 assert.expect(3);
14027
14028 var object1 = { 'a': lodashStable.noop },
14029 object2 = { 'a': noop },
14030 object3 = { 'a': {} },
14031 matches = _.matchesProperty('a', object1);
14032
14033 assert.strictEqual(matches({ 'a': object1 }), true);
14034 assert.strictEqual(matches({ 'a': object2 }), false);
14035 assert.strictEqual(matches({ 'a': object3 }), false);
14036 });
14037
14038 QUnit.test('should work with a function for `srcValue`', function(assert) {
14039 assert.expect(1);
14040
14041 function Foo() {}
14042 Foo.a = 1;
14043 Foo.b = function() {};
14044 Foo.c = 3;
14045
14046 var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
14047 actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
14048
14049 assert.deepEqual(actual, [false, true]);
14050 });
14051
14052 QUnit.test('should work with a non-plain `srcValue`', function(assert) {
14053 assert.expect(1);
14054
14055 function Foo(object) { lodashStable.assign(this, object); }
14056
14057 var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
14058 matches = _.matchesProperty('a', { 'b': 1 });
14059
14060 assert.strictEqual(matches(object), true);
14061 });
14062
14063 QUnit.test('should partial match arrays', function(assert) {
14064 assert.expect(3);
14065
14066 var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
14067 actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
14068
14069 assert.deepEqual(actual, [objects[1]]);
14070
14071 actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
14072 assert.deepEqual(actual, []);
14073
14074 actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
14075 assert.deepEqual(actual, []);
14076 });
14077
14078 QUnit.test('should partial match arrays of objects', function(assert) {
14079 assert.expect(1);
14080
14081 var objects = [
14082 { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
14083 { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
14084 ];
14085
14086 var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
14087 assert.deepEqual(actual, [objects[0]]);
14088 });
14089 QUnit.test('should partial match maps', function(assert) {
14090 assert.expect(3);
14091
14092 if (Map) {
14093 var objects = [{ 'a': new Map }, { 'a': new Map }];
14094 objects[0].a.set('a', 1);
14095 objects[1].a.set('a', 1);
14096 objects[1].a.set('b', 2);
14097
14098 var map = new Map;
14099 map.set('b', 2);
14100 var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14101
14102 assert.deepEqual(actual, [objects[1]]);
14103
14104 map['delete']('b');
14105 actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14106
14107 assert.deepEqual(actual, objects);
14108
14109 map.set('c', 3);
14110 actual = lodashStable.filter(objects, _.matchesProperty('a', map));
14111
14112 assert.deepEqual(actual, []);
14113 }
14114 else {
14115 skipAssert(assert, 3);
14116 }
14117 });
14118
14119 QUnit.test('should partial match sets', function(assert) {
14120 assert.expect(3);
14121
14122 if (Set) {
14123 var objects = [{ 'a': new Set }, { 'a': new Set }];
14124 objects[0].a.add(1);
14125 objects[1].a.add(1);
14126 objects[1].a.add(2);
14127
14128 var set = new Set;
14129 set.add(2);
14130 var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14131
14132 assert.deepEqual(actual, [objects[1]]);
14133
14134 set['delete'](2);
14135 actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14136
14137 assert.deepEqual(actual, objects);
14138
14139 set.add(3);
14140 actual = lodashStable.filter(objects, _.matchesProperty('a', set));
14141
14142 assert.deepEqual(actual, []);
14143 }
14144 else {
14145 skipAssert(assert, 3);
14146 }
14147 });
14148
14149 QUnit.test('should match `undefined` values', function(assert) {
14150 assert.expect(2);
14151
14152 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
14153 actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
14154 expected = [false, false, true];
14155
14156 assert.deepEqual(actual, expected);
14157
14158 objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
14159 actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
14160
14161 assert.deepEqual(actual, expected);
14162 });
14163
14164 QUnit.test('should match `undefined` values of nested objects', function(assert) {
14165 assert.expect(4);
14166
14167 var object = { 'a': { 'b': undefined } };
14168
14169 lodashStable.each(['a.b', ['a', 'b']], function(path) {
14170 var matches = _.matchesProperty(path, undefined);
14171 assert.strictEqual(matches(object), true);
14172 });
14173
14174 lodashStable.each(['a.a', ['a', 'a']], function(path) {
14175 var matches = _.matchesProperty(path, undefined);
14176 assert.strictEqual(matches(object), false);
14177 });
14178 });
14179
14180 QUnit.test('should match `undefined` values on primitives', function(assert) {
14181 assert.expect(2);
14182
14183 numberProto.a = 1;
14184 numberProto.b = undefined;
14185
14186 try {
14187 var matches = _.matchesProperty('b', undefined);
14188 assert.strictEqual(matches(1), true);
14189 } catch (e) {
14190 assert.ok(false, e.message);
14191 }
14192 numberProto.a = { 'b': 1, 'c': undefined };
14193 try {
14194 matches = _.matchesProperty('a', { 'c': undefined });
14195 assert.strictEqual(matches(1), true);
14196 } catch (e) {
14197 assert.ok(false, e.message);
14198 }
14199 delete numberProto.a;
14200 delete numberProto.b;
14201 });
14202
14203 QUnit.test('should return `false` when `object` is nullish', function(assert) {
14204 assert.expect(2);
14205
14206 var values = [, null, undefined],
14207 expected = lodashStable.map(values, alwaysFalse);
14208
14209 lodashStable.each(['constructor', ['constructor']], function(path) {
14210 var matches = _.matchesProperty(path, 1);
14211
14212 var actual = lodashStable.map(values, function(value, index) {
14213 try {
14214 return index ? matches(value) : matches();
14215 } catch (e) {}
14216 });
14217
14218 assert.deepEqual(actual, expected);
14219 });
14220 });
14221
14222 QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
14223 assert.expect(1);
14224
14225 var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
14226 matches = _.matchesProperty('a', { 'a': [], 'b': {} });
14227
14228 var actual = lodashStable.filter(objects, function(object) {
14229 return matches({ 'a': object });
14230 });
14231
14232 assert.deepEqual(actual, objects);
14233 });
14234
14235 QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
14236 assert.expect(9);
14237
14238 lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
14239 var object = lodashStable.cloneDeep(source),
14240 matches = _.matchesProperty('a', source);
14241
14242 assert.strictEqual(matches({ 'a': object }), true);
14243
14244 if (index) {
14245 source.a = 2;
14246 source.b = 1;
14247 source.c = 3;
14248 } else {
14249 source.a.b = 1;
14250 source.a.c = 2;
14251 source.a.d = 3;
14252 }
14253 assert.strictEqual(matches({ 'a': object }), true);
14254 assert.strictEqual(matches({ 'a': source }), false);
14255 });
14256 });
14257 }());
14258
14259 /*--------------------------------------------------------------------------*/
14260
14261 QUnit.module('lodash.max');
14262
14263 (function() {
14264 QUnit.test('should return the largest value from a collection', function(assert) {
14265 assert.expect(1);
14266
14267 assert.strictEqual(_.max([1, 2, 3]), 3);
14268 });
14269
14270 QUnit.test('should return `undefined` for empty collections', function(assert) {
14271 assert.expect(1);
14272
14273 var values = falsey.concat([[]]),
14274 expected = lodashStable.map(values, noop);
14275
14276 var actual = lodashStable.map(values, function(value, index) {
14277 try {
14278 return index ? _.max(value) : _.max();
14279 } catch (e) {}
14280 });
14281
14282 assert.deepEqual(actual, expected);
14283 });
14284
14285 QUnit.test('should work with non-numeric collection values', function(assert) {
14286 assert.expect(1);
14287
14288 assert.strictEqual(_.max(['a', 'b']), 'b');
14289 });
14290 }());
14291
14292 /*--------------------------------------------------------------------------*/
14293
14294 QUnit.module('lodash.mean');
14295
14296 (function() {
14297 QUnit.test('should return the mean of an array of numbers', function(assert) {
14298 assert.expect(1);
14299
14300 var array = [4, 2, 8, 6];
14301 assert.strictEqual(_.mean(array), 5);
14302 });
14303
14304 QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
14305 assert.expect(1);
14306
14307 var expected = lodashStable.map(empties, alwaysNaN),
14308 actual = lodashStable.map(empties, _.mean);
14309
14310 assert.deepEqual(actual, expected);
14311 });
14312 }());
14313
14314 /*--------------------------------------------------------------------------*/
14315
14316 QUnit.module('lodash.meanBy');
14317
14318 (function() {
14319 var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
14320
14321 QUnit.test('should work with an `iteratee` argument', function(assert) {
14322 assert.expect(1);
14323
14324 var actual = _.meanBy(objects, function(object) {
14325 return object.a;
14326 });
14327
14328 assert.deepEqual(actual, 2);
14329 });
14330
14331 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
14332 assert.expect(1);
14333
14334 var args;
14335
14336 _.meanBy(objects, function() {
14337 args || (args = slice.call(arguments));
14338 });
14339
14340 assert.deepEqual(args, [{ 'a': 2 }]);
14341 });
14342
14343 QUnit.test('should work with `_.property` shorthands', function(assert) {
14344 assert.expect(2);
14345
14346 var arrays = [[2], [3], [1]];
14347 assert.strictEqual(_.meanBy(arrays, 0), 2);
14348 assert.strictEqual(_.meanBy(objects, 'a'), 2);
14349 });
14350 }());
14351
14352 /*--------------------------------------------------------------------------*/
14353
14354 QUnit.module('lodash.memoize');
14355
14356 (function() {
14357 QUnit.test('should memoize results based on the first argument given', function(assert) {
14358 assert.expect(2);
14359
14360 var memoized = _.memoize(function(a, b, c) {
14361 return a + b + c;
14362 });
14363
14364 assert.strictEqual(memoized(1, 2, 3), 6);
14365 assert.strictEqual(memoized(1, 3, 5), 6);
14366 });
14367
14368 QUnit.test('should support a `resolver` argument', function(assert) {
14369 assert.expect(2);
14370
14371 var fn = function(a, b, c) { return a + b + c; },
14372 memoized = _.memoize(fn, fn);
14373
14374 assert.strictEqual(memoized(1, 2, 3), 6);
14375 assert.strictEqual(memoized(1, 3, 5), 9);
14376 });
14377
14378 QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
14379 assert.expect(2);
14380
14381 var fn = function(a, b, c) { return a + this.b + this.c; },
14382 memoized = _.memoize(fn, fn);
14383
14384 var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
14385 assert.strictEqual(object.memoized(1), 6);
14386
14387 object.b = 3;
14388 object.c = 5;
14389 assert.strictEqual(object.memoized(1), 9);
14390 });
14391
14392 QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
14393 assert.expect(1);
14394
14395 assert.raises(function() { _.memoize(noop, true); }, TypeError);
14396 });
14397
14398 QUnit.test('should not error if `resolver` is falsey', function(assert) {
14399 assert.expect(1);
14400
14401 var expected = lodashStable.map(falsey, alwaysTrue);
14402
14403 var actual = lodashStable.map(falsey, function(resolver, index) {
14404 try {
14405 return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
14406 } catch (e) {}
14407 });
14408
14409 assert.deepEqual(actual, expected);
14410 });
14411
14412 QUnit.test('should check cache for own properties', function(assert) {
14413 assert.expect(1);
14414
14415 var props = [
14416 'constructor',
14417 'hasOwnProperty',
14418 'isPrototypeOf',
14419 'propertyIsEnumerable',
14420 'toLocaleString',
14421 'toString',
14422 'valueOf'
14423 ];
14424
14425 var memoized = _.memoize(identity);
14426
14427 var actual = lodashStable.map(props, function(value) {
14428 return memoized(value);
14429 });
14430
14431 assert.deepEqual(actual, props);
14432 });
14433
14434 QUnit.test('should cache the `__proto__` key', function(assert) {
14435 assert.expect(8);
14436
14437 var array = [],
14438 key = '__proto__';
14439
14440 lodashStable.times(2, function(index) {
14441 var count = 0,
14442 resolver = index && identity;
14443
14444 var memoized = _.memoize(function() {
14445 count++;
14446 return array;
14447 }, resolver);
14448
14449 var cache = memoized.cache;
14450
14451 memoized(key);
14452 memoized(key);
14453
14454 assert.strictEqual(count, 1);
14455 assert.strictEqual(cache.get(key), array);
14456 assert.notOk(cache.__data__ instanceof Array);
14457 assert.strictEqual(cache['delete'](key), true);
14458 });
14459 });
14460
14461 QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
14462 assert.expect(4);
14463
14464 var oldCache = _.memoize.Cache;
14465
14466 function Cache() {
14467 this.__data__ = [];
14468 }
14469
14470 Cache.prototype = {
14471 'get': function(key) {
14472 var entry = _.find(this.__data__, function(entry) {
14473 return key === entry.key;
14474 });
14475 return entry && entry.value;
14476 },
14477 'has': function(key) {
14478 return _.some(this.__data__, function(entry) {
14479 return key === entry.key;
14480 });
14481 },
14482 'set': function(key, value) {
14483 this.__data__.push({ 'key': key, 'value': value });
14484 return this;
14485 }
14486 };
14487
14488 _.memoize.Cache = Cache;
14489
14490 var memoized = _.memoize(function(object) {
14491 return 'value:' + object.id;
14492 });
14493
14494 var cache = memoized.cache,
14495 key1 = { 'id': 'a' },
14496 key2 = { 'id': 'b' };
14497
14498 assert.strictEqual(memoized(key1), 'value:a');
14499 assert.strictEqual(cache.has(key1), true);
14500
14501 assert.strictEqual(memoized(key2), 'value:b');
14502 assert.strictEqual(cache.has(key2), true);
14503
14504 _.memoize.Cache = oldCache;
14505 });
14506
14507 QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
14508 assert.expect(2);
14509
14510 var oldCache = _.memoize.Cache;
14511
14512 function Cache() {
14513 this.__data__ = [];
14514 }
14515
14516 Cache.prototype = {
14517 'get': function(key) {
14518 return _.find(this.__data__, function(entry) {
14519 return key === entry.key;
14520 }).value;
14521 },
14522 'has': function(key) {
14523 return _.some(this.__data__, function(entry) {
14524 return key === entry.key;
14525 });
14526 },
14527 'set': function(key, value) {
14528 var result = new Cache;
14529 result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
14530 return result;
14531 }
14532 };
14533
14534 _.memoize.Cache = Cache;
14535
14536 var memoized = _.memoize(function(object) {
14537 return object.id;
14538 });
14539
14540 var key1 = { 'id': 'a' },
14541 key2 = { 'id': 'b' };
14542
14543 memoized(key1);
14544 memoized(key2);
14545
14546 var cache = memoized.cache;
14547 assert.strictEqual(cache.has(key1), true);
14548 assert.strictEqual(cache.has(key2), true);
14549
14550 _.memoize.Cache = oldCache;
14551 });
14552
14553 QUnit.test('should implement a `Map` interface on the cache object', function(assert) {
14554 assert.expect(164);
14555
14556 var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
14557
14558 var pairs = lodashStable.map(keys, function(key, index) {
14559 var lastIndex = keys.length - 1;
14560 return [key, keys[lastIndex - index]];
14561 });
14562
14563 lodashStable.times(2, function(index) {
14564 var memoize = (index ? (lodashBizarro || {}) : _).memoize,
14565 Cache = memoize ? memoize.Cache : undefined,
14566 cache = Cache ? new Cache(pairs) : undefined;
14567
14568 lodashStable.each(keys, function(key, index) {
14569 if (cache) {
14570 var value = pairs[index][1];
14571
14572 assert.deepEqual(cache.get(key), value);
14573 assert.strictEqual(cache.has(key), true);
14574 assert.strictEqual(cache['delete'](key), true);
14575 assert.strictEqual(cache.has(key), false);
14576 assert.strictEqual(cache.get(key), undefined);
14577 assert.strictEqual(cache['delete'](key), false);
14578 assert.strictEqual(cache.set(key, value), cache);
14579 assert.strictEqual(cache.has(key), true);
14580 }
14581 else {
14582 skipAssert(assert, 8);
14583 }
14584 });
14585
14586 if (cache) {
14587 assert.strictEqual(cache.clear(), undefined);
14588 assert.ok(lodashStable.every(keys, function(key) {
14589 return !cache.has(key);
14590 }));
14591 }
14592 else {
14593 skipAssert(assert, 2);
14594 }
14595 });
14596 });
14597 }());
14598
14599 /*--------------------------------------------------------------------------*/
14600
14601 QUnit.module('lodash.merge');
14602
14603 (function() {
14604 var args = arguments;
14605
14606 QUnit.test('should merge `source` into `object`', function(assert) {
14607 assert.expect(1);
14608
14609 var names = {
14610 'characters': [
14611 { 'name': 'barney' },
14612 { 'name': 'fred' }
14613 ]
14614 };
14615
14616 var ages = {
14617 'characters': [
14618 { 'age': 36 },
14619 { 'age': 40 }
14620 ]
14621 };
14622
14623 var heights = {
14624 'characters': [
14625 { 'height': '5\'4"' },
14626 { 'height': '5\'5"' }
14627 ]
14628 };
14629
14630 var expected = {
14631 'characters': [
14632 { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
14633 { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
14634 ]
14635 };
14636
14637 assert.deepEqual(_.merge(names, ages, heights), expected);
14638 });
14639
14640 QUnit.test('should merge sources containing circular references', function(assert) {
14641 assert.expect(2);
14642
14643 var object = {
14644 'foo': { 'a': 1 },
14645 'bar': { 'a': 2 }
14646 };
14647
14648 var source = {
14649 'foo': { 'b': { 'c': { 'd': {} } } },
14650 'bar': {}
14651 };
14652
14653 source.foo.b.c.d = source;
14654 source.bar.b = source.foo.b;
14655
14656 var actual = _.merge(object, source);
14657
14658 assert.notStrictEqual(actual.bar.b, actual.foo.b);
14659 assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
14660 });
14661
14662 QUnit.test('should work with four arguments', function(assert) {
14663 assert.expect(1);
14664
14665 var expected = { 'a': 4 },
14666 actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
14667
14668 assert.deepEqual(actual, expected);
14669 });
14670
14671 QUnit.test('should merge onto function `object` values', function(assert) {
14672 assert.expect(2);
14673
14674 function Foo() {}
14675
14676 var source = { 'a': 1 },
14677 actual = _.merge(Foo, source);
14678
14679 assert.strictEqual(actual, Foo);
14680 assert.strictEqual(Foo.a, 1);
14681 });
14682
14683 QUnit.test('should not merge onto nested function values', function(assert) {
14684 assert.expect(3);
14685
14686 var source1 = { 'a': function() {} },
14687 source2 = { 'a': { 'b': 1 } },
14688 actual = _.merge({}, source1, source2),
14689 expected = { 'a': { 'b': 1 } };
14690
14691 assert.deepEqual(actual, expected);
14692
14693 source1 = { 'a': function() {} };
14694 source2 = { 'a': { 'b': 1 } };
14695
14696 expected = { 'a': function() {} };
14697 expected.a.b = 1;
14698
14699 actual = _.merge(source1, source2);
14700 assert.strictEqual(typeof actual.a, 'function');
14701 assert.strictEqual(actual.a.b, 1);
14702 });
14703
14704 QUnit.test('should merge onto non-plain `object` values', function(assert) {
14705 assert.expect(2);
14706
14707 function Foo() {}
14708
14709 var object = new Foo,
14710 actual = _.merge(object, { 'a': 1 });
14711
14712 assert.strictEqual(actual, object);
14713 assert.strictEqual(object.a, 1);
14714 });
14715
14716 QUnit.test('should treat sparse array sources as dense', function(assert) {
14717 assert.expect(2);
14718
14719 var array = [1];
14720 array[2] = 3;
14721
14722 var actual = _.merge([], array),
14723 expected = array.slice();
14724
14725 expected[1] = undefined;
14726
14727 assert.ok('1' in actual);
14728 assert.deepEqual(actual, expected);
14729 });
14730
14731 QUnit.test('should merge `arguments` objects', function(assert) {
14732 assert.expect(7);
14733
14734 var object1 = { 'value': args },
14735 object2 = { 'value': { '3': 4 } },
14736 expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
14737 actual = _.merge(object1, object2);
14738
14739 assert.notOk('3' in args);
14740 assert.notOk(_.isArguments(actual.value));
14741 assert.deepEqual(actual.value, expected);
14742 object1.value = args;
14743
14744 actual = _.merge(object2, object1);
14745 assert.notOk(_.isArguments(actual.value));
14746 assert.deepEqual(actual.value, expected);
14747
14748 expected = { '0': 1, '1': 2, '2': 3 };
14749
14750 actual = _.merge({}, object1);
14751 assert.notOk(_.isArguments(actual.value));
14752 assert.deepEqual(actual.value, expected);
14753 });
14754
14755 QUnit.test('should merge typed arrays', function(assert) {
14756 assert.expect(4);
14757
14758 var array1 = [0],
14759 array2 = [0, 0],
14760 array3 = [0, 0, 0, 0],
14761 array4 = [0, 0, 0, 0, 0, 0, 0, 0];
14762
14763 var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
14764 buffer = ArrayBuffer && new ArrayBuffer(8);
14765
14766 // Juggle for `Float64Array` shim.
14767 if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
14768 arrays[1] = array4;
14769 }
14770 var expected = lodashStable.map(typedArrays, function(type, index) {
14771 var array = arrays[index].slice();
14772 array[0] = 1;
14773 return root[type] ? { 'value': array } : false;
14774 });
14775
14776 var actual = lodashStable.map(typedArrays, function(type) {
14777 var Ctor = root[type];
14778 return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
14779 });
14780
14781 assert.ok(lodashStable.isArray(actual));
14782 assert.deepEqual(actual, expected);
14783
14784 expected = lodashStable.map(typedArrays, function(type, index) {
14785 var array = arrays[index].slice();
14786 array.push(1);
14787 return root[type] ? { 'value': array } : false;
14788 });
14789
14790 actual = lodashStable.map(typedArrays, function(type, index) {
14791 var Ctor = root[type],
14792 array = lodashStable.range(arrays[index].length);
14793
14794 array.push(1);
14795 return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
14796 });
14797
14798 assert.ok(lodashStable.isArray(actual));
14799 assert.deepEqual(actual, expected);
14800 });
14801
14802 QUnit.test('should assign `null` values', function(assert) {
14803 assert.expect(1);
14804
14805 var actual = _.merge({ 'a': 1 }, { 'a': null });
14806 assert.strictEqual(actual.a, null);
14807 });
14808
14809 QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
14810 assert.expect(1);
14811
14812 function Foo() {}
14813
14814 var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
14815 expected = lodashStable.map(values, alwaysTrue);
14816
14817 var actual = lodashStable.map(values, function(value) {
14818 var object = _.merge({}, { 'value': value });
14819 return object.value === value;
14820 });
14821
14822 assert.deepEqual(actual, expected);
14823 });
14824
14825 QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) {
14826 assert.expect(1);
14827
14828 var typedArray = Uint8Array
14829 ? new Uint8Array(new ArrayBuffer(2))
14830 : { 'buffer': [0, 0] };
14831
14832 var props = ['0', 'a', 'buffer'],
14833 values = [[{ 'a': 1 }], { 'a': [1] }, typedArray],
14834 expected = lodashStable.map(values, alwaysTrue);
14835
14836 var actual = lodashStable.map(values, function(value, index) {
14837 var key = props[index],
14838 object = _.merge({}, { 'value': value }),
14839 newValue = object.value;
14840
14841 return (
14842 newValue !== value &&
14843 newValue[key] !== value[key] &&
14844 lodashStable.isEqual(newValue, value)
14845 );
14846 });
14847
14848 assert.deepEqual(actual, expected);
14849 });
14850
14851 QUnit.test('should not augment source objects', function(assert) {
14852 assert.expect(6);
14853
14854 var source1 = { 'a': [{ 'a': 1 }] },
14855 source2 = { 'a': [{ 'b': 2 }] },
14856 actual = _.merge({}, source1, source2);
14857
14858 assert.deepEqual(source1.a, [{ 'a': 1 }]);
14859 assert.deepEqual(source2.a, [{ 'b': 2 }]);
14860 assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
14861
14862 var source1 = { 'a': [[1, 2, 3]] },
14863 source2 = { 'a': [[3, 4]] },
14864 actual = _.merge({}, source1, source2);
14865
14866 assert.deepEqual(source1.a, [[1, 2, 3]]);
14867 assert.deepEqual(source2.a, [[3, 4]]);
14868 assert.deepEqual(actual.a, [[3, 4, 3]]);
14869 });
14870
14871 QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
14872 assert.expect(4);
14873
14874 function Foo(object) {
14875 lodashStable.assign(this, object);
14876 }
14877
14878 var object = { 'a': 1 },
14879 actual = _.merge(new Foo, object);
14880
14881 assert.ok(actual instanceof Foo);
14882 assert.deepEqual(actual, new Foo(object));
14883
14884 actual = _.merge([new Foo], [object]);
14885 assert.ok(actual[0] instanceof Foo);
14886 assert.deepEqual(actual, [new Foo(object)]);
14887 });
14888
14889 QUnit.test('should not assign `undefined` values', function(assert) {
14890 assert.expect(1);
14891
14892 var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
14893 assert.deepEqual(actual, { 'a': 1 });
14894 });
14895
14896 QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
14897 assert.expect(2);
14898
14899 var array = [1];
14900 array[2] = 3;
14901
14902 var actual = _.merge([4, 5, 6], array),
14903 expected = [1, 5, 3];
14904
14905 assert.deepEqual(actual, expected);
14906
14907 array = [1, , 3];
14908 array[1] = undefined;
14909
14910 actual = _.merge([4, 5, 6], array);
14911 assert.deepEqual(actual, expected);
14912 });
14913
14914 QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
14915 assert.expect(1);
14916
14917 if (defineProperty) {
14918 var object = {},
14919 pass = true;
14920
14921 defineProperty(object, 'a', {
14922 'enumerable': true,
14923 'configurable': true,
14924 'get': function() { pass = false; },
14925 'set': function() { pass = false; }
14926 });
14927
14928 _.merge(object, object);
14929 assert.ok(pass);
14930 }
14931 else {
14932 skipAssert(assert);
14933 }
14934 });
14935
14936 QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
14937 assert.expect(2);
14938
14939 var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
14940 actual = _.merge(object, { 'a': ['x'] });
14941
14942 assert.deepEqual(actual, { 'a': ['x', 'y'] });
14943
14944 actual = _.merge({ 'a': {} }, { 'a': [] });
14945 assert.deepEqual(actual, { 'a': [] });
14946 });
14947
14948 QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
14949 assert.expect(1);
14950
14951 var object = { 'a': 'abcde' },
14952 actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
14953
14954 assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
14955 });
14956
14957 QUnit.test('should not error on DOM elements', function(assert) {
14958 assert.expect(1);
14959
14960 var object1 = { 'el': document && document.createElement('div') },
14961 object2 = { 'el': document && document.createElement('div') },
14962 pairs = [[{}, object1], [object1, object2]],
14963 expected = lodashStable.map(pairs, alwaysTrue);
14964
14965 var actual = lodashStable.map(pairs, function(pair) {
14966 try {
14967 return _.merge(pair[0], pair[1]).el === pair[1].el;
14968 } catch (e) {}
14969 });
14970
14971 assert.deepEqual(actual, expected);
14972 });
14973 }(1, 2, 3));
14974
14975 /*--------------------------------------------------------------------------*/
14976
14977 QUnit.module('lodash.mergeWith');
14978
14979 (function() {
14980 QUnit.test('should handle merging if `customizer` returns `undefined`', function(assert) {
14981 assert.expect(2);
14982
14983 var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
14984 assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
14985
14986 actual = _.mergeWith([], [undefined], identity);
14987 assert.deepEqual(actual, [undefined]);
14988 });
14989
14990 QUnit.test('should defer to `customizer` when it returns a non `undefined` value', function(assert) {
14991 assert.expect(1);
14992
14993 var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
14994 return lodashStable.isArray(a) ? a.concat(b) : undefined;
14995 });
14996
14997 assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
14998 });
14999
15000 QUnit.test('should overwrite primitives with source object clones', function(assert) {
15001 assert.expect(1);
15002
15003 var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
15004 return lodashStable.isArray(a) ? a.concat(b) : undefined;
15005 });
15006
15007 assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
15008 });
15009
15010 QUnit.test('should clone sources when `customizer` result is `undefined`', function(assert) {
15011 assert.expect(1);
15012
15013 var source1 = { 'a': { 'b': { 'c': 1 } } },
15014 source2 = { 'a': { 'b': { 'd': 2 } } };
15015
15016 _.mergeWith({}, source1, source2, noop);
15017 assert.deepEqual(source1.a.b, { 'c': 1 });
15018 });
15019
15020 QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
15021 assert.expect(1);
15022
15023 var array = ['b', 'c'],
15024 object = { 'a': ['a'] },
15025 source = { 'a': array, 'b': array };
15026
15027 var actual = _.mergeWith(object, source, function(a, b) {
15028 return lodashStable.isArray(a) ? a.concat(b) : undefined;
15029 });
15030
15031 assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
15032 });
15033 }());
15034
15035 /*--------------------------------------------------------------------------*/
15036
15037 QUnit.module('lodash.method');
15038
15039 (function() {
15040 QUnit.test('should create a function that calls a method of a given object', function(assert) {
15041 assert.expect(4);
15042
15043 var object = { 'a': alwaysOne };
15044
15045 lodashStable.each(['a', ['a']], function(path) {
15046 var method = _.method(path);
15047 assert.strictEqual(method.length, 1);
15048 assert.strictEqual(method(object), 1);
15049 });
15050 });
15051
15052 QUnit.test('should work with deep property values', function(assert) {
15053 assert.expect(2);
15054
15055 var object = { 'a': { 'b': alwaysTwo } };
15056
15057 lodashStable.each(['a.b', ['a', 'b']], function(path) {
15058 var method = _.method(path);
15059 assert.strictEqual(method(object), 2);
15060 });
15061 });
15062
15063 QUnit.test('should work with a non-string `path`', function(assert) {
15064 assert.expect(2);
15065
15066 var array = lodashStable.times(3, _.constant);
15067
15068 lodashStable.each([1, [1]], function(path) {
15069 var method = _.method(path);
15070 assert.strictEqual(method(array), 1);
15071 });
15072 });
15073
15074 QUnit.test('should coerce key to a string', function(assert) {
15075 assert.expect(1);
15076
15077 function fn() {}
15078 fn.toString = lodashStable.constant('fn');
15079
15080 var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15081 objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
15082 values = [null, undefined, fn, {}];
15083
15084 var actual = lodashStable.transform(objects, function(result, object, index) {
15085 var key = values[index];
15086 lodashStable.each([key, [key]], function(path) {
15087 var method = _.method(key);
15088 result.push(method(object));
15089 });
15090 });
15091
15092 assert.deepEqual(actual, expected);
15093 });
15094
15095 QUnit.test('should work with inherited property values', function(assert) {
15096 assert.expect(2);
15097
15098 function Foo() {}
15099 Foo.prototype.a = alwaysOne;
15100
15101 lodashStable.each(['a', ['a']], function(path) {
15102 var method = _.method(path);
15103 assert.strictEqual(method(new Foo), 1);
15104 });
15105 });
15106
15107 QUnit.test('should use a key over a path', function(assert) {
15108 assert.expect(2);
15109
15110 var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
15111
15112 lodashStable.each(['a.b', ['a.b']], function(path) {
15113 var method = _.method(path);
15114 assert.strictEqual(method(object), 1);
15115 });
15116 });
15117
15118 QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15119 assert.expect(2);
15120
15121 var values = [, null, undefined],
15122 expected = lodashStable.map(values, noop);
15123
15124 lodashStable.each(['constructor', ['constructor']], function(path) {
15125 var method = _.method(path);
15126
15127 var actual = lodashStable.map(values, function(value, index) {
15128 return index ? method(value) : method();
15129 });
15130
15131 assert.deepEqual(actual, expected);
15132 });
15133 });
15134
15135 QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15136 assert.expect(2);
15137
15138 var values = [, null, undefined],
15139 expected = lodashStable.map(values, noop);
15140
15141 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15142 var method = _.method(path);
15143
15144 var actual = lodashStable.map(values, function(value, index) {
15145 return index ? method(value) : method();
15146 });
15147
15148 assert.deepEqual(actual, expected);
15149 });
15150 });
15151
15152 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15153 assert.expect(4);
15154
15155 var object = {};
15156
15157 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15158 var method = _.method(path);
15159 assert.strictEqual(method(object), undefined);
15160 });
15161 });
15162
15163 QUnit.test('should apply partial arguments to function', function(assert) {
15164 assert.expect(2);
15165
15166 var object = {
15167 'fn': function() {
15168 return slice.call(arguments);
15169 }
15170 };
15171
15172 lodashStable.each(['fn', ['fn']], function(path) {
15173 var method = _.method(path, 1, 2, 3);
15174 assert.deepEqual(method(object), [1, 2, 3]);
15175 });
15176 });
15177
15178 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15179 assert.expect(2);
15180
15181 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
15182
15183 lodashStable.each(['a.b', ['a', 'b']], function(path) {
15184 var method = _.method(path);
15185 assert.strictEqual(method(object), 1);
15186 });
15187 });
15188 }());
15189
15190 /*--------------------------------------------------------------------------*/
15191
15192 QUnit.module('lodash.methodOf');
15193
15194 (function() {
15195 QUnit.test('should create a function that calls a method of a given key', function(assert) {
15196 assert.expect(4);
15197
15198 var object = { 'a': alwaysOne };
15199
15200 lodashStable.each(['a', ['a']], function(path) {
15201 var methodOf = _.methodOf(object);
15202 assert.strictEqual(methodOf.length, 1);
15203 assert.strictEqual(methodOf(path), 1);
15204 });
15205 });
15206
15207 QUnit.test('should work with deep property values', function(assert) {
15208 assert.expect(2);
15209
15210 var object = { 'a': { 'b': alwaysTwo } };
15211
15212 lodashStable.each(['a.b', ['a', 'b']], function(path) {
15213 var methodOf = _.methodOf(object);
15214 assert.strictEqual(methodOf(path), 2);
15215 });
15216 });
15217
15218 QUnit.test('should work with a non-string `path`', function(assert) {
15219 assert.expect(2);
15220
15221 var array = lodashStable.times(3, _.constant);
15222
15223 lodashStable.each([1, [1]], function(path) {
15224 var methodOf = _.methodOf(array);
15225 assert.strictEqual(methodOf(path), 1);
15226 });
15227 });
15228
15229 QUnit.test('should coerce key to a string', function(assert) {
15230 assert.expect(1);
15231
15232 function fn() {}
15233 fn.toString = lodashStable.constant('fn');
15234
15235 var expected = [1, 1, 2, 2, 3, 3, 4, 4],
15236 objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
15237 values = [null, undefined, fn, {}];
15238
15239 var actual = lodashStable.transform(objects, function(result, object, index) {
15240 var key = values[index];
15241 lodashStable.each([key, [key]], function(path) {
15242 var methodOf = _.methodOf(object);
15243 result.push(methodOf(key));
15244 });
15245 });
15246
15247 assert.deepEqual(actual, expected);
15248 });
15249
15250 QUnit.test('should work with inherited property values', function(assert) {
15251 assert.expect(2);
15252
15253 function Foo() {}
15254 Foo.prototype.a = alwaysOne;
15255
15256 lodashStable.each(['a', ['a']], function(path) {
15257 var methodOf = _.methodOf(new Foo);
15258 assert.strictEqual(methodOf(path), 1);
15259 });
15260 });
15261
15262 QUnit.test('should use a key over a path', function(assert) {
15263 assert.expect(2);
15264
15265 var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
15266
15267 lodashStable.each(['a.b', ['a.b']], function(path) {
15268 var methodOf = _.methodOf(object);
15269 assert.strictEqual(methodOf(path), 1);
15270 });
15271 });
15272
15273 QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
15274 assert.expect(2);
15275
15276 var values = [, null, undefined],
15277 expected = lodashStable.map(values, noop);
15278
15279 lodashStable.each(['constructor', ['constructor']], function(path) {
15280 var actual = lodashStable.map(values, function(value, index) {
15281 var methodOf = index ? _.methodOf() : _.methodOf(value);
15282 return methodOf(path);
15283 });
15284
15285 assert.deepEqual(actual, expected);
15286 });
15287 });
15288
15289 QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
15290 assert.expect(2);
15291
15292 var values = [, null, undefined],
15293 expected = lodashStable.map(values, noop);
15294
15295 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
15296 var actual = lodashStable.map(values, function(value, index) {
15297 var methodOf = index ? _.methodOf() : _.methodOf(value);
15298 return methodOf(path);
15299 });
15300
15301 assert.deepEqual(actual, expected);
15302 });
15303 });
15304
15305 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
15306 assert.expect(4);
15307
15308 var object = {},
15309 methodOf = _.methodOf(object);
15310
15311 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
15312 assert.strictEqual(methodOf(path), undefined);
15313 });
15314 });
15315
15316 QUnit.test('should apply partial arguments to function', function(assert) {
15317 assert.expect(2);
15318
15319 var object = {
15320 'fn': function() {
15321 return slice.call(arguments);
15322 }
15323 };
15324
15325 var methodOf = _.methodOf(object, 1, 2, 3);
15326
15327 lodashStable.each(['fn', ['fn']], function(path) {
15328 assert.deepEqual(methodOf(path), [1, 2, 3]);
15329 });
15330 });
15331
15332 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
15333 assert.expect(2);
15334
15335 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
15336 methodOf = _.methodOf(object);
15337
15338 lodashStable.each(['a.b', ['a', 'b']], function(path) {
15339 assert.strictEqual(methodOf(path), 1);
15340 });
15341 });
15342 }());
15343
15344 /*--------------------------------------------------------------------------*/
15345
15346 QUnit.module('lodash.min');
15347
15348 (function() {
15349 QUnit.test('should return the smallest value from a collection', function(assert) {
15350 assert.expect(1);
15351
15352 assert.strictEqual(_.min([1, 2, 3]), 1);
15353 });
15354
15355 QUnit.test('should return `undefined` for empty collections', function(assert) {
15356 assert.expect(1);
15357
15358 var values = falsey.concat([[]]),
15359 expected = lodashStable.map(values, noop);
15360
15361 var actual = lodashStable.map(values, function(value, index) {
15362 try {
15363 return index ? _.min(value) : _.min();
15364 } catch (e) {}
15365 });
15366
15367 assert.deepEqual(actual, expected);
15368 });
15369
15370 QUnit.test('should work with non-numeric collection values', function(assert) {
15371 assert.expect(1);
15372
15373 assert.strictEqual(_.min(['a', 'b']), 'a');
15374 });
15375 }());
15376
15377 /*--------------------------------------------------------------------------*/
15378
15379 QUnit.module('extremum methods');
15380
15381 lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
15382 var func = _[methodName],
15383 isMax = /^max/.test(methodName);
15384
15385 QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
15386 assert.expect(1);
15387
15388 var curr = new Date,
15389 past = new Date(0);
15390
15391 assert.strictEqual(func([curr, past]), isMax ? curr : past);
15392 });
15393
15394 QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
15395 assert.expect(1);
15396
15397 var array = lodashStable.range(0, 5e5);
15398 assert.strictEqual(func(array), isMax ? 499999 : 0);
15399 });
15400
15401 QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
15402 assert.expect(1);
15403
15404 if (!isNpm) {
15405 var actual = _([40])[methodName]();
15406 assert.strictEqual(actual, 40);
15407 }
15408 else {
15409 skipAssert(assert);
15410 }
15411 });
15412 });
15413
15414 lodashStable.each(['maxBy', 'minBy'], function(methodName) {
15415 var array = [1, 2, 3],
15416 func = _[methodName],
15417 isMax = methodName == 'maxBy';
15418
15419 QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
15420 assert.expect(1);
15421
15422 var actual = func(array, function(n) {
15423 return -n;
15424 });
15425
15426 assert.strictEqual(actual, isMax ? 1 : 3);
15427 });
15428
15429 QUnit.test('should work with `_.property` shorthands', function(assert) {
15430 assert.expect(2);
15431
15432 var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
15433 actual = func(objects, 'a');
15434
15435 assert.deepEqual(actual, objects[isMax ? 1 : 2]);
15436
15437 var arrays = [[2], [3], [1]];
15438 actual = func(arrays, 0);
15439
15440 assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
15441 });
15442
15443 QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
15444 assert.expect(1);
15445
15446 var value = isMax ? -Infinity : Infinity,
15447 object = { 'a': value };
15448
15449 var actual = func([object, { 'a': value }], function(object) {
15450 return object.a;
15451 });
15452
15453 assert.strictEqual(actual, object);
15454 });
15455 });
15456
15457 /*--------------------------------------------------------------------------*/
15458
15459 QUnit.module('lodash.mixin');
15460
15461 (function() {
15462 function reset(wrapper) {
15463 delete wrapper.a;
15464 delete wrapper.prototype.a;
15465 delete wrapper.b;
15466 delete wrapper.prototype.b;
15467 }
15468
15469 function Wrapper(value) {
15470 if (!(this instanceof Wrapper)) {
15471 return new Wrapper(value);
15472 }
15473 if (_.has(value, '__wrapped__')) {
15474 var actions = slice.call(value.__actions__),
15475 chain = value.__chain__;
15476
15477 value = value.__wrapped__;
15478 }
15479 this.__wrapped__ = value;
15480 this.__actions__ = actions || [];
15481 this.__chain__ = chain || false;
15482 }
15483
15484 Wrapper.prototype.value = function() {
15485 return getUnwrappedValue(this);
15486 };
15487
15488 var array = ['a'],
15489 source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
15490
15491 QUnit.test('should mixin `source` methods into lodash', function(assert) {
15492 assert.expect(4);
15493
15494 if (!isNpm) {
15495 _.mixin(source);
15496
15497 assert.strictEqual(_.a(array), 'a');
15498 assert.strictEqual(_(array).a().value(), 'a');
15499 assert.notOk('b' in _);
15500 assert.notOk('b' in _.prototype);
15501
15502 reset(_);
15503 }
15504 else {
15505 skipAssert(assert, 4);
15506 }
15507 });
15508
15509 QUnit.test('should mixin chaining methods by reference', function(assert) {
15510 assert.expect(2);
15511
15512 if (!isNpm) {
15513 _.mixin(source);
15514 _.a = alwaysB;
15515
15516 assert.strictEqual(_.a(array), 'b');
15517 assert.strictEqual(_(array).a().value(), 'a');
15518
15519 reset(_);
15520 }
15521 else {
15522 skipAssert(assert, 2);
15523 }
15524 });
15525
15526 QUnit.test('should use a default `object` of `this`', function(assert) {
15527 assert.expect(3);
15528
15529 var object = lodashStable.create(_);
15530 object.mixin(source);
15531
15532 assert.strictEqual(object.a(array), 'a');
15533 assert.notOk('a' in _);
15534 assert.notOk('a' in _.prototype);
15535
15536 reset(_);
15537 });
15538
15539 QUnit.test('should accept an `object` argument', function(assert) {
15540 assert.expect(1);
15541
15542 var object = {};
15543 _.mixin(object, source);
15544 assert.strictEqual(object.a(array), 'a');
15545 });
15546
15547 QUnit.test('should accept a function `object`', function(assert) {
15548 assert.expect(2);
15549
15550 _.mixin(Wrapper, source);
15551
15552 var wrapped = Wrapper(array),
15553 actual = wrapped.a();
15554
15555 assert.strictEqual(actual.value(), 'a');
15556 assert.ok(actual instanceof Wrapper);
15557
15558 reset(Wrapper);
15559 });
15560
15561 QUnit.test('should return `object`', function(assert) {
15562 assert.expect(3);
15563
15564 var object = {};
15565 assert.strictEqual(_.mixin(object, source), object);
15566 assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
15567 assert.strictEqual(_.mixin(), _);
15568
15569 reset(Wrapper);
15570 });
15571
15572 QUnit.test('should not assign inherited `source` methods', function(assert) {
15573 assert.expect(1);
15574
15575 function Foo() {}
15576 Foo.prototype.a = noop;
15577
15578 var object = {};
15579 assert.strictEqual(_.mixin(object, new Foo), object);
15580 });
15581
15582 QUnit.test('should accept an `options` argument', function(assert) {
15583 assert.expect(8);
15584
15585 function message(func, chain) {
15586 return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
15587 }
15588
15589 lodashStable.each([_, Wrapper], function(func) {
15590 lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
15591 if (!isNpm) {
15592 if (func === _) {
15593 _.mixin(source, options);
15594 } else {
15595 _.mixin(func, source, options);
15596 }
15597 var wrapped = func(array),
15598 actual = wrapped.a();
15599
15600 if (options.chain) {
15601 assert.strictEqual(actual.value(), 'a', message(func, true));
15602 assert.ok(actual instanceof func, message(func, true));
15603 } else {
15604 assert.strictEqual(actual, 'a', message(func, false));
15605 assert.notOk(actual instanceof func, message(func, false));
15606 }
15607 reset(func);
15608 }
15609 else {
15610 skipAssert(assert, 2);
15611 }
15612 });
15613 });
15614 });
15615
15616 QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
15617 assert.expect(1);
15618
15619 _.mixin({ 'a': noop }, {});
15620 assert.notOk('a' in _);
15621 reset(_);
15622 });
15623
15624 QUnit.test('should not error for non-object `options` values', function(assert) {
15625 assert.expect(2);
15626
15627 var pass = true;
15628
15629 try {
15630 _.mixin({}, source, 1);
15631 } catch (e) {
15632 pass = false;
15633 }
15634 assert.ok(pass);
15635
15636 pass = true;
15637
15638 try {
15639 _.mixin(source, 1);
15640 } catch (e) {
15641 pass = false;
15642 }
15643 assert.ok(pass);
15644
15645 reset(_);
15646 });
15647
15648 QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
15649 assert.expect(2);
15650
15651 lodashStable.each([_, Wrapper], function(func) {
15652 if (!isNpm) {
15653 if (func === _) {
15654 var wrapped = _(source),
15655 actual = wrapped.mixin();
15656
15657 assert.strictEqual(actual.value(), _);
15658 }
15659 else {
15660 wrapped = _(func);
15661 actual = wrapped.mixin(source);
15662 assert.notStrictEqual(actual, wrapped);
15663 }
15664 reset(func);
15665 }
15666 else {
15667 skipAssert(assert);
15668 }
15669 });
15670 });
15671
15672 QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
15673 assert.expect(1);
15674
15675 if (!isNpm) {
15676 _.mixin({ 'a': _.countBy, 'b': _.filter });
15677
15678 var array = lodashStable.range(LARGE_ARRAY_SIZE),
15679 actual = _(array).a().map(square).b(isEven).take().value();
15680
15681 assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
15682
15683 reset(_);
15684 }
15685 else {
15686 skipAssert(assert);
15687 }
15688 });
15689 }());
15690
15691 /*--------------------------------------------------------------------------*/
15692
15693 QUnit.module('lodash.multiply');
15694
15695 (function() {
15696 QUnit.test('should multiply two numbers', function(assert) {
15697 assert.expect(3);
15698
15699 assert.strictEqual(_.multiply(6, 4), 24);
15700 assert.strictEqual(_.multiply(-6, 4), -24);
15701 assert.strictEqual(_.multiply(-6, -4), 24);
15702 });
15703
15704 QUnit.test('should coerce arguments to numbers', function(assert) {
15705 assert.expect(2);
15706
15707 assert.strictEqual(_.multiply('6', '4'), 24);
15708 assert.deepEqual(_.multiply('x', 'y'), NaN);
15709 });
15710 }());
15711
15712 /*--------------------------------------------------------------------------*/
15713
15714 QUnit.module('lodash.orderBy');
15715
15716 (function() {
15717 var objects = [
15718 { 'a': 'x', 'b': 3 },
15719 { 'a': 'y', 'b': 4 },
15720 { 'a': 'x', 'b': 1 },
15721 { 'a': 'y', 'b': 2 }
15722 ];
15723
15724 QUnit.test('should sort by a single property by a specified order', function(assert) {
15725 assert.expect(1);
15726
15727 var actual = _.orderBy(objects, 'a', 'desc');
15728 assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15729 });
15730
15731 QUnit.test('should sort by multiple properties by specified orders', function(assert) {
15732 assert.expect(1);
15733
15734 var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
15735 assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
15736 });
15737
15738 QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
15739 assert.expect(2);
15740
15741 var expected = [objects[2], objects[0], objects[3], objects[1]],
15742 actual = _.orderBy(objects, ['a', 'b']);
15743
15744 assert.deepEqual(actual, expected);
15745
15746 expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
15747
15748 actual = lodashStable.map(falsey, function(order, index) {
15749 return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
15750 });
15751
15752 assert.deepEqual(actual, expected);
15753 });
15754
15755 QUnit.test('should work with `orders` specified as string objects', function(assert) {
15756 assert.expect(1);
15757
15758 var actual = _.orderBy(objects, ['a'], [Object('desc')]);
15759 assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
15760 });
15761 }());
15762
15763 /*--------------------------------------------------------------------------*/
15764
15765 QUnit.module('lodash.overArgs');
15766
15767 (function() {
15768 function fn() {
15769 return slice.call(arguments);
15770 }
15771
15772 QUnit.test('should transform each argument', function(assert) {
15773 assert.expect(1);
15774
15775 var over = _.overArgs(fn, doubled, square);
15776 assert.deepEqual(over(5, 10), [10, 100]);
15777 });
15778
15779 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
15780 assert.expect(1);
15781
15782 var over = _.overArgs(fn, undefined, null);
15783 assert.deepEqual(over('a', 'b'), ['a', 'b']);
15784 });
15785
15786 QUnit.test('should work with `_.property` shorthands', function(assert) {
15787 assert.expect(1);
15788
15789 var over = _.overArgs(fn, 'b', 'a');
15790 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
15791 });
15792
15793 QUnit.test('should work with `_.matches` shorthands', function(assert) {
15794 assert.expect(1);
15795
15796 var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
15797 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
15798 });
15799
15800 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
15801 assert.expect(1);
15802
15803 var over = _.overArgs(fn, ['b', 1], [['a', 1]]);
15804 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
15805 });
15806
15807 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
15808 assert.expect(2);
15809
15810 var over = _.overArgs(fn, ['a', 1]);
15811 assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
15812
15813 over = _.overArgs(fn, [['a', 1]]);
15814 assert.deepEqual(over({ 'a': 1 }), [true]);
15815 });
15816
15817 QUnit.test('should flatten `transforms`', function(assert) {
15818 assert.expect(1);
15819
15820 var over = _.overArgs(fn, [doubled, square], String);
15821 assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
15822 });
15823
15824 QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
15825 assert.expect(1);
15826
15827 var over = _.overArgs(fn, doubled, square);
15828 assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
15829 });
15830
15831 QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
15832 assert.expect(1);
15833
15834 var over = _.overArgs(fn);
15835 assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
15836 });
15837
15838 QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
15839 assert.expect(1);
15840
15841 var over = _.overArgs(fn, doubled, identity);
15842 assert.deepEqual(over(5), [10]);
15843 });
15844
15845 QUnit.test('should provide the correct argument to each transform', function(assert) {
15846 assert.expect(1);
15847
15848 var argsList = [],
15849 transform = function() { argsList.push(slice.call(arguments)); },
15850 over = _.overArgs(noop, transform, transform, transform);
15851
15852 over('a', 'b');
15853 assert.deepEqual(argsList, [['a'], ['b']]);
15854 });
15855
15856 QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
15857 assert.expect(1);
15858
15859 var over = _.overArgs(function(x) {
15860 return this[x];
15861 }, function(x) {
15862 return this === x;
15863 });
15864
15865 var object = { 'over': over, 'true': 1 };
15866 assert.strictEqual(object.over(object), 1);
15867 });
15868 }());
15869
15870 /*--------------------------------------------------------------------------*/
15871
15872 QUnit.module('lodash.negate');
15873
15874 (function() {
15875 QUnit.test('should create a function that negates the result of `func`', function(assert) {
15876 assert.expect(2);
15877
15878 var negate = _.negate(isEven);
15879
15880 assert.strictEqual(negate(1), true);
15881 assert.strictEqual(negate(2), false);
15882 });
15883 }());
15884
15885 /*--------------------------------------------------------------------------*/
15886
15887 QUnit.module('lodash.noop');
15888
15889 (function() {
15890 QUnit.test('should return `undefined`', function(assert) {
15891 assert.expect(1);
15892
15893 var values = empties.concat(true, new Date, _, 1, /x/, 'a'),
15894 expected = lodashStable.map(values, noop);
15895
15896 var actual = lodashStable.map(values, function(value, index) {
15897 return index ? _.noop(value) : _.noop();
15898 });
15899
15900 assert.deepEqual(actual, expected);
15901 });
15902 }());
15903
15904 /*--------------------------------------------------------------------------*/
15905
15906 QUnit.module('lodash.noConflict');
15907
15908 (function() {
15909 QUnit.test('should return the `lodash` function', function(assert) {
15910 assert.expect(2);
15911
15912 if (!isModularize) {
15913 assert.strictEqual(_.noConflict(), oldDash);
15914 assert.notStrictEqual(root._, oldDash);
15915 root._ = oldDash;
15916 }
15917 else {
15918 skipAssert(assert, 2);
15919 }
15920 });
15921
15922 QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
15923 assert.expect(2);
15924
15925 if (!isModularize) {
15926 var object = root._ = {};
15927 assert.strictEqual(_.noConflict(), oldDash);
15928 assert.strictEqual(root._, object);
15929 root._ = oldDash;
15930 }
15931 else {
15932 skipAssert(assert, 2);
15933 }
15934 });
15935
15936 QUnit.test('should work with a `root` of `this`', function(assert) {
15937 assert.expect(2);
15938
15939 if (!isModularize && !coverage && (!document && realm.object)) {
15940 var fs = require('fs'),
15941 vm = require('vm'),
15942 expected = {},
15943 context = vm.createContext({ '_': expected, 'console': console }),
15944 source = fs.readFileSync(filePath, 'utf8');
15945
15946 vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
15947
15948 assert.strictEqual(context._, expected);
15949 assert.ok(context.lodash);
15950 }
15951 else {
15952 skipAssert(assert, 2);
15953 }
15954 });
15955 }());
15956
15957 /*--------------------------------------------------------------------------*/
15958
15959 QUnit.module('lodash.now');
15960
15961 (function() {
15962 QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
15963 assert.expect(2);
15964
15965 var done = assert.async();
15966
15967 var stamp = +new Date,
15968 actual = _.now();
15969
15970 assert.ok(actual >= stamp);
15971
15972 setTimeout(function() {
15973 assert.ok(_.now() > actual);
15974 done();
15975 }, 32);
15976 });
15977 }());
15978
15979 /*--------------------------------------------------------------------------*/
15980
15981 QUnit.module('lodash.nth');
15982
15983 (function() {
15984 var array = ['a', 'b', 'c', 'd'];
15985
15986 QUnit.test('should get the nth element of `array`', function(assert) {
15987 assert.expect(1);
15988
15989 var actual = lodashStable.map(array, function(value, index) {
15990 return _.nth(array, index);
15991 });
15992
15993 assert.deepEqual(actual, array);
15994 });
15995
15996 QUnit.test('should work with a negative `n`', function(assert) {
15997 assert.expect(1);
15998
15999 var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
16000 return _.nth(array, -n);
16001 });
16002
16003 assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16004 });
16005
16006 QUnit.test('should coerce `n` to an integer', function(assert) {
16007 assert.expect(2);
16008
16009 var values = falsey,
16010 expected = lodashStable.map(values, alwaysA);
16011
16012 var actual = lodashStable.map(values, function(n) {
16013 return n ? _.nth(array, n) : _.nth(array);
16014 });
16015
16016 assert.deepEqual(actual, expected);
16017
16018 values = ['1', 1.6];
16019 expected = lodashStable.map(values, alwaysB);
16020
16021 actual = lodashStable.map(values, function(n) {
16022 return _.nth(array, n);
16023 });
16024
16025 assert.deepEqual(actual, expected);
16026 });
16027
16028 QUnit.test('should return `undefined` for empty arrays', function(assert) {
16029 assert.expect(1);
16030
16031 var values = [null, undefined, []],
16032 expected = lodashStable.map(values, noop);
16033
16034 var actual = lodashStable.map(values, function(array) {
16035 return _.nth(array, 1);
16036 });
16037
16038 assert.deepEqual(actual, expected);
16039 });
16040
16041 QUnit.test('should return `undefined` for non-indexes', function(assert) {
16042 assert.expect(1);
16043
16044 var array = [1, 2],
16045 values = [Infinity, array.length],
16046 expected = lodashStable.map(values, noop);
16047
16048 array[-1] = 3;
16049
16050 var actual = lodashStable.map(values, function(n) {
16051 return _.nth(array, n);
16052 });
16053
16054 assert.deepEqual(actual, expected);
16055 });
16056 }());
16057
16058 /*--------------------------------------------------------------------------*/
16059
16060 QUnit.module('lodash.nthArg');
16061
16062 (function() {
16063 var args = ['a', 'b', 'c', 'd'];
16064
16065 QUnit.test('should create a function that returns its nth argument', function(assert) {
16066 assert.expect(1);
16067
16068 var actual = lodashStable.map(args, function(value, index) {
16069 var func = _.nthArg(index);
16070 return func.apply(undefined, args);
16071 });
16072
16073 assert.deepEqual(actual, args);
16074 });
16075
16076 QUnit.test('should work with a negative `n`', function(assert) {
16077 assert.expect(1);
16078
16079 var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
16080 var func = _.nthArg(-n);
16081 return func.apply(undefined, args);
16082 });
16083
16084 assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
16085 });
16086
16087 QUnit.test('should coerce `n` to an integer', function(assert) {
16088 assert.expect(2);
16089
16090 var values = falsey,
16091 expected = lodashStable.map(values, alwaysA);
16092
16093 var actual = lodashStable.map(values, function(n) {
16094 var func = n ? _.nthArg(n) : _.nthArg();
16095 return func.apply(undefined, args);
16096 });
16097
16098 assert.deepEqual(actual, expected);
16099
16100 values = ['1', 1.6];
16101 expected = lodashStable.map(values, alwaysB);
16102
16103 actual = lodashStable.map(values, function(n) {
16104 var func = _.nthArg(n);
16105 return func.apply(undefined, args);
16106 });
16107
16108 assert.deepEqual(actual, expected);
16109 });
16110
16111 QUnit.test('should return `undefined` for empty arrays', function(assert) {
16112 assert.expect(1);
16113
16114 var func = _.nthArg(1);
16115 assert.strictEqual(func(), undefined);
16116 });
16117
16118 QUnit.test('should return `undefined` for non-indexes', function(assert) {
16119 assert.expect(1);
16120
16121 var values = [Infinity, args.length],
16122 expected = lodashStable.map(values, noop);
16123
16124 var actual = lodashStable.map(values, function(n) {
16125 var func = _.nthArg(n);
16126 return func.apply(undefined, args);
16127 });
16128
16129 assert.deepEqual(actual, expected);
16130 });
16131 }());
16132
16133 /*--------------------------------------------------------------------------*/
16134
16135 QUnit.module('lodash.omit');
16136
16137 (function() {
16138 var args = arguments,
16139 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16140
16141 QUnit.test('should flatten `props`', function(assert) {
16142 assert.expect(2);
16143
16144 assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
16145 assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
16146 });
16147
16148 QUnit.test('should work with a primitive `object` argument', function(assert) {
16149 assert.expect(1);
16150
16151 stringProto.a = 1;
16152 stringProto.b = 2;
16153
16154 assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
16155
16156 delete stringProto.a;
16157 delete stringProto.b;
16158 });
16159
16160 QUnit.test('should return an empty object when `object` is nullish', function(assert) {
16161 assert.expect(2);
16162
16163 objectProto.a = 1;
16164 lodashStable.each([null, undefined], function(value) {
16165 assert.deepEqual(_.omit(value, 'valueOf'), {});
16166 });
16167 delete objectProto.a;
16168 });
16169
16170 QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
16171 assert.expect(1);
16172
16173 assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
16174 });
16175
16176 QUnit.test('should coerce property names to strings', function(assert) {
16177 assert.expect(1);
16178
16179 assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
16180 });
16181 }('a', 'c'));
16182
16183 /*--------------------------------------------------------------------------*/
16184
16185 QUnit.module('lodash.omitBy');
16186
16187 (function() {
16188 QUnit.test('should work with a predicate argument', function(assert) {
16189 assert.expect(1);
16190
16191 var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
16192
16193 var actual = _.omitBy(object, function(n) {
16194 return n != 2 && n != 4;
16195 });
16196
16197 assert.deepEqual(actual, { 'b': 2, 'd': 4 });
16198 });
16199 }());
16200
16201 /*--------------------------------------------------------------------------*/
16202
16203 QUnit.module('omit methods');
16204
16205 lodashStable.each(['omit', 'omitBy'], function(methodName) {
16206 var expected = { 'b': 2, 'd': 4 },
16207 func = _[methodName],
16208 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
16209 prop = lodashStable.nthArg(1);
16210
16211 if (methodName == 'omitBy') {
16212 prop = function(object, props) {
16213 props = lodashStable.castArray(props);
16214 return function(value) {
16215 return lodashStable.some(props, function(key) {
16216 key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
16217 return object[key] === value;
16218 });
16219 };
16220 };
16221 }
16222 QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
16223 assert.expect(2);
16224
16225 assert.deepEqual(func(object, prop(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
16226 assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
16227 });
16228
16229 QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
16230 assert.expect(1);
16231
16232 function Foo() {}
16233 Foo.prototype = object;
16234
16235 assert.deepEqual(func(new Foo, prop(object, ['a', 'c'])), expected);
16236 });
16237
16238 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
16239 assert.expect(1);
16240
16241 var object = { '-0': 'a', '0': 'b' },
16242 props = [-0, Object(-0), 0, Object(0)],
16243 expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
16244
16245 var actual = lodashStable.map(props, function(key) {
16246 return func(object, prop(object, key));
16247 });
16248
16249 assert.deepEqual(actual, expected);
16250 });
16251
16252 QUnit.test('`_.' + methodName + '` should include symbol properties', function(assert) {
16253 assert.expect(2);
16254
16255 function Foo() {
16256 this.a = 0;
16257 this[symbol] = 1;
16258 }
16259
16260 if (Symbol) {
16261 var symbol2 = Symbol('b');
16262 Foo.prototype[symbol2] = 2;
16263
16264 var foo = new Foo,
16265 actual = func(foo, prop(foo, 'a'));
16266
16267 assert.strictEqual(actual[symbol], 1);
16268 assert.strictEqual(actual[symbol2], 2);
16269 }
16270 else {
16271 skipAssert(assert, 2);
16272 }
16273 });
16274
16275 QUnit.test('`_.' + methodName + '` should create an object with omitted symbol properties', function(assert) {
16276 assert.expect(6);
16277
16278 function Foo() {
16279 this.a = 0;
16280 this[symbol] = 1;
16281 }
16282
16283 if (Symbol) {
16284 var symbol2 = Symbol('b');
16285 Foo.prototype[symbol2] = 2;
16286
16287 var foo = new Foo,
16288 actual = func(foo, prop(foo, symbol));
16289
16290 assert.strictEqual(actual.a, 0);
16291 assert.strictEqual(actual[symbol], undefined);
16292 assert.strictEqual(actual[symbol2], 2);
16293
16294 actual = func(foo, prop(foo, symbol2));
16295
16296 assert.strictEqual(actual.a, 0);
16297 assert.strictEqual(actual[symbol], 1);
16298 assert.strictEqual(actual[symbol2], undefined);
16299 }
16300 else {
16301 skipAssert(assert, 6);
16302 }
16303 });
16304
16305 QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
16306 assert.expect(1);
16307
16308 var array = [1, 2, 3];
16309 assert.deepEqual(func(array, prop(array, ['0', '2'])), { '1': 2 });
16310 });
16311 });
16312
16313 /*--------------------------------------------------------------------------*/
16314
16315 QUnit.module('lodash.once');
16316
16317 (function() {
16318 QUnit.test('should invoke `func` once', function(assert) {
16319 assert.expect(2);
16320
16321 var count = 0,
16322 once = _.once(function() { return ++count; });
16323
16324 once();
16325 assert.strictEqual(once(), 1);
16326 assert.strictEqual(count, 1);
16327 });
16328
16329 QUnit.test('should ignore recursive calls', function(assert) {
16330 assert.expect(2);
16331
16332 var count = 0;
16333
16334 var once = _.once(function() {
16335 once();
16336 return ++count;
16337 });
16338
16339 assert.strictEqual(once(), 1);
16340 assert.strictEqual(count, 1);
16341 });
16342
16343 QUnit.test('should not throw more than once', function(assert) {
16344 assert.expect(2);
16345
16346 var pass = true;
16347
16348 var once = _.once(function() {
16349 throw new Error;
16350 });
16351
16352 assert.raises(once);
16353
16354 try {
16355 once();
16356 } catch (e) {
16357 pass = false;
16358 }
16359 assert.ok(pass);
16360 });
16361 }());
16362
16363 /*--------------------------------------------------------------------------*/
16364
16365 QUnit.module('lodash.over');
16366
16367 (function() {
16368 QUnit.test('should create a function that invokes `iteratees`', function(assert) {
16369 assert.expect(1);
16370
16371 var over = _.over(Math.max, Math.min);
16372 assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
16373 });
16374
16375 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16376 assert.expect(1);
16377
16378 var over = _.over(undefined, null);
16379 assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
16380 });
16381
16382 QUnit.test('should work with `_.property` shorthands', function(assert) {
16383 assert.expect(1);
16384
16385 var over = _.over('b', 'a');
16386 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
16387 });
16388
16389 QUnit.test('should work with `_.matches` shorthands', function(assert) {
16390 assert.expect(1);
16391
16392 var over = _.over({ 'b': 1 }, { 'a': 1 });
16393 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
16394 });
16395
16396 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16397 assert.expect(2);
16398
16399 var over = _.over(['b', 2], [['a', 2]]);
16400
16401 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
16402 assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
16403 });
16404
16405 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16406 assert.expect(4);
16407
16408 var over = _.over(['a', 1]);
16409
16410 assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
16411 assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
16412
16413 over = _.over([['a', 1]]);
16414
16415 assert.deepEqual(over({ 'a': 1 }), [true]);
16416 assert.deepEqual(over({ 'a': 2 }), [false]);
16417 });
16418
16419 QUnit.test('should provide arguments to predicates', function(assert) {
16420 assert.expect(1);
16421
16422 var over = _.over(function() {
16423 return slice.call(arguments);
16424 });
16425
16426 assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
16427 });
16428
16429 QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
16430 assert.expect(1);
16431
16432 var over = _.over(function() { return this.b; }, function() { return this.a; }),
16433 object = { 'over': over, 'a': 1, 'b': 2 };
16434
16435 assert.deepEqual(object.over(), [2, 1]);
16436 });
16437 }());
16438
16439 /*--------------------------------------------------------------------------*/
16440
16441 QUnit.module('lodash.overEvery');
16442
16443 (function() {
16444 QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
16445 assert.expect(1);
16446
16447 var over = _.overEvery(alwaysTrue, alwaysOne, alwaysA);
16448 assert.strictEqual(over(), true);
16449 });
16450
16451 QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
16452 assert.expect(2);
16453
16454 var count = 0,
16455 countFalse = function() { count++; return false; },
16456 countTrue = function() { count++; return true; },
16457 over = _.overEvery(countTrue, countFalse, countTrue);
16458
16459 assert.strictEqual(over(), false);
16460 assert.strictEqual(count, 2);
16461 });
16462
16463 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16464 assert.expect(2);
16465
16466 var over = _.overEvery(undefined, null);
16467
16468 assert.strictEqual(over(true), true);
16469 assert.strictEqual(over(false), false);
16470 });
16471
16472 QUnit.test('should work with `_.property` shorthands', function(assert) {
16473 assert.expect(2);
16474
16475 var over = _.overEvery('b', 'a');
16476
16477 assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
16478 assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
16479 });
16480
16481 QUnit.test('should work with `_.matches` shorthands', function(assert) {
16482 assert.expect(2);
16483
16484 var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
16485
16486 assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16487 assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16488 });
16489
16490 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16491 assert.expect(2);
16492
16493 var over = _.overEvery(['b', 2], [['a', 1]]);
16494
16495 assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
16496 assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
16497 });
16498
16499 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16500 assert.expect(5);
16501
16502 var over = _.overEvery(['a', 1]);
16503
16504 assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
16505 assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
16506 assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
16507
16508 over = _.overEvery([['a', 1]]);
16509
16510 assert.strictEqual(over({ 'a': 1 }), true);
16511 assert.strictEqual(over({ 'a': 2 }), false);
16512 });
16513
16514 QUnit.test('should flatten `predicates`', function(assert) {
16515 assert.expect(1);
16516
16517 var over = _.overEvery(alwaysTrue, [alwaysFalse]);
16518 assert.strictEqual(over(), false);
16519 });
16520
16521 QUnit.test('should provide arguments to predicates', function(assert) {
16522 assert.expect(1);
16523
16524 var args;
16525
16526 var over = _.overEvery(function() {
16527 args = slice.call(arguments);
16528 });
16529
16530 over('a', 'b', 'c');
16531 assert.deepEqual(args, ['a', 'b', 'c']);
16532 });
16533
16534 QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16535 assert.expect(2);
16536
16537 var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
16538 object = { 'over': over, 'a': 1, 'b': 2 };
16539
16540 assert.strictEqual(object.over(), true);
16541
16542 object.a = 0;
16543 assert.strictEqual(object.over(), false);
16544 });
16545 }());
16546
16547 /*--------------------------------------------------------------------------*/
16548
16549 QUnit.module('lodash.overSome');
16550
16551 (function() {
16552 QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
16553 assert.expect(2);
16554
16555 var over = _.overSome(alwaysFalse, alwaysOne, alwaysEmptyString);
16556 assert.strictEqual(over(), true);
16557
16558 over = _.overSome(alwaysNull, alwaysA, alwaysZero);
16559 assert.strictEqual(over(), true);
16560 });
16561
16562 QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
16563 assert.expect(2);
16564
16565 var count = 0,
16566 countFalse = function() { count++; return false; },
16567 countTrue = function() { count++; return true; },
16568 over = _.overSome(countFalse, countTrue, countFalse);
16569
16570 assert.strictEqual(over(), true);
16571 assert.strictEqual(count, 2);
16572 });
16573
16574 QUnit.test('should return `false` if all predicates return falsey', function(assert) {
16575 assert.expect(2);
16576
16577 var over = _.overSome(alwaysFalse, alwaysFalse, alwaysFalse);
16578 assert.strictEqual(over(), false);
16579
16580 over = _.overSome(alwaysNull, alwaysZero, alwaysEmptyString);
16581 assert.strictEqual(over(), false);
16582 });
16583
16584 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
16585 assert.expect(2);
16586
16587 var over = _.overSome(undefined, null);
16588
16589 assert.strictEqual(over(true), true);
16590 assert.strictEqual(over(false), false);
16591 });
16592
16593 QUnit.test('should work with `_.property` shorthands', function(assert) {
16594 assert.expect(2);
16595
16596 var over = _.overSome('b', 'a');
16597
16598 assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
16599 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16600 });
16601
16602 QUnit.test('should work with `_.matches` shorthands', function(assert) {
16603 assert.expect(2);
16604
16605 var over = _.overSome({ 'b': 2 }, { 'a': 1 });
16606
16607 assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16608 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16609 });
16610
16611 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
16612 assert.expect(2);
16613
16614 var over = _.overSome(['a', 1], [['b', 2]]);
16615
16616 assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
16617 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
16618 });
16619
16620 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
16621 assert.expect(5);
16622
16623 var over = _.overSome(['a', 1]);
16624
16625 assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
16626 assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
16627 assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
16628
16629 over = _.overSome([['a', 1]]);
16630
16631 assert.strictEqual(over({ 'a': 1 }), true);
16632 assert.strictEqual(over({ 'a': 2 }), false);
16633 });
16634
16635 QUnit.test('should flatten `predicates`', function(assert) {
16636 assert.expect(1);
16637
16638 var over = _.overSome(alwaysFalse, [alwaysTrue]);
16639 assert.strictEqual(over(), true);
16640 });
16641
16642 QUnit.test('should provide arguments to predicates', function(assert) {
16643 assert.expect(1);
16644
16645 var args;
16646
16647 var over = _.overSome(function() {
16648 args = slice.call(arguments);
16649 });
16650
16651 over('a', 'b', 'c');
16652 assert.deepEqual(args, ['a', 'b', 'c']);
16653 });
16654
16655 QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
16656 assert.expect(2);
16657
16658 var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
16659 object = { 'over': over, 'a': 1, 'b': 2 };
16660
16661 assert.strictEqual(object.over(), true);
16662
16663 object.a = object.b = 0;
16664 assert.strictEqual(object.over(), false);
16665 });
16666 }());
16667
16668 /*--------------------------------------------------------------------------*/
16669
16670 QUnit.module('lodash.pad');
16671
16672 (function() {
16673 var string = 'abc';
16674
16675 QUnit.test('should pad a string to a given length', function(assert) {
16676 assert.expect(1);
16677
16678 var values = [, undefined],
16679 expected = lodashStable.map(values, lodashStable.constant(' abc '));
16680
16681 var actual = lodashStable.map(values, function(value, index) {
16682 return index ? _.pad(string, 6, value) : _.pad(string, 6);
16683 });
16684
16685 assert.deepEqual(actual, expected);
16686 });
16687
16688 QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16689 assert.expect(2);
16690
16691 assert.strictEqual(_.pad(string, 8), ' abc ');
16692 assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
16693 });
16694
16695 QUnit.test('should coerce `string` to a string', function(assert) {
16696 assert.expect(1);
16697
16698 var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16699 expected = lodashStable.map(values, alwaysTrue);
16700
16701 var actual = lodashStable.map(values, function(value) {
16702 return _.pad(value, 6) === ' abc ';
16703 });
16704
16705 assert.deepEqual(actual, expected);
16706 });
16707 }());
16708
16709 /*--------------------------------------------------------------------------*/
16710
16711 QUnit.module('lodash.padEnd');
16712
16713 (function() {
16714 var string = 'abc';
16715
16716 QUnit.test('should pad a string to a given length', function(assert) {
16717 assert.expect(1);
16718
16719 var values = [, undefined],
16720 expected = lodashStable.map(values, lodashStable.constant('abc '));
16721
16722 var actual = lodashStable.map(values, function(value, index) {
16723 return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
16724 });
16725
16726 assert.deepEqual(actual, expected);
16727 });
16728
16729 QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16730 assert.expect(1);
16731
16732 assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
16733 });
16734
16735 QUnit.test('should coerce `string` to a string', function(assert) {
16736 assert.expect(1);
16737
16738 var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16739 expected = lodashStable.map(values, alwaysTrue);
16740
16741 var actual = lodashStable.map(values, function(value) {
16742 return _.padEnd(value, 6) === 'abc ';
16743 });
16744
16745 assert.deepEqual(actual, expected);
16746 });
16747 }());
16748
16749 /*--------------------------------------------------------------------------*/
16750
16751 QUnit.module('lodash.padStart');
16752
16753 (function() {
16754 var string = 'abc';
16755
16756 QUnit.test('should pad a string to a given length', function(assert) {
16757 assert.expect(1);
16758
16759 var values = [, undefined],
16760 expected = lodashStable.map(values, lodashStable.constant(' abc'));
16761
16762 var actual = lodashStable.map(values, function(value, index) {
16763 return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
16764 });
16765
16766 assert.deepEqual(actual, expected);
16767 });
16768
16769 QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
16770 assert.expect(1);
16771
16772 assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
16773 });
16774
16775 QUnit.test('should coerce `string` to a string', function(assert) {
16776 assert.expect(1);
16777
16778 var values = [Object(string), { 'toString': lodashStable.constant(string) }],
16779 expected = lodashStable.map(values, alwaysTrue);
16780
16781 var actual = lodashStable.map(values, function(value) {
16782 return _.padStart(value, 6) === ' abc';
16783 });
16784
16785 assert.deepEqual(actual, expected);
16786 });
16787 }());
16788
16789 /*--------------------------------------------------------------------------*/
16790
16791 QUnit.module('pad methods');
16792
16793 lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
16794 var func = _[methodName],
16795 isPad = methodName == 'pad',
16796 isStart = methodName == 'padStart',
16797 string = 'abc';
16798
16799 QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
16800 assert.expect(2);
16801
16802 assert.strictEqual(func(string, 2), string);
16803 assert.strictEqual(func(string, 3), string);
16804 });
16805
16806 QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
16807 assert.expect(2);
16808
16809 lodashStable.each([0, -2], function(length) {
16810 assert.strictEqual(func(string, length), string);
16811 });
16812 });
16813
16814 QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
16815 assert.expect(2);
16816
16817 lodashStable.each(['', '4'], function(length) {
16818 var actual = length ? (isStart ? ' abc' : 'abc ') : string;
16819 assert.strictEqual(func(string, length), actual);
16820 });
16821 });
16822
16823 QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
16824 assert.expect(6);
16825
16826 lodashStable.each([undefined, '_-'], function(chars) {
16827 var expected = chars ? (isPad ? '__' : chars) : ' ';
16828 assert.strictEqual(func(null, 2, chars), expected);
16829 assert.strictEqual(func(undefined, 2, chars), expected);
16830 assert.strictEqual(func('', 2, chars), expected);
16831 });
16832 });
16833
16834 QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
16835 assert.expect(1);
16836
16837 var values = ['', Object('')],
16838 expected = lodashStable.map(values, lodashStable.constant(string));
16839
16840 var actual = lodashStable.map(values, function(value) {
16841 return _.pad(string, 6, value);
16842 });
16843
16844 assert.deepEqual(actual, expected);
16845 });
16846 });
16847
16848 /*--------------------------------------------------------------------------*/
16849
16850 QUnit.module('lodash.parseInt');
16851
16852 (function() {
16853 QUnit.test('should accept a `radix` argument', function(assert) {
16854 assert.expect(1);
16855
16856 var expected = lodashStable.range(2, 37);
16857
16858 var actual = lodashStable.map(expected, function(radix) {
16859 return _.parseInt('10', radix);
16860 });
16861
16862 assert.deepEqual(actual, expected);
16863 });
16864
16865 QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
16866 assert.expect(4);
16867
16868 assert.strictEqual(_.parseInt('10'), 10);
16869 assert.strictEqual(_.parseInt('10', 0), 10);
16870 assert.strictEqual(_.parseInt('10', 10), 10);
16871 assert.strictEqual(_.parseInt('10', undefined), 10);
16872 });
16873
16874 QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
16875 assert.expect(8);
16876
16877 lodashStable.each(['0x20', '0X20'], function(string) {
16878 assert.strictEqual(_.parseInt(string), 32);
16879 assert.strictEqual(_.parseInt(string, 0), 32);
16880 assert.strictEqual(_.parseInt(string, 16), 32);
16881 assert.strictEqual(_.parseInt(string, undefined), 32);
16882 });
16883 });
16884
16885 QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
16886 assert.expect(2);
16887
16888 assert.strictEqual(_.parseInt('08'), 8);
16889 assert.strictEqual(_.parseInt('08', 10), 8);
16890 });
16891
16892 QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
16893 assert.expect(2);
16894
16895 var expected = [8, 8, 10, 10, 32, 32, 32, 32];
16896
16897 lodashStable.times(2, function(index) {
16898 var actual = [],
16899 func = (index ? (lodashBizarro || {}) : _).parseInt;
16900
16901 if (func) {
16902 lodashStable.times(2, function(otherIndex) {
16903 var string = otherIndex ? '10' : '08';
16904 actual.push(
16905 func(whitespace + string, 10),
16906 func(whitespace + string)
16907 );
16908 });
16909
16910 lodashStable.each(['0x20', '0X20'], function(string) {
16911 actual.push(
16912 func(whitespace + string),
16913 func(whitespace + string, 16)
16914 );
16915 });
16916
16917 assert.deepEqual(actual, expected);
16918 }
16919 else {
16920 skipAssert(assert);
16921 }
16922 });
16923 });
16924
16925 QUnit.test('should coerce `radix` to a number', function(assert) {
16926 assert.expect(2);
16927
16928 var object = { 'valueOf': alwaysZero };
16929 assert.strictEqual(_.parseInt('08', object), 8);
16930 assert.strictEqual(_.parseInt('0x20', object), 32);
16931 });
16932
16933 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
16934 assert.expect(2);
16935
16936 var strings = lodashStable.map(['6', '08', '10'], Object),
16937 actual = lodashStable.map(strings, _.parseInt);
16938
16939 assert.deepEqual(actual, [6, 8, 10]);
16940
16941 actual = lodashStable.map('123', _.parseInt);
16942 assert.deepEqual(actual, [1, 2, 3]);
16943 });
16944 }());
16945
16946 /*--------------------------------------------------------------------------*/
16947
16948 QUnit.module('partial methods');
16949
16950 lodashStable.each(['partial', 'partialRight'], function(methodName) {
16951 var func = _[methodName],
16952 isPartial = methodName == 'partial',
16953 ph = func.placeholder;
16954
16955 QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
16956 assert.expect(1);
16957
16958 var par = func(identity, 'a');
16959 assert.strictEqual(par(), 'a');
16960 });
16961
16962 QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
16963 assert.expect(1);
16964
16965 var fn = function(a, b) { return [a, b]; },
16966 par = func(fn, 'a'),
16967 expected = isPartial ? ['a', 'b'] : ['b', 'a'];
16968
16969 assert.deepEqual(par('b'), expected);
16970 });
16971
16972 QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
16973 assert.expect(1);
16974
16975 var fn = function() { return arguments.length; },
16976 par = func(fn);
16977
16978 assert.strictEqual(par(), 0);
16979 });
16980
16981 QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
16982 assert.expect(1);
16983
16984 var par = func(identity);
16985 assert.strictEqual(par('a'), 'a');
16986 });
16987
16988 QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
16989 assert.expect(4);
16990
16991 var fn = function() { return slice.call(arguments); },
16992 par = func(fn, ph, 'b', ph);
16993
16994 assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
16995 assert.deepEqual(par('a'), ['a', 'b', undefined]);
16996 assert.deepEqual(par(), [undefined, 'b', undefined]);
16997
16998 if (isPartial) {
16999 assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
17000 } else {
17001 par = func(fn, ph, 'c', ph);
17002 assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
17003 }
17004 });
17005
17006 QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
17007 assert.expect(1);
17008
17009 if (!isModularize) {
17010 var _ph = _.placeholder = {},
17011 fn = function() { return slice.call(arguments); },
17012 par = func(fn, _ph, 'b', ph),
17013 expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
17014
17015 assert.deepEqual(par('a', 'c'), expected);
17016 delete _.placeholder;
17017 }
17018 else {
17019 skipAssert(assert);
17020 }
17021 });
17022
17023 QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
17024 assert.expect(1);
17025
17026 var fn = function(a, b, c) {},
17027 par = func(fn, 'a');
17028
17029 assert.strictEqual(par.length, 0);
17030 });
17031
17032 QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
17033 assert.expect(2);
17034
17035 function Foo(value) {
17036 return value && object;
17037 }
17038
17039 var object = {},
17040 par = func(Foo);
17041
17042 assert.ok(new par instanceof Foo);
17043 assert.strictEqual(new par(true), object);
17044 });
17045
17046 QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
17047 assert.expect(3);
17048
17049 function greet(greeting, name) {
17050 return greeting + ' ' + name;
17051 }
17052
17053 var par1 = func(greet, 'hi'),
17054 par2 = func(par1, 'barney'),
17055 par3 = func(par1, 'pebbles');
17056
17057 assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
17058 assert.strictEqual(par2(), isPartial ? 'hi barney' : 'barney hi');
17059 assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
17060 });
17061
17062 QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
17063 assert.expect(2);
17064
17065 var fn = function(a, b, c) { return a + b + c; },
17066 curried = _.curry(func(fn, 1), 2);
17067
17068 assert.strictEqual(curried(2, 3), 6);
17069 assert.strictEqual(curried(2)(3), 6);
17070 });
17071
17072 QUnit.test('should work with placeholders and curried functions', function(assert) {
17073 assert.expect(1);
17074
17075 var fn = function() { return slice.call(arguments); },
17076 curried = _.curry(fn),
17077 par = func(curried, ph, 'b', ph, 'd');
17078
17079 assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
17080 });
17081 });
17082
17083 /*--------------------------------------------------------------------------*/
17084
17085 QUnit.module('lodash.partialRight');
17086
17087 (function() {
17088 QUnit.test('should work as a deep `_.defaults`', function(assert) {
17089 assert.expect(1);
17090
17091 var object = { 'a': { 'b': 1 } },
17092 source = { 'a': { 'b': 2, 'c': 3 } },
17093 expected = { 'a': { 'b': 1, 'c': 3 } };
17094
17095 var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
17096 return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
17097 });
17098
17099 assert.deepEqual(defaultsDeep(object, source), expected);
17100 });
17101 }());
17102
17103 /*--------------------------------------------------------------------------*/
17104
17105 QUnit.module('methods using `createWrapper`');
17106
17107 (function() {
17108 function fn() {
17109 return slice.call(arguments);
17110 }
17111
17112 var ph1 = _.bind.placeholder,
17113 ph2 = _.bindKey.placeholder,
17114 ph3 = _.partial.placeholder,
17115 ph4 = _.partialRight.placeholder;
17116
17117 QUnit.test('should work with combinations of partial functions', function(assert) {
17118 assert.expect(1);
17119
17120 var a = _.partial(fn),
17121 b = _.partialRight(a, 3),
17122 c = _.partial(b, 1);
17123
17124 assert.deepEqual(c(2), [1, 2, 3]);
17125 });
17126
17127 QUnit.test('should work with combinations of bound and partial functions', function(assert) {
17128 assert.expect(3);
17129
17130 var fn = function() {
17131 var result = [this.a];
17132 push.apply(result, arguments);
17133 return result;
17134 };
17135
17136 var expected = [1, 2, 3, 4],
17137 object = { 'a': 1, 'fn': fn };
17138
17139 var a = _.bindKey(object, 'fn'),
17140 b = _.partialRight(a, 4),
17141 c = _.partial(b, 2);
17142
17143 assert.deepEqual(c(3), expected);
17144
17145 a = _.bind(fn, object);
17146 b = _.partialRight(a, 4);
17147 c = _.partial(b, 2);
17148
17149 assert.deepEqual(c(3), expected);
17150
17151 a = _.partial(fn, 2);
17152 b = _.bind(a, object);
17153 c = _.partialRight(b, 4);
17154
17155 assert.deepEqual(c(3), expected);
17156 });
17157
17158 QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
17159 assert.expect(2);
17160
17161 function Foo(a, b, c) {
17162 return b === 0 && object;
17163 }
17164
17165 var combo = _.partial(_.partialRight(Foo, 3), 1),
17166 object = {};
17167
17168 assert.ok(new combo(2) instanceof Foo);
17169 assert.strictEqual(new combo(0), object);
17170 });
17171
17172 QUnit.test('should work with combinations of functions with placeholders', function(assert) {
17173 assert.expect(3);
17174
17175 var expected = [1, 2, 3, 4, 5, 6],
17176 object = { 'fn': fn };
17177
17178 var a = _.bindKey(object, 'fn', ph2, 2),
17179 b = _.partialRight(a, ph4, 6),
17180 c = _.partial(b, 1, ph3, 4);
17181
17182 assert.deepEqual(c(3, 5), expected);
17183
17184 a = _.bind(fn, object, ph1, 2);
17185 b = _.partialRight(a, ph4, 6);
17186 c = _.partial(b, 1, ph3, 4);
17187
17188 assert.deepEqual(c(3, 5), expected);
17189
17190 a = _.partial(fn, ph3, 2);
17191 b = _.bind(a, object, 1, ph1, 4);
17192 c = _.partialRight(b, ph4, 6);
17193
17194 assert.deepEqual(c(3, 5), expected);
17195 });
17196
17197 QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
17198 assert.expect(3);
17199
17200 var expected = [1, 2, 3, 4],
17201 object = { 'fn': fn };
17202
17203 var a = _.bindKey(object, 'fn', ph2, 2),
17204 b = _.partialRight(a, ph4, 4),
17205 c = _.partial(b, ph3, 3);
17206
17207 assert.deepEqual(c(1), expected);
17208
17209 a = _.bind(fn, object, ph1, 2);
17210 b = _.partialRight(a, ph4, 4);
17211 c = _.partial(b, ph3, 3);
17212
17213 assert.deepEqual(c(1), expected);
17214
17215 a = _.partial(fn, ph3, 2);
17216 b = _.bind(a, object, ph1, 3);
17217 c = _.partialRight(b, ph4, 4);
17218
17219 assert.deepEqual(c(1), expected);
17220 });
17221
17222 QUnit.test('should work with recursively bound functions', function(assert) {
17223 assert.expect(1);
17224
17225 var fn = function() {
17226 return this.a;
17227 };
17228
17229 var a = _.bind(fn, { 'a': 1 }),
17230 b = _.bind(a, { 'a': 2 }),
17231 c = _.bind(b, { 'a': 3 });
17232
17233 assert.strictEqual(c(), 1);
17234 });
17235
17236 QUnit.test('should work when hot', function(assert) {
17237 assert.expect(12);
17238
17239 lodashStable.times(2, function(index) {
17240 var fn = function() {
17241 var result = [this];
17242 push.apply(result, arguments);
17243 return result;
17244 };
17245
17246 var object = {},
17247 bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17248 expected = [object, 1, 2, 3];
17249
17250 var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17251 var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17252 return index ? bound2(3) : bound2(1, 2, 3);
17253 }));
17254
17255 assert.deepEqual(actual, expected);
17256
17257 actual = _.last(lodashStable.times(HOT_COUNT, function() {
17258 var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
17259 bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
17260
17261 return index ? bound2(3) : bound2(1, 2, 3);
17262 }));
17263
17264 assert.deepEqual(actual, expected);
17265 });
17266
17267 lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
17268 var fn = function(a, b, c) { return [a, b, c]; },
17269 curried = _[methodName](fn),
17270 expected = index ? [3, 2, 1] : [1, 2, 3];
17271
17272 var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17273 return curried(1)(2)(3);
17274 }));
17275
17276 assert.deepEqual(actual, expected);
17277
17278 actual = _.last(lodashStable.times(HOT_COUNT, function() {
17279 var curried = _[methodName](fn);
17280 return curried(1)(2)(3);
17281 }));
17282
17283 assert.deepEqual(actual, expected);
17284 });
17285
17286 lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
17287 var func = _[methodName],
17288 fn = function() { return slice.call(arguments); },
17289 par1 = func(fn, 1),
17290 expected = index ? [3, 2, 1] : [1, 2, 3];
17291
17292 var actual = _.last(lodashStable.times(HOT_COUNT, function() {
17293 var par2 = func(par1, 2);
17294 return par2(3);
17295 }));
17296
17297 assert.deepEqual(actual, expected);
17298
17299 actual = _.last(lodashStable.times(HOT_COUNT, function() {
17300 var par1 = func(fn, 1),
17301 par2 = func(par1, 2);
17302
17303 return par2(3);
17304 }));
17305
17306 assert.deepEqual(actual, expected);
17307 });
17308 });
17309 }());
17310
17311 /*--------------------------------------------------------------------------*/
17312
17313 QUnit.module('lodash.partition');
17314
17315 (function() {
17316 var array = [1, 0, 1];
17317
17318 QUnit.test('should split elements into two groups by `predicate`', function(assert) {
17319 assert.expect(3);
17320
17321 assert.deepEqual(_.partition([], identity), [[], []]);
17322 assert.deepEqual(_.partition(array, alwaysTrue), [array, []]);
17323 assert.deepEqual(_.partition(array, alwaysFalse), [[], array]);
17324 });
17325
17326 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
17327 assert.expect(1);
17328
17329 var values = [, null, undefined],
17330 expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
17331
17332 var actual = lodashStable.map(values, function(value, index) {
17333 return index ? _.partition(array, value) : _.partition(array);
17334 });
17335
17336 assert.deepEqual(actual, expected);
17337 });
17338
17339 QUnit.test('should work with `_.property` shorthands', function(assert) {
17340 assert.expect(1);
17341
17342 var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
17343 actual = _.partition(objects, 'a');
17344
17345 assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
17346 });
17347
17348 QUnit.test('should work with a number for `predicate`', function(assert) {
17349 assert.expect(2);
17350
17351 var array = [
17352 [1, 0],
17353 [0, 1],
17354 [1, 0]
17355 ];
17356
17357 assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
17358 assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
17359 });
17360
17361 QUnit.test('should work with an object for `collection`', function(assert) {
17362 assert.expect(1);
17363
17364 var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
17365 assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
17366 });
17367 }());
17368
17369 /*--------------------------------------------------------------------------*/
17370
17371 QUnit.module('lodash.pick');
17372
17373 (function() {
17374 var args = arguments,
17375 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17376
17377 QUnit.test('should flatten `props`', function(assert) {
17378 assert.expect(2);
17379
17380 assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
17381 assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
17382 });
17383
17384 QUnit.test('should work with a primitive `object` argument', function(assert) {
17385 assert.expect(1);
17386
17387 assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
17388 });
17389
17390 QUnit.test('should return an empty object when `object` is nullish', function(assert) {
17391 assert.expect(2);
17392
17393 lodashStable.each([null, undefined], function(value) {
17394 assert.deepEqual(_.pick(value, 'valueOf'), {});
17395 });
17396 });
17397
17398 QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
17399 assert.expect(1);
17400
17401 assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
17402 });
17403
17404 QUnit.test('should coerce property names to strings', function(assert) {
17405 assert.expect(1);
17406
17407 assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
17408 });
17409 }('a', 'c'));
17410
17411 /*--------------------------------------------------------------------------*/
17412
17413 QUnit.module('lodash.pickBy');
17414
17415 (function() {
17416 QUnit.test('should work with a predicate argument', function(assert) {
17417 assert.expect(1);
17418
17419 var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
17420
17421 var actual = _.pickBy(object, function(n) {
17422 return n == 1 || n == 3;
17423 });
17424
17425 assert.deepEqual(actual, { 'a': 1, 'c': 3 });
17426 });
17427 }());
17428
17429 /*--------------------------------------------------------------------------*/
17430
17431 QUnit.module('pick methods');
17432
17433 lodashStable.each(['pick', 'pickBy'], function(methodName) {
17434 var expected = { 'a': 1, 'c': 3 },
17435 func = _[methodName],
17436 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
17437 prop = lodashStable.nthArg(1);
17438
17439 if (methodName == 'pickBy') {
17440 prop = function(object, props) {
17441 props = lodashStable.castArray(props);
17442 return function(value) {
17443 return lodashStable.some(props, function(key) {
17444 key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
17445 return object[key] === value;
17446 });
17447 };
17448 };
17449 }
17450 QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
17451 assert.expect(2);
17452
17453 assert.deepEqual(func(object, prop(object, 'a')), { 'a': 1 });
17454 assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
17455 });
17456
17457 QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
17458 assert.expect(1);
17459
17460 function Foo() {}
17461 Foo.prototype = object;
17462
17463 var foo = new Foo;
17464 assert.deepEqual(func(foo, prop(foo, ['a', 'c'])), expected);
17465 });
17466
17467 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
17468 assert.expect(1);
17469
17470 var object = { '-0': 'a', '0': 'b' },
17471 props = [-0, Object(-0), 0, Object(0)],
17472 expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
17473
17474 var actual = lodashStable.map(props, function(key) {
17475 return func(object, prop(object, key));
17476 });
17477
17478 assert.deepEqual(actual, expected);
17479 });
17480
17481 QUnit.test('`_.' + methodName + '` should pick symbol properties', function(assert) {
17482 assert.expect(2);
17483
17484 function Foo() {
17485 this[symbol] = 1;
17486 }
17487
17488 if (Symbol) {
17489 var symbol2 = Symbol('b');
17490 Foo.prototype[symbol2] = 2;
17491
17492 var foo = new Foo,
17493 actual = func(foo, prop(foo, [symbol, symbol2]));
17494
17495 assert.strictEqual(actual[symbol], 1);
17496 assert.strictEqual(actual[symbol2], 2);
17497 }
17498 else {
17499 skipAssert(assert, 2);
17500 }
17501 });
17502
17503 QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
17504 assert.expect(1);
17505
17506 var array = [1, 2, 3];
17507 assert.deepEqual(func(array, prop(array, '1')), { '1': 2 });
17508 });
17509 });
17510
17511 /*--------------------------------------------------------------------------*/
17512
17513 QUnit.module('lodash.property');
17514
17515 (function() {
17516 QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
17517 assert.expect(4);
17518
17519 var object = { 'a': 1 };
17520
17521 lodashStable.each(['a', ['a']], function(path) {
17522 var prop = _.property(path);
17523 assert.strictEqual(prop.length, 1);
17524 assert.strictEqual(prop(object), 1);
17525 });
17526 });
17527
17528 QUnit.test('should pluck deep property values', function(assert) {
17529 assert.expect(2);
17530
17531 var object = { 'a': { 'b': 2 } };
17532
17533 lodashStable.each(['a.b', ['a', 'b']], function(path) {
17534 var prop = _.property(path);
17535 assert.strictEqual(prop(object), 2);
17536 });
17537 });
17538
17539 QUnit.test('should pluck inherited property values', function(assert) {
17540 assert.expect(2);
17541
17542 function Foo() {}
17543 Foo.prototype.a = 1;
17544
17545 lodashStable.each(['a', ['a']], function(path) {
17546 var prop = _.property(path);
17547 assert.strictEqual(prop(new Foo), 1);
17548 });
17549 });
17550
17551 QUnit.test('should work with a non-string `path`', function(assert) {
17552 assert.expect(2);
17553
17554 var array = [1, 2, 3];
17555
17556 lodashStable.each([1, [1]], function(path) {
17557 var prop = _.property(path);
17558 assert.strictEqual(prop(array), 2);
17559 });
17560 });
17561
17562 QUnit.test('should preserve the sign of `0`', function(assert) {
17563 assert.expect(1);
17564
17565 var object = { '-0': 'a', '0': 'b' },
17566 props = [-0, Object(-0), 0, Object(0)];
17567
17568 var actual = lodashStable.map(props, function(key) {
17569 var prop = _.property(key);
17570 return prop(object);
17571 });
17572
17573 assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17574 });
17575
17576 QUnit.test('should coerce key to a string', function(assert) {
17577 assert.expect(1);
17578
17579 function fn() {}
17580 fn.toString = lodashStable.constant('fn');
17581
17582 var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
17583 values = [null, undefined, fn, {}];
17584
17585 var actual = lodashStable.transform(objects, function(result, object, index) {
17586 var key = values[index];
17587 lodashStable.each([key, [key]], function(path) {
17588 var prop = _.property(key);
17589 result.push(prop(object));
17590 });
17591 });
17592
17593 assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
17594 });
17595
17596 QUnit.test('should pluck a key over a path', function(assert) {
17597 assert.expect(2);
17598
17599 var object = { 'a.b': 1, 'a': { 'b': 2 } };
17600
17601 lodashStable.each(['a.b', ['a.b']], function(path) {
17602 var prop = _.property(path);
17603 assert.strictEqual(prop(object), 1);
17604 });
17605 });
17606
17607 QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17608 assert.expect(2);
17609
17610 var values = [, null, undefined],
17611 expected = lodashStable.map(values, noop);
17612
17613 lodashStable.each(['constructor', ['constructor']], function(path) {
17614 var prop = _.property(path);
17615
17616 var actual = lodashStable.map(values, function(value, index) {
17617 return index ? prop(value) : prop();
17618 });
17619
17620 assert.deepEqual(actual, expected);
17621 });
17622 });
17623
17624 QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
17625 assert.expect(2);
17626
17627 var values = [, null, undefined],
17628 expected = lodashStable.map(values, noop);
17629
17630 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17631 var prop = _.property(path);
17632
17633 var actual = lodashStable.map(values, function(value, index) {
17634 return index ? prop(value) : prop();
17635 });
17636
17637 assert.deepEqual(actual, expected);
17638 });
17639 });
17640
17641 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17642 assert.expect(4);
17643
17644 var object = {};
17645
17646 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17647 var prop = _.property(path);
17648 assert.strictEqual(prop(object), undefined);
17649 });
17650 });
17651 }());
17652
17653 /*--------------------------------------------------------------------------*/
17654
17655 QUnit.module('lodash.propertyOf');
17656
17657 (function() {
17658 QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
17659 assert.expect(3);
17660
17661 var object = { 'a': 1 },
17662 propOf = _.propertyOf(object);
17663
17664 assert.strictEqual(propOf.length, 1);
17665 lodashStable.each(['a', ['a']], function(path) {
17666 assert.strictEqual(propOf(path), 1);
17667 });
17668 });
17669
17670 QUnit.test('should pluck deep property values', function(assert) {
17671 assert.expect(2);
17672
17673 var object = { 'a': { 'b': 2 } },
17674 propOf = _.propertyOf(object);
17675
17676 lodashStable.each(['a.b', ['a', 'b']], function(path) {
17677 assert.strictEqual(propOf(path), 2);
17678 });
17679 });
17680
17681 QUnit.test('should pluck inherited property values', function(assert) {
17682 assert.expect(2);
17683
17684 function Foo() {
17685 this.a = 1;
17686 }
17687 Foo.prototype.b = 2;
17688
17689 var propOf = _.propertyOf(new Foo);
17690
17691 lodashStable.each(['b', ['b']], function(path) {
17692 assert.strictEqual(propOf(path), 2);
17693 });
17694 });
17695
17696 QUnit.test('should work with a non-string `path`', function(assert) {
17697 assert.expect(2);
17698
17699 var array = [1, 2, 3],
17700 propOf = _.propertyOf(array);
17701
17702 lodashStable.each([1, [1]], function(path) {
17703 assert.strictEqual(propOf(path), 2);
17704 });
17705 });
17706
17707 QUnit.test('should preserve the sign of `0`', function(assert) {
17708 assert.expect(1);
17709
17710 var object = { '-0': 'a', '0': 'b' },
17711 props = [-0, Object(-0), 0, Object(0)];
17712
17713 var actual = lodashStable.map(props, function(key) {
17714 var propOf = _.propertyOf(object);
17715 return propOf(key);
17716 });
17717
17718 assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
17719 });
17720
17721 QUnit.test('should coerce key to a string', function(assert) {
17722 assert.expect(1);
17723
17724 function fn() {}
17725 fn.toString = lodashStable.constant('fn');
17726
17727 var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
17728 values = [null, undefined, fn, {}];
17729
17730 var actual = lodashStable.transform(objects, function(result, object, index) {
17731 var key = values[index];
17732 lodashStable.each([key, [key]], function(path) {
17733 var propOf = _.propertyOf(object);
17734 result.push(propOf(key));
17735 });
17736 });
17737
17738 assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
17739 });
17740
17741 QUnit.test('should pluck a key over a path', function(assert) {
17742 assert.expect(2);
17743
17744 var object = { 'a.b': 1, 'a': { 'b': 2 } },
17745 propOf = _.propertyOf(object);
17746
17747 lodashStable.each(['a.b', ['a.b']], function(path) {
17748 assert.strictEqual(propOf(path), 1);
17749 });
17750 });
17751
17752 QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
17753 assert.expect(2);
17754
17755 var values = [, null, undefined],
17756 expected = lodashStable.map(values, noop);
17757
17758 lodashStable.each(['constructor', ['constructor']], function(path) {
17759 var actual = lodashStable.map(values, function(value, index) {
17760 var propOf = index ? _.propertyOf(value) : _.propertyOf();
17761 return propOf(path);
17762 });
17763
17764 assert.deepEqual(actual, expected);
17765 });
17766 });
17767
17768 QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
17769 assert.expect(2);
17770
17771 var values = [, null, undefined],
17772 expected = lodashStable.map(values, noop);
17773
17774 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
17775 var actual = lodashStable.map(values, function(value, index) {
17776 var propOf = index ? _.propertyOf(value) : _.propertyOf();
17777 return propOf(path);
17778 });
17779
17780 assert.deepEqual(actual, expected);
17781 });
17782 });
17783
17784 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
17785 assert.expect(4);
17786
17787 var propOf = _.propertyOf({});
17788
17789 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
17790 assert.strictEqual(propOf(path), undefined);
17791 });
17792 });
17793 }());
17794
17795 /*--------------------------------------------------------------------------*/
17796
17797 QUnit.module('lodash.pullAllBy');
17798
17799 (function() {
17800 QUnit.test('should accept an `iteratee` argument', function(assert) {
17801 assert.expect(1);
17802
17803 var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
17804
17805 var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
17806 return object.x;
17807 });
17808
17809 assert.deepEqual(actual, [{ 'x': 2 }]);
17810 });
17811
17812 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
17813 assert.expect(1);
17814
17815 var args,
17816 array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
17817
17818 _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
17819 args || (args = slice.call(arguments));
17820 });
17821
17822 assert.deepEqual(args, [{ 'x': 1 }]);
17823 });
17824 }());
17825
17826 /*--------------------------------------------------------------------------*/
17827
17828 QUnit.module('lodash.pullAllWith');
17829
17830 (function() {
17831 QUnit.test('should work with a `comparator` argument', function(assert) {
17832 assert.expect(1);
17833
17834 var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
17835 expected = [objects[0], objects[2]],
17836 actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
17837
17838 assert.deepEqual(actual, expected);
17839 });
17840 }());
17841
17842 /*--------------------------------------------------------------------------*/
17843
17844 QUnit.module('pull methods');
17845
17846 lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
17847 var func = _[methodName],
17848 isPull = methodName == 'pull';
17849
17850 function pull(array, values) {
17851 return isPull
17852 ? func.apply(undefined, [array].concat(values))
17853 : func(array, values);
17854 }
17855
17856 QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
17857 assert.expect(2);
17858
17859 var array = [1, 2, 3],
17860 actual = pull(array, [1, 3]);
17861
17862 assert.deepEqual(array, [2]);
17863 assert.ok(actual === array);
17864 });
17865
17866 QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
17867 assert.expect(2);
17868
17869 var array = [1, 2, 3, 4];
17870 delete array[1];
17871 delete array[3];
17872
17873 pull(array, [1]);
17874 assert.notOk('0' in array);
17875 assert.notOk('2' in array);
17876 });
17877
17878 QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
17879 assert.expect(1);
17880
17881 var array = [1, 2, 3];
17882 delete array[1];
17883
17884 pull(array, [undefined]);
17885 assert.deepEqual(array, [1, 3]);
17886 });
17887
17888 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
17889 assert.expect(1);
17890
17891 var array = [1, NaN, 3, NaN];
17892
17893 pull(array, [NaN]);
17894 assert.deepEqual(array, [1, 3]);
17895 });
17896 });
17897
17898 /*--------------------------------------------------------------------------*/
17899
17900 QUnit.module('lodash.pullAt');
17901
17902 (function() {
17903 QUnit.test('should modify the array and return removed elements', function(assert) {
17904 assert.expect(2);
17905
17906 var array = [1, 2, 3],
17907 actual = _.pullAt(array, [0, 1]);
17908
17909 assert.deepEqual(array, [3]);
17910 assert.deepEqual(actual, [1, 2]);
17911 });
17912
17913 QUnit.test('should work with unsorted indexes', function(assert) {
17914 assert.expect(2);
17915
17916 var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
17917 actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
17918
17919 assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
17920 assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
17921 });
17922
17923 QUnit.test('should work with repeated indexes', function(assert) {
17924 assert.expect(2);
17925
17926 var array = [1, 2, 3, 4],
17927 actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
17928
17929 assert.deepEqual(array, [4]);
17930 assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
17931 });
17932
17933 QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
17934 assert.expect(2);
17935
17936 var array = ['a', 'b', 'c'],
17937 actual = _.pullAt(array, [2, 4, 0]);
17938
17939 assert.deepEqual(array, ['b']);
17940 assert.deepEqual(actual, ['c', undefined, 'a']);
17941 });
17942
17943 QUnit.test('should flatten `indexes`', function(assert) {
17944 assert.expect(4);
17945
17946 var array = ['a', 'b', 'c'];
17947 assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
17948 assert.deepEqual(array, ['b']);
17949
17950 array = ['a', 'b', 'c', 'd'];
17951 assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
17952 assert.deepEqual(array, ['b']);
17953 });
17954
17955 QUnit.test('should return an empty array when no indexes are given', function(assert) {
17956 assert.expect(4);
17957
17958 var array = ['a', 'b', 'c'],
17959 actual = _.pullAt(array);
17960
17961 assert.deepEqual(array, ['a', 'b', 'c']);
17962 assert.deepEqual(actual, []);
17963
17964 actual = _.pullAt(array, [], []);
17965
17966 assert.deepEqual(array, ['a', 'b', 'c']);
17967 assert.deepEqual(actual, []);
17968 });
17969
17970 QUnit.test('should work with non-index paths', function(assert) {
17971 assert.expect(2);
17972
17973 var values = lodashStable.reject(empties, function(value) {
17974 return (value === 0) || lodashStable.isArray(value);
17975 }).concat(-1, 1.1);
17976
17977 var array = lodashStable.transform(values, function(result, value) {
17978 result[value] = 1;
17979 }, []);
17980
17981 var expected = lodashStable.map(values, alwaysOne),
17982 actual = _.pullAt(array, values);
17983
17984 assert.deepEqual(actual, expected);
17985
17986 expected = lodashStable.map(values, noop),
17987 actual = lodashStable.at(array, values);
17988
17989 assert.deepEqual(actual, expected);
17990 });
17991
17992 QUnit.test('should preserve the sign of `0`', function(assert) {
17993 assert.expect(1);
17994
17995 var props = [-0, Object(-0), 0, Object(0)];
17996
17997 var actual = lodashStable.map(props, function(key) {
17998 var array = [-1];
17999 array['-0'] = -2;
18000 return _.pullAt(array, key);
18001 });
18002
18003 assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
18004 });
18005
18006 QUnit.test('should work with deep paths', function(assert) {
18007 assert.expect(3);
18008
18009 var array = [];
18010 array.a = { 'b': 2 };
18011
18012 var actual = _.pullAt(array, 'a.b');
18013
18014 assert.deepEqual(actual, [2]);
18015 assert.deepEqual(array.a, {});
18016
18017 try {
18018 actual = _.pullAt(array, 'a.b.c');
18019 } catch (e) {}
18020
18021 assert.deepEqual(actual, [undefined]);
18022 });
18023
18024 QUnit.test('should work with a falsey `array` argument when keys are given', function(assert) {
18025 assert.expect(1);
18026
18027 var values = falsey.slice(),
18028 expected = lodashStable.map(values, lodashStable.constant(Array(4)));
18029
18030 var actual = lodashStable.map(values, function(array) {
18031 try {
18032 return _.pullAt(array, 0, 1, 'pop', 'push');
18033 } catch (e) {}
18034 });
18035
18036 assert.deepEqual(actual, expected);
18037 });
18038 }());
18039
18040 /*--------------------------------------------------------------------------*/
18041
18042 QUnit.module('lodash.random');
18043
18044 (function() {
18045 var array = Array(1000);
18046
18047 QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
18048 assert.expect(1);
18049
18050 var actual = lodashStable.uniq(lodashStable.map(array, function() {
18051 return _.random();
18052 })).sort();
18053
18054 assert.deepEqual(actual, [0, 1]);
18055 });
18056
18057 QUnit.test('should support a `min` and `max` argument', function(assert) {
18058 assert.expect(1);
18059
18060 var min = 5,
18061 max = 10;
18062
18063 assert.ok(_.some(array, function() {
18064 var result = _.random(min, max);
18065 return result >= min && result <= max;
18066 }));
18067 });
18068
18069 QUnit.test('should support not providing a `max` argument', function(assert) {
18070 assert.expect(1);
18071
18072 var min = 0,
18073 max = 5;
18074
18075 assert.ok(_.some(array, function() {
18076 var result = _.random(max);
18077 return result >= min && result <= max;
18078 }));
18079 });
18080
18081 QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
18082 assert.expect(1);
18083
18084 var min = 4,
18085 max = 2,
18086 expected = [2, 3, 4];
18087
18088 var actual = lodashStable.uniq(lodashStable.map(array, function() {
18089 return _.random(min, max);
18090 })).sort();
18091
18092 assert.deepEqual(actual, expected);
18093 });
18094
18095 QUnit.test('should support large integer values', function(assert) {
18096 assert.expect(2);
18097
18098 var min = Math.pow(2, 31),
18099 max = Math.pow(2, 62);
18100
18101 assert.ok(lodashStable.every(array, function() {
18102 var result = _.random(min, max);
18103 return result >= min && result <= max;
18104 }));
18105
18106 assert.ok(_.some(array, function() {
18107 return _.random(MAX_INTEGER) > 0;
18108 }));
18109 });
18110
18111 QUnit.test('should coerce arguments to finite numbers', function(assert) {
18112 assert.expect(2);
18113
18114 assert.strictEqual(_.random('1', '1'), 1);
18115 assert.strictEqual(_.random(NaN, NaN), 0);
18116 });
18117
18118 QUnit.test('should support floats', function(assert) {
18119 assert.expect(2);
18120
18121 var min = 1.5,
18122 max = 1.6,
18123 actual = _.random(min, max);
18124
18125 assert.ok(actual % 1);
18126 assert.ok(actual >= min && actual <= max);
18127 });
18128
18129 QUnit.test('should support providing a `floating` argument', function(assert) {
18130 assert.expect(3);
18131
18132 var actual = _.random(true);
18133 assert.ok(actual % 1 && actual >= 0 && actual <= 1);
18134
18135 actual = _.random(2, true);
18136 assert.ok(actual % 1 && actual >= 0 && actual <= 2);
18137
18138 actual = _.random(2, 4, true);
18139 assert.ok(actual % 1 && actual >= 2 && actual <= 4);
18140 });
18141
18142 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18143 assert.expect(1);
18144
18145 var array = [1, 2, 3],
18146 expected = lodashStable.map(array, alwaysTrue),
18147 randoms = lodashStable.map(array, _.random);
18148
18149 var actual = lodashStable.map(randoms, function(result, index) {
18150 return result >= 0 && result <= array[index] && (result % 1) == 0;
18151 });
18152
18153 assert.deepEqual(actual, expected);
18154 });
18155 }());
18156
18157 /*--------------------------------------------------------------------------*/
18158
18159 QUnit.module('range methods');
18160
18161 lodashStable.each(['range', 'rangeRight'], function(methodName) {
18162 var func = _[methodName],
18163 isRange = methodName == 'range';
18164
18165 function resolve(range) {
18166 return isRange ? range : range.reverse();
18167 }
18168
18169 QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
18170 assert.expect(2);
18171
18172 assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
18173 assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
18174 });
18175
18176 QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
18177 assert.expect(2);
18178
18179 assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
18180 assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
18181 });
18182
18183 QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
18184 assert.expect(3);
18185
18186 assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18187 assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
18188 assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
18189 });
18190
18191 QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
18192 assert.expect(1);
18193
18194 assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
18195 });
18196
18197 QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
18198 assert.expect(1);
18199
18200 assert.deepEqual(func(1, 5, 20), [1]);
18201 });
18202
18203 QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
18204 assert.expect(2);
18205
18206 assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
18207 assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
18208 });
18209
18210 QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
18211 assert.expect(1);
18212
18213 var actual = func(-0, 1);
18214 assert.strictEqual(1 / actual[0], -Infinity);
18215 });
18216
18217 QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
18218 assert.expect(13);
18219
18220 lodashStable.each(falsey, function(value, index) {
18221 if (index) {
18222 assert.deepEqual(func(value), []);
18223 assert.deepEqual(func(value, 1), [0]);
18224 } else {
18225 assert.deepEqual(func(), []);
18226 }
18227 });
18228 });
18229
18230 QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
18231 assert.expect(1);
18232
18233 var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
18234 assert.deepEqual(actual, [[0], [0], [0], [], []]);
18235 });
18236
18237 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
18238 assert.expect(2);
18239
18240 var array = [1, 2, 3],
18241 object = { 'a': 1, 'b': 2, 'c': 3 },
18242 expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
18243
18244 lodashStable.each([array, object], function(collection) {
18245 var actual = lodashStable.map(collection, func);
18246 assert.deepEqual(actual, expected);
18247 });
18248 });
18249 });
18250
18251 /*--------------------------------------------------------------------------*/
18252
18253 QUnit.module('lodash.rearg');
18254
18255 (function() {
18256 function fn() {
18257 return slice.call(arguments);
18258 }
18259
18260 QUnit.test('should reorder arguments provided to `func`', function(assert) {
18261 assert.expect(1);
18262
18263 var rearged = _.rearg(fn, [2, 0, 1]);
18264 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18265 });
18266
18267 QUnit.test('should work with repeated indexes', function(assert) {
18268 assert.expect(1);
18269
18270 var rearged = _.rearg(fn, [1, 1, 1]);
18271 assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
18272 });
18273
18274 QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
18275 assert.expect(1);
18276
18277 var rearged = _.rearg(fn, [1, 4]);
18278 assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
18279 });
18280
18281 QUnit.test('should use `undefined` for non-index values', function(assert) {
18282 assert.expect(1);
18283
18284 var values = lodashStable.reject(empties, function(value) {
18285 return (value === 0) || lodashStable.isArray(value);
18286 }).concat(-1, 1.1);
18287
18288 var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
18289
18290 var actual = lodashStable.map(values, function(value) {
18291 var rearged = _.rearg(fn, [value]);
18292 return rearged('a', 'b', 'c');
18293 });
18294
18295 assert.deepEqual(actual, expected);
18296 });
18297
18298 QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
18299 assert.expect(2);
18300
18301 var rearged = _.rearg(fn);
18302 assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18303
18304 rearged = _.rearg(fn, [], []);
18305 assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
18306 });
18307
18308 QUnit.test('should accept multiple index arguments', function(assert) {
18309 assert.expect(1);
18310
18311 var rearged = _.rearg(fn, 2, 0, 1);
18312 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18313 });
18314
18315 QUnit.test('should accept multiple arrays of indexes', function(assert) {
18316 assert.expect(1);
18317
18318 var rearged = _.rearg(fn, [2], [0, 1]);
18319 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
18320 });
18321
18322 QUnit.test('should work with fewer indexes than arguments', function(assert) {
18323 assert.expect(1);
18324
18325 var rearged = _.rearg(fn, [1, 0]);
18326 assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
18327 });
18328
18329 QUnit.test('should work on functions that have been rearged', function(assert) {
18330 assert.expect(1);
18331
18332 var rearged1 = _.rearg(fn, 2, 1, 0),
18333 rearged2 = _.rearg(rearged1, 1, 0, 2);
18334
18335 assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
18336 });
18337 }());
18338
18339 /*--------------------------------------------------------------------------*/
18340
18341 QUnit.module('lodash.reduce');
18342
18343 (function() {
18344 var array = [1, 2, 3];
18345
18346 QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
18347 assert.expect(1);
18348
18349 assert.strictEqual(_.reduce(array), 1);
18350 });
18351
18352 QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18353 assert.expect(2);
18354
18355 var args;
18356
18357 _.reduce(array, function() {
18358 args || (args = slice.call(arguments));
18359 }, 0);
18360
18361 assert.deepEqual(args, [0, 1, 0, array]);
18362
18363 args = undefined;
18364 _.reduce(array, function() {
18365 args || (args = slice.call(arguments));
18366 });
18367
18368 assert.deepEqual(args, [1, 2, 1, array]);
18369 });
18370
18371 QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18372 assert.expect(2);
18373
18374 var args,
18375 object = { 'a': 1, 'b': 2 },
18376 firstKey = _.head(_.keys(object));
18377
18378 var expected = firstKey == 'a'
18379 ? [0, 1, 'a', object]
18380 : [0, 2, 'b', object];
18381
18382 _.reduce(object, function() {
18383 args || (args = slice.call(arguments));
18384 }, 0);
18385
18386 assert.deepEqual(args, expected);
18387
18388 args = undefined;
18389 expected = firstKey == 'a'
18390 ? [1, 2, 'b', object]
18391 : [2, 1, 'a', object];
18392
18393 _.reduce(object, function() {
18394 args || (args = slice.call(arguments));
18395 });
18396
18397 assert.deepEqual(args, expected);
18398 });
18399 }());
18400
18401 /*--------------------------------------------------------------------------*/
18402
18403 QUnit.module('lodash.reduceRight');
18404
18405 (function() {
18406 var array = [1, 2, 3];
18407
18408 QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
18409 assert.expect(1);
18410
18411 assert.strictEqual(_.reduceRight(array), 3);
18412 });
18413
18414 QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
18415 assert.expect(2);
18416
18417 var args;
18418
18419 _.reduceRight(array, function() {
18420 args || (args = slice.call(arguments));
18421 }, 0);
18422
18423 assert.deepEqual(args, [0, 3, 2, array]);
18424
18425 args = undefined;
18426 _.reduceRight(array, function() {
18427 args || (args = slice.call(arguments));
18428 });
18429
18430 assert.deepEqual(args, [3, 2, 1, array]);
18431 });
18432
18433 QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
18434 assert.expect(2);
18435
18436 var args,
18437 object = { 'a': 1, 'b': 2 },
18438 isFIFO = lodashStable.keys(object)[0] == 'a';
18439
18440 var expected = isFIFO
18441 ? [0, 2, 'b', object]
18442 : [0, 1, 'a', object];
18443
18444 _.reduceRight(object, function() {
18445 args || (args = slice.call(arguments));
18446 }, 0);
18447
18448 assert.deepEqual(args, expected);
18449
18450 args = undefined;
18451 expected = isFIFO
18452 ? [2, 1, 'a', object]
18453 : [1, 2, 'b', object];
18454
18455 _.reduceRight(object, function() {
18456 args || (args = slice.call(arguments));
18457 });
18458
18459 assert.deepEqual(args, expected);
18460 });
18461 }());
18462
18463 /*--------------------------------------------------------------------------*/
18464
18465 QUnit.module('reduce methods');
18466
18467 lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
18468 var func = _[methodName],
18469 array = [1, 2, 3],
18470 isReduce = methodName == 'reduce';
18471
18472 QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
18473 assert.expect(1);
18474
18475 var actual = func(['a', 'b', 'c'], function(accumulator, value) {
18476 return accumulator + value;
18477 }, '');
18478
18479 assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
18480 });
18481
18482 QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
18483 assert.expect(1);
18484
18485 var actual = [],
18486 expected = lodashStable.map(empties, noop);
18487
18488 lodashStable.each(empties, function(value) {
18489 try {
18490 actual.push(func(value, noop));
18491 } catch (e) {}
18492 });
18493
18494 assert.deepEqual(actual, expected);
18495 });
18496
18497 QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
18498 assert.expect(1);
18499
18500 var expected = lodashStable.map(empties, lodashStable.constant('x'));
18501
18502 var actual = lodashStable.map(empties, function(value) {
18503 try {
18504 return func(value, noop, 'x');
18505 } catch (e) {}
18506 });
18507
18508 assert.deepEqual(actual, expected);
18509 });
18510
18511 QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
18512 assert.expect(1);
18513
18514 var actual = func([], noop, undefined);
18515 assert.strictEqual(actual, undefined);
18516 });
18517
18518 QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
18519 assert.expect(2);
18520
18521 var array = [],
18522 object = { '0': 1, 'length': 0 };
18523
18524 if ('__proto__' in array) {
18525 array.__proto__ = object;
18526 assert.strictEqual(func(array, noop), undefined);
18527 }
18528 else {
18529 skipAssert(assert);
18530 }
18531 assert.strictEqual(func(object, noop), undefined);
18532 });
18533
18534 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
18535 assert.expect(1);
18536
18537 if (!isNpm) {
18538 assert.strictEqual(_(array)[methodName](add), 6);
18539 }
18540 else {
18541 skipAssert(assert);
18542 }
18543 });
18544
18545 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
18546 assert.expect(1);
18547
18548 if (!isNpm) {
18549 assert.ok(_(array).chain()[methodName](add) instanceof _);
18550 }
18551 else {
18552 skipAssert(assert);
18553 }
18554 });
18555 });
18556
18557 /*--------------------------------------------------------------------------*/
18558
18559 QUnit.module('lodash.reject');
18560
18561 (function() {
18562 var array = [1, 2, 3];
18563
18564 QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
18565 assert.expect(1);
18566
18567 assert.deepEqual(_.reject(array, isEven), [1, 3]);
18568 });
18569 }());
18570
18571 /*--------------------------------------------------------------------------*/
18572
18573 QUnit.module('filter methods');
18574
18575 lodashStable.each(['filter', 'reject'], function(methodName) {
18576 var array = [1, 2, 3, 4],
18577 func = _[methodName],
18578 isFilter = methodName == 'filter',
18579 objects = [{ 'a': 0 }, { 'a': 1 }];
18580
18581 QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
18582 assert.expect(1);
18583
18584 var actual = func([0], function(value, index, array) {
18585 array[index] = 1;
18586 return isFilter;
18587 });
18588
18589 assert.deepEqual(actual, [0]);
18590 });
18591
18592 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
18593 assert.expect(1);
18594
18595 assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
18596 });
18597
18598 QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
18599 assert.expect(1);
18600
18601 assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
18602 });
18603
18604 QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
18605 assert.expect(2);
18606
18607 if (!isNpm) {
18608 var wrapped = _(array);
18609
18610 var actual = wrapped[methodName](function(n) {
18611 return n < 3;
18612 });
18613
18614 assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
18615
18616 actual = wrapped[methodName](function(n) {
18617 return n > 2;
18618 });
18619
18620 assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
18621 }
18622 else {
18623 skipAssert(assert, 2);
18624 }
18625 });
18626
18627 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
18628 assert.expect(2);
18629
18630 if (!isNpm) {
18631 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18632 predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
18633 actual = _(array).slice(1).map(square)[methodName](predicate).value();
18634
18635 assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
18636
18637 var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
18638 return ['key' + index, index];
18639 }));
18640
18641 actual = _(object).mapValues(square)[methodName](predicate).value();
18642 assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
18643 }
18644 else {
18645 skipAssert(assert, 2);
18646 }
18647 });
18648
18649 QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
18650 assert.expect(5);
18651
18652 if (!isNpm) {
18653 var args,
18654 array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
18655 expected = [1, 0, lodashStable.map(array.slice(1), square)];
18656
18657 _(array).slice(1)[methodName](function(value, index, array) {
18658 args || (args = slice.call(arguments));
18659 }).value();
18660
18661 assert.deepEqual(args, [1, 0, array.slice(1)]);
18662
18663 args = undefined;
18664 _(array).slice(1).map(square)[methodName](function(value, index, array) {
18665 args || (args = slice.call(arguments));
18666 }).value();
18667
18668 assert.deepEqual(args, expected);
18669
18670 args = undefined;
18671 _(array).slice(1).map(square)[methodName](function(value, index) {
18672 args || (args = slice.call(arguments));
18673 }).value();
18674
18675 assert.deepEqual(args, expected);
18676
18677 args = undefined;
18678 _(array).slice(1).map(square)[methodName](function(value) {
18679 args || (args = slice.call(arguments));
18680 }).value();
18681
18682 assert.deepEqual(args, [1]);
18683
18684 args = undefined;
18685 _(array).slice(1).map(square)[methodName](function() {
18686 args || (args = slice.call(arguments));
18687 }).value();
18688
18689 assert.deepEqual(args, expected);
18690 }
18691 else {
18692 skipAssert(assert, 5);
18693 }
18694 });
18695 });
18696
18697 /*--------------------------------------------------------------------------*/
18698
18699 QUnit.module('lodash.remove');
18700
18701 (function() {
18702 QUnit.test('should modify the array and return removed elements', function(assert) {
18703 assert.expect(2);
18704
18705 var array = [1, 2, 3, 4];
18706
18707 var actual = _.remove(array, function(n) {
18708 return n % 2 == 0;
18709 });
18710
18711 assert.deepEqual(array, [1, 3]);
18712 assert.deepEqual(actual, [2, 4]);
18713 });
18714
18715 QUnit.test('should provide the correct `predicate` arguments', function(assert) {
18716 assert.expect(1);
18717
18718 var argsList = [],
18719 array = [1, 2, 3],
18720 clone = array.slice();
18721
18722 _.remove(array, function(n, index) {
18723 var args = slice.call(arguments);
18724 args[2] = args[2].slice();
18725 argsList.push(args);
18726 return isEven(index);
18727 });
18728
18729 assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
18730 });
18731
18732 QUnit.test('should work with `_.matches` shorthands', function(assert) {
18733 assert.expect(1);
18734
18735 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
18736 _.remove(objects, { 'a': 1 });
18737 assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
18738 });
18739
18740 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
18741 assert.expect(1);
18742
18743 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
18744 _.remove(objects, ['a', 1]);
18745 assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
18746 });
18747
18748 QUnit.test('should work with `_.property` shorthands', function(assert) {
18749 assert.expect(1);
18750
18751 var objects = [{ 'a': 0 }, { 'a': 1 }];
18752 _.remove(objects, 'a');
18753 assert.deepEqual(objects, [{ 'a': 0 }]);
18754 });
18755
18756 QUnit.test('should preserve holes in arrays', function(assert) {
18757 assert.expect(2);
18758
18759 var array = [1, 2, 3, 4];
18760 delete array[1];
18761 delete array[3];
18762
18763 _.remove(array, function(n) {
18764 return n === 1;
18765 });
18766
18767 assert.notOk('0' in array);
18768 assert.notOk('2' in array);
18769 });
18770
18771 QUnit.test('should treat holes as `undefined`', function(assert) {
18772 assert.expect(1);
18773
18774 var array = [1, 2, 3];
18775 delete array[1];
18776
18777 _.remove(array, function(n) {
18778 return n == null;
18779 });
18780
18781 assert.deepEqual(array, [1, 3]);
18782 });
18783
18784 QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
18785 assert.expect(1);
18786
18787 var array = [1, 2, 3];
18788
18789 _.remove(array, function(n, index) {
18790 return isEven(index);
18791 });
18792
18793 assert.deepEqual(array, [2]);
18794 });
18795 }());
18796
18797 /*--------------------------------------------------------------------------*/
18798
18799 QUnit.module('lodash.repeat');
18800
18801 (function() {
18802 var string = 'abc';
18803
18804 QUnit.test('should repeat a string `n` times', function(assert) {
18805 assert.expect(2);
18806
18807 assert.strictEqual(_.repeat('*', 3), '***');
18808 assert.strictEqual(_.repeat(string, 2), 'abcabc');
18809 });
18810
18811 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
18812 assert.expect(1);
18813
18814 var expected = lodashStable.map(falsey, function(value) {
18815 return value === undefined ? string : '';
18816 });
18817
18818 var actual = lodashStable.map(falsey, function(n, index) {
18819 return index ? _.repeat(string, n) : _.repeat(string);
18820 });
18821
18822 assert.deepEqual(actual, expected);
18823 });
18824
18825 QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
18826 assert.expect(2);
18827
18828 assert.strictEqual(_.repeat(string, 0), '');
18829 assert.strictEqual(_.repeat(string, -2), '');
18830 });
18831
18832 QUnit.test('should coerce `n` to an integer', function(assert) {
18833 assert.expect(3);
18834
18835 assert.strictEqual(_.repeat(string, '2'), 'abcabc');
18836 assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
18837 assert.strictEqual(_.repeat('*', { 'valueOf': alwaysThree }), '***');
18838 });
18839
18840 QUnit.test('should coerce `string` to a string', function(assert) {
18841 assert.expect(2);
18842
18843 assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
18844 assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
18845 });
18846
18847 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
18848 assert.expect(1);
18849
18850 var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
18851 assert.deepEqual(actual, ['a', 'b', 'c']);
18852 });
18853 }());
18854
18855 /*--------------------------------------------------------------------------*/
18856
18857 QUnit.module('lodash.replace');
18858
18859 (function() {
18860 QUnit.test('should replace the matched pattern', function(assert) {
18861 assert.expect(2);
18862
18863 var string = 'abcde';
18864 assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
18865 assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
18866 });
18867 }());
18868
18869 /*--------------------------------------------------------------------------*/
18870
18871 QUnit.module('lodash.result');
18872
18873 (function() {
18874 var object = { 'a': 1, 'b': alwaysB };
18875
18876 QUnit.test('should invoke function values', function(assert) {
18877 assert.expect(1);
18878
18879 assert.strictEqual(_.result(object, 'b'), 'b');
18880 });
18881
18882 QUnit.test('should invoke default function values', function(assert) {
18883 assert.expect(1);
18884
18885 var actual = _.result(object, 'c', object.b);
18886 assert.strictEqual(actual, 'b');
18887 });
18888
18889 QUnit.test('should invoke nested function values', function(assert) {
18890 assert.expect(2);
18891
18892 var value = { 'a': lodashStable.constant({ 'b': alwaysB }) };
18893
18894 lodashStable.each(['a.b', ['a', 'b']], function(path) {
18895 assert.strictEqual(_.result(value, path), 'b');
18896 });
18897 });
18898
18899 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
18900 assert.expect(2);
18901
18902 var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
18903
18904 lodashStable.each(['a.b', ['a', 'b']], function(path) {
18905 assert.strictEqual(_.result(value, path), 1);
18906 });
18907 });
18908 }());
18909
18910 /*--------------------------------------------------------------------------*/
18911
18912 QUnit.module('lodash.get and lodash.result');
18913
18914 lodashStable.each(['get', 'result'], function(methodName) {
18915 var func = _[methodName];
18916
18917 QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
18918 assert.expect(2);
18919
18920 var object = { 'a': 1 };
18921
18922 lodashStable.each(['a', ['a']], function(path) {
18923 assert.strictEqual(func(object, path), 1);
18924 });
18925 });
18926
18927 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
18928 assert.expect(1);
18929
18930 var object = { '-0': 'a', '0': 'b' },
18931 props = [-0, Object(-0), 0, Object(0)];
18932
18933 var actual = lodashStable.map(props, function(key) {
18934 return func(object, key);
18935 });
18936
18937 assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
18938 });
18939
18940 QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
18941 assert.expect(1);
18942
18943 if (Symbol) {
18944 var object = {};
18945 object[symbol] = 1;
18946
18947 assert.strictEqual(func(object, symbol), 1);
18948 }
18949 else {
18950 skipAssert(assert);
18951 }
18952 });
18953
18954 QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
18955 assert.expect(2);
18956
18957 var object = { 'a': { 'b': 2 } };
18958
18959 lodashStable.each(['a.b', ['a', 'b']], function(path) {
18960 assert.strictEqual(func(object, path), 2);
18961 });
18962 });
18963
18964 QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
18965 assert.expect(2);
18966
18967 var object = { 'a.b': 1, 'a': { 'b': 2 } };
18968
18969 lodashStable.each(['a.b', ['a.b']], function(path) {
18970 assert.strictEqual(func(object, path), 1);
18971 });
18972 });
18973
18974 QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
18975 assert.expect(1);
18976
18977 var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
18978 assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
18979 });
18980
18981 QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
18982 assert.expect(1);
18983
18984 var object = { 'a': 1 };
18985 assert.strictEqual(func(object, 'a[]'), 1);
18986 });
18987
18988 QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
18989 assert.expect(4);
18990
18991 lodashStable.each([['', ''], [[], ['']]], function(pair) {
18992 assert.strictEqual(func({}, pair[0]), undefined);
18993 assert.strictEqual(func({ '': 3 }, pair[1]), 3);
18994 });
18995 });
18996
18997 QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
18998 assert.expect(2);
18999
19000 var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
19001
19002 var paths = [
19003 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19004 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19005 ];
19006
19007 lodashStable.each(paths, function(path) {
19008 assert.strictEqual(func(object, path), 8);
19009 });
19010 });
19011
19012 QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
19013 assert.expect(4);
19014
19015 lodashStable.each(['constructor', ['constructor']], function(path) {
19016 assert.strictEqual(func(null, path), undefined);
19017 assert.strictEqual(func(undefined, path), undefined);
19018 });
19019 });
19020
19021 QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
19022 assert.expect(2);
19023
19024 var values = [null, undefined],
19025 expected = lodashStable.map(values, noop),
19026 paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
19027
19028 lodashStable.each(paths, function(path) {
19029 var actual = lodashStable.map(values, function(value) {
19030 return func(value, path);
19031 });
19032
19033 assert.deepEqual(actual, expected);
19034 });
19035 });
19036
19037 QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
19038 assert.expect(2);
19039
19040 var object = { 'a': [, null] };
19041
19042 lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19043 assert.strictEqual(func(object, path), undefined);
19044 });
19045 });
19046
19047 QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
19048 assert.expect(2);
19049
19050 var object = { 'a': { 'b': null } };
19051
19052 lodashStable.each(['a.b', ['a', 'b']], function(path) {
19053 assert.strictEqual(func(object, path), null);
19054 });
19055 });
19056
19057 QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19058 assert.expect(2);
19059
19060 var paths = ['a.b', ['a', 'b']];
19061
19062 lodashStable.each(paths, function(path) {
19063 numberProto.a = { 'b': 2 };
19064 assert.strictEqual(func(0, path), 2);
19065 delete numberProto.a;
19066 });
19067 });
19068
19069 QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
19070 assert.expect(1);
19071
19072 var object = { 'a': {} },
19073 values = empties.concat(true, new Date, 1, /x/, 'a');
19074
19075 var expected = lodashStable.transform(values, function(result, value) {
19076 result.push(value, value, value, value);
19077 });
19078
19079 var actual = lodashStable.transform(values, function(result, value) {
19080 lodashStable.each(['a.b', ['a', 'b']], function(path) {
19081 result.push(
19082 func(object, path, value),
19083 func(null, path, value)
19084 );
19085 });
19086 });
19087
19088 assert.deepEqual(actual, expected);
19089 });
19090
19091 QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
19092 assert.expect(1);
19093
19094 assert.strictEqual(func({}, [], 'a'), 'a');
19095 });
19096 });
19097
19098 /*--------------------------------------------------------------------------*/
19099
19100 QUnit.module('lodash.rest');
19101
19102 (function() {
19103 function fn(a, b, c) {
19104 return slice.call(arguments);
19105 }
19106
19107 QUnit.test('should apply a rest parameter to `func`', function(assert) {
19108 assert.expect(1);
19109
19110 var rest = _.rest(fn);
19111 assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
19112 });
19113
19114 QUnit.test('should work with `start`', function(assert) {
19115 assert.expect(1);
19116
19117 var rest = _.rest(fn, 1);
19118 assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
19119 });
19120
19121 QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
19122 assert.expect(1);
19123
19124 var values = [-1, NaN, 'a'],
19125 expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
19126
19127 var actual = lodashStable.map(values, function(value) {
19128 var rest = _.rest(fn, value);
19129 return rest(1, 2, 3, 4);
19130 });
19131
19132 assert.deepEqual(actual, expected);
19133 });
19134
19135 QUnit.test('should coerce `start` to an integer', function(assert) {
19136 assert.expect(1);
19137
19138 var rest = _.rest(fn, 1.6);
19139 assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
19140 });
19141
19142 QUnit.test('should use an empty array when `start` is not reached', function(assert) {
19143 assert.expect(1);
19144
19145 var rest = _.rest(fn);
19146 assert.deepEqual(rest(1), [1, undefined, []]);
19147 });
19148
19149 QUnit.test('should work on functions with more than three parameters', function(assert) {
19150 assert.expect(1);
19151
19152 var rest = _.rest(function(a, b, c, d) {
19153 return slice.call(arguments);
19154 });
19155
19156 assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
19157 });
19158 }());
19159
19160 /*--------------------------------------------------------------------------*/
19161
19162 QUnit.module('lodash.reverse');
19163
19164 (function() {
19165 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
19166 smallArray = [0, 1, 2, null];
19167
19168 QUnit.test('should reverse `array`', function(assert) {
19169 assert.expect(2);
19170
19171 var array = [1, 2, 3],
19172 actual = _.reverse(array);
19173
19174 assert.deepEqual(array, [3, 2, 1]);
19175 assert.strictEqual(actual, array);
19176 });
19177
19178 QUnit.test('should return the wrapped reversed `array`', function(assert) {
19179 assert.expect(6);
19180
19181 if (!isNpm) {
19182 lodashStable.times(2, function(index) {
19183 var array = (index ? largeArray : smallArray).slice(),
19184 clone = array.slice(),
19185 wrapped = _(array).reverse(),
19186 actual = wrapped.value();
19187
19188 assert.ok(wrapped instanceof _);
19189 assert.strictEqual(actual, array);
19190 assert.deepEqual(actual, clone.slice().reverse());
19191 });
19192 }
19193 else {
19194 skipAssert(assert, 6);
19195 }
19196 });
19197
19198 QUnit.test('should work in a lazy sequence', function(assert) {
19199 assert.expect(4);
19200
19201 if (!isNpm) {
19202 lodashStable.times(2, function(index) {
19203 var array = (index ? largeArray : smallArray).slice(),
19204 expected = array.slice(),
19205 actual = _(array).slice(1).reverse().value();
19206
19207 assert.deepEqual(actual, expected.slice(1).reverse());
19208 assert.deepEqual(array, expected);
19209 });
19210 }
19211 else {
19212 skipAssert(assert, 4);
19213 }
19214 });
19215
19216 QUnit.test('should be lazy when in a lazy sequence', function(assert) {
19217 assert.expect(3);
19218
19219 if (!isNpm) {
19220 var spy = {
19221 'toString': function() {
19222 throw new Error('spy was revealed');
19223 }
19224 };
19225
19226 var array = largeArray.concat(spy),
19227 expected = array.slice();
19228
19229 try {
19230 var wrapped = _(array).slice(1).map(String).reverse(),
19231 actual = wrapped.last();
19232 } catch (e) {}
19233
19234 assert.ok(wrapped instanceof _);
19235 assert.strictEqual(actual, '1');
19236 assert.deepEqual(array, expected);
19237 }
19238 else {
19239 skipAssert(assert, 3);
19240 }
19241 });
19242
19243 QUnit.test('should work in a hybrid sequence', function(assert) {
19244 assert.expect(8);
19245
19246 if (!isNpm) {
19247 lodashStable.times(2, function(index) {
19248 var clone = (index ? largeArray : smallArray).slice();
19249
19250 lodashStable.each(['map', 'filter'], function(methodName) {
19251 var array = clone.slice(),
19252 expected = clone.slice(1, -1).reverse(),
19253 actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
19254
19255 assert.deepEqual(actual, expected);
19256
19257 array = clone.slice();
19258 actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
19259
19260 assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
19261 });
19262 });
19263 }
19264 else {
19265 skipAssert(assert, 8);
19266 }
19267 });
19268
19269 QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
19270 assert.expect(6);
19271
19272 if (!isNpm) {
19273 lodashStable.times(2, function(index) {
19274 var array = (index ? largeArray : smallArray).slice(),
19275 expected = array.slice().reverse(),
19276 wrapped = _(array).chain().reverse().head();
19277
19278 assert.ok(wrapped instanceof _);
19279 assert.strictEqual(wrapped.value(), _.head(expected));
19280 assert.deepEqual(array, expected);
19281 });
19282 }
19283 else {
19284 skipAssert(assert, 6);
19285 }
19286 });
19287 }());
19288
19289 /*--------------------------------------------------------------------------*/
19290
19291 QUnit.module('round methods');
19292
19293 lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
19294 var func = _[methodName],
19295 isCeil = methodName == 'ceil',
19296 isFloor = methodName == 'floor';
19297
19298 QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
19299 assert.expect(1);
19300
19301 var actual = func(4.006);
19302 assert.strictEqual(actual, isCeil ? 5 : 4);
19303 });
19304
19305 QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
19306 assert.expect(1);
19307
19308 var actual = func(4.006, 0);
19309 assert.strictEqual(actual, isCeil ? 5 : 4);
19310 });
19311
19312 QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
19313 assert.expect(2);
19314
19315 var actual = func(4.016, 2);
19316 assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
19317
19318 actual = func(4.1, 2);
19319 assert.strictEqual(actual, 4.1);
19320 });
19321
19322 QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
19323 assert.expect(1);
19324
19325 var actual = func(4160, -2);
19326 assert.strictEqual(actual, isFloor ? 4100 : 4200);
19327 });
19328
19329 QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
19330 assert.expect(3);
19331
19332 var actual = func(4.006, NaN);
19333 assert.strictEqual(actual, isCeil ? 5 : 4);
19334
19335 var expected = isFloor ? 4.01 : 4.02;
19336
19337 actual = func(4.016, 2.6);
19338 assert.strictEqual(actual, expected);
19339
19340 actual = func(4.016, '+2');
19341 assert.strictEqual(actual, expected);
19342 });
19343
19344 QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
19345 assert.expect(3);
19346
19347 var actual = func(5e1, 2);
19348 assert.deepEqual(actual, 50);
19349
19350 actual = func('5e', 1);
19351 assert.deepEqual(actual, NaN);
19352
19353 actual = func('5e1e1', 1);
19354 assert.deepEqual(actual, NaN);
19355 });
19356
19357 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19358 assert.expect(1);
19359
19360 var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
19361 expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
19362
19363 var actual = lodashStable.map(values, function(args) {
19364 return 1 / func.apply(undefined, args);
19365 });
19366
19367 assert.deepEqual(actual, expected);
19368 });
19369 });
19370
19371 /*--------------------------------------------------------------------------*/
19372
19373 QUnit.module('lodash.runInContext');
19374
19375 (function() {
19376 QUnit.test('should not require a fully populated `context` object', function(assert) {
19377 assert.expect(1);
19378
19379 if (!isModularize) {
19380 var lodash = _.runInContext({
19381 'setTimeout': function(callback) {
19382 callback();
19383 }
19384 });
19385
19386 var pass = false;
19387 lodash.delay(function() { pass = true; }, 32);
19388 assert.ok(pass);
19389 }
19390 else {
19391 skipAssert(assert);
19392 }
19393 });
19394
19395 QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
19396 assert.expect(3);
19397
19398 if (!isModularize) {
19399 lodashStable.times(2, _.uniqueId);
19400
19401 var oldId = Number(_.uniqueId()),
19402 lodash = _.runInContext();
19403
19404 assert.ok(_.uniqueId() > oldId);
19405
19406 var id = lodash.uniqueId();
19407 assert.strictEqual(id, '1');
19408 assert.ok(id < oldId);
19409 }
19410 else {
19411 skipAssert(assert, 3);
19412 }
19413 });
19414 }());
19415
19416 /*--------------------------------------------------------------------------*/
19417
19418 QUnit.module('lodash.sample');
19419
19420 (function() {
19421 var array = [1, 2, 3];
19422
19423 QUnit.test('should return a random element', function(assert) {
19424 assert.expect(1);
19425
19426 var actual = _.sample(array);
19427 assert.ok(lodashStable.includes(array, actual));
19428 });
19429
19430 QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
19431 assert.expect(1);
19432
19433 var expected = lodashStable.map(empties, noop);
19434
19435 var actual = lodashStable.transform(empties, function(result, value) {
19436 try {
19437 result.push(_.sample(value));
19438 } catch (e) {}
19439 });
19440
19441 assert.deepEqual(actual, expected);
19442 });
19443
19444 QUnit.test('should sample an object', function(assert) {
19445 assert.expect(1);
19446
19447 var object = { 'a': 1, 'b': 2, 'c': 3 },
19448 actual = _.sample(object);
19449
19450 assert.ok(lodashStable.includes(array, actual));
19451 });
19452 }());
19453
19454 /*--------------------------------------------------------------------------*/
19455
19456 QUnit.module('lodash.sampleSize');
19457
19458 (function() {
19459 var array = [1, 2, 3];
19460
19461 QUnit.test('should return an array of random elements', function(assert) {
19462 assert.expect(2);
19463
19464 var actual = _.sampleSize(array, 2);
19465
19466 assert.strictEqual(actual.length, 2);
19467 assert.deepEqual(lodashStable.difference(actual, array), []);
19468 });
19469
19470 QUnit.test('should contain elements of the collection', function(assert) {
19471 assert.expect(1);
19472
19473 var actual = _.sampleSize(array, array.length).sort();
19474
19475 assert.deepEqual(actual, array);
19476 });
19477
19478 QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
19479 assert.expect(1);
19480
19481 var expected = lodashStable.map(falsey, function(value) {
19482 return value === undefined ? ['a'] : [];
19483 });
19484
19485 var actual = lodashStable.map(falsey, function(size, index) {
19486 return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
19487 });
19488
19489 assert.deepEqual(actual, expected);
19490 });
19491
19492 QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
19493 assert.expect(3);
19494
19495 lodashStable.each([0, -1, -Infinity], function(n) {
19496 assert.deepEqual(_.sampleSize(array, n), []);
19497 });
19498 });
19499
19500 QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
19501 assert.expect(4);
19502
19503 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
19504 var actual = _.sampleSize(array, n).sort();
19505 assert.deepEqual(actual, array);
19506 });
19507 });
19508
19509 QUnit.test('should coerce `n` to an integer', function(assert) {
19510 assert.expect(1);
19511
19512 var actual = _.sampleSize(array, 1.6);
19513 assert.strictEqual(actual.length, 1);
19514 });
19515
19516 QUnit.test('should return an empty array for empty collections', function(assert) {
19517 assert.expect(1);
19518
19519 var expected = lodashStable.map(empties, alwaysEmptyArray);
19520
19521 var actual = lodashStable.transform(empties, function(result, value) {
19522 try {
19523 result.push(_.sampleSize(value, 1));
19524 } catch (e) {}
19525 });
19526
19527 assert.deepEqual(actual, expected);
19528 });
19529
19530 QUnit.test('should sample an object', function(assert) {
19531 assert.expect(2);
19532
19533 var object = { 'a': 1, 'b': 2, 'c': 3 },
19534 actual = _.sampleSize(object, 2);
19535
19536 assert.strictEqual(actual.length, 2);
19537 assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
19538 });
19539
19540 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
19541 assert.expect(1);
19542
19543 var actual = lodashStable.map([['a']], _.sampleSize);
19544 assert.deepEqual(actual, [['a']]);
19545 });
19546 }());
19547
19548 /*--------------------------------------------------------------------------*/
19549
19550 QUnit.module('lodash.setWith');
19551
19552 (function() {
19553 QUnit.test('should work with a `customizer` callback', function(assert) {
19554 assert.expect(1);
19555
19556 var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
19557 return lodashStable.isObject(value) ? undefined : {};
19558 });
19559
19560 assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
19561 });
19562
19563 QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
19564 assert.expect(1);
19565
19566 var actual = _.setWith({}, 'a[0].b.c', 4, noop);
19567 assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
19568 });
19569 }());
19570
19571 /*--------------------------------------------------------------------------*/
19572
19573 QUnit.module('set methods');
19574
19575 lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
19576 var func = _[methodName],
19577 isUpdate = methodName == 'update' || methodName == 'updateWith';
19578
19579 var oldValue = 1,
19580 value = 2,
19581 updater = isUpdate ? lodashStable.constant(value) : value;
19582
19583 QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
19584 assert.expect(4);
19585
19586 lodashStable.each(['a', ['a']], function(path) {
19587 var object = { 'a': oldValue },
19588 actual = func(object, path, updater);
19589
19590 assert.strictEqual(actual, object);
19591 assert.strictEqual(object.a, value);
19592 });
19593 });
19594
19595 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
19596 assert.expect(1);
19597
19598 var props = [-0, Object(-0), 0, Object(0)],
19599 expected = lodashStable.map(props, lodashStable.constant(value));
19600
19601 var actual = lodashStable.map(props, function(key) {
19602 var object = { '-0': 'a', '0': 'b' };
19603 func(object, key, updater);
19604 return object[lodashStable.toString(key)];
19605 });
19606
19607 assert.deepEqual(actual, expected);
19608 });
19609
19610 QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
19611 assert.expect(2);
19612
19613 if (Symbol) {
19614 var object = {};
19615 object[symbol] = 1;
19616
19617 assert.strictEqual(_.unset(object, symbol), true);
19618 assert.notOk(symbol in object);
19619 }
19620 else {
19621 skipAssert(assert, 2);
19622 }
19623 });
19624
19625 QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
19626 assert.expect(4);
19627
19628 lodashStable.each(['a.b', ['a', 'b']], function(path) {
19629 var object = { 'a': { 'b': oldValue } },
19630 actual = func(object, path, updater);
19631
19632 assert.strictEqual(actual, object);
19633 assert.strictEqual(object.a.b, value);
19634 });
19635 });
19636
19637 QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
19638 assert.expect(4);
19639
19640 lodashStable.each(['a.b', ['a.b']], function(path) {
19641 var object = { 'a.b': oldValue },
19642 actual = func(object, path, updater);
19643
19644 assert.strictEqual(actual, object);
19645 assert.deepEqual(object, { 'a.b': value });
19646 });
19647 });
19648
19649 QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
19650 assert.expect(1);
19651
19652 var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
19653
19654 func(object, ['a', 'b', 'c'], updater);
19655 assert.strictEqual(object.a.b.c, value);
19656 });
19657
19658 QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
19659 assert.expect(1);
19660
19661 var object = {};
19662
19663 func(object, 'a[]', updater);
19664 assert.deepEqual(object, { 'a': value });
19665 });
19666
19667 QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
19668 assert.expect(4);
19669
19670 lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
19671 var object = {};
19672
19673 func(object, pair[0], updater);
19674 assert.deepEqual(object, index ? {} : { '': value });
19675
19676 func(object, pair[1], updater);
19677 assert.deepEqual(object, { '': value });
19678 });
19679 });
19680
19681 QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
19682 assert.expect(2);
19683
19684 var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
19685
19686 var paths = [
19687 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
19688 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
19689 ];
19690
19691 lodashStable.each(paths, function(path) {
19692 func(object, path, updater);
19693 assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
19694 object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
19695 });
19696 });
19697
19698 QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
19699 assert.expect(6);
19700
19701 var object = {};
19702
19703 lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
19704 var actual = func(object, path, updater);
19705
19706 assert.strictEqual(actual, object);
19707 assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
19708 assert.notOk('0' in object.a);
19709
19710 delete object.a;
19711 });
19712 });
19713
19714 QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
19715 assert.expect(1);
19716
19717 var values = [null, undefined],
19718 expected = [[null, null], [undefined, undefined]];
19719
19720 var actual = lodashStable.map(values, function(value) {
19721 try {
19722 return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
19723 } catch (e) {
19724 return e.message;
19725 }
19726 });
19727
19728 assert.deepEqual(actual, expected);
19729 });
19730
19731 QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
19732 assert.expect(4);
19733
19734 var object = { 'a': '' },
19735 paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
19736
19737 lodashStable.each(paths, function(path) {
19738 func(0, path, updater);
19739 assert.strictEqual(0..a, value);
19740 delete numberProto.a;
19741 });
19742
19743 lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
19744 func(object, path, updater);
19745 assert.strictEqual(stringProto.replace.b, value);
19746 delete stringProto.replace.b;
19747 });
19748 });
19749
19750 QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
19751 'use strict';
19752
19753 assert.expect(2);
19754
19755 lodashStable.each(['a', 'a.a.a'], function(path) {
19756 numberProto.a = oldValue;
19757 try {
19758 func(0, path, updater);
19759 assert.strictEqual(0..a, oldValue);
19760 } catch (e) {
19761 assert.ok(false, e.message);
19762 }
19763 });
19764
19765 delete numberProto.a;
19766 });
19767
19768 QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
19769 assert.expect(1);
19770
19771 var object = {};
19772
19773 func(object, ['1a', '2b', '3c'], updater);
19774 assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
19775 });
19776
19777 QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
19778 assert.expect(4);
19779
19780 lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
19781 if (defineProperty) {
19782 var object = {},
19783 pass = true,
19784 updater = isUpdate ? lodashStable.constant(value) : value;
19785
19786 defineProperty(object, 'a', {
19787 'enumerable': true,
19788 'configurable': true,
19789 'get': lodashStable.constant(value),
19790 'set': function() { pass = false; }
19791 });
19792
19793 func(object, 'a', updater);
19794 assert.ok(pass);
19795 }
19796 else {
19797 skipAssert(assert);
19798 }
19799 });
19800 });
19801 });
19802
19803 /*--------------------------------------------------------------------------*/
19804
19805 QUnit.module('lodash.shuffle');
19806
19807 (function() {
19808 var array = [1, 2, 3],
19809 object = { 'a': 1, 'b': 2, 'c': 3 };
19810
19811 QUnit.test('should return a new array', function(assert) {
19812 assert.expect(1);
19813
19814 assert.notStrictEqual(_.shuffle(array), array);
19815 });
19816
19817 QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
19818 assert.expect(2);
19819
19820 assert.deepEqual(_.shuffle(array).sort(), array);
19821 assert.deepEqual(_.shuffle(object).sort(), array);
19822 });
19823
19824 QUnit.test('should shuffle small collections', function(assert) {
19825 assert.expect(1);
19826
19827 var actual = lodashStable.times(1000, function(assert) {
19828 return _.shuffle([1, 2]);
19829 });
19830
19831 assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
19832 });
19833
19834 QUnit.test('should treat number values for `collection` as empty', function(assert) {
19835 assert.expect(1);
19836
19837 assert.deepEqual(_.shuffle(1), []);
19838 });
19839 }());
19840
19841 /*--------------------------------------------------------------------------*/
19842
19843 QUnit.module('lodash.size');
19844
19845 (function() {
19846 var args = arguments,
19847 array = [1, 2, 3];
19848
19849 QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
19850 assert.expect(1);
19851
19852 assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
19853 });
19854
19855 QUnit.test('should return the length of an array', function(assert) {
19856 assert.expect(1);
19857
19858 assert.strictEqual(_.size(array), 3);
19859 });
19860
19861 QUnit.test('should accept a falsey `object` argument', function(assert) {
19862 assert.expect(1);
19863
19864 var expected = lodashStable.map(falsey, alwaysZero);
19865
19866 var actual = lodashStable.map(falsey, function(object, index) {
19867 try {
19868 return index ? _.size(object) : _.size();
19869 } catch (e) {}
19870 });
19871
19872 assert.deepEqual(actual, expected);
19873 });
19874
19875 QUnit.test('should work with `arguments` objects', function(assert) {
19876 assert.expect(1);
19877
19878 assert.strictEqual(_.size(args), 3);
19879 });
19880
19881 QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
19882 assert.expect(1);
19883
19884 function Foo(elements) {
19885 push.apply(this, elements);
19886 }
19887 Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
19888
19889 assert.strictEqual(_.size(new Foo(array)), 3);
19890 });
19891
19892 QUnit.test('should work with maps', function(assert) {
19893 assert.expect(2);
19894
19895 if (Map) {
19896 lodashStable.each([new Map, realm.map], function(map) {
19897 map.set('a', 1);
19898 map.set('b', 2);
19899 assert.strictEqual(_.size(map), 2);
19900 map.clear();
19901 });
19902 }
19903 else {
19904 skipAssert(assert, 2);
19905 }
19906 });
19907
19908 QUnit.test('should work with sets', function(assert) {
19909 assert.expect(2);
19910
19911 if (Set) {
19912 lodashStable.each([new Set, realm.set], function(set) {
19913 set.add(1);
19914 set.add(2);
19915 assert.strictEqual(_.size(set), 2);
19916 set.clear();
19917 });
19918 }
19919 else {
19920 skipAssert(assert, 2);
19921 }
19922 });
19923
19924 QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
19925 assert.expect(1);
19926
19927 assert.strictEqual(_.size({ 'length': -1 }), 1);
19928 });
19929
19930 QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
19931 assert.expect(1);
19932
19933 assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
19934 });
19935
19936 QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
19937 assert.expect(1);
19938
19939 assert.strictEqual(_.size({ 'length': '0' }), 1);
19940 });
19941 }(1, 2, 3));
19942
19943 /*--------------------------------------------------------------------------*/
19944
19945 QUnit.module('lodash.slice');
19946
19947 (function() {
19948 var array = [1, 2, 3];
19949
19950 QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
19951 assert.expect(2);
19952
19953 var actual = _.slice(array);
19954 assert.deepEqual(actual, array);
19955 assert.notStrictEqual(actual, array);
19956 });
19957
19958 QUnit.test('should work with a positive `start`', function(assert) {
19959 assert.expect(2);
19960
19961 assert.deepEqual(_.slice(array, 1), [2, 3]);
19962 assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
19963 });
19964
19965 QUnit.test('should work with a `start` >= `array.length`', function(assert) {
19966 assert.expect(4);
19967
19968 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
19969 assert.deepEqual(_.slice(array, start), []);
19970 });
19971 });
19972
19973 QUnit.test('should treat falsey `start` values as `0`', function(assert) {
19974 assert.expect(1);
19975
19976 var expected = lodashStable.map(falsey, lodashStable.constant(array));
19977
19978 var actual = lodashStable.map(falsey, function(start) {
19979 return _.slice(array, start);
19980 });
19981
19982 assert.deepEqual(actual, expected);
19983 });
19984
19985 QUnit.test('should work with a negative `start`', function(assert) {
19986 assert.expect(1);
19987
19988 assert.deepEqual(_.slice(array, -1), [3]);
19989 });
19990
19991 QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
19992 assert.expect(3);
19993
19994 lodashStable.each([-3, -4, -Infinity], function(start) {
19995 assert.deepEqual(_.slice(array, start), array);
19996 });
19997 });
19998
19999 QUnit.test('should work with `start` >= `end`', function(assert) {
20000 assert.expect(2);
20001
20002 lodashStable.each([2, 3], function(start) {
20003 assert.deepEqual(_.slice(array, start, 2), []);
20004 });
20005 });
20006
20007 QUnit.test('should work with a positive `end`', function(assert) {
20008 assert.expect(1);
20009
20010 assert.deepEqual(_.slice(array, 0, 1), [1]);
20011 });
20012
20013 QUnit.test('should work with a `end` >= `array.length`', function(assert) {
20014 assert.expect(4);
20015
20016 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
20017 assert.deepEqual(_.slice(array, 0, end), array);
20018 });
20019 });
20020
20021 QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
20022 assert.expect(1);
20023
20024 var expected = lodashStable.map(falsey, function(value) {
20025 return value === undefined ? array : [];
20026 });
20027
20028 var actual = lodashStable.map(falsey, function(end, index) {
20029 return index ? _.slice(array, 0, end) : _.slice(array, 0);
20030 });
20031
20032 assert.deepEqual(actual, expected);
20033 });
20034
20035 QUnit.test('should work with a negative `end`', function(assert) {
20036 assert.expect(1);
20037
20038 assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
20039 });
20040
20041 QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
20042 assert.expect(3);
20043
20044 lodashStable.each([-3, -4, -Infinity], function(end) {
20045 assert.deepEqual(_.slice(array, 0, end), []);
20046 });
20047 });
20048
20049 QUnit.test('should coerce `start` and `end` to integers', function(assert) {
20050 assert.expect(1);
20051
20052 var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
20053
20054 var actual = lodashStable.map(positions, function(pos) {
20055 return _.slice.apply(_, [array].concat(pos));
20056 });
20057
20058 assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
20059 });
20060
20061 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20062 assert.expect(2);
20063
20064 var array = [[1], [2, 3]],
20065 actual = lodashStable.map(array, _.slice);
20066
20067 assert.deepEqual(actual, array);
20068 assert.notStrictEqual(actual, array);
20069 });
20070
20071 QUnit.test('should work in a lazy sequence', function(assert) {
20072 assert.expect(38);
20073
20074 if (!isNpm) {
20075 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
20076 length = array.length,
20077 wrapped = _(array);
20078
20079 lodashStable.each(['map', 'filter'], function(methodName) {
20080 assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
20081 assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
20082 assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
20083 assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
20084
20085 assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
20086 assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
20087 assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
20088 assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
20089
20090 assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
20091 assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
20092 assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
20093
20094 assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
20095 assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
20096
20097 assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
20098 assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
20099 assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
20100 assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
20101 assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
20102 assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
20103 });
20104 }
20105 else {
20106 skipAssert(assert, 38);
20107 }
20108 });
20109 }());
20110
20111 /*--------------------------------------------------------------------------*/
20112
20113 QUnit.module('lodash.some');
20114
20115 (function() {
20116 QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
20117 assert.expect(2);
20118
20119 assert.strictEqual(_.some([false, 1, ''], identity), true);
20120 assert.strictEqual(_.some([null, 'a', 0], identity), true);
20121 });
20122
20123 QUnit.test('should return `false` for empty collections', function(assert) {
20124 assert.expect(1);
20125
20126 var expected = lodashStable.map(empties, alwaysFalse);
20127
20128 var actual = lodashStable.map(empties, function(value) {
20129 try {
20130 return _.some(value, identity);
20131 } catch (e) {}
20132 });
20133
20134 assert.deepEqual(actual, expected);
20135 });
20136
20137 QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
20138 assert.expect(2);
20139
20140 var count = 0;
20141
20142 assert.strictEqual(_.some([null, true, null], function(value) {
20143 count++;
20144 return value;
20145 }), true);
20146
20147 assert.strictEqual(count, 2);
20148 });
20149
20150 QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
20151 assert.expect(2);
20152
20153 assert.strictEqual(_.some([false, false, false], identity), false);
20154 assert.strictEqual(_.some([null, 0, ''], identity), false);
20155 });
20156
20157 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
20158 assert.expect(2);
20159
20160 var values = [, null, undefined],
20161 expected = lodashStable.map(values, alwaysFalse);
20162
20163 var actual = lodashStable.map(values, function(value, index) {
20164 var array = [0, 0];
20165 return index ? _.some(array, value) : _.some(array);
20166 });
20167
20168 assert.deepEqual(actual, expected);
20169
20170 expected = lodashStable.map(values, alwaysTrue);
20171 actual = lodashStable.map(values, function(value, index) {
20172 var array = [0, 1];
20173 return index ? _.some(array, value) : _.some(array);
20174 });
20175
20176 assert.deepEqual(actual, expected);
20177 });
20178
20179 QUnit.test('should work with `_.property` shorthands', function(assert) {
20180 assert.expect(2);
20181
20182 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
20183 assert.strictEqual(_.some(objects, 'a'), false);
20184 assert.strictEqual(_.some(objects, 'b'), true);
20185 });
20186
20187 QUnit.test('should work with `_.matches` shorthands', function(assert) {
20188 assert.expect(2);
20189
20190 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
20191 assert.strictEqual(_.some(objects, { 'a': 0 }), true);
20192 assert.strictEqual(_.some(objects, { 'b': 2 }), false);
20193 });
20194
20195 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20196 assert.expect(1);
20197
20198 var actual = lodashStable.map([[1]], _.some);
20199 assert.deepEqual(actual, [true]);
20200 });
20201 }());
20202
20203 /*--------------------------------------------------------------------------*/
20204
20205 QUnit.module('lodash.sortBy');
20206
20207 (function() {
20208 var objects = [
20209 { 'a': 'x', 'b': 3 },
20210 { 'a': 'y', 'b': 4 },
20211 { 'a': 'x', 'b': 1 },
20212 { 'a': 'y', 'b': 2 }
20213 ];
20214
20215 QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
20216 assert.expect(1);
20217
20218 var actual = lodashStable.map(_.sortBy(objects, function(object) {
20219 return object.b;
20220 }), 'b');
20221
20222 assert.deepEqual(actual, [1, 2, 3, 4]);
20223 });
20224
20225 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
20226 assert.expect(1);
20227
20228 var array = [3, 2, 1],
20229 values = [, null, undefined],
20230 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
20231
20232 var actual = lodashStable.map(values, function(value, index) {
20233 return index ? _.sortBy(array, value) : _.sortBy(array);
20234 });
20235
20236 assert.deepEqual(actual, expected);
20237 });
20238
20239 QUnit.test('should work with `_.property` shorthands', function(assert) {
20240 assert.expect(1);
20241
20242 var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
20243 assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
20244 });
20245
20246 QUnit.test('should work with an object for `collection`', function(assert) {
20247 assert.expect(1);
20248
20249 var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
20250 assert.deepEqual(actual, [3, 1, 2]);
20251 });
20252
20253 QUnit.test('should move symbol, `null`, `undefined`, and `NaN` values to the end', function(assert) {
20254 assert.expect(2);
20255
20256 var symbol1 = Symbol ? Symbol('a') : null,
20257 symbol2 = Symbol ? Symbol('b') : null,
20258 array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
20259 expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20260
20261 assert.deepEqual(_.sortBy(array), expected);
20262
20263 array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
20264 expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
20265
20266 assert.deepEqual(_.sortBy(array), expected);
20267 });
20268
20269 QUnit.test('should treat number values for `collection` as empty', function(assert) {
20270 assert.expect(1);
20271
20272 assert.deepEqual(_.sortBy(1), []);
20273 });
20274
20275 QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
20276 assert.expect(1);
20277
20278 var actual = _.sortBy(objects, function(object) {
20279 var result = [object.a, object.b];
20280 result.toString = function() { return String(this[0]); };
20281 return result;
20282 });
20283
20284 assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
20285 });
20286
20287 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20288 assert.expect(1);
20289
20290 var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
20291 assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
20292 });
20293 }());
20294
20295 /*--------------------------------------------------------------------------*/
20296
20297 QUnit.module('sortBy methods');
20298
20299 lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
20300 var func = _[methodName];
20301
20302 function Pair(a, b, c) {
20303 this.a = a;
20304 this.b = b;
20305 this.c = c;
20306 }
20307
20308 var objects = [
20309 { 'a': 'x', 'b': 3 },
20310 { 'a': 'y', 'b': 4 },
20311 { 'a': 'x', 'b': 1 },
20312 { 'a': 'y', 'b': 2 }
20313 ];
20314
20315 var stableArray = [
20316 new Pair(1, 1, 1), new Pair(1, 2, 1),
20317 new Pair(1, 1, 1), new Pair(1, 2, 1),
20318 new Pair(1, 3, 1), new Pair(1, 4, 1),
20319 new Pair(1, 5, 1), new Pair(1, 6, 1),
20320 new Pair(2, 1, 2), new Pair(2, 2, 2),
20321 new Pair(2, 3, 2), new Pair(2, 4, 2),
20322 new Pair(2, 5, 2), new Pair(2, 6, 2),
20323 new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
20324 new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
20325 new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
20326 ];
20327
20328 var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
20329
20330 QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
20331 assert.expect(1);
20332
20333 var actual = func(objects, ['a', 'b']);
20334 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20335 });
20336
20337 QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
20338 assert.expect(1);
20339
20340 var actual = func(objects, ['a', function(object) { return object.b; }]);
20341 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
20342 });
20343
20344 QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
20345 assert.expect(2);
20346
20347 lodashStable.each([stableArray, stableObject], function(value, index) {
20348 var actual = func(value, ['a', 'c']);
20349 assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
20350 });
20351 });
20352
20353 QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
20354 assert.expect(1);
20355
20356 try {
20357 var actual = func(objects.concat(null, undefined), ['a', 'b']);
20358 } catch (e) {}
20359
20360 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
20361 });
20362
20363 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
20364 assert.expect(3);
20365
20366 var objects = [
20367 { 'a': 'x', '0': 3 },
20368 { 'a': 'y', '0': 4 },
20369 { 'a': 'x', '0': 1 },
20370 { 'a': 'y', '0': 2 }
20371 ];
20372
20373 var funcs = [func, lodashStable.partialRight(func, 'bogus')];
20374
20375 lodashStable.each(['a', 0, [0]], function(props, index) {
20376 var expected = lodashStable.map(funcs, lodashStable.constant(
20377 index
20378 ? [objects[2], objects[3], objects[0], objects[1]]
20379 : [objects[0], objects[2], objects[1], objects[3]]
20380 ));
20381
20382 var actual = lodashStable.map(funcs, function(func) {
20383 return lodashStable.reduce([props], func, objects);
20384 });
20385
20386 assert.deepEqual(actual, expected);
20387 });
20388 });
20389 });
20390
20391 /*--------------------------------------------------------------------------*/
20392
20393 QUnit.module('sortedIndex methods');
20394
20395 lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
20396 var func = _[methodName],
20397 isSortedIndex = methodName == 'sortedIndex';
20398
20399 QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
20400 assert.expect(1);
20401
20402 var array = [30, 50],
20403 values = [30, 40, 50],
20404 expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20405
20406 var actual = lodashStable.map(values, function(value) {
20407 return func(array, value);
20408 });
20409
20410 assert.deepEqual(actual, expected);
20411 });
20412
20413 QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
20414 assert.expect(1);
20415
20416 var array = ['a', 'c'],
20417 values = ['a', 'b', 'c'],
20418 expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
20419
20420 var actual = lodashStable.map(values, function(value) {
20421 return func(array, value);
20422 });
20423
20424 assert.deepEqual(actual, expected);
20425 });
20426
20427 QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
20428 assert.expect(1);
20429
20430 var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
20431
20432 var actual = lodashStable.map(falsey, function(array) {
20433 return [func(array, 1), func(array, undefined), func(array, NaN)];
20434 });
20435
20436 assert.deepEqual(actual, expected);
20437 });
20438
20439 QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
20440 assert.expect(12);
20441
20442 var symbol1 = Symbol ? Symbol('a') : null,
20443 symbol2 = Symbol ? Symbol('b') : null,
20444 expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
20445
20446 lodashStable.each([
20447 [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
20448 ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
20449 ], function(array) {
20450 assert.deepEqual(_.sortBy(array), expected);
20451 assert.strictEqual(func(expected, 3), 2);
20452 assert.strictEqual(func(expected, symbol1), (isSortedIndex ? 3 : (Symbol ? 5 : 6)));
20453 assert.strictEqual(func(expected, null), (isSortedIndex ? (Symbol ? 5 : 3) : 6));
20454 assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
20455 assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
20456 });
20457 });
20458 });
20459
20460 /*--------------------------------------------------------------------------*/
20461
20462 QUnit.module('sortedIndexBy methods');
20463
20464 lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
20465 var func = _[methodName],
20466 isSortedIndexBy = methodName == 'sortedIndexBy';
20467
20468 QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
20469 assert.expect(1);
20470
20471 var args;
20472
20473 func([30, 50], 40, function(assert) {
20474 args || (args = slice.call(arguments));
20475 });
20476
20477 assert.deepEqual(args, [40]);
20478 });
20479
20480 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
20481 assert.expect(1);
20482
20483 var objects = [{ 'x': 30 }, { 'x': 50 }],
20484 actual = func(objects, { 'x': 40 }, 'x');
20485
20486 assert.strictEqual(actual, 1);
20487 });
20488
20489 QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
20490 assert.expect(12);
20491
20492 lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
20493 var array = [],
20494 values = [MAX_ARRAY_LENGTH, NaN, undefined];
20495
20496 array.length = length;
20497
20498 lodashStable.each(values, function(value) {
20499 var steps = 0;
20500
20501 var actual = func(array, value, function(value) {
20502 steps++;
20503 return value;
20504 });
20505
20506 var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
20507 ? 0
20508 : Math.min(length, MAX_ARRAY_INDEX);
20509
20510 // Avoid false fails in older Firefox.
20511 if (array.length == length) {
20512 assert.ok(steps == 32 || steps == 33);
20513 assert.strictEqual(actual, expected);
20514 }
20515 else {
20516 skipAssert(assert, 2);
20517 }
20518 });
20519 });
20520 });
20521 });
20522
20523 /*--------------------------------------------------------------------------*/
20524
20525 QUnit.module('sortedIndexOf methods');
20526
20527 lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
20528 var func = _[methodName],
20529 isSortedIndexOf = methodName == 'sortedIndexOf';
20530
20531 QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
20532 assert.expect(1);
20533
20534 var sorted = [4, 4, 5, 5, 6, 6];
20535 assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
20536 });
20537 });
20538
20539 /*--------------------------------------------------------------------------*/
20540
20541 QUnit.module('lodash.sortedUniq');
20542
20543 (function() {
20544 QUnit.test('should return unique values of a sorted array', function(assert) {
20545 assert.expect(3);
20546
20547 var expected = [1, 2, 3];
20548
20549 lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
20550 assert.deepEqual(_.sortedUniq(array), expected);
20551 });
20552 });
20553 }());
20554
20555 /*--------------------------------------------------------------------------*/
20556
20557 QUnit.module('lodash.split');
20558
20559 (function() {
20560 QUnit.test('should split a string by `separator`', function(assert) {
20561 assert.expect(3);
20562
20563 var string = 'abcde';
20564 assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
20565 assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
20566 assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
20567 });
20568
20569 QUnit.test('should return an array containing an empty string for empty values', function(assert) {
20570 assert.expect(1);
20571
20572 var values = [, null, undefined, ''],
20573 expected = lodashStable.map(values, lodashStable.constant(['']));
20574
20575 var actual = lodashStable.map(values, function(value, index) {
20576 return index ? _.split(value) : _.split();
20577 });
20578
20579 assert.deepEqual(actual, expected);
20580 });
20581
20582 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
20583 assert.expect(1);
20584
20585 var strings = ['abc', 'def', 'ghi'],
20586 actual = lodashStable.map(strings, _.split);
20587
20588 assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
20589 });
20590
20591 QUnit.test('should allow mixed string and array prototype methods', function(assert) {
20592 assert.expect(1);
20593
20594 if (!isNpm) {
20595 var wrapped = _('abc');
20596 assert.strictEqual(wrapped.split('b').join(','), 'a,c');
20597 }
20598 else {
20599 skipAssert(assert);
20600 }
20601 });
20602 }());
20603
20604 /*--------------------------------------------------------------------------*/
20605
20606 QUnit.module('lodash.spread');
20607
20608 (function() {
20609 function fn(a, b, c) {
20610 return slice.call(arguments);
20611 }
20612
20613 QUnit.test('should spread arguments to `func`', function(assert) {
20614 assert.expect(1);
20615
20616 var spread = _.spread(fn);
20617 assert.deepEqual(spread([4, 2]), [4, 2]);
20618 });
20619
20620 QUnit.test('should accept a falsey `array` argument', function(assert) {
20621 assert.expect(1);
20622
20623 var spread = _.spread(alwaysTrue),
20624 expected = lodashStable.map(falsey, alwaysTrue);
20625
20626 var actual = lodashStable.map(falsey, function(array, index) {
20627 try {
20628 return index ? spread(array) : spread();
20629 } catch (e) {}
20630 });
20631
20632 assert.deepEqual(actual, expected);
20633 });
20634
20635 QUnit.test('should provide the correct `func` arguments', function(assert) {
20636 assert.expect(1);
20637
20638 var args;
20639
20640 var spread = _.spread(function() {
20641 args = slice.call(arguments);
20642 });
20643
20644 spread([4, 2], 'ignored');
20645 assert.deepEqual(args, [4, 2]);
20646 });
20647
20648 QUnit.test('should work with `start`', function(assert) {
20649 assert.expect(1);
20650
20651 var spread = _.spread(fn, 1);
20652 assert.deepEqual(spread(1, [2, 3, 4]), [1, 2, 3, 4]);
20653 });
20654
20655 QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
20656 assert.expect(1);
20657
20658 var values = [-1, NaN, 'a'],
20659 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
20660
20661 var actual = lodashStable.map(values, function(value) {
20662 var spread = _.spread(fn, value);
20663 return spread([1, 2, 3, 4]);
20664 });
20665
20666 assert.deepEqual(actual, expected);
20667 });
20668
20669 QUnit.test('should coerce `start` to an integer', function(assert) {
20670 assert.expect(1);
20671
20672 var spread = _.spread(fn, 1.6);
20673 assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
20674 });
20675 }());
20676
20677 /*--------------------------------------------------------------------------*/
20678
20679 QUnit.module('lodash.startCase');
20680
20681 (function() {
20682 QUnit.test('should uppercase only the first character of each word', function(assert) {
20683 assert.expect(3);
20684
20685 assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
20686 assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
20687 assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
20688 });
20689 }());
20690
20691 /*--------------------------------------------------------------------------*/
20692
20693 QUnit.module('lodash.startsWith');
20694
20695 (function() {
20696 var string = 'abc';
20697
20698 QUnit.test('should return `true` if a string starts with `target`', function(assert) {
20699 assert.expect(1);
20700
20701 assert.strictEqual(_.startsWith(string, 'a'), true);
20702 });
20703
20704 QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
20705 assert.expect(1);
20706
20707 assert.strictEqual(_.startsWith(string, 'b'), false);
20708 });
20709
20710 QUnit.test('should work with a `position` argument', function(assert) {
20711 assert.expect(1);
20712
20713 assert.strictEqual(_.startsWith(string, 'b', 1), true);
20714 });
20715
20716 QUnit.test('should work with `position` >= `string.length`', function(assert) {
20717 assert.expect(4);
20718
20719 lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
20720 assert.strictEqual(_.startsWith(string, 'a', position), false);
20721 });
20722 });
20723
20724 QUnit.test('should treat falsey `position` values as `0`', function(assert) {
20725 assert.expect(1);
20726
20727 var expected = lodashStable.map(falsey, alwaysTrue);
20728
20729 var actual = lodashStable.map(falsey, function(position) {
20730 return _.startsWith(string, 'a', position);
20731 });
20732
20733 assert.deepEqual(actual, expected);
20734 });
20735
20736 QUnit.test('should treat a negative `position` as `0`', function(assert) {
20737 assert.expect(6);
20738
20739 lodashStable.each([-1, -3, -Infinity], function(position) {
20740 assert.strictEqual(_.startsWith(string, 'a', position), true);
20741 assert.strictEqual(_.startsWith(string, 'b', position), false);
20742 });
20743 });
20744
20745 QUnit.test('should coerce `position` to an integer', function(assert) {
20746 assert.expect(1);
20747
20748 assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
20749 });
20750
20751 QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
20752 assert.expect(1);
20753
20754 assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
20755 return _.startsWith(string, '', position, true);
20756 }));
20757 });
20758 }());
20759
20760 /*--------------------------------------------------------------------------*/
20761
20762 QUnit.module('lodash.startsWith and lodash.endsWith');
20763
20764 lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
20765 var func = _[methodName],
20766 isStartsWith = methodName == 'startsWith';
20767
20768 var string = 'abc',
20769 chr = isStartsWith ? 'a' : 'c';
20770
20771 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
20772 assert.expect(2);
20773
20774 assert.strictEqual(func(Object(string), chr), true);
20775 assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
20776 });
20777
20778 QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
20779 assert.expect(2);
20780
20781 assert.strictEqual(func(string, Object(chr)), true);
20782 assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
20783 });
20784
20785 QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
20786 assert.expect(2);
20787
20788 var position = isStartsWith ? 1 : 2;
20789 assert.strictEqual(func(string, 'b', Object(position)), true);
20790 assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
20791 });
20792 });
20793
20794 /*--------------------------------------------------------------------------*/
20795
20796 QUnit.module('lodash.subtract');
20797
20798 (function() {
20799 QUnit.test('should subtract two numbers', function(assert) {
20800 assert.expect(3);
20801
20802 assert.strictEqual(_.subtract(6, 4), 2);
20803 assert.strictEqual(_.subtract(-6, 4), -10);
20804 assert.strictEqual(_.subtract(-6, -4), -2);
20805 });
20806
20807 QUnit.test('should coerce arguments to numbers', function(assert) {
20808 assert.expect(2);
20809
20810 assert.strictEqual(_.subtract('6', '4'), 2);
20811 assert.deepEqual(_.subtract('x', 'y'), NaN);
20812 });
20813 }());
20814
20815 /*--------------------------------------------------------------------------*/
20816
20817 QUnit.module('math operator methods');
20818
20819 lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
20820 var func = _[methodName];
20821
20822 QUnit.test('`_.' + methodName + '` should return `0` when no arguments are given', function(assert) {
20823 assert.expect(1);
20824
20825 assert.strictEqual(func(), 0);
20826 });
20827
20828 QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
20829 assert.expect(3);
20830
20831 assert.strictEqual(func(6), 6);
20832 assert.strictEqual(func(6, undefined), 6);
20833 assert.strictEqual(func(undefined, 4), 4);
20834 });
20835
20836 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
20837 assert.expect(2);
20838
20839 var values = [0, '0', -0, '-0'],
20840 expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
20841
20842 lodashStable.times(2, function(index) {
20843 var actual = lodashStable.map(values, function(value) {
20844 var result = index ? func(undefined, value) : func(value);
20845 return [result, 1 / result];
20846 });
20847
20848 assert.deepEqual(actual, expected);
20849 });
20850 });
20851
20852 QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
20853 assert.expect(2);
20854
20855 assert.deepEqual(func(0, {}), NaN);
20856 assert.deepEqual(func({}, 0), NaN);
20857 });
20858
20859 QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
20860 assert.expect(2);
20861
20862 if (Symbol) {
20863 assert.deepEqual(func(0, symbol), NaN);
20864 assert.deepEqual(func(symbol, 0), NaN);
20865 }
20866 else {
20867 skipAssert(assert, 2);
20868 }
20869 });
20870
20871 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
20872 assert.expect(1);
20873
20874 if (!isNpm) {
20875 var actual = _(1)[methodName](2);
20876 assert.notOk(actual instanceof _);
20877 }
20878 else {
20879 skipAssert(assert);
20880 }
20881 });
20882
20883 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
20884 assert.expect(1);
20885
20886 if (!isNpm) {
20887 var actual = _(1).chain()[methodName](2);
20888 assert.ok(actual instanceof _);
20889 }
20890 else {
20891 skipAssert(assert);
20892 }
20893 });
20894 });
20895
20896 /*--------------------------------------------------------------------------*/
20897
20898 QUnit.module('lodash.sumBy');
20899
20900 (function() {
20901 var array = [6, 4, 2],
20902 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
20903
20904 QUnit.test('should work with an `iteratee` argument', function(assert) {
20905 assert.expect(1);
20906
20907 var actual = _.sumBy(objects, function(object) {
20908 return object.a;
20909 });
20910
20911 assert.deepEqual(actual, 6);
20912 });
20913
20914 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
20915 assert.expect(1);
20916
20917 var args;
20918
20919 _.sumBy(array, function() {
20920 args || (args = slice.call(arguments));
20921 });
20922
20923 assert.deepEqual(args, [6]);
20924 });
20925
20926 QUnit.test('should work with `_.property` shorthands', function(assert) {
20927 assert.expect(2);
20928
20929 var arrays = [[2], [3], [1]];
20930 assert.strictEqual(_.sumBy(arrays, 0), 6);
20931 assert.strictEqual(_.sumBy(objects, 'a'), 6);
20932 });
20933 }());
20934
20935 /*--------------------------------------------------------------------------*/
20936
20937 QUnit.module('sum methods');
20938
20939 lodashStable.each(['sum', 'sumBy'], function(methodName) {
20940 var array = [6, 4, 2],
20941 func = _[methodName];
20942
20943 QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
20944 assert.expect(1);
20945
20946 assert.strictEqual(func(array), 12);
20947 });
20948
20949 QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
20950 assert.expect(1);
20951
20952 var expected = lodashStable.map(empties, alwaysZero);
20953
20954 var actual = lodashStable.map(empties, function(value) {
20955 return func(value);
20956 });
20957
20958 assert.deepEqual(actual, expected);
20959 });
20960
20961 QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
20962 assert.expect(1);
20963
20964 assert.strictEqual(func([1, undefined]), 1);
20965 });
20966
20967 QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
20968 assert.expect(1);
20969
20970 assert.deepEqual(func([1, NaN]), NaN);
20971 });
20972
20973 QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
20974 assert.expect(1);
20975
20976 assert.strictEqual(func(['1', '2']), '12');
20977 });
20978 });
20979
20980 /*--------------------------------------------------------------------------*/
20981
20982 QUnit.module('lodash.tail');
20983
20984 (function() {
20985 var array = [1, 2, 3];
20986
20987 QUnit.test('should accept a falsey `array` argument', function(assert) {
20988 assert.expect(1);
20989
20990 var expected = lodashStable.map(falsey, alwaysEmptyArray);
20991
20992 var actual = lodashStable.map(falsey, function(array, index) {
20993 try {
20994 return index ? _.tail(array) : _.tail();
20995 } catch (e) {}
20996 });
20997
20998 assert.deepEqual(actual, expected);
20999 });
21000
21001 QUnit.test('should exclude the first element', function(assert) {
21002 assert.expect(1);
21003
21004 assert.deepEqual(_.tail(array), [2, 3]);
21005 });
21006
21007 QUnit.test('should return an empty when querying empty arrays', function(assert) {
21008 assert.expect(1);
21009
21010 assert.deepEqual(_.tail([]), []);
21011 });
21012
21013 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21014 assert.expect(1);
21015
21016 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21017 actual = lodashStable.map(array, _.tail);
21018
21019 assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
21020 });
21021
21022 QUnit.test('should work in a lazy sequence', function(assert) {
21023 assert.expect(4);
21024
21025 if (!isNpm) {
21026 var array = lodashStable.range(LARGE_ARRAY_SIZE),
21027 values = [];
21028
21029 var actual = _(array).tail().filter(function(value) {
21030 values.push(value);
21031 return false;
21032 })
21033 .value();
21034
21035 assert.deepEqual(actual, []);
21036 assert.deepEqual(values, array.slice(1));
21037
21038 values = [];
21039
21040 actual = _(array).filter(function(value) {
21041 values.push(value);
21042 return isEven(value);
21043 })
21044 .tail()
21045 .value();
21046
21047 assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
21048 assert.deepEqual(values, array);
21049 }
21050 else {
21051 skipAssert(assert, 4);
21052 }
21053 });
21054
21055 QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
21056 assert.expect(4);
21057
21058 if (!isNpm) {
21059 var array = lodashStable.range(LARGE_ARRAY_SIZE),
21060 iteratee = function() { pass = false; },
21061 pass = true,
21062 actual = _(array).slice(0, 1).tail().map(iteratee).value();
21063
21064 assert.ok(pass);
21065 assert.deepEqual(actual, []);
21066
21067 pass = true;
21068 actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
21069
21070 assert.ok(pass);
21071 assert.deepEqual(actual, []);
21072 }
21073 else {
21074 skipAssert(assert, 4);
21075 }
21076 });
21077 }());
21078
21079 /*--------------------------------------------------------------------------*/
21080
21081 QUnit.module('lodash.take');
21082
21083 (function() {
21084 var array = [1, 2, 3];
21085
21086 QUnit.test('should take the first two elements', function(assert) {
21087 assert.expect(1);
21088
21089 assert.deepEqual(_.take(array, 2), [1, 2]);
21090 });
21091
21092 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21093 assert.expect(1);
21094
21095 var expected = lodashStable.map(falsey, function(value) {
21096 return value === undefined ? [1] : [];
21097 });
21098
21099 var actual = lodashStable.map(falsey, function(n) {
21100 return _.take(array, n);
21101 });
21102
21103 assert.deepEqual(actual, expected);
21104 });
21105
21106 QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21107 assert.expect(3);
21108
21109 lodashStable.each([0, -1, -Infinity], function(n) {
21110 assert.deepEqual(_.take(array, n), []);
21111 });
21112 });
21113
21114 QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
21115 assert.expect(4);
21116
21117 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21118 assert.deepEqual(_.take(array, n), array);
21119 });
21120 });
21121
21122 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21123 assert.expect(1);
21124
21125 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21126 actual = lodashStable.map(array, _.take);
21127
21128 assert.deepEqual(actual, [[1], [4], [7]]);
21129 });
21130
21131 QUnit.test('should work in a lazy sequence', function(assert) {
21132 assert.expect(6);
21133
21134 if (!isNpm) {
21135 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
21136 predicate = function(value) { values.push(value); return isEven(value); },
21137 values = [],
21138 actual = _(array).take(2).take().value();
21139
21140 assert.deepEqual(actual, _.take(_.take(array, 2)));
21141
21142 actual = _(array).filter(predicate).take(2).take().value();
21143 assert.deepEqual(values, [1, 2]);
21144 assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
21145
21146 actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
21147 assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
21148
21149 values = [];
21150
21151 actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
21152 assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
21153 assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
21154 }
21155 else {
21156 skipAssert(assert, 6);
21157 }
21158 });
21159 }());
21160
21161 /*--------------------------------------------------------------------------*/
21162
21163 QUnit.module('lodash.takeRight');
21164
21165 (function() {
21166 var array = [1, 2, 3];
21167
21168 QUnit.test('should take the last two elements', function(assert) {
21169 assert.expect(1);
21170
21171 assert.deepEqual(_.takeRight(array, 2), [2, 3]);
21172 });
21173
21174 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
21175 assert.expect(1);
21176
21177 var expected = lodashStable.map(falsey, function(value) {
21178 return value === undefined ? [3] : [];
21179 });
21180
21181 var actual = lodashStable.map(falsey, function(n) {
21182 return _.takeRight(array, n);
21183 });
21184
21185 assert.deepEqual(actual, expected);
21186 });
21187
21188 QUnit.test('should return an empty array when `n` < `1`', function(assert) {
21189 assert.expect(3);
21190
21191 lodashStable.each([0, -1, -Infinity], function(n) {
21192 assert.deepEqual(_.takeRight(array, n), []);
21193 });
21194 });
21195
21196 QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
21197 assert.expect(4);
21198
21199 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
21200 assert.deepEqual(_.takeRight(array, n), array);
21201 });
21202 });
21203
21204 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
21205 assert.expect(1);
21206
21207 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
21208 actual = lodashStable.map(array, _.takeRight);
21209
21210 assert.deepEqual(actual, [[3], [6], [9]]);
21211 });
21212
21213 QUnit.test('should work in a lazy sequence', function(assert) {
21214 assert.expect(6);
21215
21216 if (!isNpm) {
21217 var array = lodashStable.range(LARGE_ARRAY_SIZE),
21218 predicate = function(value) { values.push(value); return isEven(value); },
21219 values = [],
21220 actual = _(array).takeRight(2).takeRight().value();
21221
21222 assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
21223
21224 actual = _(array).filter(predicate).takeRight(2).takeRight().value();
21225 assert.deepEqual(values, array);
21226 assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
21227
21228 actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
21229 assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
21230
21231 values = [];
21232
21233 actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
21234 assert.deepEqual(values, array);
21235 assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
21236 }
21237 else {
21238 skipAssert(assert, 6);
21239 }
21240 });
21241 }());
21242
21243 /*--------------------------------------------------------------------------*/
21244
21245 QUnit.module('lodash.takeRightWhile');
21246
21247 (function() {
21248 var array = [1, 2, 3, 4];
21249
21250 var objects = [
21251 { 'a': 0, 'b': 0 },
21252 { 'a': 1, 'b': 1 },
21253 { 'a': 2, 'b': 2 }
21254 ];
21255
21256 QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21257 assert.expect(1);
21258
21259 var actual = _.takeRightWhile(array, function(n) {
21260 return n > 2;
21261 });
21262
21263 assert.deepEqual(actual, [3, 4]);
21264 });
21265
21266 QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21267 assert.expect(1);
21268
21269 var args;
21270
21271 _.takeRightWhile(array, function() {
21272 args = slice.call(arguments);
21273 });
21274
21275 assert.deepEqual(args, [4, 3, array]);
21276 });
21277
21278 QUnit.test('should work with `_.matches` shorthands', function(assert) {
21279 assert.expect(1);
21280
21281 assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
21282 });
21283
21284 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21285 assert.expect(1);
21286
21287 assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
21288 });
21289
21290 QUnit.test('should work with `_.property` shorthands', function(assert) {
21291 assert.expect(1);
21292
21293 assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
21294 });
21295
21296 QUnit.test('should work in a lazy sequence', function(assert) {
21297 assert.expect(3);
21298
21299 if (!isNpm) {
21300 var array = lodashStable.range(LARGE_ARRAY_SIZE),
21301 predicate = function(n) { return n > 2; },
21302 expected = _.takeRightWhile(array, predicate),
21303 wrapped = _(array).takeRightWhile(predicate);
21304
21305 assert.deepEqual(wrapped.value(), expected);
21306 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21307 assert.strictEqual(wrapped.last(), _.last(expected));
21308 }
21309 else {
21310 skipAssert(assert, 3);
21311 }
21312 });
21313
21314 QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21315 assert.expect(5);
21316
21317 if (!isNpm) {
21318 var args,
21319 array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21320 expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
21321
21322 _(array).slice(1).takeRightWhile(function(value, index, array) {
21323 args = slice.call(arguments);
21324 }).value();
21325
21326 assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
21327
21328 _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
21329 args = slice.call(arguments);
21330 }).value();
21331
21332 assert.deepEqual(args, expected);
21333
21334 _(array).slice(1).map(square).takeRightWhile(function(value, index) {
21335 args = slice.call(arguments);
21336 }).value();
21337
21338 assert.deepEqual(args, expected);
21339
21340 _(array).slice(1).map(square).takeRightWhile(function(index) {
21341 args = slice.call(arguments);
21342 }).value();
21343
21344 assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
21345
21346 _(array).slice(1).map(square).takeRightWhile(function() {
21347 args = slice.call(arguments);
21348 }).value();
21349
21350 assert.deepEqual(args, expected);
21351 }
21352 else {
21353 skipAssert(assert, 5);
21354 }
21355 });
21356 }());
21357
21358 /*--------------------------------------------------------------------------*/
21359
21360 QUnit.module('lodash.takeWhile');
21361
21362 (function() {
21363 var array = [1, 2, 3, 4];
21364
21365 var objects = [
21366 { 'a': 2, 'b': 2 },
21367 { 'a': 1, 'b': 1 },
21368 { 'a': 0, 'b': 0 }
21369 ];
21370
21371 QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
21372 assert.expect(1);
21373
21374 var actual = _.takeWhile(array, function(n) {
21375 return n < 3;
21376 });
21377
21378 assert.deepEqual(actual, [1, 2]);
21379 });
21380
21381 QUnit.test('should provide the correct `predicate` arguments', function(assert) {
21382 assert.expect(1);
21383
21384 var args;
21385
21386 _.takeWhile(array, function() {
21387 args = slice.call(arguments);
21388 });
21389
21390 assert.deepEqual(args, [1, 0, array]);
21391 });
21392
21393 QUnit.test('should work with `_.matches` shorthands', function(assert) {
21394 assert.expect(1);
21395
21396 assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
21397 });
21398
21399 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
21400 assert.expect(1);
21401
21402 assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
21403 });
21404 QUnit.test('should work with `_.property` shorthands', function(assert) {
21405 assert.expect(1);
21406
21407 assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
21408 });
21409
21410 QUnit.test('should work in a lazy sequence', function(assert) {
21411 assert.expect(3);
21412
21413 if (!isNpm) {
21414 var array = lodashStable.range(LARGE_ARRAY_SIZE),
21415 predicate = function(n) { return n < 3; },
21416 expected = _.takeWhile(array, predicate),
21417 wrapped = _(array).takeWhile(predicate);
21418
21419 assert.deepEqual(wrapped.value(), expected);
21420 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
21421 assert.strictEqual(wrapped.last(), _.last(expected));
21422 }
21423 else {
21424 skipAssert(assert, 3);
21425 }
21426 });
21427
21428 QUnit.test('should work in a lazy sequence with `take`', function(assert) {
21429 assert.expect(1);
21430
21431 if (!isNpm) {
21432 var array = lodashStable.range(LARGE_ARRAY_SIZE);
21433
21434 var actual = _(array)
21435 .takeWhile(function(n) { return n < 4; })
21436 .take(2)
21437 .takeWhile(function(n) { return n == 0; })
21438 .value();
21439
21440 assert.deepEqual(actual, [0]);
21441 }
21442 else {
21443 skipAssert(assert);
21444 }
21445 });
21446
21447 QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
21448 assert.expect(5);
21449
21450 if (!isNpm) {
21451 var args,
21452 array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
21453 expected = [1, 0, lodashStable.map(array.slice(1), square)];
21454
21455 _(array).slice(1).takeWhile(function(value, index, array) {
21456 args = slice.call(arguments);
21457 }).value();
21458
21459 assert.deepEqual(args, [1, 0, array.slice(1)]);
21460
21461 _(array).slice(1).map(square).takeWhile(function(value, index, array) {
21462 args = slice.call(arguments);
21463 }).value();
21464
21465 assert.deepEqual(args, expected);
21466
21467 _(array).slice(1).map(square).takeWhile(function(value, index) {
21468 args = slice.call(arguments);
21469 }).value();
21470
21471 assert.deepEqual(args, expected);
21472
21473 _(array).slice(1).map(square).takeWhile(function(value) {
21474 args = slice.call(arguments);
21475 }).value();
21476
21477 assert.deepEqual(args, [1]);
21478
21479 _(array).slice(1).map(square).takeWhile(function() {
21480 args = slice.call(arguments);
21481 }).value();
21482
21483 assert.deepEqual(args, expected);
21484 }
21485 else {
21486 skipAssert(assert, 5);
21487 }
21488 });
21489 }());
21490
21491 /*--------------------------------------------------------------------------*/
21492
21493 QUnit.module('lodash.tap');
21494
21495 (function() {
21496 QUnit.test('should intercept and return the given value', function(assert) {
21497 assert.expect(2);
21498
21499 if (!isNpm) {
21500 var intercepted,
21501 array = [1, 2, 3];
21502
21503 var actual = _.tap(array, function(value) {
21504 intercepted = value;
21505 });
21506
21507 assert.strictEqual(actual, array);
21508 assert.strictEqual(intercepted, array);
21509 }
21510 else {
21511 skipAssert(assert, 2);
21512 }
21513 });
21514
21515 QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
21516 assert.expect(2);
21517
21518 if (!isNpm) {
21519 var intercepted,
21520 array = [1, 2, 3];
21521
21522 var wrapped = _(array).tap(function(value) {
21523 intercepted = value;
21524 value.pop();
21525 });
21526
21527 assert.ok(wrapped instanceof _);
21528
21529 wrapped.value();
21530 assert.strictEqual(intercepted, array);
21531 }
21532 else {
21533 skipAssert(assert, 2);
21534 }
21535 });
21536 }());
21537
21538 /*--------------------------------------------------------------------------*/
21539
21540 QUnit.module('lodash.template');
21541
21542 (function() {
21543 QUnit.test('should escape values in "escape" delimiters', function(assert) {
21544 assert.expect(1);
21545
21546 var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
21547 expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
21548 data = { 'value': '&<>"\'`\/' };
21549
21550 var actual = lodashStable.map(strings, function(string) {
21551 return _.template(string)(data);
21552 });
21553
21554 assert.deepEqual(actual, expected);
21555 });
21556
21557 QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
21558 assert.expect(1);
21559
21560 var compiled = _.template('<%= typeof __e %>');
21561 assert.strictEqual(compiled({}), 'undefined');
21562 });
21563
21564 QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
21565 assert.expect(1);
21566
21567 var compiled = _.template(
21568 '<ul><%\
21569 for (var key in collection) {\
21570 %><li><%= collection[key] %></li><%\
21571 } %></ul>'
21572 );
21573
21574 var data = { 'collection': { 'a': 'A', 'b': 'B' } },
21575 actual = compiled(data);
21576
21577 assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
21578 });
21579
21580 QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
21581 assert.expect(1);
21582
21583 var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
21584 data = { 'value': true };
21585
21586 assert.strictEqual(compiled(data), 'yap');
21587 });
21588
21589 QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
21590 assert.expect(1);
21591
21592 var compiled = _.template('<% var b = a; %><%= b.value %>'),
21593 data = { 'a': { 'value': 1 } };
21594
21595 assert.strictEqual(compiled(data), '1');
21596 });
21597
21598 QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
21599 assert.expect(1);
21600
21601 var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
21602 expected = lodashStable.map(strings, lodashStable.constant('ABC')),
21603 data = { 'a': 'A' };
21604
21605 var actual = lodashStable.map(strings, function(string) {
21606 return _.template(string)(data);
21607 });
21608
21609 assert.deepEqual(actual, expected);
21610 });
21611
21612 QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
21613 assert.expect(1);
21614
21615 var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
21616 data = { 'a': true };
21617
21618 assert.strictEqual(compiled(data), 'a="A"');
21619 });
21620
21621 QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
21622 assert.expect(1);
21623
21624 var compiled = _.template('<%= value ? value : "b" %>'),
21625 data = { 'value': 'a' };
21626
21627 assert.strictEqual(compiled(data), 'a');
21628 });
21629
21630 QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
21631 assert.expect(1);
21632
21633 var compiled = _.template('<%= typeof Math.abs %>');
21634
21635 try {
21636 var actual = compiled();
21637 } catch (e) {}
21638
21639 assert.strictEqual(actual, 'function');
21640 });
21641
21642 QUnit.test('should support complex "interpolate" delimiters', function(assert) {
21643 assert.expect(22);
21644
21645 lodashStable.forOwn({
21646 '<%= a + b %>': '3',
21647 '<%= b - a %>': '1',
21648 '<%= a = b %>': '2',
21649 '<%= !a %>': 'false',
21650 '<%= ~a %>': '-2',
21651 '<%= a * b %>': '2',
21652 '<%= a / b %>': '0.5',
21653 '<%= a % b %>': '1',
21654 '<%= a >> b %>': '0',
21655 '<%= a << b %>': '4',
21656 '<%= a & b %>': '0',
21657 '<%= a ^ b %>': '3',
21658 '<%= a | b %>': '3',
21659 '<%= {}.toString.call(0) %>': numberTag,
21660 '<%= a.toFixed(2) %>': '1.00',
21661 '<%= obj["a"] %>': '1',
21662 '<%= delete a %>': 'true',
21663 '<%= "a" in obj %>': 'true',
21664 '<%= obj instanceof Object %>': 'true',
21665 '<%= new Boolean %>': 'false',
21666 '<%= typeof a %>': 'number',
21667 '<%= void a %>': ''
21668 },
21669 function(value, key) {
21670 var compiled = _.template(key),
21671 data = { 'a': 1, 'b': 2 };
21672
21673 assert.strictEqual(compiled(data), value, key);
21674 });
21675 });
21676
21677 QUnit.test('should support ES6 template delimiters', function(assert) {
21678 assert.expect(2);
21679
21680 var data = { 'value': 2 };
21681 assert.strictEqual(_.template('1${value}3')(data), '123');
21682 assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
21683 });
21684
21685 QUnit.test('should support the "imports" option', function(assert) {
21686 assert.expect(1);
21687
21688 var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
21689 assert.strictEqual(compiled({}), '1');
21690 });
21691
21692 QUnit.test('should support the "variable" options', function(assert) {
21693 assert.expect(1);
21694
21695 var compiled = _.template(
21696 '<% _.each( data.a, function( value ) { %>' +
21697 '<%= value.valueOf() %>' +
21698 '<% }) %>', { 'variable': 'data' }
21699 );
21700
21701 var data = { 'a': [1, 2, 3] };
21702
21703 try {
21704 assert.strictEqual(compiled(data), '123');
21705 } catch (e) {
21706 assert.ok(false, e.message);
21707 }
21708 });
21709
21710 QUnit.test('should support custom delimiters', function(assert) {
21711 assert.expect(2);
21712
21713 lodashStable.times(2, function(index) {
21714 var settingsClone = lodashStable.clone(_.templateSettings);
21715
21716 var settings = lodashStable.assign(index ? _.templateSettings : {}, {
21717 'escape': /\{\{-([\s\S]+?)\}\}/g,
21718 'evaluate': /\{\{([\s\S]+?)\}\}/g,
21719 'interpolate': /\{\{=([\s\S]+?)\}\}/g
21720 });
21721
21722 var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
21723 compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
21724 data = { 'collection': ['a & A', 'b & B'] };
21725
21726 assert.strictEqual(compiled(data), expected);
21727 lodashStable.assign(_.templateSettings, settingsClone);
21728 });
21729 });
21730
21731 QUnit.test('should support custom delimiters containing special characters', function(assert) {
21732 assert.expect(2);
21733
21734 lodashStable.times(2, function(index) {
21735 var settingsClone = lodashStable.clone(_.templateSettings);
21736
21737 var settings = lodashStable.assign(index ? _.templateSettings : {}, {
21738 'escape': /<\?-([\s\S]+?)\?>/g,
21739 'evaluate': /<\?([\s\S]+?)\?>/g,
21740 'interpolate': /<\?=([\s\S]+?)\?>/g
21741 });
21742
21743 var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
21744 compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
21745 data = { 'collection': ['a & A', 'b & B'] };
21746
21747 assert.strictEqual(compiled(data), expected);
21748 lodashStable.assign(_.templateSettings, settingsClone);
21749 });
21750 });
21751
21752 QUnit.test('should use a `with` statement by default', function(assert) {
21753 assert.expect(1);
21754
21755 var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
21756 actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
21757
21758 assert.strictEqual(actual, '1b012');
21759 });
21760
21761 QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
21762 assert.expect(1);
21763
21764 var lodash = _.templateSettings.imports._,
21765 settingsClone = lodashStable.clone(lodash.templateSettings);
21766
21767 lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
21768 'interpolate': /\{\{=([\s\S]+?)\}\}/g
21769 });
21770
21771 var compiled = _.template('{{= a }}');
21772 assert.strictEqual(compiled({ 'a': 1 }), '1');
21773
21774 if (settingsClone) {
21775 lodashStable.assign(lodash.templateSettings, settingsClone);
21776 } else {
21777 delete lodash.templateSettings;
21778 }
21779 });
21780
21781 QUnit.test('should fallback to `_.templateSettings`', function(assert) {
21782 assert.expect(1);
21783
21784 var lodash = _.templateSettings.imports._,
21785 delimiter = _.templateSettings.interpolate;
21786
21787 _.templateSettings.imports._ = { 'escape': lodashStable.escape };
21788 _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
21789
21790 var compiled = _.template('{{= a }}');
21791 assert.strictEqual(compiled({ 'a': 1 }), '1');
21792
21793 _.templateSettings.imports._ = lodash;
21794 _.templateSettings.interpolate = delimiter;
21795 });
21796
21797 QUnit.test('should ignore `null` delimiters', function(assert) {
21798 assert.expect(3);
21799
21800 var delimiter = {
21801 'escape': /\{\{-([\s\S]+?)\}\}/g,
21802 'evaluate': /\{\{([\s\S]+?)\}\}/g,
21803 'interpolate': /\{\{=([\s\S]+?)\}\}/g
21804 };
21805
21806 lodashStable.forOwn({
21807 'escape': '{{- a }}',
21808 'evaluate': '{{ print(a) }}',
21809 'interpolate': '{{= a }}'
21810 },
21811 function(value, key) {
21812 var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
21813 settings[key] = delimiter[key];
21814
21815 var expected = '1 <%- a %> <% print(a) %> <%= a %>',
21816 compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
21817 data = { 'a': 1 };
21818
21819 assert.strictEqual(compiled(data), expected);
21820 });
21821 });
21822
21823 QUnit.test('should work without delimiters', function(assert) {
21824 assert.expect(1);
21825
21826 var expected = 'abc';
21827 assert.strictEqual(_.template(expected)({}), expected);
21828 });
21829
21830 QUnit.test('should work with `this` references', function(assert) {
21831 assert.expect(2);
21832
21833 var compiled = _.template('a<%= this.String("b") %>c');
21834 assert.strictEqual(compiled(), 'abc');
21835
21836 var object = { 'b': 'B' };
21837 object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
21838 assert.strictEqual(object.compiled(), 'ABC');
21839 });
21840
21841 QUnit.test('should work with backslashes', function(assert) {
21842 assert.expect(1);
21843
21844 var compiled = _.template('<%= a %> \\b'),
21845 data = { 'a': 'A' };
21846
21847 assert.strictEqual(compiled(data), 'A \\b');
21848 });
21849
21850 QUnit.test('should work with escaped characters in string literals', function(assert) {
21851 assert.expect(2);
21852
21853 var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
21854 assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
21855
21856 var data = { 'a': 'A' };
21857 compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
21858 assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
21859 });
21860
21861 QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
21862 assert.expect(1);
21863
21864 var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
21865 assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
21866 });
21867
21868 QUnit.test('should work with statements containing quotes', function(assert) {
21869 assert.expect(1);
21870
21871 var compiled = _.template("<%\
21872 if (a == 'A' || a == \"a\") {\
21873 %>'a',\"A\"<%\
21874 } %>"
21875 );
21876
21877 var data = { 'a': 'A' };
21878 assert.strictEqual(compiled(data), "'a',\"A\"");
21879 });
21880
21881 QUnit.test('should work with templates containing newlines and comments', function(assert) {
21882 assert.expect(1);
21883
21884 var compiled = _.template('<%\n\
21885 // A code comment.\n\
21886 if (value) { value += 3; }\n\
21887 %><p><%= value %></p>'
21888 );
21889
21890 assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
21891 });
21892
21893 QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
21894 assert.expect(1);
21895
21896 var compiled = _.template(''),
21897 pass = true;
21898
21899 /*@cc_on @*/
21900 try {
21901 compiled();
21902 } catch (e) {
21903 pass = false;
21904 }
21905 assert.ok(pass);
21906 });
21907
21908 QUnit.test('should tokenize delimiters', function(assert) {
21909 assert.expect(1);
21910
21911 var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
21912 data = { 'type': 1 };
21913
21914 assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
21915 });
21916
21917 QUnit.test('should evaluate delimiters once', function(assert) {
21918 assert.expect(1);
21919
21920 var actual = [],
21921 compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
21922 data = { 'func': function(value) { actual.push(value); } };
21923
21924 compiled(data);
21925 assert.deepEqual(actual, ['a', 'b', 'c']);
21926 });
21927
21928 QUnit.test('should match delimiters before escaping text', function(assert) {
21929 assert.expect(1);
21930
21931 var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
21932 assert.strictEqual(compiled(), '<<\n a \n>>');
21933 });
21934
21935 QUnit.test('should resolve nullish values to an empty string', function(assert) {
21936 assert.expect(3);
21937
21938 var compiled = _.template('<%= a %><%- a %>'),
21939 data = { 'a': null };
21940
21941 assert.strictEqual(compiled(data), '');
21942
21943 data = { 'a': undefined };
21944 assert.strictEqual(compiled(data), '');
21945
21946 data = { 'a': {} };
21947 compiled = _.template('<%= a.b %><%- a.b %>');
21948 assert.strictEqual(compiled(data), '');
21949 });
21950
21951 QUnit.test('should return an empty string for empty values', function(assert) {
21952 assert.expect(1);
21953
21954 var values = [, null, undefined, ''],
21955 expected = lodashStable.map(values, alwaysEmptyString),
21956 data = { 'a': 1 };
21957
21958 var actual = lodashStable.map(values, function(value, index) {
21959 var compiled = index ? _.template(value) : _.template();
21960 return compiled(data);
21961 });
21962
21963 assert.deepEqual(actual, expected);
21964 });
21965
21966 QUnit.test('should parse delimiters without newlines', function(assert) {
21967 assert.expect(1);
21968
21969 var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
21970 compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
21971 data = { 'value': true };
21972
21973 assert.strictEqual(compiled(data), expected);
21974 });
21975
21976 QUnit.test('should support recursive calls', function(assert) {
21977 assert.expect(1);
21978
21979 var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
21980 data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
21981
21982 assert.strictEqual(compiled(data), 'AB');
21983 });
21984
21985 QUnit.test('should coerce `text` argument to a string', function(assert) {
21986 assert.expect(1);
21987
21988 var object = { 'toString': lodashStable.constant('<%= a %>') },
21989 data = { 'a': 1 };
21990
21991 assert.strictEqual(_.template(object)(data), '1');
21992 });
21993
21994 QUnit.test('should not modify the `options` object', function(assert) {
21995 assert.expect(1);
21996
21997 var options = {};
21998 _.template('', options);
21999 assert.deepEqual(options, {});
22000 });
22001
22002 QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
22003 assert.expect(2);
22004
22005 var data = { 'a': 1 };
22006
22007 assert.notOk('a' in _.templateSettings);
22008 _.template('', {}, data);
22009 assert.notOk('a' in _.templateSettings);
22010
22011 delete _.templateSettings.a;
22012 });
22013
22014 QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
22015 assert.expect(2);
22016
22017 var pass = true;
22018
22019 try {
22020 _.template('')(1);
22021 } catch (e) {
22022 pass = false;
22023 }
22024 assert.ok(pass, '`data` value');
22025
22026 pass = true;
22027
22028 try {
22029 _.template('', 1)(1);
22030 } catch (e) {
22031 pass = false;
22032 }
22033 assert.ok(pass, '`options` value');
22034 });
22035
22036 QUnit.test('should expose the source on compiled templates', function(assert) {
22037 assert.expect(1);
22038
22039 var compiled = _.template('x'),
22040 values = [String(compiled), compiled.source],
22041 expected = lodashStable.map(values, alwaysTrue);
22042
22043 var actual = lodashStable.map(values, function(value) {
22044 return lodashStable.includes(value, '__p');
22045 });
22046
22047 assert.deepEqual(actual, expected);
22048 });
22049
22050 QUnit.test('should expose the source on SyntaxErrors', function(assert) {
22051 assert.expect(1);
22052
22053 try {
22054 _.template('<% if x %>');
22055 } catch (e) {
22056 var source = e.source;
22057 }
22058 assert.ok(lodashStable.includes(source, '__p'));
22059 });
22060
22061 QUnit.test('should not include sourceURLs in the source', function(assert) {
22062 assert.expect(1);
22063
22064 var options = { 'sourceURL': '/a/b/c' },
22065 compiled = _.template('x', options),
22066 values = [compiled.source, undefined];
22067
22068 try {
22069 _.template('<% if x %>', options);
22070 } catch (e) {
22071 values[1] = e.source;
22072 }
22073 var expected = lodashStable.map(values, alwaysFalse);
22074
22075 var actual = lodashStable.map(values, function(value) {
22076 return lodashStable.includes(value, 'sourceURL');
22077 });
22078
22079 assert.deepEqual(actual, expected);
22080 });
22081
22082 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22083 assert.expect(1);
22084
22085 var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
22086 compiles = lodashStable.map(array, _.template),
22087 data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
22088
22089 var actual = lodashStable.map(compiles, function(compiled) {
22090 return compiled(data);
22091 });
22092
22093 assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
22094 });
22095 }());
22096
22097 /*--------------------------------------------------------------------------*/
22098
22099 QUnit.module('lodash.truncate');
22100
22101 (function() {
22102 var string = 'hi-diddly-ho there, neighborino';
22103
22104 QUnit.test('should use a default `length` of `30`', function(assert) {
22105 assert.expect(1);
22106
22107 assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
22108 });
22109
22110 QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
22111 assert.expect(2);
22112
22113 assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
22114 assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
22115 });
22116
22117 QUnit.test('should truncate string the given length', function(assert) {
22118 assert.expect(1);
22119
22120 assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
22121 });
22122
22123 QUnit.test('should support a `omission` option', function(assert) {
22124 assert.expect(1);
22125
22126 assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
22127 });
22128
22129 QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
22130 assert.expect(2);
22131
22132 assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
22133 assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
22134 });
22135
22136 QUnit.test('should support a `length` option', function(assert) {
22137 assert.expect(1);
22138
22139 assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
22140 });
22141
22142 QUnit.test('should support a `separator` option', function(assert) {
22143 assert.expect(3);
22144
22145 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
22146 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
22147 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
22148 });
22149
22150 QUnit.test('should treat negative `length` as `0`', function(assert) {
22151 assert.expect(2);
22152
22153 lodashStable.each([0, -2], function(length) {
22154 assert.strictEqual(_.truncate(string, { 'length': length }), '...');
22155 });
22156 });
22157
22158 QUnit.test('should coerce `length` to an integer', function(assert) {
22159 assert.expect(4);
22160
22161 lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
22162 var actual = index > 1 ? 'h...' : '...';
22163 assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
22164 });
22165 });
22166
22167 QUnit.test('should coerce `string` to a string', function(assert) {
22168 assert.expect(2);
22169
22170 assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
22171 assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
22172 });
22173
22174 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
22175 assert.expect(1);
22176
22177 var actual = lodashStable.map([string, string, string], _.truncate),
22178 truncated = 'hi-diddly-ho there, neighbo...';
22179
22180 assert.deepEqual(actual, [truncated, truncated, truncated]);
22181 });
22182 }());
22183
22184 /*--------------------------------------------------------------------------*/
22185
22186 QUnit.module('lodash.throttle');
22187
22188 (function() {
22189 QUnit.test('should throttle a function', function(assert) {
22190 assert.expect(2);
22191
22192 var done = assert.async();
22193
22194 var callCount = 0,
22195 throttled = _.throttle(function() { callCount++; }, 32);
22196
22197 throttled();
22198 throttled();
22199 throttled();
22200
22201 var lastCount = callCount;
22202 assert.ok(callCount > 0);
22203
22204 setTimeout(function() {
22205 assert.ok(callCount > lastCount);
22206 done();
22207 }, 64);
22208 });
22209
22210 QUnit.test('subsequent calls should return the result of the first call', function(assert) {
22211 assert.expect(5);
22212
22213 var done = assert.async();
22214
22215 var throttled = _.throttle(identity, 32),
22216 result = [throttled('a'), throttled('b')];
22217
22218 assert.deepEqual(result, ['a', 'a']);
22219
22220 setTimeout(function() {
22221 var result = [throttled('x'), throttled('y')];
22222 assert.notEqual(result[0], 'a');
22223 assert.notStrictEqual(result[0], undefined);
22224
22225 assert.notEqual(result[1], 'y');
22226 assert.notStrictEqual(result[1], undefined);
22227 done();
22228 }, 64);
22229 });
22230
22231 QUnit.test('should clear timeout when `func` is called', function(assert) {
22232 assert.expect(1);
22233
22234 var done = assert.async();
22235
22236 if (!isModularize) {
22237 var callCount = 0,
22238 dateCount = 0;
22239
22240 var getTime = function() {
22241 return ++dateCount == 5
22242 ? Infinity
22243 : +new Date;
22244 };
22245
22246 var lodash = _.runInContext(lodashStable.assign({}, root, {
22247 'Date': lodashStable.assign(function() {
22248 return { 'getTime': getTime };
22249 }, {
22250 'now': Date.now
22251 })
22252 }));
22253
22254 var throttled = lodash.throttle(function() { callCount++; }, 32);
22255
22256 throttled();
22257 throttled();
22258
22259 setTimeout(function() {
22260 assert.strictEqual(callCount, 2);
22261 done();
22262 }, 64);
22263 }
22264 else {
22265 skipAssert(assert);
22266 done();
22267 }
22268 });
22269
22270 QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
22271 assert.expect(2);
22272
22273 var done = assert.async();
22274
22275 var callCount = 0,
22276 throttled = _.throttle(function() { callCount++; }, 32);
22277
22278 throttled();
22279 assert.strictEqual(callCount, 1);
22280
22281 setTimeout(function() {
22282 assert.strictEqual(callCount, 1);
22283 done();
22284 }, 64);
22285 });
22286
22287 lodashStable.times(2, function(index) {
22288 QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
22289 assert.expect(1);
22290
22291 var done = assert.async();
22292
22293 var callCount = 0,
22294 limit = (argv || isPhantom) ? 1000 : 320,
22295 options = index ? { 'leading': false } : {},
22296 throttled = _.throttle(function() { callCount++; }, 32, options);
22297
22298 var start = +new Date;
22299 while ((new Date - start) < limit) {
22300 throttled();
22301 }
22302 var actual = callCount > 1;
22303 setTimeout(function() {
22304 assert.ok(actual);
22305 done();
22306 }, 1);
22307 });
22308 });
22309
22310 QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
22311 assert.expect(3);
22312
22313 var done = assert.async();
22314
22315 var callCount = 0;
22316
22317 var throttled = _.throttle(function() {
22318 callCount++;
22319 }, 128, { 'leading': false });
22320
22321 throttled();
22322
22323 setTimeout(function() {
22324 assert.strictEqual(callCount, 1);
22325 throttled();
22326 }, 192);
22327
22328 setTimeout(function() {
22329 assert.strictEqual(callCount, 1);
22330 }, 254);
22331
22332 setTimeout(function() {
22333 assert.strictEqual(callCount, 2);
22334 done();
22335 }, 384);
22336 });
22337
22338 QUnit.test('should apply default options', function(assert) {
22339 assert.expect(2);
22340
22341 var done = assert.async();
22342
22343 var callCount = 0,
22344 throttled = _.throttle(function() { callCount++; }, 32, {});
22345
22346 throttled();
22347 throttled();
22348 assert.strictEqual(callCount, 1);
22349
22350 setTimeout(function() {
22351 assert.strictEqual(callCount, 2);
22352 done();
22353 }, 128);
22354 });
22355
22356 QUnit.test('should support a `leading` option', function(assert) {
22357 assert.expect(2);
22358
22359 var withLeading = _.throttle(identity, 32, { 'leading': true });
22360 assert.strictEqual(withLeading('a'), 'a');
22361
22362 var withoutLeading = _.throttle(identity, 32, { 'leading': false });
22363 assert.strictEqual(withoutLeading('a'), undefined);
22364 });
22365
22366 QUnit.test('should support a `trailing` option', function(assert) {
22367 assert.expect(6);
22368
22369 var done = assert.async();
22370
22371 var withCount = 0,
22372 withoutCount = 0;
22373
22374 var withTrailing = _.throttle(function(value) {
22375 withCount++;
22376 return value;
22377 }, 64, { 'trailing': true });
22378
22379 var withoutTrailing = _.throttle(function(value) {
22380 withoutCount++;
22381 return value;
22382 }, 64, { 'trailing': false });
22383
22384 assert.strictEqual(withTrailing('a'), 'a');
22385 assert.strictEqual(withTrailing('b'), 'a');
22386
22387 assert.strictEqual(withoutTrailing('a'), 'a');
22388 assert.strictEqual(withoutTrailing('b'), 'a');
22389
22390 setTimeout(function() {
22391 assert.strictEqual(withCount, 2);
22392 assert.strictEqual(withoutCount, 1);
22393 done();
22394 }, 256);
22395 });
22396
22397 QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
22398 assert.expect(1);
22399
22400 var done = assert.async();
22401
22402 var callCount = 0;
22403
22404 var throttled = _.throttle(function() {
22405 callCount++;
22406 }, 64, { 'trailing': false });
22407
22408 throttled();
22409 throttled();
22410
22411 setTimeout(function() {
22412 throttled();
22413 throttled();
22414 }, 96);
22415
22416 setTimeout(function() {
22417 assert.ok(callCount > 1);
22418 done();
22419 }, 192);
22420 });
22421 }());
22422
22423 /*--------------------------------------------------------------------------*/
22424
22425 QUnit.module('lodash.debounce and lodash.throttle');
22426
22427 lodashStable.each(['debounce', 'throttle'], function(methodName) {
22428 var func = _[methodName],
22429 isDebounce = methodName == 'debounce';
22430
22431 QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
22432 assert.expect(1);
22433
22434 var pass = true;
22435
22436 try {
22437 func(noop, 32, 1);
22438 } catch (e) {
22439 pass = false;
22440 }
22441 assert.ok(pass);
22442 });
22443
22444 QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
22445 assert.expect(1);
22446
22447 var done = assert.async();
22448
22449 var callCount = 0,
22450 funced = func(function() { callCount++; });
22451
22452 funced();
22453
22454 setTimeout(function() {
22455 funced();
22456 assert.strictEqual(callCount, isDebounce ? 1 : 2);
22457 done();
22458 }, 32);
22459 });
22460
22461 QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
22462 assert.expect(1);
22463
22464 var done = assert.async();
22465
22466 var actual = [],
22467 object = { 'funced': func(function() { actual.push(this); }, 32) },
22468 expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
22469
22470 object.funced();
22471 if (!isDebounce) {
22472 object.funced();
22473 }
22474 setTimeout(function() {
22475 assert.deepEqual(actual, expected);
22476 done();
22477 }, 64);
22478 });
22479
22480 QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
22481 assert.expect(2);
22482
22483 var done = assert.async();
22484
22485 var actual = [],
22486 args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
22487 expected = args.slice(),
22488 queue = args.slice();
22489
22490 var funced = func(function() {
22491 var current = [this];
22492 push.apply(current, arguments);
22493 actual.push(current);
22494
22495 var next = queue.shift();
22496 if (next) {
22497 funced.call(next[0], next[1]);
22498 }
22499 }, 32);
22500
22501 var next = queue.shift();
22502 funced.call(next[0], next[1]);
22503 assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
22504
22505 setTimeout(function() {
22506 assert.deepEqual(actual, expected.slice(0, actual.length));
22507 done();
22508 }, 256);
22509 });
22510
22511 QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
22512 assert.expect(1);
22513
22514 var done = assert.async();
22515
22516 if (!isModularize) {
22517 var callCount = 0,
22518 dateCount = 0;
22519
22520 var getTime = function() {
22521 return ++dateCount === 4
22522 ? +new Date(2012, 3, 23, 23, 27, 18)
22523 : +new Date;
22524 };
22525
22526 var lodash = _.runInContext(lodashStable.assign({}, root, {
22527 'Date': lodashStable.assign(function() {
22528 return { 'getTime': getTime, 'valueOf': getTime };
22529 }, {
22530 'now': Date.now
22531 })
22532 }));
22533
22534 var funced = lodash[methodName](function() {
22535 callCount++;
22536 }, 32);
22537
22538 funced();
22539
22540 setTimeout(function() {
22541 funced();
22542 assert.strictEqual(callCount, isDebounce ? 1 : 2);
22543 done();
22544 }, 64);
22545 }
22546 else {
22547 skipAssert(assert);
22548 done();
22549 }
22550 });
22551
22552 QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
22553 assert.expect(1);
22554
22555 var done = assert.async();
22556
22557 var callCount = 0;
22558
22559 var funced = func(function() {
22560 callCount++;
22561 }, 32, { 'leading': false });
22562
22563 funced();
22564 funced.cancel();
22565
22566 setTimeout(function() {
22567 assert.strictEqual(callCount, 0);
22568 done();
22569 }, 64);
22570 });
22571
22572 QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
22573 assert.expect(3);
22574
22575 var done = assert.async();
22576
22577 var callCount = 0;
22578
22579 var funced = func(function() {
22580 return ++callCount;
22581 }, 32, { 'leading': true });
22582
22583 assert.strictEqual(funced(), 1);
22584 funced.cancel();
22585
22586 assert.strictEqual(funced(), 2);
22587 funced();
22588
22589 setTimeout(function() {
22590 assert.strictEqual(callCount, 3);
22591 done();
22592 }, 64);
22593 });
22594
22595 QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
22596 assert.expect(2);
22597
22598 var done = assert.async();
22599
22600 var callCount = 0;
22601
22602 var funced = func(function() {
22603 return ++callCount;
22604 }, 32, { 'leading': false });
22605
22606 funced();
22607 assert.strictEqual(funced.flush(), 1);
22608
22609 setTimeout(function() {
22610 assert.strictEqual(callCount, 1);
22611 done();
22612 }, 64);
22613 });
22614
22615 QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
22616 assert.expect(2);
22617
22618 var done = assert.async();
22619
22620 var callCount = 0,
22621 funced = func(function() { callCount++; }, 32);
22622
22623 funced.cancel();
22624 assert.strictEqual(funced.flush(), undefined);
22625
22626 setTimeout(function() {
22627 assert.strictEqual(callCount, 0);
22628 done();
22629 }, 64);
22630 });
22631 });
22632
22633 /*--------------------------------------------------------------------------*/
22634
22635 QUnit.module('lodash.times');
22636
22637 (function() {
22638 QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
22639 assert.expect(3);
22640
22641 lodashStable.each([-Infinity, NaN, Infinity], function(n) {
22642 assert.deepEqual(_.times(n), []);
22643 });
22644 });
22645
22646 QUnit.test('should coerce `n` to an integer', function(assert) {
22647 assert.expect(1);
22648
22649 var actual = _.times(2.6, _.indentify);
22650 assert.deepEqual(actual, [0, 1]);
22651 });
22652
22653 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
22654 assert.expect(1);
22655
22656 var args;
22657
22658 _.times(1, function(assert) {
22659 args || (args = slice.call(arguments));
22660 });
22661
22662 assert.deepEqual(args, [0]);
22663 });
22664
22665 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
22666 assert.expect(1);
22667
22668 var values = [, null, undefined],
22669 expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
22670
22671 var actual = lodashStable.map(values, function(value, index) {
22672 return index ? _.times(3, value) : _.times(3);
22673 });
22674
22675 assert.deepEqual(actual, expected);
22676 });
22677
22678 QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
22679 assert.expect(1);
22680
22681 assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
22682 });
22683
22684 QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
22685 assert.expect(1);
22686
22687 var values = falsey.concat(-1, -Infinity),
22688 expected = lodashStable.map(values, alwaysEmptyArray);
22689
22690 var actual = lodashStable.map(values, function(value, index) {
22691 return index ? _.times(value) : _.times();
22692 });
22693
22694 assert.deepEqual(actual, expected);
22695 });
22696
22697 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
22698 assert.expect(1);
22699
22700 if (!isNpm) {
22701 assert.deepEqual(_(3).times(), [0, 1, 2]);
22702 }
22703 else {
22704 skipAssert(assert);
22705 }
22706 });
22707
22708 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
22709 assert.expect(1);
22710
22711 if (!isNpm) {
22712 assert.ok(_(3).chain().times() instanceof _);
22713 }
22714 else {
22715 skipAssert(assert);
22716 }
22717 });
22718 }());
22719
22720 /*--------------------------------------------------------------------------*/
22721
22722 QUnit.module('lodash.toArray');
22723
22724 (function() {
22725 QUnit.test('should convert objects to arrays', function(assert) {
22726 assert.expect(1);
22727
22728 assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
22729 });
22730
22731 QUnit.test('should convert strings to arrays', function(assert) {
22732 assert.expect(3);
22733
22734 assert.deepEqual(_.toArray(''), []);
22735 assert.deepEqual(_.toArray('ab'), ['a', 'b']);
22736 assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
22737 });
22738
22739 QUnit.test('should convert iterables to arrays', function(assert) {
22740 assert.expect(1);
22741
22742 if (!isNpm && Symbol && Symbol.iterator) {
22743 var object = { '0': 'a', 'length': 1 };
22744 object[Symbol.iterator] = arrayProto[Symbol.iterator];
22745
22746 assert.deepEqual(_.toArray(object), ['a']);
22747 }
22748 else {
22749 skipAssert(assert);
22750 }
22751 });
22752
22753 QUnit.test('should work in a lazy sequence', function(assert) {
22754 assert.expect(2);
22755
22756 if (!isNpm) {
22757 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
22758 actual = _(array).slice(1).map(String).toArray().value();
22759
22760 assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
22761
22762 var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
22763 return ['key' + index, index];
22764 }));
22765
22766 actual = _(object).toArray().slice(1).map(String).value();
22767 assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
22768 }
22769 else {
22770 skipAssert(assert, 2);
22771 }
22772 });
22773 }());
22774
22775 /*--------------------------------------------------------------------------*/
22776
22777 QUnit.module('lodash.toLower');
22778
22779 (function() {
22780 QUnit.test('should convert whole string to lower case', function(assert) {
22781 assert.expect(3);
22782
22783 assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
22784 assert.deepEqual(_.toLower('fooBar'), 'foobar');
22785 assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
22786 });
22787 }());
22788
22789 /*--------------------------------------------------------------------------*/
22790
22791 QUnit.module('lodash.toUpper');
22792
22793 (function() {
22794 QUnit.test('should convert whole string to upper case', function(assert) {
22795 assert.expect(3);
22796
22797 assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
22798 assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
22799 assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
22800 });
22801 }());
22802
22803 /*--------------------------------------------------------------------------*/
22804
22805 QUnit.module('lodash.slice and lodash.toArray');
22806
22807 lodashStable.each(['slice', 'toArray'], function(methodName) {
22808 var args = (function() { return arguments; }(1, 2, 3)),
22809 array = [1, 2, 3],
22810 func = _[methodName];
22811
22812 QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
22813 assert.expect(3);
22814
22815 var sparse = Array(3);
22816 sparse[1] = 2;
22817
22818 var actual = func(sparse);
22819
22820 assert.ok('0' in actual);
22821 assert.ok('2' in actual);
22822 assert.deepEqual(actual, sparse);
22823 });
22824
22825 QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
22826 assert.expect(2);
22827
22828 var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
22829 assert.deepEqual(func(object), ['a', 'b', 'c']);
22830 assert.deepEqual(func(args), array);
22831 });
22832
22833 QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
22834 assert.expect(2);
22835
22836 var actual = func(array);
22837 assert.deepEqual(actual, array);
22838 assert.notStrictEqual(actual, array);
22839 });
22840
22841 QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
22842 assert.expect(1);
22843
22844 if (document) {
22845 try {
22846 var actual = func(document.getElementsByTagName('body'));
22847 } catch (e) {}
22848
22849 assert.deepEqual(actual, [body]);
22850 }
22851 else {
22852 skipAssert(assert);
22853 }
22854 });
22855 });
22856
22857 /*--------------------------------------------------------------------------*/
22858
22859 QUnit.module('toInteger methods');
22860
22861 lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
22862 var func = _[methodName],
22863 isSafe = methodName == 'toSafeInteger';
22864
22865 QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
22866 assert.expect(6);
22867
22868 assert.strictEqual(func(-5.6), -5);
22869 assert.strictEqual(func('5.6'), 5);
22870 assert.strictEqual(func(), 0);
22871 assert.strictEqual(func(NaN), 0);
22872
22873 var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
22874 assert.strictEqual(func(Infinity), expected);
22875 assert.strictEqual(func(-Infinity), -expected);
22876 });
22877
22878 QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
22879 assert.expect(1);
22880
22881 assert.strictEqual(1 / func(-0), -Infinity);
22882 });
22883 });
22884
22885 /*--------------------------------------------------------------------------*/
22886
22887 QUnit.module('lodash.toLength');
22888
22889 (function() {
22890 QUnit.test('should return a valid length', function(assert) {
22891 assert.expect(4);
22892
22893 assert.strictEqual(_.toLength(-1), 0);
22894 assert.strictEqual(_.toLength('1'), 1);
22895 assert.strictEqual(_.toLength(1.1), 1);
22896 assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
22897 });
22898
22899 QUnit.test('should return `value` if a valid length', function(assert) {
22900 assert.expect(3);
22901
22902 assert.strictEqual(_.toLength(0), 0);
22903 assert.strictEqual(_.toLength(3), 3);
22904 assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
22905 });
22906
22907 QUnit.test('should convert `-0` to `0`', function(assert) {
22908 assert.expect(1);
22909
22910 assert.strictEqual(1 / _.toLength(-0), Infinity);
22911 });
22912 }());
22913
22914 /*--------------------------------------------------------------------------*/
22915
22916 QUnit.module('number coercion methods');
22917
22918 lodashStable.each(['toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
22919 var func = _[methodName];
22920
22921 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
22922 assert.expect(2);
22923
22924 var values = [0, '0', -0, '-0'],
22925 expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
22926
22927 lodashStable.times(2, function(index) {
22928 var others = lodashStable.map(values, index ? Object : identity);
22929
22930 var actual = lodashStable.map(others, function(value) {
22931 var result = func(value);
22932 return [result, 1 / result];
22933 });
22934
22935 assert.deepEqual(actual, expected);
22936 });
22937 });
22938 });
22939
22940 lodashStable.each(['toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
22941 var func = _[methodName],
22942 isToLength = methodName == 'toLength',
22943 isToNumber = methodName == 'toNumber',
22944 isToSafeInteger = methodName == 'toSafeInteger';
22945
22946 function negative(string) {
22947 return '-' + string;
22948 }
22949
22950 function pad(string) {
22951 return whitespace + string + whitespace;
22952 }
22953
22954 function positive(string) {
22955 return '+' + string;
22956 }
22957
22958 QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
22959 assert.expect(1);
22960
22961 var values = [0, 1, NaN];
22962
22963 var expected = lodashStable.map(values, function(value) {
22964 return (!isToNumber && value !== value) ? 0 : value;
22965 });
22966
22967 var actual = lodashStable.map(values, func);
22968
22969 assert.deepEqual(actual, expected);
22970 });
22971
22972 QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
22973 assert.expect(1);
22974
22975 var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
22976
22977 var expected = lodashStable.map(values, function(value) {
22978 if (!isToNumber) {
22979 if (value == 1.2) {
22980 value = 1;
22981 }
22982 else if (value == Infinity) {
22983 value = MAX_INTEGER;
22984 }
22985 else if (value !== value) {
22986 value = 0;
22987 }
22988 if (isToLength || isToSafeInteger) {
22989 value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
22990 }
22991 }
22992 var neg = isToLength ? 0 : -value;
22993 return [value, value, neg, neg];
22994 });
22995
22996 var actual = lodashStable.map(values, function(value) {
22997 return [func(value), func(Object(value)), func(-value), func(Object(-value))];
22998 });
22999
23000 assert.deepEqual(actual, expected);
23001 });
23002
23003 QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
23004 assert.expect(1);
23005
23006 var transforms = [identity, pad, positive, negative];
23007
23008 var values = [
23009 '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
23010 '1e+308', '1e308', '1E+308', '1E308',
23011 '5e-324', '5E-324',
23012 'Infinity', 'NaN'
23013 ];
23014
23015 var expected = lodashStable.map(values, function(value) {
23016 var n = +value;
23017 if (!isToNumber) {
23018 if (n == 1.234567890) {
23019 n = 1;
23020 }
23021 else if (n == Infinity) {
23022 n = MAX_INTEGER;
23023 }
23024 else if (n == Number.MIN_VALUE || n !== n) {
23025 n = 0;
23026 }
23027 if (isToLength || isToSafeInteger) {
23028 n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
23029 }
23030 }
23031 var neg = isToLength ? 0 : -n;
23032 return [n, n, n, n, n, n, neg, neg];
23033 });
23034
23035 var actual = lodashStable.map(values, function(value) {
23036 return lodashStable.flatMap(transforms, function(mod) {
23037 return [func(mod(value)), func(Object(mod(value)))];
23038 });
23039 });
23040
23041 assert.deepEqual(actual, expected);
23042 });
23043
23044 QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
23045 assert.expect(1);
23046
23047 var numbers = [42, 5349, 1715004],
23048 transforms = [identity, pad],
23049 values = ['0b101010', '0o12345', '0x1a2b3c'];
23050
23051 var expected = lodashStable.map(numbers, function(n) {
23052 return lodashStable.times(8, lodashStable.constant(n));
23053 });
23054
23055 var actual = lodashStable.map(values, function(value) {
23056 var upper = value.toUpperCase();
23057 return lodashStable.flatMap(transforms, function(mod) {
23058 return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
23059 });
23060 });
23061
23062 assert.deepEqual(actual, expected);
23063 });
23064
23065 QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23066 assert.expect(1);
23067
23068 var transforms = [identity, pad, positive, negative],
23069 values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
23070
23071 var expected = lodashStable.map(values, function(n) {
23072 return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
23073 });
23074
23075 var actual = lodashStable.map(values, function(value) {
23076 return lodashStable.flatMap(transforms, function(mod) {
23077 return [func(mod(value)), func(Object(mod(value)))];
23078 });
23079 });
23080
23081 assert.deepEqual(actual, expected);
23082 });
23083
23084 QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
23085 assert.expect(1);
23086
23087 if (Symbol) {
23088 var object1 = Object(symbol),
23089 object2 = Object(symbol),
23090 values = [symbol, object1, object2],
23091 expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
23092
23093 object2.valueOf = undefined;
23094 var actual = lodashStable.map(values, func);
23095
23096 assert.deepEqual(actual, expected);
23097 }
23098 else {
23099 skipAssert(assert);
23100 }
23101 });
23102
23103 QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
23104 assert.expect(1);
23105
23106 var values = falsey.concat(whitespace);
23107
23108 var expected = lodashStable.map(values, function(value) {
23109 return (isToNumber && value !== whitespace) ? Number(value) : 0;
23110 });
23111
23112 var actual = lodashStable.map(values, function(value, index) {
23113 return index ? func(value) : func();
23114 });
23115
23116 assert.deepEqual(actual, expected);
23117 });
23118
23119 QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
23120 assert.expect(1);
23121
23122 var values = [
23123 {},
23124 [],
23125 [1],
23126 [1, 2],
23127 { 'valueOf': '1.1' },
23128 { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
23129 { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
23130 { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
23131 { 'valueOf': lodashStable.constant('-0x1a2b3c') },
23132 { 'toString': lodashStable.constant('-0x1a2b3c') },
23133 { 'valueOf': lodashStable.constant('0o12345') },
23134 { 'toString': lodashStable.constant('0o12345') },
23135 { 'valueOf': lodashStable.constant('0b101010') },
23136 { 'toString': lodashStable.constant('0b101010') }
23137 ];
23138
23139 var expected = [
23140 NaN, 0, 1, NaN,
23141 NaN, 2.2, 1.1, 1.1,
23142 NaN, NaN,
23143 5349, 5349,
23144 42, 42
23145 ];
23146
23147 if (!isToNumber) {
23148 expected = [
23149 0, 0, 1, 0,
23150 0, 2, 1, 1,
23151 0, 0,
23152 5349, 5349,
23153 42, 42
23154 ];
23155 }
23156 var actual = lodashStable.map(values, func);
23157
23158 assert.deepEqual(actual, expected);
23159 });
23160 });
23161
23162 /*--------------------------------------------------------------------------*/
23163
23164 QUnit.module('lodash.toPairs');
23165
23166 (function() {
23167 QUnit.test('should be aliased', function(assert) {
23168 assert.expect(1);
23169
23170 assert.strictEqual(_.entries, _.toPairs);
23171 });
23172 }());
23173
23174 /*--------------------------------------------------------------------------*/
23175
23176 QUnit.module('lodash.toPairsIn');
23177
23178 (function() {
23179 QUnit.test('should be aliased', function(assert) {
23180 assert.expect(1);
23181
23182 assert.strictEqual(_.entriesIn, _.toPairsIn);
23183 });
23184 }());
23185
23186 /*--------------------------------------------------------------------------*/
23187
23188 QUnit.module('toPairs methods');
23189
23190 lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
23191 var func = _[methodName],
23192 isToPairs = methodName == 'toPairs';
23193
23194 QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
23195 assert.expect(1);
23196
23197 var object = { 'a': 1, 'b': 2 },
23198 actual = lodashStable.sortBy(func(object), 0);
23199
23200 assert.deepEqual(actual, [['a', 1], ['b', 2]]);
23201 });
23202
23203 QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
23204 assert.expect(1);
23205
23206 var object = { '0': 'a', '1': 'b', 'length': 2 },
23207 actual = lodashStable.sortBy(func(object), 0);
23208
23209 assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
23210 });
23211
23212 QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
23213 assert.expect(1);
23214
23215 function Foo() {
23216 this.a = 1;
23217 }
23218 Foo.prototype.b = 2;
23219
23220 var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
23221 actual = lodashStable.sortBy(func(new Foo), 0);
23222
23223 assert.deepEqual(actual, expected);
23224 });
23225
23226 QUnit.test('`_.' + methodName + '` should work with strings', function(assert) {
23227 assert.expect(2);
23228
23229 lodashStable.each(['xo', Object('xo')], function(string) {
23230 var actual = lodashStable.sortBy(func(string), 0);
23231 assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
23232 });
23233 });
23234 });
23235
23236 /*--------------------------------------------------------------------------*/
23237
23238 QUnit.module('lodash.toPath');
23239
23240 (function() {
23241 QUnit.test('should convert a string to a path', function(assert) {
23242 assert.expect(2);
23243
23244 assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
23245 assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
23246 });
23247
23248 QUnit.test('should coerce array elements to strings', function(assert) {
23249 assert.expect(4);
23250
23251 var array = ['a', 'b', 'c'];
23252
23253 lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
23254 var actual = _.toPath(value);
23255 assert.deepEqual(actual, array);
23256 assert.notStrictEqual(actual, array);
23257 });
23258 });
23259
23260 QUnit.test('should a new path array', function(assert) {
23261 assert.expect(1);
23262
23263 assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
23264 });
23265
23266 QUnit.test('should not coerce symbols to strings', function(assert) {
23267 assert.expect(4);
23268
23269 if (Symbol) {
23270 var object = Object(symbol);
23271 lodashStable.each([symbol, object, [symbol], [object]], function(value) {
23272 var actual = _.toPath(value);
23273 assert.ok(lodashStable.isSymbol(actual[0]));
23274 });
23275 }
23276 else {
23277 skipAssert(assert, 4);
23278 }
23279 });
23280
23281 QUnit.test('should handle complex paths', function(assert) {
23282 assert.expect(1);
23283
23284 var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
23285 assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
23286 });
23287
23288 QUnit.test('should ignore consecutive brackets and dots', function(assert) {
23289 assert.expect(4);
23290
23291 var expected = ['a'];
23292 assert.deepEqual(_.toPath('a.'), expected);
23293 assert.deepEqual(_.toPath('a[]'), expected);
23294
23295 expected = ['a', 'b'];
23296 assert.deepEqual(_.toPath('a..b'), expected);
23297 assert.deepEqual(_.toPath('a[][]b'), expected);
23298 });
23299 }());
23300
23301 /*--------------------------------------------------------------------------*/
23302
23303 QUnit.module('lodash.toPlainObject');
23304
23305 (function() {
23306 var args = arguments;
23307
23308 QUnit.test('should flatten inherited string keyed properties', function(assert) {
23309 assert.expect(1);
23310
23311 function Foo() {
23312 this.b = 2;
23313 }
23314 Foo.prototype.c = 3;
23315
23316 var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
23317 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
23318 });
23319
23320 QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
23321 assert.expect(1);
23322
23323 var actual = _.toPlainObject(args),
23324 expected = { '0': 1, '1': 2, '2': 3 };
23325
23326 assert.deepEqual(actual, expected);
23327 });
23328
23329 QUnit.test('should convert arrays to plain objects', function(assert) {
23330 assert.expect(1);
23331
23332 var actual = _.toPlainObject(['a', 'b', 'c']),
23333 expected = { '0': 'a', '1': 'b', '2': 'c' };
23334
23335 assert.deepEqual(actual, expected);
23336 });
23337 }(1, 2, 3));
23338
23339 /*--------------------------------------------------------------------------*/
23340
23341 QUnit.module('lodash.toString');
23342
23343 (function() {
23344 QUnit.test('should treat nullish values as empty strings', function(assert) {
23345 assert.expect(1);
23346
23347 var values = [, null, undefined],
23348 expected = lodashStable.map(values, alwaysEmptyString);
23349
23350 var actual = lodashStable.map(values, function(value, index) {
23351 return index ? _.toString(value) : _.toString();
23352 });
23353
23354 assert.deepEqual(actual, expected);
23355 });
23356
23357 QUnit.test('should preserve the sign of `0`', function(assert) {
23358 assert.expect(1);
23359
23360 var values = [-0, Object(-0), 0, Object(0)],
23361 expected = ['-0', '-0', '0', '0'],
23362 actual = lodashStable.map(values, _.toString);
23363
23364 assert.deepEqual(actual, expected);
23365 });
23366
23367 QUnit.test('should not error on symbols', function(assert) {
23368 assert.expect(1);
23369
23370 if (Symbol) {
23371 try {
23372 assert.strictEqual(_.toString(symbol), 'Symbol(a)');
23373 } catch (e) {
23374 assert.ok(false, e.message);
23375 }
23376 }
23377 else {
23378 skipAssert(assert);
23379 }
23380 });
23381
23382 QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
23383 assert.expect(1);
23384
23385 if (!isNpm) {
23386 var wrapped = _([1, 2, 3]);
23387 assert.strictEqual(wrapped.toString(), '1,2,3');
23388 }
23389 else {
23390 skipAssert(assert);
23391 }
23392 });
23393 }());
23394
23395 /*--------------------------------------------------------------------------*/
23396
23397 QUnit.module('lodash.transform');
23398
23399 (function() {
23400 function Foo() {
23401 this.a = 1;
23402 this.b = 2;
23403 this.c = 3;
23404 }
23405
23406 QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
23407 assert.expect(4);
23408
23409 var accumulators = [, null, undefined],
23410 object = new Foo,
23411 expected = lodashStable.map(accumulators, alwaysTrue);
23412
23413 var iteratee = function(result, value, key) {
23414 result[key] = square(value);
23415 };
23416
23417 var mapper = function(accumulator, index) {
23418 return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
23419 };
23420
23421 var results = lodashStable.map(accumulators, mapper);
23422
23423 var actual = lodashStable.map(results, function(result) {
23424 return result instanceof Foo;
23425 });
23426
23427 assert.deepEqual(actual, expected);
23428
23429 expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
23430 actual = lodashStable.map(results, lodashStable.toPlainObject);
23431
23432 assert.deepEqual(actual, expected);
23433
23434 object = { 'a': 1, 'b': 2, 'c': 3 };
23435 actual = lodashStable.map(accumulators, mapper);
23436
23437 assert.deepEqual(actual, expected);
23438
23439 object = [1, 2, 3];
23440 expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
23441 actual = lodashStable.map(accumulators, mapper);
23442
23443 assert.deepEqual(actual, expected);
23444 });
23445
23446 QUnit.test('should create regular arrays from typed arrays', function(assert) {
23447 assert.expect(1);
23448
23449 var expected = lodashStable.map(typedArrays, alwaysTrue);
23450
23451 var actual = lodashStable.map(typedArrays, function(type) {
23452 var Ctor = root[type],
23453 array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
23454
23455 return lodashStable.isArray(_.transform(array, noop));
23456 });
23457
23458 assert.deepEqual(actual, expected);
23459 });
23460
23461 QUnit.test('should support an `accumulator` value', function(assert) {
23462 assert.expect(6);
23463
23464 var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
23465 expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
23466
23467 var actual = lodashStable.map(values, function(value) {
23468 return _.transform(value, function(result, value) {
23469 result.push(square(value));
23470 }, []);
23471 });
23472
23473 assert.deepEqual(actual, expected);
23474
23475 var object = { 'a': 1, 'b': 4, 'c': 9 },
23476 expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
23477
23478 actual = lodashStable.map(values, function(value) {
23479 return _.transform(value, function(result, value, key) {
23480 result[key] = square(value);
23481 }, {});
23482 });
23483
23484 assert.deepEqual(actual, expected);
23485
23486 lodashStable.each([[], {}], function(accumulator) {
23487 var actual = lodashStable.map(values, function(value) {
23488 return _.transform(value, noop, accumulator);
23489 });
23490
23491 assert.ok(lodashStable.every(actual, function(result) {
23492 return result === accumulator;
23493 }));
23494
23495 assert.strictEqual(_.transform(null, null, accumulator), accumulator);
23496 });
23497 });
23498
23499 QUnit.test('should treat sparse arrays as dense', function(assert) {
23500 assert.expect(1);
23501
23502 var actual = _.transform(Array(1), function(result, value, index) {
23503 result[index] = String(value);
23504 });
23505
23506 assert.deepEqual(actual, ['undefined']);
23507 });
23508
23509 QUnit.test('should work without an `iteratee` argument', function(assert) {
23510 assert.expect(1);
23511
23512 assert.ok(_.transform(new Foo) instanceof Foo);
23513 });
23514
23515 QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
23516 assert.expect(2);
23517
23518 var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
23519 values = [false, true, 0, 1, NaN, '', 'a'],
23520 expected = lodashStable.map(values, alwaysEmptyObject);
23521
23522 var results = lodashStable.map(values, function(value) {
23523 return _.transform(value);
23524 });
23525
23526 assert.deepEqual(results, expected);
23527
23528 expected = lodashStable.map(values, alwaysFalse);
23529
23530 var actual = lodashStable.map(results, function(value, index) {
23531 return value instanceof Ctors[index];
23532 });
23533
23534 assert.deepEqual(actual, expected);
23535 });
23536
23537 QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
23538 assert.expect(1);
23539
23540 Foo.prototype.constructor = null;
23541 assert.notOk(_.transform(new Foo) instanceof Foo);
23542 Foo.prototype.constructor = Foo;
23543 });
23544
23545 QUnit.test('should create an empty object when given a falsey `object` argument', function(assert) {
23546 assert.expect(1);
23547
23548 var expected = lodashStable.map(falsey, alwaysEmptyObject);
23549
23550 var actual = lodashStable.map(falsey, function(object, index) {
23551 return index ? _.transform(object) : _.transform();
23552 });
23553
23554 assert.deepEqual(actual, expected);
23555 });
23556
23557 lodashStable.each({
23558 'array': [1, 2, 3],
23559 'object': { 'a': 1, 'b': 2, 'c': 3 }
23560 },
23561 function(object, key) {
23562 QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
23563 assert.expect(2);
23564
23565 var args;
23566
23567 _.transform(object, function() {
23568 args || (args = slice.call(arguments));
23569 });
23570
23571 var first = args[0];
23572 if (key == 'array') {
23573 assert.ok(first !== object && lodashStable.isArray(first));
23574 assert.deepEqual(args, [first, 1, 0, object]);
23575 } else {
23576 assert.ok(first !== object && lodashStable.isPlainObject(first));
23577 assert.deepEqual(args, [first, 1, 'a', object]);
23578 }
23579 });
23580 });
23581
23582 QUnit.test('should create an object from the same realm as `object`', function(assert) {
23583 assert.expect(1);
23584
23585 var objects = lodashStable.filter(realm, function(value) {
23586 return lodashStable.isObject(value) && !lodashStable.isElement(value);
23587 });
23588
23589 var expected = lodashStable.map(objects, alwaysTrue);
23590
23591 var actual = lodashStable.map(objects, function(object) {
23592 var Ctor = object.constructor,
23593 result = _.transform(object);
23594
23595 if (result === object) {
23596 return false;
23597 }
23598 if (lodashStable.isTypedArray(object)) {
23599 return result instanceof Array;
23600 }
23601 return result instanceof Ctor || !(new Ctor instanceof Ctor);
23602 });
23603
23604 assert.deepEqual(actual, expected);
23605 });
23606 }());
23607
23608 /*--------------------------------------------------------------------------*/
23609
23610 QUnit.module('trim methods');
23611
23612 lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
23613 var func = _[methodName],
23614 parts = [];
23615
23616 if (index != 2) {
23617 parts.push('leading');
23618 }
23619 if (index != 1) {
23620 parts.push('trailing');
23621 }
23622 parts = parts.join(' and ');
23623
23624 QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
23625 assert.expect(1);
23626
23627 var string = whitespace + 'a b c' + whitespace,
23628 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23629
23630 assert.strictEqual(func(string), expected);
23631 });
23632
23633 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
23634 assert.expect(1);
23635
23636 var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
23637 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23638
23639 assert.strictEqual(func(object), expected);
23640 });
23641
23642 QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
23643 assert.expect(1);
23644
23645 var string = '-_-a-b-c-_-',
23646 expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
23647
23648 assert.strictEqual(func(string, '_-'), expected);
23649 });
23650
23651 QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
23652 assert.expect(1);
23653
23654 var object = { 'toString': lodashStable.constant('_-') },
23655 string = '-_-a-b-c-_-',
23656 expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
23657
23658 assert.strictEqual(func(string, object), expected);
23659 });
23660
23661 QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
23662 assert.expect(6);
23663
23664 lodashStable.each([null, '_-'], function(chars) {
23665 assert.strictEqual(func(null, chars), '');
23666 assert.strictEqual(func(undefined, chars), '');
23667 assert.strictEqual(func('', chars), '');
23668 });
23669 });
23670
23671 QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
23672 assert.expect(2);
23673
23674 var string = whitespace + 'a b c' + whitespace,
23675 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23676
23677 assert.strictEqual(func(string, undefined), expected);
23678 assert.strictEqual(func(string, ''), string);
23679 });
23680
23681 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
23682 assert.expect(1);
23683
23684 var string = Object(whitespace + 'a b c' + whitespace),
23685 trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
23686 actual = lodashStable.map([string, string, string], func);
23687
23688 assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
23689 });
23690
23691 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
23692 assert.expect(1);
23693
23694 if (!isNpm) {
23695 var string = whitespace + 'a b c' + whitespace,
23696 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
23697
23698 assert.strictEqual(_(string)[methodName](), expected);
23699 }
23700 else {
23701 skipAssert(assert);
23702 }
23703 });
23704
23705 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
23706 assert.expect(1);
23707
23708 if (!isNpm) {
23709 var string = whitespace + 'a b c' + whitespace;
23710 assert.ok(_(string).chain()[methodName]() instanceof _);
23711 }
23712 else {
23713 skipAssert(assert);
23714 }
23715 });
23716 });
23717
23718 /*--------------------------------------------------------------------------*/
23719
23720 QUnit.module('uncommon symbols');
23721
23722 (function() {
23723 var flag = '\ud83c\uddfa\ud83c\uddf8',
23724 heart = '\u2764' + emojiVar,
23725 hearts = '\ud83d\udc95',
23726 comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
23727 hashKeycap = '#' + emojiVar + '\u20e3',
23728 leafs = '\ud83c\udf42',
23729 mic = '\ud83c\udf99',
23730 noMic = mic + '\u20e0',
23731 raisedHand = '\u270B' + emojiVar,
23732 rocket = '\ud83d\ude80',
23733 thumbsUp = '\ud83d\udc4d';
23734
23735 QUnit.test('should account for astral symbols', function(assert) {
23736 assert.expect(34);
23737
23738 var allHearts = _.repeat(hearts, 10),
23739 chars = hearts + comboGlyph,
23740 string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
23741 trimChars = comboGlyph + hearts,
23742 trimString = trimChars + string + trimChars;
23743
23744 assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
23745 assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
23746 assert.strictEqual(_.capitalize(rocket), rocket);
23747
23748 assert.strictEqual(_.pad(string, 16), ' ' + string + ' ');
23749 assert.strictEqual(_.padStart(string, 16), ' ' + string);
23750 assert.strictEqual(_.padEnd(string, 16), string + ' ');
23751
23752 assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
23753 assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
23754 assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
23755
23756 assert.strictEqual(_.size(string), 13);
23757 assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
23758 assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
23759 assert.deepEqual(_.split(string, undefined), [string]);
23760 assert.deepEqual(_.split(string, undefined, -1), [string]);
23761 assert.deepEqual(_.split(string, undefined, 0), []);
23762
23763 var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
23764
23765 assert.deepEqual(_.split(string, ''), expected);
23766 assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
23767 assert.deepEqual(_.toArray(string), expected);
23768
23769 assert.strictEqual(_.trim(trimString, chars), string);
23770 assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
23771 assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
23772
23773 assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
23774 assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
23775
23776 assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
23777 assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
23778 assert.deepEqual(_.toArray(noMic), [noMic]);
23779
23780 lodashStable.times(2, function(index) {
23781 var separator = index ? RegExp(hearts) : hearts,
23782 options = { 'length': 4, 'separator': separator },
23783 actual = _.truncate(string, options);
23784
23785 assert.strictEqual(actual, 'A...');
23786 assert.strictEqual(actual.length, 4);
23787
23788 actual = _.truncate(allHearts, options);
23789 assert.strictEqual(actual, hearts + '...');
23790 assert.strictEqual(actual.length, 5);
23791 });
23792 });
23793
23794 QUnit.test('should account for combining diacritical marks', function(assert) {
23795 assert.expect(1);
23796
23797 var values = lodashStable.map(comboMarks, function(mark) {
23798 return 'o' + mark;
23799 });
23800
23801 var expected = lodashStable.map(values, function(value) {
23802 return [1, [value], [value]];
23803 });
23804
23805 var actual = lodashStable.map(values, function(value) {
23806 return [_.size(value), _.toArray(value), _.words(value)];
23807 });
23808
23809 assert.deepEqual(actual, expected);
23810 });
23811
23812 QUnit.test('should account for fitzpatrick modifiers', function(assert) {
23813 assert.expect(1);
23814
23815 var values = lodashStable.map(fitzModifiers, function(modifier) {
23816 return thumbsUp + modifier;
23817 });
23818
23819 var expected = lodashStable.map(values, function(value) {
23820 return [1, [value], [value]];
23821 });
23822
23823 var actual = lodashStable.map(values, function(value) {
23824 return [_.size(value), _.toArray(value), _.words(value)];
23825 });
23826
23827 assert.deepEqual(actual, expected);
23828 });
23829
23830 QUnit.test('should account for regional symbols', function(assert) {
23831 assert.expect(6);
23832
23833 var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
23834 regionals = pair.join(' ');
23835
23836 assert.strictEqual(_.size(flag), 1);
23837 assert.strictEqual(_.size(regionals), 3);
23838
23839 assert.deepEqual(_.toArray(flag), [flag]);
23840 assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
23841
23842 assert.deepEqual(_.words(flag), [flag]);
23843 assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
23844 });
23845
23846 QUnit.test('should account for variation selectors', function(assert) {
23847 assert.expect(3);
23848
23849 assert.strictEqual(_.size(heart), 1);
23850 assert.deepEqual(_.toArray(heart), [heart]);
23851 assert.deepEqual(_.words(heart), [heart]);
23852 });
23853
23854 QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
23855 assert.expect(1);
23856
23857 var values = lodashStable.map(fitzModifiers, function(modifier) {
23858 return raisedHand + modifier;
23859 });
23860
23861 var expected = lodashStable.map(values, function(value) {
23862 return [1, [value], [value]];
23863 });
23864
23865 var actual = lodashStable.map(values, function(value) {
23866 return [_.size(value), _.toArray(value), _.words(value)];
23867 });
23868
23869 assert.deepEqual(actual, expected);
23870 });
23871
23872 QUnit.test('should match lone surrogates', function(assert) {
23873 assert.expect(3);
23874
23875 var pair = hearts.split(''),
23876 surrogates = pair[0] + ' ' + pair[1];
23877
23878 assert.strictEqual(_.size(surrogates), 3);
23879 assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
23880 assert.deepEqual(_.words(surrogates), []);
23881 });
23882
23883 QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
23884 assert.expect(1);
23885
23886 var string = fitzModifiers[0] + fitzModifiers[0];
23887 assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
23888 });
23889 }());
23890
23891 /*--------------------------------------------------------------------------*/
23892
23893 QUnit.module('lodash.unary');
23894
23895 (function() {
23896 function fn() {
23897 return slice.call(arguments);
23898 }
23899
23900 QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
23901 assert.expect(1);
23902
23903 var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
23904 assert.deepEqual(actual, [6, 8, 10]);
23905 });
23906
23907 QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
23908 assert.expect(1);
23909
23910 var capped = _.unary(fn);
23911 assert.deepEqual(capped(), []);
23912 });
23913 }());
23914
23915 /*--------------------------------------------------------------------------*/
23916
23917 QUnit.module('lodash.unescape');
23918
23919 (function() {
23920 var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
23921 unescaped = '&<>"\'\/';
23922
23923 escaped += escaped;
23924 unescaped += unescaped;
23925
23926 QUnit.test('should unescape entities in order', function(assert) {
23927 assert.expect(1);
23928
23929 assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
23930 });
23931
23932 QUnit.test('should unescape the proper entities', function(assert) {
23933 assert.expect(1);
23934
23935 assert.strictEqual(_.unescape(escaped), unescaped);
23936 });
23937
23938 QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
23939 assert.expect(1);
23940
23941 assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
23942 });
23943
23944 QUnit.test('should handle strings with nothing to unescape', function(assert) {
23945 assert.expect(1);
23946
23947 assert.strictEqual(_.unescape('abc'), 'abc');
23948 });
23949
23950 QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
23951 assert.expect(1);
23952
23953 assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
23954 });
23955 }());
23956
23957 /*--------------------------------------------------------------------------*/
23958
23959 QUnit.module('lodash.unionBy');
23960
23961 (function() {
23962 QUnit.test('should accept an `iteratee` argument', function(assert) {
23963 assert.expect(2);
23964
23965 var actual = _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
23966 assert.deepEqual(actual, [2.1, 1.2, 4.3]);
23967
23968 actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
23969 assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
23970 });
23971
23972 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
23973 assert.expect(1);
23974
23975 var args;
23976
23977 _.unionBy([2.1, 1.2], [4.3, 2.4], function() {
23978 args || (args = slice.call(arguments));
23979 });
23980
23981 assert.deepEqual(args, [2.1]);
23982 });
23983 }());
23984
23985 /*--------------------------------------------------------------------------*/
23986
23987 QUnit.module('lodash.unionWith');
23988
23989 (function() {
23990 QUnit.test('should work with a `comparator` argument', function(assert) {
23991 assert.expect(1);
23992
23993 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
23994 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
23995 actual = _.unionWith(objects, others, lodashStable.isEqual);
23996
23997 assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
23998 });
23999 }());
24000
24001 /*--------------------------------------------------------------------------*/
24002
24003 QUnit.module('union methods');
24004
24005 lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
24006 var args = (function() { return arguments; }(1, 2, 3)),
24007 func = _[methodName];
24008
24009 QUnit.test('`_.' + methodName + '` should return the union of the given arrays', function(assert) {
24010 assert.expect(1);
24011
24012 var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
24013 assert.deepEqual(actual, [1, 3, 2, 5, 4]);
24014 });
24015
24016 QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
24017 assert.expect(1);
24018
24019 var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
24020 assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
24021 });
24022
24023 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24024 assert.expect(3);
24025
24026 var array = [0];
24027 assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24028 assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
24029 assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
24030 });
24031 });
24032
24033 /*--------------------------------------------------------------------------*/
24034
24035 QUnit.module('lodash.uniq');
24036
24037 (function() {
24038 QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
24039 assert.expect(1);
24040
24041 var array = [[2, 1, 2], [1, 2, 1]],
24042 actual = lodashStable.map(array, lodashStable.uniq);
24043
24044 assert.deepEqual(actual, [[2, 1], [1, 2]]);
24045 });
24046 }());
24047
24048 /*--------------------------------------------------------------------------*/
24049
24050 QUnit.module('uniqBy methods');
24051
24052 lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
24053 var func = _[methodName],
24054 isSorted = methodName == 'sortedUniqBy',
24055 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24056
24057 if (isSorted) {
24058 objects = _.sortBy(objects, 'a');
24059 }
24060 QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
24061 assert.expect(1);
24062
24063 var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
24064
24065 var actual = func(objects, function(object) {
24066 return object.a;
24067 });
24068
24069 assert.deepEqual(actual, expected);
24070 });
24071
24072 QUnit.test('should work with large arrays', function(assert) {
24073 assert.expect(2);
24074
24075 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
24076 return [1, 2];
24077 });
24078
24079 var actual = func(largeArray, String);
24080
24081 assert.deepEqual(actual, [[1, 2]]);
24082 assert.strictEqual(actual[0], largeArray[0]);
24083 });
24084
24085 QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
24086 assert.expect(1);
24087
24088 var args;
24089
24090 func(objects, function() {
24091 args || (args = slice.call(arguments));
24092 });
24093
24094 assert.deepEqual(args, [objects[0]]);
24095 });
24096
24097 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
24098 assert.expect(2);
24099
24100 var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
24101 actual = func(objects, 'a');
24102
24103 assert.deepEqual(actual, expected);
24104
24105 var arrays = [[2], [3], [1], [2], [3], [1]];
24106 if (isSorted) {
24107 arrays = lodashStable.sortBy(arrays, 0);
24108 }
24109 expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
24110 actual = func(arrays, 0);
24111
24112 assert.deepEqual(actual, expected);
24113 });
24114
24115 lodashStable.each({
24116 'an array': [0, 'a'],
24117 'an object': { '0': 'a' },
24118 'a number': 0,
24119 'a string': '0'
24120 },
24121 function(iteratee, key) {
24122 QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
24123 assert.expect(1);
24124
24125 var actual = func([['a'], ['a'], ['b']], iteratee);
24126 assert.deepEqual(actual, [['a'], ['b']]);
24127 });
24128 });
24129 });
24130
24131 /*--------------------------------------------------------------------------*/
24132
24133 QUnit.module('lodash.uniqWith');
24134
24135 (function() {
24136 QUnit.test('should work with a `comparator` argument', function(assert) {
24137 assert.expect(1);
24138
24139 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }],
24140 actual = _.uniqWith(objects, lodashStable.isEqual);
24141
24142 assert.deepEqual(actual, [objects[0], objects[1]]);
24143 });
24144
24145 QUnit.test('should preserve the sign of `0`', function(assert) {
24146 assert.expect(1);
24147
24148 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24149 return isEven(index) ? -0 : 0;
24150 });
24151
24152 var arrays = [[-0, 0], largeArray],
24153 expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
24154
24155 var actual = lodashStable.map(arrays, function(array) {
24156 return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
24157 });
24158
24159 assert.deepEqual(actual, expected);
24160 });
24161 }());
24162
24163 /*--------------------------------------------------------------------------*/
24164
24165 QUnit.module('uniq methods');
24166
24167 lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
24168 var func = _[methodName],
24169 isSorted = /^sorted/.test(methodName),
24170 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
24171
24172 if (isSorted) {
24173 objects = _.sortBy(objects, 'a');
24174 }
24175 else {
24176 QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
24177 assert.expect(1);
24178
24179 var array = [2, 3, 1, 2, 3, 1];
24180 assert.deepEqual(func(array), [2, 3, 1]);
24181 });
24182 }
24183 QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
24184 assert.expect(1);
24185
24186 var array = [1, 1, 2, 2, 3];
24187 assert.deepEqual(func(array), [1, 2, 3]);
24188 });
24189
24190 QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
24191 assert.expect(1);
24192
24193 assert.deepEqual(func(objects), objects);
24194 });
24195
24196 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
24197 assert.expect(1);
24198
24199 var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
24200 assert.deepEqual(actual, ['0']);
24201 });
24202
24203 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
24204 assert.expect(1);
24205
24206 assert.deepEqual(func([NaN, NaN]), [NaN]);
24207 });
24208
24209 QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
24210 assert.expect(1);
24211
24212 var largeArray = [],
24213 expected = [0, {}, 'a'],
24214 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24215
24216 lodashStable.each(expected, function(value) {
24217 lodashStable.times(count, function() {
24218 largeArray.push(value);
24219 });
24220 });
24221
24222 assert.deepEqual(func(largeArray), expected);
24223 });
24224
24225 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
24226 assert.expect(1);
24227
24228 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
24229 return isEven(index) ? -0 : 0;
24230 });
24231
24232 var actual = lodashStable.map(func(largeArray), lodashStable.toString);
24233 assert.deepEqual(actual, ['0']);
24234 });
24235
24236 QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
24237 assert.expect(1);
24238
24239 var largeArray = [],
24240 expected = [null, undefined, false, true, NaN],
24241 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24242
24243 lodashStable.each(expected, function(value) {
24244 lodashStable.times(count, function() {
24245 largeArray.push(value);
24246 });
24247 });
24248
24249 assert.deepEqual(func(largeArray), expected);
24250 });
24251
24252 QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
24253 assert.expect(1);
24254
24255 if (Symbol) {
24256 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
24257 assert.deepEqual(func(largeArray), largeArray);
24258 }
24259 else {
24260 skipAssert(assert);
24261 }
24262 });
24263
24264 QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
24265 assert.expect(1);
24266
24267 // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
24268 if (Symbol) {
24269 var expected = [
24270 Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
24271 Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
24272 Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
24273 ];
24274
24275 var largeArray = [],
24276 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24277
24278 expected = lodashStable.map(expected, function(symbol) {
24279 return symbol || {};
24280 });
24281
24282 lodashStable.each(expected, function(value) {
24283 lodashStable.times(count, function() {
24284 largeArray.push(value);
24285 });
24286 });
24287
24288 assert.deepEqual(func(largeArray), expected);
24289 }
24290 else {
24291 skipAssert(assert);
24292 }
24293 });
24294
24295 QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
24296 assert.expect(1);
24297
24298 var largeArray = [],
24299 expected = ['2', 2, Object('2'), Object(2)],
24300 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
24301
24302 lodashStable.each(expected, function(value) {
24303 lodashStable.times(count, function() {
24304 largeArray.push(value);
24305 });
24306 });
24307
24308 assert.deepEqual(func(largeArray), expected);
24309 });
24310 });
24311
24312 /*--------------------------------------------------------------------------*/
24313
24314 QUnit.module('lodash.uniqueId');
24315
24316 (function() {
24317 QUnit.test('should generate unique ids', function(assert) {
24318 assert.expect(1);
24319
24320 var actual = lodashStable.times(1000, function(assert) {
24321 return _.uniqueId();
24322 });
24323
24324 assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
24325 });
24326
24327 QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
24328 assert.expect(1);
24329
24330 assert.strictEqual(typeof _.uniqueId(), 'string');
24331 });
24332
24333 QUnit.test('should coerce the prefix argument to a string', function(assert) {
24334 assert.expect(1);
24335
24336 var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
24337 assert.ok(/3\d+,2\d+,1\d+/.test(actual));
24338 });
24339 }());
24340
24341 /*--------------------------------------------------------------------------*/
24342
24343 QUnit.module('lodash.unset');
24344
24345 (function() {
24346 QUnit.test('should unset property values', function(assert) {
24347 assert.expect(4);
24348
24349 lodashStable.each(['a', ['a']], function(path) {
24350 var object = { 'a': 1, 'c': 2 };
24351 assert.strictEqual(_.unset(object, path), true);
24352 assert.deepEqual(object, { 'c': 2 });
24353 });
24354 });
24355
24356 QUnit.test('should preserve the sign of `0`', function(assert) {
24357 assert.expect(1);
24358
24359 var props = [-0, Object(-0), 0, Object(0)],
24360 expected = lodashStable.map(props, lodashStable.constant([true, false]));
24361
24362 var actual = lodashStable.map(props, function(key) {
24363 var object = { '-0': 'a', '0': 'b' };
24364 return [_.unset(object, key), lodashStable.toString(key) in object];
24365 });
24366
24367 assert.deepEqual(actual, expected);
24368 });
24369
24370 QUnit.test('should unset symbol keyed property values', function(assert) {
24371 assert.expect(2);
24372
24373 if (Symbol) {
24374 var object = {};
24375 object[symbol] = 1;
24376
24377 assert.strictEqual(_.unset(object, symbol), true);
24378 assert.notOk(symbol in object);
24379 }
24380 else {
24381 skipAssert(assert, 2);
24382 }
24383 });
24384
24385 QUnit.test('should unset deep property values', function(assert) {
24386 assert.expect(4);
24387
24388 lodashStable.each(['a.b', ['a', 'b']], function(path) {
24389 var object = { 'a': { 'b': null } };
24390 assert.strictEqual(_.unset(object, path), true);
24391 assert.deepEqual(object, { 'a': {} });
24392 });
24393 });
24394
24395 QUnit.test('should handle complex paths', function(assert) {
24396 assert.expect(4);
24397
24398 var paths = [
24399 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
24400 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
24401 ];
24402
24403 lodashStable.each(paths, function(path) {
24404 var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
24405 assert.strictEqual(_.unset(object, path), true);
24406 assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
24407 });
24408 });
24409
24410 QUnit.test('should return `true` for nonexistent paths', function(assert) {
24411 assert.expect(5);
24412
24413 var object = { 'a': { 'b': { 'c': null } } };
24414
24415 lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
24416 assert.strictEqual(_.unset(object, path), true);
24417 });
24418
24419 assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
24420 });
24421
24422 QUnit.test('should not error when `object` is nullish', function(assert) {
24423 assert.expect(1);
24424
24425 var values = [null, undefined],
24426 expected = [[true, true], [true, true]];
24427
24428 var actual = lodashStable.map(values, function(value) {
24429 try {
24430 return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
24431 } catch (e) {
24432 return e.message;
24433 }
24434 });
24435
24436 assert.deepEqual(actual, expected);
24437 });
24438
24439 QUnit.test('should follow `path` over non-plain objects', function(assert) {
24440 assert.expect(8);
24441
24442 var object = { 'a': '' },
24443 paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
24444
24445 lodashStable.each(paths, function(path) {
24446 numberProto.a = 1;
24447
24448 var actual = _.unset(0, path);
24449 assert.strictEqual(actual, true);
24450 assert.notOk('a' in numberProto);
24451
24452 delete numberProto.a;
24453 });
24454
24455 lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
24456 stringProto.replace.b = 1;
24457
24458 var actual = _.unset(object, path);
24459 assert.strictEqual(actual, true);
24460 assert.notOk('a' in stringProto.replace);
24461
24462 delete stringProto.replace.b;
24463 });
24464 });
24465
24466 QUnit.test('should return `false` for non-configurable properties', function(assert) {
24467 assert.expect(1);
24468
24469 var object = {};
24470
24471 if (!isStrict && defineProperty) {
24472 defineProperty(object, 'a', {
24473 'configurable': false,
24474 'enumerable': true,
24475 'writable': true,
24476 'value': 1,
24477 });
24478 assert.strictEqual(_.unset(object, 'a'), false);
24479 }
24480 else {
24481 skipAssert(assert);
24482 }
24483 });
24484 }());
24485
24486 /*--------------------------------------------------------------------------*/
24487
24488 QUnit.module('lodash.unzipWith');
24489
24490 (function() {
24491 QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
24492 assert.expect(1);
24493
24494 var array = [[1, 4], [2, 5], [3, 6]];
24495
24496 var actual = _.unzipWith(array, function(a, b, c) {
24497 return a + b + c;
24498 });
24499
24500 assert.deepEqual(actual, [6, 15]);
24501 });
24502
24503 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24504 assert.expect(1);
24505
24506 var args;
24507
24508 _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
24509 args || (args = slice.call(arguments));
24510 });
24511
24512 assert.deepEqual(args, [1, 2]);
24513 });
24514
24515 QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
24516 assert.expect(1);
24517
24518 var array = [[1, 3], [2, 4]],
24519 values = [, null, undefined],
24520 expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
24521
24522 var actual = lodashStable.map(values, function(value, index) {
24523 return index ? _.unzipWith(array, value) : _.unzipWith(array);
24524 });
24525
24526 assert.deepEqual(actual, expected);
24527 });
24528 }());
24529
24530 /*--------------------------------------------------------------------------*/
24531
24532 QUnit.module('lodash.updateWith');
24533
24534 (function() {
24535 QUnit.test('should work with a `customizer` callback', function(assert) {
24536 assert.expect(1);
24537
24538 var actual = _.updateWith({ '0': {} }, '[0][1][2]', alwaysThree, function(value) {
24539 return lodashStable.isObject(value) ? undefined : {};
24540 });
24541
24542 assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
24543 });
24544
24545 QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
24546 assert.expect(1);
24547
24548 var actual = _.updateWith({}, 'a[0].b.c', alwaysFour, noop);
24549 assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
24550 });
24551 }());
24552
24553 /*--------------------------------------------------------------------------*/
24554
24555 QUnit.module('update methods');
24556
24557 lodashStable.each(['update', 'updateWith'], function(methodName) {
24558 var func = _[methodName],
24559 oldValue = 1;
24560
24561 QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
24562 assert.expect(4);
24563
24564 var object = { 'a': [{ 'b': { 'c': oldValue } }] },
24565 expected = oldValue + 1;
24566
24567 lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
24568 func(object, path, function(n) {
24569 assert.strictEqual(n, oldValue);
24570 return ++n;
24571 });
24572
24573 assert.strictEqual(object.a[0].b.c, expected);
24574 object.a[0].b.c = oldValue;
24575 });
24576 });
24577 });
24578
24579 /*--------------------------------------------------------------------------*/
24580
24581 QUnit.module('lodash.upperCase');
24582
24583 (function() {
24584 QUnit.test('should uppercase as space-separated words', function(assert) {
24585 assert.expect(3);
24586
24587 assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
24588 assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
24589 assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
24590 });
24591 }());
24592
24593 /*--------------------------------------------------------------------------*/
24594
24595 QUnit.module('lodash.upperFirst');
24596
24597 (function() {
24598 QUnit.test('should uppercase only the first character', function(assert) {
24599 assert.expect(3);
24600
24601 assert.strictEqual(_.upperFirst('fred'), 'Fred');
24602 assert.strictEqual(_.upperFirst('Fred'), 'Fred');
24603 assert.strictEqual(_.upperFirst('FRED'), 'FRED');
24604 });
24605 }());
24606
24607 /*--------------------------------------------------------------------------*/
24608
24609 QUnit.module('values methods');
24610
24611 lodashStable.each(['values', 'valuesIn'], function(methodName) {
24612 var args = (function() { return arguments; }(1, 2, 3)),
24613 strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
24614 func = _[methodName],
24615 isValues = methodName == 'values';
24616
24617 QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
24618 assert.expect(1);
24619
24620 var object = { 'a': 1, 'b': 2 },
24621 actual = func(object).sort();
24622
24623 assert.deepEqual(actual, [1, 2]);
24624 });
24625
24626 QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
24627 assert.expect(1);
24628
24629 var object = { '0': 'a', '1': 'b', 'length': 2 },
24630 actual = func(object).sort();
24631
24632 assert.deepEqual(actual, [2, 'a', 'b']);
24633 });
24634
24635 QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
24636 assert.expect(1);
24637
24638 function Foo() {
24639 this.a = 1;
24640 }
24641 Foo.prototype.b = 2;
24642
24643 var expected = isValues ? [1] : [1, 2],
24644 actual = func(new Foo).sort();
24645
24646 assert.deepEqual(actual, expected);
24647 });
24648
24649 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
24650 assert.expect(1);
24651
24652 var values = [args, strictArgs],
24653 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
24654
24655 var actual = lodashStable.map(values, function(value) {
24656 return func(value).sort();
24657 });
24658
24659 assert.deepEqual(actual, expected);
24660 });
24661 });
24662
24663 /*--------------------------------------------------------------------------*/
24664
24665 QUnit.module('lodash.without');
24666
24667 (function() {
24668 QUnit.test('should use strict equality to determine the values to reject', function(assert) {
24669 assert.expect(2);
24670
24671 var object1 = { 'a': 1 },
24672 object2 = { 'b': 2 },
24673 array = [object1, object2];
24674
24675 assert.deepEqual(_.without(array, { 'a': 1 }), array);
24676 assert.deepEqual(_.without(array, object1), [object2]);
24677 });
24678
24679 QUnit.test('should remove all occurrences of each value from an array', function(assert) {
24680 assert.expect(1);
24681
24682 var array = [1, 2, 3, 1, 2, 3];
24683 assert.deepEqual(_.without(array, 1, 2), [3, 3]);
24684 });
24685 }(1, 2, 3));
24686
24687 /*--------------------------------------------------------------------------*/
24688
24689 QUnit.module('lodash.words');
24690
24691 (function() {
24692 QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
24693 assert.expect(1);
24694
24695 var expected = lodashStable.map(burredLetters, function(letter) {
24696 return [letter];
24697 });
24698
24699 var actual = lodashStable.map(burredLetters, function(letter) {
24700 return _.words(letter);
24701 });
24702
24703 assert.deepEqual(actual, expected);
24704 });
24705
24706 QUnit.test('should not treat mathematical operators as words', function(assert) {
24707 assert.expect(1);
24708
24709 var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
24710 expected = lodashStable.map(operators, alwaysEmptyArray),
24711 actual = lodashStable.map(operators, _.words);
24712
24713 assert.deepEqual(actual, expected);
24714 });
24715
24716 QUnit.test('should not treat punctuation as words', function(assert) {
24717 assert.expect(1);
24718
24719 var marks = [
24720 '\u2012', '\u2013', '\u2014', '\u2015',
24721 '\u2024', '\u2025', '\u2026',
24722 '\u205d', '\u205e'
24723 ];
24724
24725 var expected = lodashStable.map(marks, alwaysEmptyArray),
24726 actual = lodashStable.map(marks, _.words);
24727
24728 assert.deepEqual(actual, expected);
24729 });
24730
24731 QUnit.test('should support a `pattern` argument', function(assert) {
24732 assert.expect(2);
24733
24734 assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
24735 assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
24736 });
24737
24738 QUnit.test('should work with compound words', function(assert) {
24739 assert.expect(12);
24740
24741 assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
24742 assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
24743 assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
24744 assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
24745 assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
24746 assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
24747 assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
24748 assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
24749 assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
24750 assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
24751 assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
24752 assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
24753 });
24754
24755 QUnit.test('should work with compound words containing diacritical marks', function(assert) {
24756 assert.expect(3);
24757
24758 assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
24759 assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
24760 assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
24761 });
24762
24763 QUnit.test('should work with contractions', function(assert) {
24764 assert.expect(2);
24765
24766 var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
24767
24768 lodashStable.each(["'", '\u2019'], function(apos) {
24769 var actual = lodashStable.map(postfixes, function(postfix) {
24770 return _.words('a b' + apos + postfix + ' c');
24771 });
24772
24773 var expected = lodashStable.map(postfixes, function(postfix) {
24774 return ['a', 'b' + apos + postfix, 'c'];
24775 });
24776
24777 assert.deepEqual(actual, expected);
24778 });
24779 });
24780
24781 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
24782 assert.expect(1);
24783
24784 var strings = lodashStable.map(['a', 'b', 'c'], Object),
24785 actual = lodashStable.map(strings, _.words);
24786
24787 assert.deepEqual(actual, [['a'], ['b'], ['c']]);
24788 });
24789 }());
24790
24791 /*--------------------------------------------------------------------------*/
24792
24793 QUnit.module('lodash.wrap');
24794
24795 (function() {
24796 QUnit.test('should create a wrapped function', function(assert) {
24797 assert.expect(1);
24798
24799 var p = _.wrap(_.escape, function(func, text) {
24800 return '<p>' + func(text) + '</p>';
24801 });
24802
24803 assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
24804 });
24805
24806 QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
24807 assert.expect(1);
24808
24809 var args;
24810
24811 var wrapped = _.wrap(noop, function() {
24812 args || (args = slice.call(arguments));
24813 });
24814
24815 wrapped(1, 2, 3);
24816 assert.deepEqual(args, [noop, 1, 2, 3]);
24817 });
24818
24819 QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
24820 assert.expect(1);
24821
24822 var values = [, null, undefined],
24823 expected = lodashStable.map(values, alwaysA);
24824
24825 var actual = lodashStable.map(values, function(value, index) {
24826 var wrapped = index ? _.wrap('a', value) : _.wrap('a');
24827 return wrapped('b', 'c');
24828 });
24829
24830 assert.deepEqual(actual, expected);
24831 });
24832
24833 QUnit.test('should not set a `this` binding', function(assert) {
24834 assert.expect(1);
24835
24836 var p = _.wrap(_.escape, function(func) {
24837 return '<p>' + func(this.text) + '</p>';
24838 });
24839
24840 var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
24841 assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
24842 });
24843 }());
24844
24845 /*--------------------------------------------------------------------------*/
24846
24847 QUnit.module('xor methods');
24848
24849 lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
24850 var args = (function() { return arguments; }(1, 2, 3)),
24851 func = _[methodName];
24852
24853 QUnit.test('`_.' + methodName + '` should return the symmetric difference of the given arrays', function(assert) {
24854 assert.expect(1);
24855
24856 var actual = func([1, 2, 5], [2, 3, 5], [3, 4, 5]);
24857 assert.deepEqual(actual, [1, 4, 5]);
24858 });
24859
24860 QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
24861 assert.expect(2);
24862
24863 var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
24864 assert.deepEqual(actual, [1, 4, 5]);
24865
24866 actual = func([1, 1]);
24867 assert.deepEqual(actual, [1]);
24868 });
24869
24870 QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
24871 assert.expect(1);
24872
24873 var array = [1];
24874 assert.notStrictEqual(func(array), array);
24875 });
24876
24877 QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
24878 assert.expect(1);
24879
24880 var array = [0];
24881 assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
24882 });
24883
24884 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
24885 assert.expect(3);
24886
24887 var array = [1, 2];
24888 assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
24889 assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
24890 assert.deepEqual(func(array, null, args, null), [3]);
24891 });
24892
24893 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
24894 assert.expect(1);
24895
24896 if (!isNpm) {
24897 var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
24898 assert.ok(wrapped instanceof _);
24899 }
24900 else {
24901 skipAssert(assert);
24902 }
24903 });
24904
24905 QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
24906 assert.expect(1);
24907
24908 if (!isNpm) {
24909 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
24910 wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
24911
24912 var actual = lodashStable.map(['head', 'last'], function(methodName) {
24913 return wrapped[methodName]();
24914 });
24915
24916 assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
24917 }
24918 else {
24919 skipAssert(assert);
24920 }
24921 });
24922 });
24923
24924 /*--------------------------------------------------------------------------*/
24925
24926 QUnit.module('lodash.xorBy');
24927
24928 (function() {
24929 QUnit.test('should accept an `iteratee` argument', function(assert) {
24930 assert.expect(2);
24931
24932 var actual = _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
24933 assert.deepEqual(actual, [1.2, 4.3]);
24934
24935 actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
24936 assert.deepEqual(actual, [{ 'x': 2 }]);
24937 });
24938
24939 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
24940 assert.expect(1);
24941
24942 var args;
24943
24944 _.xorBy([2.1, 1.2], [4.3, 2.4], function() {
24945 args || (args = slice.call(arguments));
24946 });
24947
24948 assert.deepEqual(args, [4.3]);
24949 });
24950 }());
24951
24952 /*--------------------------------------------------------------------------*/
24953
24954 QUnit.module('lodash.xorWith');
24955
24956 (function() {
24957 QUnit.test('should work with a `comparator` argument', function(assert) {
24958 assert.expect(1);
24959
24960 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
24961 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
24962 actual = _.xorWith(objects, others, lodashStable.isEqual);
24963
24964 assert.deepEqual(actual, [objects[1], others[0]]);
24965 });
24966 }());
24967
24968 /*--------------------------------------------------------------------------*/
24969
24970 QUnit.module('zipObject methods');
24971
24972 lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
24973 var func = _[methodName],
24974 object = { 'barney': 36, 'fred': 40 },
24975 isDeep = methodName == 'zipObjectDeep';
24976
24977 QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
24978 assert.expect(1);
24979
24980 var actual = func(['barney', 'fred'], [36, 40]);
24981 assert.deepEqual(actual, object);
24982 });
24983
24984 QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
24985 assert.expect(1);
24986
24987 assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
24988 });
24989
24990 QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
24991 assert.expect(1);
24992
24993 assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
24994 });
24995
24996 QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
24997 assert.expect(2);
24998
24999 lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
25000 var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
25001 assert.deepEqual(func([path], [1]), expected);
25002 });
25003 });
25004
25005 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
25006 assert.expect(1);
25007
25008 if (!isNpm) {
25009 var values = lodashStable.range(LARGE_ARRAY_SIZE),
25010 props = lodashStable.map(values, function(value) { return 'key' + value; }),
25011 actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
25012
25013 assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
25014 }
25015 else {
25016 skipAssert(assert);
25017 }
25018 });
25019 });
25020
25021 /*--------------------------------------------------------------------------*/
25022
25023 QUnit.module('lodash.zipWith');
25024
25025 (function() {
25026 QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
25027 assert.expect(2);
25028
25029 var array1 = [1, 2, 3],
25030 array2 = [4, 5, 6],
25031 array3 = [7, 8, 9];
25032
25033 var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
25034 return a + b + c;
25035 });
25036
25037 assert.deepEqual(actual, [12, 15, 18]);
25038
25039 var actual = _.zipWith(array1, [], function(a, b) {
25040 return a + (b || 0);
25041 });
25042
25043 assert.deepEqual(actual, [1, 2, 3]);
25044 });
25045
25046 QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
25047 assert.expect(1);
25048
25049 var args;
25050
25051 _.zipWith([1, 2], [3, 4], [5, 6], function() {
25052 args || (args = slice.call(arguments));
25053 });
25054
25055 assert.deepEqual(args, [1, 3, 5]);
25056 });
25057
25058 QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
25059 assert.expect(1);
25060
25061 var array1 = [1, 2],
25062 array2 = [3, 4],
25063 values = [, null, undefined],
25064 expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
25065
25066 var actual = lodashStable.map(values, function(value, index) {
25067 return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
25068 });
25069
25070 assert.deepEqual(actual, expected);
25071 });
25072 }());
25073
25074 /*--------------------------------------------------------------------------*/
25075
25076 QUnit.module('lodash.unzip and lodash.zip');
25077
25078 lodashStable.each(['unzip', 'zip'], function(methodName, index) {
25079 var func = _[methodName];
25080 func = lodashStable.bind(index ? func.apply : func.call, func, null);
25081
25082 var object = {
25083 'an empty array': [
25084 [],
25085 []
25086 ],
25087 '0-tuples': [
25088 [[], []],
25089 []
25090 ],
25091 '2-tuples': [
25092 [['barney', 'fred'], [36, 40]],
25093 [['barney', 36], ['fred', 40]]
25094 ],
25095 '3-tuples': [
25096 [['barney', 'fred'], [36, 40], [false, true]],
25097 [['barney', 36, false], ['fred', 40, true]]
25098 ]
25099 };
25100
25101 lodashStable.forOwn(object, function(pair, key) {
25102 QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
25103 assert.expect(2);
25104
25105 var actual = func(pair[0]);
25106 assert.deepEqual(actual, pair[1]);
25107 assert.deepEqual(func(actual), actual.length ? pair[0] : []);
25108 });
25109 });
25110
25111 QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
25112 assert.expect(4);
25113
25114 var pair = [
25115 [['barney', 36], ['fred', 40, false]],
25116 [['barney', 'fred'], [36, 40], [undefined, false]]
25117 ];
25118
25119 var actual = func(pair[0]);
25120 assert.ok('0' in actual[2]);
25121 assert.deepEqual(actual, pair[1]);
25122
25123 actual = func(actual);
25124 assert.ok('2' in actual[0]);
25125 assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
25126 });
25127
25128 QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
25129 assert.expect(1);
25130
25131 var expected = lodashStable.map(falsey, alwaysEmptyArray);
25132
25133 var actual = lodashStable.map(falsey, function(value) {
25134 return func([value, value, value]);
25135 });
25136
25137 assert.deepEqual(actual, expected);
25138 });
25139
25140 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
25141 assert.expect(1);
25142
25143 var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
25144 assert.deepEqual(func(array), [[1, 3], [2, 4]]);
25145 });
25146
25147 QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
25148 assert.expect(1);
25149
25150 var expected = [['barney', 'fred'], [36, 40]];
25151 assert.deepEqual(func(func(func(func(expected)))), expected);
25152 });
25153 });
25154
25155 /*--------------------------------------------------------------------------*/
25156
25157 QUnit.module('lodash(...).commit');
25158
25159 (function() {
25160 QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
25161 assert.expect(4);
25162
25163 if (!isNpm) {
25164 var array = [1],
25165 wrapped = _(array).push(2).push(3);
25166
25167 assert.deepEqual(array, [1]);
25168
25169 var otherWrapper = wrapped.commit();
25170 assert.ok(otherWrapper instanceof _);
25171 assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
25172 assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25173 }
25174 else {
25175 skipAssert(assert, 4);
25176 }
25177 });
25178
25179 QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
25180 assert.expect(2);
25181
25182 if (!isNpm) {
25183 var wrapped = _([1]).chain().commit().head();
25184 assert.ok(wrapped instanceof _);
25185 assert.strictEqual(wrapped.value(), 1);
25186 }
25187 else {
25188 skipAssert(assert, 2);
25189 }
25190 });
25191 }());
25192
25193 /*--------------------------------------------------------------------------*/
25194
25195 QUnit.module('lodash(...).next');
25196
25197 lodashStable.each([false, true], function(implict) {
25198 function chain(value) {
25199 return implict ? _(value) : _.chain(value);
25200 }
25201
25202 var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
25203
25204 QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
25205 assert.expect(3);
25206
25207 if (!isNpm) {
25208 var wrapped = chain([1, 2]);
25209
25210 assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
25211 assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
25212 assert.deepEqual(wrapped.next(), { 'done': true, 'value': undefined });
25213 }
25214 else {
25215 skipAssert(assert, 3);
25216 }
25217 });
25218
25219 QUnit.test('should act as an iterable ' + chainType, function(assert) {
25220 assert.expect(2);
25221
25222 if (!isNpm && Symbol && Symbol.iterator) {
25223 var array = [1, 2],
25224 wrapped = chain(array);
25225
25226 assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
25227 assert.deepEqual(_.toArray(wrapped), array);
25228 }
25229 else {
25230 skipAssert(assert, 2);
25231 }
25232 });
25233
25234 QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
25235 assert.expect(3);
25236
25237 if (!isNpm && Array.from) {
25238 var hearts = '\ud83d\udc95',
25239 values = [[1], { 'a': 1 }, hearts];
25240
25241 lodashStable.each(values, function(value) {
25242 var wrapped = chain(value);
25243 assert.deepEqual(Array.from(wrapped), _.toArray(value));
25244 });
25245 }
25246 else {
25247 skipAssert(assert, 3);
25248 }
25249 });
25250
25251 QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
25252 assert.expect(4);
25253
25254 if (!isNpm && Symbol && Symbol.iterator) {
25255 var array = [1, 2],
25256 wrapped = chain(array);
25257
25258 assert.deepEqual(_.toArray(wrapped), array);
25259 assert.deepEqual(_.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
25260
25261 var other = wrapped.filter();
25262 assert.deepEqual(_.toArray(other), array, 'reset for new chain segments');
25263 assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted');
25264 }
25265 else {
25266 skipAssert(assert, 4);
25267 }
25268 });
25269
25270 QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
25271 assert.expect(3);
25272
25273 if (!isNpm && Symbol && Symbol.iterator) {
25274 var array = lodashStable.range(LARGE_ARRAY_SIZE),
25275 predicate = function(value) { values.push(value); return isEven(value); },
25276 values = [],
25277 wrapped = chain(array);
25278
25279 assert.deepEqual(_.toArray(wrapped), array);
25280
25281 wrapped = wrapped.filter(predicate);
25282 assert.deepEqual(_.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
25283 assert.deepEqual(values, array, 'memoizes iterator values');
25284 }
25285 else {
25286 skipAssert(assert, 3);
25287 }
25288 });
25289 });
25290
25291 /*--------------------------------------------------------------------------*/
25292
25293 QUnit.module('lodash(...).plant');
25294
25295 (function() {
25296 QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
25297 assert.expect(2);
25298
25299 if (!isNpm) {
25300 var array1 = [5, null, 3, null, 1],
25301 array2 = [10, null, 8, null, 6],
25302 wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
25303 wrapped2 = wrapped1.plant(array2);
25304
25305 assert.deepEqual(wrapped2.value(), [36, 64]);
25306 assert.deepEqual(wrapped1.value(), [1, 9]);
25307 }
25308 else {
25309 skipAssert(assert, 2);
25310 }
25311 });
25312
25313 QUnit.test('should clone `chainAll` settings', function(assert) {
25314 assert.expect(1);
25315
25316 if (!isNpm) {
25317 var array1 = [2, 4],
25318 array2 = [6, 8],
25319 wrapped1 = _(array1).chain().map(square),
25320 wrapped2 = wrapped1.plant(array2);
25321
25322 assert.deepEqual(wrapped2.head().value(), 36);
25323 }
25324 else {
25325 skipAssert(assert);
25326 }
25327 });
25328
25329 QUnit.test('should reset iterator data on cloned sequences', function(assert) {
25330 assert.expect(3);
25331
25332 if (!isNpm && Symbol && Symbol.iterator) {
25333 var array1 = [2, 4],
25334 array2 = [6, 8],
25335 wrapped1 = _(array1).map(square);
25336
25337 assert.deepEqual(_.toArray(wrapped1), [4, 16]);
25338 assert.deepEqual(_.toArray(wrapped1), []);
25339
25340 var wrapped2 = wrapped1.plant(array2);
25341 assert.deepEqual(_.toArray(wrapped2), [36, 64]);
25342 }
25343 else {
25344 skipAssert(assert, 3);
25345 }
25346 });
25347 }());
25348
25349 /*--------------------------------------------------------------------------*/
25350
25351 QUnit.module('lodash(...).pop');
25352
25353 (function() {
25354 QUnit.test('should remove elements from the end of `array`', function(assert) {
25355 assert.expect(5);
25356
25357 if (!isNpm) {
25358 var array = [1, 2],
25359 wrapped = _(array);
25360
25361 assert.strictEqual(wrapped.pop(), 2);
25362 assert.deepEqual(wrapped.value(), [1]);
25363 assert.strictEqual(wrapped.pop(), 1);
25364
25365 var actual = wrapped.value();
25366 assert.deepEqual(actual, []);
25367 assert.strictEqual(actual, array);
25368 }
25369 else {
25370 skipAssert(assert, 5);
25371 }
25372 });
25373
25374 QUnit.test('should accept falsey arguments', function(assert) {
25375 assert.expect(1);
25376
25377 if (!isNpm) {
25378 var expected = lodashStable.map(falsey, alwaysTrue);
25379
25380 var actual = lodashStable.map(falsey, function(value, index) {
25381 try {
25382 var result = index ? _(value).pop() : _().pop();
25383 return result === undefined;
25384 } catch (e) {}
25385 });
25386
25387 assert.deepEqual(actual, expected);
25388 }
25389 else {
25390 skipAssert(assert);
25391 }
25392 });
25393 }());
25394
25395 /*--------------------------------------------------------------------------*/
25396
25397 QUnit.module('lodash(...).push');
25398
25399 (function() {
25400 QUnit.test('should append elements to `array`', function(assert) {
25401 assert.expect(2);
25402
25403 if (!isNpm) {
25404 var array = [1],
25405 wrapped = _(array).push(2, 3),
25406 actual = wrapped.value();
25407
25408 assert.strictEqual(actual, array);
25409 assert.deepEqual(actual, [1, 2, 3]);
25410 }
25411 else {
25412 skipAssert(assert, 2);
25413 }
25414 });
25415
25416 QUnit.test('should accept falsey arguments', function(assert) {
25417 assert.expect(1);
25418
25419 if (!isNpm) {
25420 var expected = lodashStable.map(falsey, alwaysTrue);
25421
25422 var actual = lodashStable.map(falsey, function(value, index) {
25423 try {
25424 var result = index ? _(value).push(1).value() : _().push(1).value();
25425 return lodashStable.eq(result, value);
25426 } catch (e) {}
25427 });
25428
25429 assert.deepEqual(actual, expected);
25430 }
25431 else {
25432 skipAssert(assert);
25433 }
25434 });
25435 }());
25436
25437 /*--------------------------------------------------------------------------*/
25438
25439 QUnit.module('lodash(...).shift');
25440
25441 (function() {
25442 QUnit.test('should remove elements from the front of `array`', function(assert) {
25443 assert.expect(5);
25444
25445 if (!isNpm) {
25446 var array = [1, 2],
25447 wrapped = _(array);
25448
25449 assert.strictEqual(wrapped.shift(), 1);
25450 assert.deepEqual(wrapped.value(), [2]);
25451 assert.strictEqual(wrapped.shift(), 2);
25452
25453 var actual = wrapped.value();
25454 assert.deepEqual(actual, []);
25455 assert.strictEqual(actual, array);
25456 }
25457 else {
25458 skipAssert(assert, 5);
25459 }
25460 });
25461
25462 QUnit.test('should accept falsey arguments', function(assert) {
25463 assert.expect(1);
25464
25465 if (!isNpm) {
25466 var expected = lodashStable.map(falsey, alwaysTrue);
25467
25468 var actual = lodashStable.map(falsey, function(value, index) {
25469 try {
25470 var result = index ? _(value).shift() : _().shift();
25471 return result === undefined;
25472 } catch (e) {}
25473 });
25474
25475 assert.deepEqual(actual, expected);
25476 }
25477 else {
25478 skipAssert(assert);
25479 }
25480 });
25481 }());
25482
25483 /*--------------------------------------------------------------------------*/
25484
25485 QUnit.module('lodash(...).sort');
25486
25487 (function() {
25488 QUnit.test('should return the wrapped sorted `array`', function(assert) {
25489 assert.expect(2);
25490
25491 if (!isNpm) {
25492 var array = [3, 1, 2],
25493 wrapped = _(array).sort(),
25494 actual = wrapped.value();
25495
25496 assert.strictEqual(actual, array);
25497 assert.deepEqual(actual, [1, 2, 3]);
25498 }
25499 else {
25500 skipAssert(assert, 2);
25501 }
25502 });
25503
25504 QUnit.test('should accept falsey arguments', function(assert) {
25505 assert.expect(1);
25506
25507 if (!isNpm) {
25508 var expected = lodashStable.map(falsey, alwaysTrue);
25509
25510 var actual = lodashStable.map(falsey, function(value, index) {
25511 try {
25512 var result = index ? _(value).sort().value() : _().sort().value();
25513 return lodashStable.eq(result, value);
25514 } catch (e) {}
25515 });
25516
25517 assert.deepEqual(actual, expected);
25518 }
25519 else {
25520 skipAssert(assert);
25521 }
25522 });
25523 }());
25524
25525 /*--------------------------------------------------------------------------*/
25526
25527 QUnit.module('lodash(...).splice');
25528
25529 (function() {
25530 QUnit.test('should support removing and inserting elements', function(assert) {
25531 assert.expect(5);
25532
25533 if (!isNpm) {
25534 var array = [1, 2],
25535 wrapped = _(array);
25536
25537 assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
25538 assert.deepEqual(wrapped.value(), [1, 3]);
25539 assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
25540
25541 var actual = wrapped.value();
25542 assert.deepEqual(actual, []);
25543 assert.strictEqual(actual, array);
25544 }
25545 else {
25546 skipAssert(assert, 5);
25547 }
25548 });
25549
25550 QUnit.test('should accept falsey arguments', function(assert) {
25551 assert.expect(1);
25552
25553 if (!isNpm) {
25554 var expected = lodashStable.map(falsey, alwaysTrue);
25555
25556 var actual = lodashStable.map(falsey, function(value, index) {
25557 try {
25558 var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
25559 return lodashStable.isEqual(result, []);
25560 } catch (e) {}
25561 });
25562
25563 assert.deepEqual(actual, expected);
25564 }
25565 else {
25566 skipAssert(assert);
25567 }
25568 });
25569 }());
25570
25571 /*--------------------------------------------------------------------------*/
25572
25573 QUnit.module('lodash(...).unshift');
25574
25575 (function() {
25576 QUnit.test('should prepend elements to `array`', function(assert) {
25577 assert.expect(2);
25578
25579 if (!isNpm) {
25580 var array = [3],
25581 wrapped = _(array).unshift(1, 2),
25582 actual = wrapped.value();
25583
25584 assert.strictEqual(actual, array);
25585 assert.deepEqual(actual, [1, 2, 3]);
25586 }
25587 else {
25588 skipAssert(assert, 2);
25589 }
25590 });
25591
25592 QUnit.test('should accept falsey arguments', function(assert) {
25593 assert.expect(1);
25594
25595 if (!isNpm) {
25596 var expected = lodashStable.map(falsey, alwaysTrue);
25597
25598 var actual = lodashStable.map(falsey, function(value, index) {
25599 try {
25600 var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
25601 return lodashStable.eq(result, value);
25602 } catch (e) {}
25603 });
25604
25605 assert.deepEqual(actual, expected);
25606 }
25607 else {
25608 skipAssert(assert);
25609 }
25610 });
25611 }());
25612
25613 /*--------------------------------------------------------------------------*/
25614
25615 QUnit.module('lodash(...).value');
25616
25617 (function() {
25618 QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
25619 assert.expect(4);
25620
25621 if (!isNpm) {
25622 var array = [1],
25623 wrapped = _(array).push(2).push(3);
25624
25625 assert.deepEqual(array, [1]);
25626 assert.deepEqual(wrapped.value(), [1, 2, 3]);
25627 assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
25628 assert.deepEqual(array, [1, 2, 3, 2, 3]);
25629 }
25630 else {
25631 skipAssert(assert, 4);
25632 }
25633 });
25634
25635 QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
25636 assert.expect(1);
25637
25638 if (!isNpm) {
25639 var wrapped = _(123);
25640 assert.strictEqual(Number(wrapped), 123);
25641 }
25642 else {
25643 skipAssert(assert);
25644 }
25645 });
25646
25647 QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
25648 assert.expect(1);
25649
25650 if (!isNpm && JSON) {
25651 var wrapped = _([1, 2, 3]);
25652 assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
25653 }
25654 else {
25655 skipAssert(assert);
25656 }
25657 });
25658
25659 QUnit.test('should be aliased', function(assert) {
25660 assert.expect(2);
25661
25662 if (!isNpm) {
25663 var expected = _.prototype.value;
25664 assert.strictEqual(_.prototype.toJSON, expected);
25665 assert.strictEqual(_.prototype.valueOf, expected);
25666 }
25667 else {
25668 skipAssert(assert, 2);
25669 }
25670 });
25671 }());
25672
25673 /*--------------------------------------------------------------------------*/
25674
25675 QUnit.module('lodash(...) methods that return the wrapped modified array');
25676
25677 (function() {
25678 var funcs = [
25679 'push',
25680 'reverse',
25681 'sort',
25682 'unshift'
25683 ];
25684
25685 lodashStable.each(funcs, function(methodName) {
25686 QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
25687 assert.expect(2);
25688
25689 if (!isNpm) {
25690 var array = [1, 2, 3],
25691 wrapped = _(array),
25692 actual = wrapped[methodName]();
25693
25694 assert.ok(actual instanceof _);
25695 assert.notStrictEqual(actual, wrapped);
25696 }
25697 else {
25698 skipAssert(assert, 2);
25699 }
25700 });
25701 });
25702 }());
25703
25704 /*--------------------------------------------------------------------------*/
25705
25706 QUnit.module('lodash(...) methods that return new wrapped values');
25707
25708 (function() {
25709 var funcs = [
25710 'castArray',
25711 'concat',
25712 'difference',
25713 'differenceBy',
25714 'differenceWith',
25715 'intersection',
25716 'intersectionBy',
25717 'intersectionWith',
25718 'pull',
25719 'pullAll',
25720 'pullAt',
25721 'sampleSize',
25722 'shuffle',
25723 'slice',
25724 'splice',
25725 'split',
25726 'toArray',
25727 'union',
25728 'unionBy',
25729 'unionWith',
25730 'uniq',
25731 'uniqBy',
25732 'uniqWith',
25733 'words',
25734 'xor',
25735 'xorBy',
25736 'xorWith'
25737 ];
25738
25739 lodashStable.each(funcs, function(methodName) {
25740 QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
25741 assert.expect(2);
25742
25743 if (!isNpm) {
25744 var value = methodName == 'split' ? 'abc' : [1, 2, 3],
25745 wrapped = _(value),
25746 actual = wrapped[methodName]();
25747
25748 assert.ok(actual instanceof _);
25749 assert.notStrictEqual(actual, wrapped);
25750 }
25751 else {
25752 skipAssert(assert, 2);
25753 }
25754 });
25755 });
25756 }());
25757
25758 /*--------------------------------------------------------------------------*/
25759
25760 QUnit.module('lodash(...) methods that return unwrapped values');
25761
25762 (function() {
25763 var funcs = [
25764 'add',
25765 'camelCase',
25766 'capitalize',
25767 'ceil',
25768 'clone',
25769 'deburr',
25770 'divide',
25771 'endsWith',
25772 'escape',
25773 'escapeRegExp',
25774 'every',
25775 'find',
25776 'floor',
25777 'has',
25778 'hasIn',
25779 'head',
25780 'includes',
25781 'isArguments',
25782 'isArray',
25783 'isArrayBuffer',
25784 'isArrayLike',
25785 'isBoolean',
25786 'isBuffer',
25787 'isDate',
25788 'isElement',
25789 'isEmpty',
25790 'isEqual',
25791 'isError',
25792 'isFinite',
25793 'isFunction',
25794 'isInteger',
25795 'isMap',
25796 'isNaN',
25797 'isNative',
25798 'isNil',
25799 'isNull',
25800 'isNumber',
25801 'isObject',
25802 'isObjectLike',
25803 'isPlainObject',
25804 'isRegExp',
25805 'isSafeInteger',
25806 'isSet',
25807 'isString',
25808 'isUndefined',
25809 'isWeakMap',
25810 'isWeakSet',
25811 'join',
25812 'kebabCase',
25813 'last',
25814 'lowerCase',
25815 'lowerFirst',
25816 'max',
25817 'maxBy',
25818 'min',
25819 'minBy',
25820 'multiply',
25821 'nth',
25822 'pad',
25823 'padEnd',
25824 'padStart',
25825 'parseInt',
25826 'pop',
25827 'random',
25828 'reduce',
25829 'reduceRight',
25830 'repeat',
25831 'replace',
25832 'round',
25833 'sample',
25834 'shift',
25835 'size',
25836 'snakeCase',
25837 'some',
25838 'startCase',
25839 'startsWith',
25840 'subtract',
25841 'sum',
25842 'toInteger',
25843 'toLower',
25844 'toNumber',
25845 'toSafeInteger',
25846 'toString',
25847 'toUpper',
25848 'trim',
25849 'trimEnd',
25850 'trimStart',
25851 'truncate',
25852 'unescape',
25853 'upperCase',
25854 'upperFirst'
25855 ];
25856
25857 lodashStable.each(funcs, function(methodName) {
25858 QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
25859 assert.expect(1);
25860
25861 if (!isNpm) {
25862 var actual = _()[methodName]();
25863 assert.notOk(actual instanceof _);
25864 }
25865 else {
25866 skipAssert(assert);
25867 }
25868 });
25869
25870 QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
25871 assert.expect(1);
25872
25873 if (!isNpm) {
25874 var actual = _().chain()[methodName]();
25875 assert.ok(actual instanceof _);
25876 }
25877 else {
25878 skipAssert(assert);
25879 }
25880 });
25881 });
25882 }());
25883
25884 /*--------------------------------------------------------------------------*/
25885
25886 QUnit.module('"Arrays" category methods');
25887
25888 (function() {
25889 var args = (function() { return arguments; }(1, null, [3], null, 5)),
25890 sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
25891 array = [1, 2, 3, 4, 5, 6];
25892
25893 QUnit.test('should work with `arguments` objects', function(assert) {
25894 assert.expect(30);
25895
25896 function message(methodName) {
25897 return '`_.' + methodName + '` should work with `arguments` objects';
25898 }
25899
25900 assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
25901 assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
25902
25903 assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
25904 assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
25905
25906 assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
25907 assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
25908 assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
25909 assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
25910 assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
25911 assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
25912 assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
25913 assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
25914 assert.deepEqual(_.head(args), 1, message('head'));
25915 assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
25916 assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
25917 assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
25918 assert.deepEqual(_.last(args), 5, message('last'));
25919 assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
25920 assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
25921 assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
25922 assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
25923 assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
25924 assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
25925 assert.deepEqual(_.take(args, 2), [1, null], message('take'));
25926 assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
25927 assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
25928 assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
25929 assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
25930 assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
25931 assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
25932 });
25933
25934 QUnit.test('should accept falsey primary arguments', function(assert) {
25935 assert.expect(4);
25936
25937 function message(methodName) {
25938 return '`_.' + methodName + '` should accept falsey primary arguments';
25939 }
25940
25941 assert.deepEqual(_.difference(null, array), [], message('difference'));
25942 assert.deepEqual(_.intersection(null, array), [], message('intersection'));
25943 assert.deepEqual(_.union(null, array), array, message('union'));
25944 assert.deepEqual(_.xor(null, array), array, message('xor'));
25945 });
25946
25947 QUnit.test('should accept falsey secondary arguments', function(assert) {
25948 assert.expect(3);
25949
25950 function message(methodName) {
25951 return '`_.' + methodName + '` should accept falsey secondary arguments';
25952 }
25953
25954 assert.deepEqual(_.difference(array, null), array, message('difference'));
25955 assert.deepEqual(_.intersection(array, null), [], message('intersection'));
25956 assert.deepEqual(_.union(array, null), array, message('union'));
25957 });
25958 }());
25959
25960 /*--------------------------------------------------------------------------*/
25961
25962 QUnit.module('"Strings" category methods');
25963
25964 (function() {
25965 var stringMethods = [
25966 'camelCase',
25967 'capitalize',
25968 'escape',
25969 'kebabCase',
25970 'lowerCase',
25971 'lowerFirst',
25972 'pad',
25973 'padEnd',
25974 'padStart',
25975 'repeat',
25976 'snakeCase',
25977 'toLower',
25978 'toUpper',
25979 'trim',
25980 'trimEnd',
25981 'trimStart',
25982 'truncate',
25983 'unescape',
25984 'upperCase',
25985 'upperFirst'
25986 ];
25987
25988 lodashStable.each(stringMethods, function(methodName) {
25989 var func = _[methodName];
25990
25991 QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
25992 assert.expect(1);
25993
25994 var values = [, null, undefined, ''],
25995 expected = lodashStable.map(values, alwaysEmptyString);
25996
25997 var actual = lodashStable.map(values, function(value, index) {
25998 return index ? func(value) : func();
25999 });
26000
26001 assert.deepEqual(actual, expected);
26002 });
26003 });
26004 }());
26005
26006 /*--------------------------------------------------------------------------*/
26007
26008 QUnit.module('lodash methods');
26009
26010 (function() {
26011 var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
26012 return lodashStable.startsWith(methodName, '_');
26013 });
26014
26015 var checkFuncs = [
26016 'after',
26017 'ary',
26018 'before',
26019 'bind',
26020 'curry',
26021 'curryRight',
26022 'debounce',
26023 'defer',
26024 'delay',
26025 'flip',
26026 'flow',
26027 'flowRight',
26028 'memoize',
26029 'negate',
26030 'once',
26031 'partial',
26032 'partialRight',
26033 'rearg',
26034 'rest',
26035 'spread',
26036 'throttle',
26037 'unary'
26038 ];
26039
26040 var noBinding = [
26041 'flip',
26042 'memoize',
26043 'negate',
26044 'once',
26045 'overArgs',
26046 'partial',
26047 'partialRight',
26048 'rearg',
26049 'rest',
26050 'spread'
26051 ];
26052
26053 var rejectFalsey = [
26054 'tap',
26055 'thru'
26056 ].concat(checkFuncs);
26057
26058 var returnArrays = [
26059 'at',
26060 'chunk',
26061 'compact',
26062 'difference',
26063 'drop',
26064 'filter',
26065 'flatten',
26066 'functions',
26067 'initial',
26068 'intersection',
26069 'invokeMap',
26070 'keys',
26071 'map',
26072 'orderBy',
26073 'pull',
26074 'pullAll',
26075 'pullAt',
26076 'range',
26077 'rangeRight',
26078 'reject',
26079 'remove',
26080 'shuffle',
26081 'sortBy',
26082 'tail',
26083 'take',
26084 'times',
26085 'toArray',
26086 'toPairs',
26087 'toPairsIn',
26088 'union',
26089 'uniq',
26090 'values',
26091 'without',
26092 'xor',
26093 'zip'
26094 ];
26095
26096 var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
26097
26098 QUnit.test('should accept falsey arguments', function(assert) {
26099 assert.expect(308);
26100
26101 var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
26102
26103 lodashStable.each(acceptFalsey, function(methodName) {
26104 var expected = emptyArrays,
26105 func = _[methodName],
26106 pass = true;
26107
26108 var actual = lodashStable.map(falsey, function(value, index) {
26109 try {
26110 return index ? func(value) : func();
26111 } catch (e) {
26112 pass = false;
26113 }
26114 });
26115
26116 if (methodName == 'noConflict') {
26117 root._ = oldDash;
26118 }
26119 else if (methodName == 'pull' || methodName == 'pullAll') {
26120 expected = falsey;
26121 }
26122 if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
26123 assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
26124 }
26125 assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
26126 });
26127
26128 // Skip tests for missing methods of modularized builds.
26129 lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
26130 if (!_[methodName]) {
26131 skipAssert(assert);
26132 }
26133 });
26134 });
26135
26136 QUnit.test('should return an array', function(assert) {
26137 assert.expect(70);
26138
26139 var array = [1, 2, 3];
26140
26141 lodashStable.each(returnArrays, function(methodName) {
26142 var actual,
26143 func = _[methodName];
26144
26145 switch (methodName) {
26146 case 'invokeMap':
26147 actual = func(array, 'toFixed');
26148 break;
26149 case 'sample':
26150 actual = func(array, 1);
26151 break;
26152 default:
26153 actual = func(array);
26154 }
26155 assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
26156
26157 var isPull = methodName == 'pull' || methodName == 'pullAll';
26158 assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
26159 });
26160 });
26161
26162 QUnit.test('should throw an error for falsey arguments', function(assert) {
26163 assert.expect(24);
26164
26165 lodashStable.each(rejectFalsey, function(methodName) {
26166 var expected = lodashStable.map(falsey, alwaysTrue),
26167 func = _[methodName];
26168
26169 var actual = lodashStable.map(falsey, function(value, index) {
26170 var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
26171
26172 try {
26173 index ? func(value) : func();
26174 } catch (e) {
26175 pass = !pass && (e instanceof TypeError) &&
26176 (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
26177 }
26178 return pass;
26179 });
26180
26181 assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
26182 });
26183 });
26184
26185 QUnit.test('should not set a `this` binding', function(assert) {
26186 assert.expect(30);
26187
26188 lodashStable.each(noBinding, function(methodName) {
26189 var fn = function() { return this.a; },
26190 func = _[methodName],
26191 isNegate = methodName == 'negate',
26192 object = { 'a': 1 },
26193 expected = isNegate ? false : 1;
26194
26195 var wrapper = func(_.bind(fn, object));
26196 assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
26197
26198 wrapper = _.bind(func(fn), object);
26199 assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
26200
26201 object.wrapper = func(fn);
26202 assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
26203 });
26204 });
26205
26206 QUnit.test('should not contain minified method names (test production builds)', function(assert) {
26207 assert.expect(1);
26208
26209 var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
26210 assert.ok(lodashStable.every(_.functions(_), function(methodName) {
26211 return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
26212 }));
26213 });
26214 }());
26215
26216 /*--------------------------------------------------------------------------*/
26217
26218 QUnit.config.asyncRetries = 10;
26219 QUnit.config.hidepassed = true;
26220
26221 if (!document) {
26222 QUnit.config.noglobals = true;
26223 QUnit.load();
26224 }
26225}.call(this));