1;(function() { 2 3 /** Used as a safe reference for `undefined` in pre-ES5 environments. */ 4 var undefined; 5 6 /** Used to detect when a function becomes hot. */ 7 var HOT_COUNT = 150; 8 9 /** Used as the size to cover large array optimizations. */ 10 var LARGE_ARRAY_SIZE = 200; 11 12 /** Used as the `TypeError` message for "Functions" methods. */ 13 var FUNC_ERROR_TEXT = 'Expected a function'; 14 15 /** Used as the maximum memoize cache size. */ 16 var MAX_MEMOIZE_SIZE = 500; 17 18 /** Used as references for various `Number` constants. */ 19 var MAX_SAFE_INTEGER = 9007199254740991, 20 MAX_INTEGER = 1.7976931348623157e+308; 21 22 /** Used as references for the maximum length and index of an array. */ 23 var MAX_ARRAY_LENGTH = 4294967295, 24 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; 25 26 /** `Object#toString` result references. */ 27 var funcTag = '[object Function]', 28 numberTag = '[object Number]', 29 objectTag = '[object Object]'; 30 31 /** Used as a reference to the global object. */ 32 var root = (typeof global == 'object' && global) || this; 33 34 /** Used to store lodash to test for bad extensions/shims. */ 35 var lodashBizarro = root.lodashBizarro; 36 37 /** Used for native method references. */ 38 var arrayProto = Array.prototype, 39 funcProto = Function.prototype, 40 objectProto = Object.prototype, 41 numberProto = Number.prototype, 42 stringProto = String.prototype; 43 44 /** Method and object shortcuts. */ 45 var phantom = root.phantom, 46 process = root.process, 47 amd = root.define ? define.amd : undefined, 48 args = toArgs([1, 2, 3]), 49 argv = process ? process.argv : undefined, 50 defineProperty = Object.defineProperty, 51 document = phantom ? undefined : root.document, 52 body = root.document ? root.document.body : undefined, 53 create = Object.create, 54 fnToString = funcProto.toString, 55 freeze = Object.freeze, 56 getSymbols = Object.getOwnPropertySymbols, 57 identity = function(value) { return value; }, 58 noop = function() {}, 59 objToString = objectProto.toString, 60 params = argv, 61 push = arrayProto.push, 62 realm = {}, 63 slice = arrayProto.slice, 64 strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)); 65 66 var ArrayBuffer = root.ArrayBuffer, 67 Buffer = root.Buffer, 68 Map = root.Map, 69 Promise = root.Promise, 70 Proxy = root.Proxy, 71 Set = root.Set, 72 Symbol = root.Symbol, 73 Uint8Array = root.Uint8Array, 74 WeakMap = root.WeakMap, 75 WeakSet = root.WeakSet; 76 77 var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined, 78 map = Map ? new Map : undefined, 79 promise = Promise ? Promise.resolve(1) : undefined, 80 set = Set ? new Set : undefined, 81 symbol = Symbol ? Symbol('a') : undefined, 82 weakMap = WeakMap ? new WeakMap : undefined, 83 weakSet = WeakSet ? new WeakSet : undefined; 84 85 /** Math helpers. */ 86 var add = function(x, y) { return x + y; }, 87 doubled = function(n) { return n * 2; }, 88 isEven = function(n) { return n % 2 == 0; }, 89 square = function(n) { return n * n; }; 90 91 /** Stub functions. */ 92 var stubA = function() { return 'a'; }, 93 stubB = function() { return 'b'; }, 94 stubC = function() { return 'c'; }; 95 96 var stubTrue = function() { return true; }, 97 stubFalse = function() { return false; }; 98 99 var stubNaN = function() { return NaN; }, 100 stubNull = function() { return null; }; 101 102 var stubZero = function() { return 0; }, 103 stubOne = function() { return 1; }, 104 stubTwo = function() { return 2; }, 105 stubThree = function() { return 3; }, 106 stubFour = function() { return 4; }; 107 108 var stubArray = function() { return []; }, 109 stubObject = function() { return {}; }, 110 stubString = function() { return ''; }; 111 112 /** List of Latin Unicode letters. */ 113 var burredLetters = [ 114 // Latin-1 Supplement letters. 115 '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', 116 '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', 117 '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', 118 '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', 119 // Latin Extended-A letters. 120 '\u0100', '\u0101', '\u0102', '\u0103', '\u0104', '\u0105', '\u0106', '\u0107', '\u0108', '\u0109', '\u010a', '\u010b', '\u010c', '\u010d', '\u010e', '\u010f', 121 '\u0110', '\u0111', '\u0112', '\u0113', '\u0114', '\u0115', '\u0116', '\u0117', '\u0118', '\u0119', '\u011a', '\u011b', '\u011c', '\u011d', '\u011e', '\u011f', 122 '\u0120', '\u0121', '\u0122', '\u0123', '\u0124', '\u0125', '\u0126', '\u0127', '\u0128', '\u0129', '\u012a', '\u012b', '\u012c', '\u012d', '\u012e', '\u012f', 123 '\u0130', '\u0131', '\u0132', '\u0133', '\u0134', '\u0135', '\u0136', '\u0137', '\u0138', '\u0139', '\u013a', '\u013b', '\u013c', '\u013d', '\u013e', '\u013f', 124 '\u0140', '\u0141', '\u0142', '\u0143', '\u0144', '\u0145', '\u0146', '\u0147', '\u0148', '\u0149', '\u014a', '\u014b', '\u014c', '\u014d', '\u014e', '\u014f', 125 '\u0150', '\u0151', '\u0152', '\u0153', '\u0154', '\u0155', '\u0156', '\u0157', '\u0158', '\u0159', '\u015a', '\u015b', '\u015c', '\u015d', '\u015e', '\u015f', 126 '\u0160', '\u0161', '\u0162', '\u0163', '\u0164', '\u0165', '\u0166', '\u0167', '\u0168', '\u0169', '\u016a', '\u016b', '\u016c', '\u016d', '\u016e', '\u016f', 127 '\u0170', '\u0171', '\u0172', '\u0173', '\u0174', '\u0175', '\u0176', '\u0177', '\u0178', '\u0179', '\u017a', '\u017b', '\u017c', '\u017d', '\u017e', '\u017f' 128 ]; 129 130 /** List of combining diacritical marks. */ 131 var comboMarks = [ 132 '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f', 133 '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f', 134 '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f', 135 '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f', 136 '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f', 137 '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f', 138 '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f', 139 '\ufe20', '\ufe21', '\ufe22', '\ufe23' 140 ]; 141 142 /** List of converted Latin Unicode letters. */ 143 var deburredLetters = [ 144 // Converted Latin-1 Supplement letters. 145 'A', 'A', 'A', 'A', 'A', 'A', 'Ae', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 146 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th', 147 'ss', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 148 'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y', 149 // Converted Latin Extended-A letters. 150 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 151 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 152 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 153 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 154 'K', 'k', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 155 'N', 'n', 'N', 'n', 'N', 'n', "'n", 'N', 'n', 156 'O', 'o', 'O', 'o', 'O', 'o', 'Oe', 'oe', 157 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 158 'T', 't', 'T', 't', 'T', 't', 159 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 160 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's' 161 ]; 162 163 /** Used to provide falsey values to methods. */ 164 var falsey = [, null, undefined, false, 0, NaN, '']; 165 166 /** Used to specify the emoji style glyph variant of characters. */ 167 var emojiVar = '\ufe0f'; 168 169 /** Used to provide empty values to methods. */ 170 var empties = [[], {}].concat(falsey.slice(1)); 171 172 /** Used to test error objects. */ 173 var errors = [ 174 new Error, 175 new EvalError, 176 new RangeError, 177 new ReferenceError, 178 new SyntaxError, 179 new TypeError, 180 new URIError 181 ]; 182 183 /** List of fitzpatrick modifiers. */ 184 var fitzModifiers = [ 185 '\ud83c\udffb', 186 '\ud83c\udffc', 187 '\ud83c\udffd', 188 '\ud83c\udffe', 189 '\ud83c\udfff' 190 ]; 191 192 /** Used to provide primitive values to methods. */ 193 var primitives = [null, undefined, false, true, 1, NaN, 'a']; 194 195 /** Used to check whether methods support typed arrays. */ 196 var typedArrays = [ 197 'Float32Array', 198 'Float64Array', 199 'Int8Array', 200 'Int16Array', 201 'Int32Array', 202 'Uint8Array', 203 'Uint8ClampedArray', 204 'Uint16Array', 205 'Uint32Array' 206 ]; 207 208 /** Used to check whether methods support array views. */ 209 var arrayViews = typedArrays.concat('DataView'); 210 211 /** The file path of the lodash file to test. */ 212 var filePath = (function() { 213 var min = 2, 214 result = params || []; 215 216 if (phantom) { 217 min = 0; 218 result = params = phantom.args || require('system').args; 219 } 220 var last = result[result.length - 1]; 221 result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js'; 222 223 if (!amd) { 224 try { 225 result = require('fs').realpathSync(result); 226 } catch (e) {} 227 228 try { 229 result = require.resolve(result); 230 } catch (e) {} 231 } 232 return result; 233 }()); 234 235 /** The `ui` object. */ 236 var ui = root.ui || (root.ui = { 237 'buildPath': filePath, 238 'loaderPath': '', 239 'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath), 240 'isStrict': /\bes\b/.test(filePath) || 'default' in require(filePath), 241 'urlParams': {} 242 }); 243 244 /** The basename of the lodash file to test. */ 245 var basename = /[\w.-]+$/.exec(filePath)[0]; 246 247 /** Used to indicate testing a modularized build. */ 248 var isModularize = ui.isModularize; 249 250 /** Detect if testing `npm` modules. */ 251 var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]); 252 253 /** Detect if running in PhantomJS. */ 254 var isPhantom = phantom || (typeof callPhantom == 'function'); 255 256 /** Detect if lodash is in strict mode. */ 257 var isStrict = ui.isStrict; 258 259 /*--------------------------------------------------------------------------*/ 260 261 // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs. 262 root.msWDfn = undefined; 263 264 // Assign `setTimeout` to itself to avoid being flagged as a leak. 265 setProperty(root, 'setTimeout', setTimeout); 266 267 // Exit early if going to run tests in a PhantomJS web page. 268 if (phantom && isModularize) { 269 var page = require('webpage').create(); 270 271 page.onCallback = function(details) { 272 var coverage = details.coverage; 273 if (coverage) { 274 var fs = require('fs'), 275 cwd = fs.workingDirectory, 276 sep = fs.separator; 277 278 fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage)); 279 } 280 phantom.exit(details.failed ? 1 : 0); 281 }; 282 283 page.onConsoleMessage = function(message) { 284 console.log(message); 285 }; 286 287 page.onInitialized = function() { 288 page.evaluate(function() { 289 document.addEventListener('DOMContentLoaded', function() { 290 QUnit.done(function(details) { 291 details.coverage = window.__coverage__; 292 callPhantom(details); 293 }); 294 }); 295 }); 296 }; 297 298 page.open(filePath, function(status) { 299 if (status != 'success') { 300 console.log('PhantomJS failed to load page: ' + filePath); 301 phantom.exit(1); 302 } 303 }); 304 305 console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params))); 306 return; 307 } 308 309 /*--------------------------------------------------------------------------*/ 310 311 /** Used to test Web Workers. */ 312 var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) && 313 (document && document.origin != 'null') && root.Worker; 314 315 /** Used to test host objects in IE. */ 316 try { 317 var xml = new ActiveXObject('Microsoft.XMLDOM'); 318 } catch (e) {} 319 320 /** Poison the free variable `root` in Node.js */ 321 try { 322 defineProperty(global.root, 'root', { 323 'configurable': false, 324 'enumerable': false, 325 'get': function() { throw new ReferenceError; } 326 }); 327 } catch (e) {} 328 329 /** Load QUnit and extras. */ 330 var QUnit = root.QUnit || require('qunit-extras'); 331 332 /** Load stable Lodash. */ 333 var lodashStable = root.lodashStable; 334 if (!lodashStable) { 335 try { 336 lodashStable = interopRequire('../node_modules/lodash/lodash.js'); 337 } catch (e) { 338 console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.'); 339 return; 340 } 341 lodashStable = lodashStable.noConflict(); 342 } 343 344 /** The `lodash` function to test. */ 345 var _ = root._ || (root._ = interopRequire(filePath)); 346 347 /** Used to test pseudo private map caches. */ 348 var mapCaches = (function() { 349 var MapCache = (_.memoize || lodashStable.memoize).Cache; 350 var result = { 351 'Hash': new MapCache().__data__.hash.constructor, 352 'MapCache': MapCache 353 }; 354 (_.isMatchWith || lodashStable.isMatchWith)({ 'a': 1 }, { 'a': 1 }, function() { 355 var stack = lodashStable.last(arguments); 356 result.ListCache = stack.__data__.constructor; 357 result.Stack = stack.constructor; 358 }); 359 return result; 360 }()); 361 362 /** Used to detect instrumented istanbul code coverage runs. */ 363 var coverage = root.__coverage__ || root[lodashStable.find(lodashStable.keys(root), function(key) { 364 return /^(?:\$\$cov_\d+\$\$)$/.test(key); 365 })]; 366 367 /** Used to test async functions. */ 368 var asyncFunc = lodashStable.attempt(function() { 369 return Function('return async () => {}'); 370 }); 371 372 /** Used to test generator functions. */ 373 var genFunc = lodashStable.attempt(function() { 374 return Function('return function*(){}'); 375 }); 376 377 /** Used to restore the `_` reference. */ 378 var oldDash = root._; 379 380 /** 381 * Used to check for problems removing whitespace. For a whitespace reference, 382 * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js). 383 */ 384 var whitespace = lodashStable.filter([ 385 // Basic whitespace characters. 386 ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff', 387 388 // Line terminators. 389 '\n', '\r', '\u2028', '\u2029', 390 391 // Unicode category "Zs" space separators. 392 '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', 393 '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000' 394 ], 395 function(chr) { return /\s/.exec(chr); }) 396 .join(''); 397 398 /** 399 * Creates a custom error object. 400 * 401 * @private 402 * @constructor 403 * @param {string} message The error message. 404 */ 405 function CustomError(message) { 406 this.name = 'CustomError'; 407 this.message = message; 408 } 409 410 CustomError.prototype = lodashStable.create(Error.prototype, { 411 'constructor': CustomError 412 }); 413 414 /** 415 * Removes all own enumerable string keyed properties from a given object. 416 * 417 * @private 418 * @param {Object} object The object to empty. 419 */ 420 function emptyObject(object) { 421 lodashStable.forOwn(object, function(value, key, object) { 422 delete object[key]; 423 }); 424 } 425 426 /** 427 * Extracts the unwrapped value from its wrapper. 428 * 429 * @private 430 * @param {Object} wrapper The wrapper to unwrap. 431 * @returns {*} Returns the unwrapped value. 432 */ 433 function getUnwrappedValue(wrapper) { 434 var index = -1, 435 actions = wrapper.__actions__, 436 length = actions.length, 437 result = wrapper.__wrapped__; 438 439 while (++index < length) { 440 var args = [result], 441 action = actions[index]; 442 443 push.apply(args, action.args); 444 result = action.func.apply(action.thisArg, args); 445 } 446 return result; 447 } 448 449 /** 450 * Loads the module of `id`. If the module has an `exports.default`, the 451 * exported default value is returned as the resolved module. 452 * 453 * @private 454 * @param {string} id The identifier of the module to resolve. 455 * @returns {*} Returns the resolved module. 456 */ 457 function interopRequire(id) { 458 var result = require(id); 459 return 'default' in result ? result['default'] : result; 460 } 461 462 /** 463 * Sets a non-enumerable property value on `object`. 464 * 465 * Note: This function is used to avoid a bug in older versions of V8 where 466 * overwriting non-enumerable built-ins makes them enumerable. 467 * See https://code.google.com/p/v8/issues/detail?id=1623 468 * 469 * @private 470 * @param {Object} object The object modify. 471 * @param {string} key The name of the property to set. 472 * @param {*} value The property value. 473 */ 474 function setProperty(object, key, value) { 475 try { 476 defineProperty(object, key, { 477 'configurable': true, 478 'enumerable': false, 479 'writable': true, 480 'value': value 481 }); 482 } catch (e) { 483 object[key] = value; 484 } 485 return object; 486 } 487 488 /** 489 * Skips a given number of tests with a passing result. 490 * 491 * @private 492 * @param {Object} assert The QUnit assert object. 493 * @param {number} [count=1] The number of tests to skip. 494 */ 495 function skipAssert(assert, count) { 496 count || (count = 1); 497 while (count--) { 498 assert.ok(true, 'test skipped'); 499 } 500 } 501 502 /** 503 * Converts `array` to an `arguments` object. 504 * 505 * @private 506 * @param {Array} array The array to convert. 507 * @returns {Object} Returns the converted `arguments` object. 508 */ 509 function toArgs(array) { 510 return (function() { return arguments; }.apply(undefined, array)); 511 } 512 513 /*--------------------------------------------------------------------------*/ 514 515 // Add bizarro values. 516 (function() { 517 if (document || (typeof require != 'function')) { 518 return; 519 } 520 var nativeString = fnToString.call(toString), 521 reToString = /toString/g; 522 523 function createToString(funcName) { 524 return lodashStable.constant(nativeString.replace(reToString, funcName)); 525 } 526 527 // Allow bypassing native checks. 528 setProperty(funcProto, 'toString', function wrapper() { 529 setProperty(funcProto, 'toString', fnToString); 530 var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this); 531 setProperty(funcProto, 'toString', wrapper); 532 return result; 533 }); 534 535 // Add prototype extensions. 536 funcProto._method = noop; 537 538 // Set bad shims. 539 setProperty(Object, 'create', undefined); 540 setProperty(Object, 'getOwnPropertySymbols', undefined); 541 542 var _propertyIsEnumerable = objectProto.propertyIsEnumerable; 543 setProperty(objectProto, 'propertyIsEnumerable', function(key) { 544 return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); 545 }); 546 547 if (Buffer) { 548 defineProperty(root, 'Buffer', { 549 'configurable': true, 550 'enumerable': true, 551 'get': function get() { 552 var caller = get.caller, 553 name = caller ? caller.name : ''; 554 555 if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) { 556 return Buffer; 557 } 558 } 559 }); 560 } 561 if (Map) { 562 setProperty(root, 'Map', (function() { 563 var count = 0; 564 return function() { 565 if (count++) { 566 return new Map; 567 } 568 setProperty(root, 'Map', Map); 569 return {}; 570 }; 571 }())); 572 573 setProperty(root.Map, 'toString', createToString('Map')); 574 } 575 setProperty(root, 'Promise', noop); 576 setProperty(root, 'Set', noop); 577 setProperty(root, 'Symbol', undefined); 578 setProperty(root, 'WeakMap', noop); 579 580 // Fake `WinRTError`. 581 setProperty(root, 'WinRTError', Error); 582 583 // Clear cache so lodash can be reloaded. 584 emptyObject(require.cache); 585 586 // Load lodash and expose it to the bad extensions/shims. 587 lodashBizarro = interopRequire(filePath); 588 root._ = oldDash; 589 590 // Restore built-in methods. 591 setProperty(Object, 'create', create); 592 setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); 593 setProperty(root, 'Buffer', Buffer); 594 595 if (getSymbols) { 596 Object.getOwnPropertySymbols = getSymbols; 597 } else { 598 delete Object.getOwnPropertySymbols; 599 } 600 if (Map) { 601 setProperty(root, 'Map', Map); 602 } else { 603 delete root.Map; 604 } 605 if (Promise) { 606 setProperty(root, 'Promise', Promise); 607 } else { 608 delete root.Promise; 609 } 610 if (Set) { 611 setProperty(root, 'Set', Set); 612 } else { 613 delete root.Set; 614 } 615 if (Symbol) { 616 setProperty(root, 'Symbol', Symbol); 617 } else { 618 delete root.Symbol; 619 } 620 if (WeakMap) { 621 setProperty(root, 'WeakMap', WeakMap); 622 } else { 623 delete root.WeakMap; 624 } 625 delete root.WinRTError; 626 delete funcProto._method; 627 }()); 628 629 // Add other realm values from the `vm` module. 630 lodashStable.attempt(function() { 631 lodashStable.assign(realm, require('vm').runInNewContext([ 632 '(function() {', 633 ' var noop = function() {},', 634 ' root = this;', 635 '', 636 ' var object = {', 637 " 'ArrayBuffer': root.ArrayBuffer,", 638 " 'arguments': (function() { return arguments; }(1, 2, 3)),", 639 " 'array': [1],", 640 " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,", 641 " 'boolean': Object(false),", 642 " 'date': new Date,", 643 " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],", 644 " 'function': noop,", 645 " 'map': root.Map ? new root.Map : undefined,", 646 " 'nan': NaN,", 647 " 'null': null,", 648 " 'number': Object(0),", 649 " 'object': { 'a': 1 },", 650 " 'promise': root.Promise ? Promise.resolve(1) : undefined,", 651 " 'regexp': /x/,", 652 " 'set': root.Set ? new root.Set : undefined,", 653 " 'string': Object('a'),", 654 " 'symbol': root.Symbol ? root.Symbol() : undefined,", 655 " 'undefined': undefined,", 656 " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,", 657 " 'weakSet': root.WeakSet ? new root.WeakSet : undefined", 658 ' };', 659 '', 660 " ['" + arrayViews.join("', '") + "'].forEach(function(type) {", 661 ' var Ctor = root[type]', 662 ' object[type] = Ctor;', 663 ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;', 664 ' });', 665 '', 666 ' return object;', 667 '}());' 668 ].join('\n'))); 669 }); 670 671 // Add other realm values from an iframe. 672 lodashStable.attempt(function() { 673 _._realm = realm; 674 675 var iframe = document.createElement('iframe'); 676 iframe.frameBorder = iframe.height = iframe.width = 0; 677 body.appendChild(iframe); 678 679 var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc; 680 idoc.write([ 681 '<html>', 682 '<body>', 683 '<script>', 684 'var _ = parent._,', 685 ' noop = function() {},', 686 ' root = this;', 687 '', 688 'var object = {', 689 " 'ArrayBuffer': root.ArrayBuffer,", 690 " 'arguments': (function() { return arguments; }(1, 2, 3)),", 691 " 'array': [1],", 692 " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,", 693 " 'boolean': Object(false),", 694 " 'date': new Date,", 695 " 'element': document.body,", 696 " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],", 697 " 'function': noop,", 698 " 'map': root.Map ? new root.Map : undefined,", 699 " 'nan': NaN,", 700 " 'null': null,", 701 " 'number': Object(0),", 702 " 'object': { 'a': 1 },", 703 " 'promise': root.Promise ? Promise.resolve(1) : undefined,", 704 " 'regexp': /x/,", 705 " 'set': root.Set ? new root.Set : undefined,", 706 " 'string': Object('a'),", 707 " 'symbol': root.Symbol ? root.Symbol() : undefined,", 708 " 'undefined': undefined,", 709 " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,", 710 " 'weakSet': root.WeakSet ? new root.WeakSet : undefined", 711 '};', 712 '', 713 "_.each(['" + arrayViews.join("', '") + "'], function(type) {", 714 ' var Ctor = root[type];', 715 ' object[type] = Ctor;', 716 ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;', 717 '});', 718 '', 719 '_.assign(_._realm, object);', 720 '</script>', 721 '</body>', 722 '</html>' 723 ].join('\n')); 724 725 idoc.close(); 726 delete _._realm; 727 }); 728 729 // Add a web worker. 730 lodashStable.attempt(function() { 731 var worker = new Worker('./asset/worker.js?t=' + (+new Date)); 732 worker.addEventListener('message', function(e) { 733 _._VERSION = e.data || ''; 734 }, false); 735 736 worker.postMessage(ui.buildPath); 737 }); 738 739 // Expose internal modules for better code coverage. 740 lodashStable.attempt(function() { 741 var path = require('path'), 742 basePath = path.dirname(filePath); 743 744 if (isModularize && !(amd || isNpm)) { 745 lodashStable.each([ 746 'baseEach', 747 'isIndex', 748 'isIterateeCall', 749 'memoizeCapped' 750 ], function(funcName) { 751 _['_' + funcName] = interopRequire(path.join(basePath, '_' + funcName)); 752 }); 753 } 754 }); 755 756 /*--------------------------------------------------------------------------*/ 757 758 if (params) { 759 console.log('Running lodash tests.'); 760 console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params))); 761 } 762 763 QUnit.module(basename); 764 765 (function() { 766 QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) { 767 assert.expect(1); 768 769 if (amd) { 770 assert.strictEqual((lodashModule || {}).moduleName, 'lodash'); 771 } 772 else { 773 skipAssert(assert); 774 } 775 }); 776 777 QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) { 778 assert.expect(1); 779 780 if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) { 781 assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed'); 782 } else { 783 skipAssert(assert); 784 } 785 }); 786 787 QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) { 788 assert.expect(1); 789 790 if (amd) { 791 assert.strictEqual((underscoreModule || {}).moduleName, 'underscore'); 792 } 793 else { 794 skipAssert(assert); 795 } 796 }); 797 798 QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) { 799 assert.expect(1); 800 801 var done = assert.async(); 802 803 if (Worker) { 804 var limit = 30000 / QUnit.config.asyncRetries, 805 start = +new Date; 806 807 var attempt = function() { 808 var actual = _._VERSION; 809 if ((new Date - start) < limit && typeof actual != 'string') { 810 setTimeout(attempt, 16); 811 return; 812 } 813 assert.strictEqual(actual, _.VERSION); 814 done(); 815 }; 816 817 attempt(); 818 } 819 else { 820 skipAssert(assert); 821 done(); 822 } 823 }); 824 825 QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) { 826 assert.expect(1); 827 828 if (lodashBizarro) { 829 assert.notOk('_method' in lodashBizarro); 830 } 831 else { 832 skipAssert(assert); 833 } 834 }); 835 836 QUnit.test('should avoid non-native built-ins', function(assert) { 837 assert.expect(6); 838 839 function message(lodashMethod, nativeMethod) { 840 return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`'; 841 } 842 843 function Foo() { 844 this.a = 1; 845 } 846 Foo.prototype.b = 2; 847 848 var object = { 'a': 1 }, 849 otherObject = { 'b': 2 }, 850 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object)); 851 852 if (lodashBizarro) { 853 try { 854 var actual = lodashBizarro.create(Foo.prototype); 855 } catch (e) { 856 actual = null; 857 } 858 var label = message('_.create', 'Object.create'); 859 assert.ok(actual instanceof Foo, label); 860 861 try { 862 actual = [ 863 lodashBizarro.difference([object, otherObject], largeArray), 864 lodashBizarro.intersection(largeArray, [object]), 865 lodashBizarro.uniq(largeArray) 866 ]; 867 } catch (e) { 868 actual = null; 869 } 870 label = message('_.difference`, `_.intersection`, and `_.uniq', 'Map'); 871 assert.deepEqual(actual, [[otherObject], [object], [object]], label); 872 873 try { 874 if (Symbol) { 875 object[symbol] = {}; 876 } 877 actual = [ 878 lodashBizarro.clone(object), 879 lodashBizarro.cloneDeep(object) 880 ]; 881 } catch (e) { 882 actual = null; 883 } 884 label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols'); 885 assert.deepEqual(actual, [object, object], label); 886 887 try { 888 // Avoid buggy symbol detection in Babel's `_typeof` helper. 889 var symObject = setProperty(Object(symbol), 'constructor', Object); 890 actual = [ 891 Symbol ? lodashBizarro.clone(symObject) : {}, 892 Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false, 893 Symbol ? lodashBizarro.toString(symObject) : '' 894 ]; 895 } catch (e) { 896 actual = null; 897 } 898 label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol'); 899 assert.deepEqual(actual, [{}, false, ''], label); 900 901 try { 902 var map = new lodashBizarro.memoize.Cache; 903 actual = map.set('a', 1).get('a'); 904 } catch (e) { 905 actual = null; 906 } 907 label = message('_.memoize.Cache', 'Map'); 908 assert.deepEqual(actual, 1, label); 909 910 try { 911 map = new (Map || Object); 912 if (Symbol && Symbol.iterator) { 913 map[Symbol.iterator] = null; 914 } 915 actual = lodashBizarro.toArray(map); 916 } catch (e) { 917 actual = null; 918 } 919 label = message('_.toArray', 'Map'); 920 assert.deepEqual(actual, [], label); 921 } 922 else { 923 skipAssert(assert, 6); 924 } 925 }); 926 }()); 927 928 /*--------------------------------------------------------------------------*/ 929 930 QUnit.module('isIndex'); 931 932 (function() { 933 var func = _._isIndex; 934 935 QUnit.test('should return `true` for indexes', function(assert) { 936 assert.expect(1); 937 938 if (func) { 939 var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]], 940 expected = lodashStable.map(values, stubTrue); 941 942 var actual = lodashStable.map(values, function(args) { 943 return func.apply(undefined, args); 944 }); 945 946 assert.deepEqual(actual, expected); 947 } 948 else { 949 skipAssert(assert); 950 } 951 }); 952 953 QUnit.test('should return `false` for non-indexes', function(assert) { 954 assert.expect(1); 955 956 if (func) { 957 var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]], 958 expected = lodashStable.map(values, stubFalse); 959 960 var actual = lodashStable.map(values, function(args) { 961 return func.apply(undefined, args); 962 }); 963 964 assert.deepEqual(actual, expected); 965 } 966 else { 967 skipAssert(assert); 968 } 969 }); 970 }()); 971 972 /*--------------------------------------------------------------------------*/ 973 974 QUnit.module('isIterateeCall'); 975 976 (function() { 977 var array = [1], 978 func = _._isIterateeCall, 979 object = { 'a': 1 }; 980 981 QUnit.test('should return `true` for iteratee calls', function(assert) { 982 assert.expect(3); 983 984 function Foo() {} 985 Foo.prototype.a = 1; 986 987 if (func) { 988 assert.strictEqual(func(1, 0, array), true); 989 assert.strictEqual(func(1, 'a', object), true); 990 assert.strictEqual(func(1, 'a', new Foo), true); 991 } 992 else { 993 skipAssert(assert, 3); 994 } 995 }); 996 997 QUnit.test('should return `false` for non-iteratee calls', function(assert) { 998 assert.expect(4); 999 1000 if (func) { 1001 assert.strictEqual(func(2, 0, array), false); 1002 assert.strictEqual(func(1, 1.1, array), false); 1003 assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false); 1004 assert.strictEqual(func(1, 'b', object), false); 1005 } 1006 else { 1007 skipAssert(assert, 4); 1008 } 1009 }); 1010 1011 QUnit.test('should work with `NaN` values', function(assert) { 1012 assert.expect(2); 1013 1014 if (func) { 1015 assert.strictEqual(func(NaN, 0, [NaN]), true); 1016 assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true); 1017 } 1018 else { 1019 skipAssert(assert, 2); 1020 } 1021 }); 1022 1023 QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) { 1024 assert.expect(1); 1025 1026 if (func) { 1027 try { 1028 var actual = func(1, { 'toString': null }, [1]); 1029 } catch (e) { 1030 var message = e.message; 1031 } 1032 assert.strictEqual(actual, false, message || ''); 1033 } 1034 else { 1035 skipAssert(assert); 1036 } 1037 }); 1038 }()); 1039 1040 /*--------------------------------------------------------------------------*/ 1041 1042 QUnit.module('map caches'); 1043 1044 (function() { 1045 var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || noop]; 1046 1047 var pairs = lodashStable.map(keys, function(key, index) { 1048 var lastIndex = keys.length - 1; 1049 return [key, keys[lastIndex - index]]; 1050 }); 1051 1052 function createCaches(pairs) { 1053 var largeStack = new mapCaches.Stack(pairs), 1054 length = pairs ? pairs.length : 0; 1055 1056 lodashStable.times(LARGE_ARRAY_SIZE - length, function() { 1057 largeStack.set({}, {}); 1058 }); 1059 1060 return { 1061 'hashes': new mapCaches.Hash(pairs), 1062 'list caches': new mapCaches.ListCache(pairs), 1063 'map caches': new mapCaches.MapCache(pairs), 1064 'stack caches': new mapCaches.Stack(pairs), 1065 'large stacks': largeStack 1066 }; 1067 } 1068 1069 lodashStable.forOwn(createCaches(pairs), function(cache, kind) { 1070 var isLarge = /^large/.test(kind); 1071 1072 QUnit.test('should implement a `Map` interface for ' + kind, function(assert) { 1073 assert.expect(83); 1074 1075 lodashStable.each(keys, function(key, index) { 1076 var value = pairs[index][1]; 1077 1078 assert.deepEqual(cache.get(key), value); 1079 assert.strictEqual(cache.has(key), true); 1080 assert.strictEqual(cache.delete(key), true); 1081 assert.strictEqual(cache.has(key), false); 1082 assert.strictEqual(cache.get(key), undefined); 1083 assert.strictEqual(cache.delete(key), false); 1084 assert.strictEqual(cache.set(key, value), cache); 1085 assert.strictEqual(cache.has(key), true); 1086 }); 1087 1088 assert.strictEqual(cache.size, isLarge ? LARGE_ARRAY_SIZE : keys.length); 1089 assert.strictEqual(cache.clear(), undefined); 1090 assert.ok(lodashStable.every(keys, function(key) { 1091 return !cache.has(key); 1092 })); 1093 }); 1094 }); 1095 1096 lodashStable.forOwn(createCaches(), function(cache, kind) { 1097 QUnit.test('should support changing values of ' + kind, function(assert) { 1098 assert.expect(10); 1099 1100 lodashStable.each(keys, function(key) { 1101 cache.set(key, 1).set(key, 2); 1102 assert.strictEqual(cache.get(key), 2); 1103 }); 1104 }); 1105 }); 1106 }()); 1107 1108 /*--------------------------------------------------------------------------*/ 1109 1110 QUnit.module('lodash constructor'); 1111 1112 (function() { 1113 var values = empties.concat(true, 1, 'a'), 1114 expected = lodashStable.map(values, stubTrue); 1115 1116 QUnit.test('should create a new instance when called without the `new` operator', function(assert) { 1117 assert.expect(1); 1118 1119 if (!isNpm) { 1120 var actual = lodashStable.map(values, function(value) { 1121 return _(value) instanceof _; 1122 }); 1123 1124 assert.deepEqual(actual, expected); 1125 } 1126 else { 1127 skipAssert(assert); 1128 } 1129 }); 1130 1131 QUnit.test('should return the given `lodash` instances', function(assert) { 1132 assert.expect(1); 1133 1134 if (!isNpm) { 1135 var actual = lodashStable.map(values, function(value) { 1136 var wrapped = _(value); 1137 return _(wrapped) === wrapped; 1138 }); 1139 1140 assert.deepEqual(actual, expected); 1141 } 1142 else { 1143 skipAssert(assert); 1144 } 1145 }); 1146 1147 QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) { 1148 assert.expect(1); 1149 1150 if (!isNpm && lodashBizarro) { 1151 var actual = lodashStable.map(values, function(value) { 1152 var wrapped = _(lodashBizarro(value)), 1153 unwrapped = wrapped.value(); 1154 1155 return wrapped instanceof _ && 1156 ((unwrapped === value) || (unwrapped !== unwrapped && value !== value)); 1157 }); 1158 1159 assert.deepEqual(actual, expected); 1160 } 1161 else { 1162 skipAssert(assert); 1163 } 1164 }); 1165 }()); 1166 1167 /*--------------------------------------------------------------------------*/ 1168 1169 QUnit.module('lodash.add'); 1170 1171 (function() { 1172 QUnit.test('should add two numbers', function(assert) { 1173 assert.expect(3); 1174 1175 assert.strictEqual(_.add(6, 4), 10); 1176 assert.strictEqual(_.add(-6, 4), -2); 1177 assert.strictEqual(_.add(-6, -4), -10); 1178 }); 1179 1180 QUnit.test('should not coerce arguments to numbers', function(assert) { 1181 assert.expect(2); 1182 1183 assert.strictEqual(_.add('6', '4'), '64'); 1184 assert.strictEqual(_.add('x', 'y'), 'xy'); 1185 }); 1186 }()); 1187 1188 /*--------------------------------------------------------------------------*/ 1189 1190 QUnit.module('lodash.after'); 1191 1192 (function() { 1193 function after(n, times) { 1194 var count = 0; 1195 lodashStable.times(times, _.after(n, function() { count++; })); 1196 return count; 1197 } 1198 1199 QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) { 1200 assert.expect(4); 1201 1202 assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times'); 1203 assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times'); 1204 assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately'); 1205 assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once'); 1206 }); 1207 1208 QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) { 1209 assert.expect(1); 1210 1211 assert.strictEqual(after(NaN, 1), 1); 1212 }); 1213 1214 QUnit.test('should use `this` binding of function', function(assert) { 1215 assert.expect(2); 1216 1217 var after = _.after(1, function(assert) { return ++this.count; }), 1218 object = { 'after': after, 'count': 0 }; 1219 1220 object.after(); 1221 assert.strictEqual(object.after(), 2); 1222 assert.strictEqual(object.count, 2); 1223 }); 1224 }()); 1225 1226 /*--------------------------------------------------------------------------*/ 1227 1228 QUnit.module('lodash.ary'); 1229 1230 (function() { 1231 function fn(a, b, c) { 1232 return slice.call(arguments); 1233 } 1234 1235 QUnit.test('should cap the number of arguments provided to `func`', function(assert) { 1236 assert.expect(2); 1237 1238 var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1)); 1239 assert.deepEqual(actual, [6, 8, 10]); 1240 1241 var capped = _.ary(fn, 2); 1242 assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']); 1243 }); 1244 1245 QUnit.test('should use `func.length` if `n` is not given', function(assert) { 1246 assert.expect(1); 1247 1248 var capped = _.ary(fn); 1249 assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']); 1250 }); 1251 1252 QUnit.test('should treat a negative `n` as `0`', function(assert) { 1253 assert.expect(1); 1254 1255 var capped = _.ary(fn, -1); 1256 1257 try { 1258 var actual = capped('a'); 1259 } catch (e) {} 1260 1261 assert.deepEqual(actual, []); 1262 }); 1263 1264 QUnit.test('should coerce `n` to an integer', function(assert) { 1265 assert.expect(1); 1266 1267 var values = ['1', 1.6, 'xyz'], 1268 expected = [['a'], ['a'], []]; 1269 1270 var actual = lodashStable.map(values, function(n) { 1271 var capped = _.ary(fn, n); 1272 return capped('a', 'b'); 1273 }); 1274 1275 assert.deepEqual(actual, expected); 1276 }); 1277 1278 QUnit.test('should not force a minimum argument count', function(assert) { 1279 assert.expect(1); 1280 1281 var args = ['a', 'b', 'c'], 1282 capped = _.ary(fn, 3); 1283 1284 var expected = lodashStable.map(args, function(arg, index) { 1285 return args.slice(0, index); 1286 }); 1287 1288 var actual = lodashStable.map(expected, function(array) { 1289 return capped.apply(undefined, array); 1290 }); 1291 1292 assert.deepEqual(actual, expected); 1293 }); 1294 1295 QUnit.test('should use `this` binding of function', function(assert) { 1296 assert.expect(1); 1297 1298 var capped = _.ary(function(a, b) { return this; }, 1), 1299 object = { 'capped': capped }; 1300 1301 assert.strictEqual(object.capped(), object); 1302 }); 1303 1304 QUnit.test('should use the existing `ary` if smaller', function(assert) { 1305 assert.expect(1); 1306 1307 var capped = _.ary(_.ary(fn, 1), 2); 1308 assert.deepEqual(capped('a', 'b', 'c'), ['a']); 1309 }); 1310 1311 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 1312 assert.expect(1); 1313 1314 var funcs = lodashStable.map([fn], _.ary), 1315 actual = funcs[0]('a', 'b', 'c'); 1316 1317 assert.deepEqual(actual, ['a', 'b', 'c']); 1318 }); 1319 1320 QUnit.test('should work when combined with other methods that use metadata', function(assert) { 1321 assert.expect(2); 1322 1323 var array = ['a', 'b', 'c'], 1324 includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2); 1325 1326 assert.strictEqual(includes('b')(array, 2), true); 1327 1328 if (!isNpm) { 1329 includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value(); 1330 assert.strictEqual(includes('b')(array, 2), true); 1331 } 1332 else { 1333 skipAssert(assert); 1334 } 1335 }); 1336 }()); 1337 1338 /*--------------------------------------------------------------------------*/ 1339 1340 QUnit.module('lodash.assignIn'); 1341 1342 (function() { 1343 QUnit.test('should be aliased', function(assert) { 1344 assert.expect(1); 1345 1346 assert.strictEqual(_.extend, _.assignIn); 1347 }); 1348 }()); 1349 1350 /*--------------------------------------------------------------------------*/ 1351 1352 QUnit.module('lodash.assign and lodash.assignIn'); 1353 1354 lodashStable.each(['assign', 'assignIn'], function(methodName) { 1355 var func = _[methodName]; 1356 1357 QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) { 1358 assert.expect(1); 1359 1360 assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 }); 1361 }); 1362 1363 QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) { 1364 assert.expect(2); 1365 1366 var expected = { 'a': 1, 'b': 2, 'c': 3 }; 1367 assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected); 1368 assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected); 1369 }); 1370 1371 QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) { 1372 assert.expect(1); 1373 1374 var expected = { 'a': 3, 'b': 2, 'c': 1 }; 1375 assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); 1376 }); 1377 1378 QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) { 1379 assert.expect(1); 1380 1381 var expected = { 'a': null, 'b': undefined, 'c': null }; 1382 assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); 1383 }); 1384 1385 QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) { 1386 assert.expect(1); 1387 1388 var object = {}; 1389 1390 var descriptor = { 1391 'configurable': true, 1392 'enumerable': true, 1393 'set': function() { throw new Error; } 1394 }; 1395 1396 var source = { 1397 'a': 1, 1398 'b': undefined, 1399 'c': NaN, 1400 'd': undefined, 1401 'constructor': Object, 1402 'toString': lodashStable.constant('source') 1403 }; 1404 1405 defineProperty(object, 'a', lodashStable.assign({}, descriptor, { 1406 'get': stubOne 1407 })); 1408 1409 defineProperty(object, 'b', lodashStable.assign({}, descriptor, { 1410 'get': noop 1411 })); 1412 1413 defineProperty(object, 'c', lodashStable.assign({}, descriptor, { 1414 'get': stubNaN 1415 })); 1416 1417 defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, { 1418 'get': lodashStable.constant(Object) 1419 })); 1420 1421 try { 1422 var actual = func(object, source); 1423 } catch (e) {} 1424 1425 assert.deepEqual(actual, source); 1426 }); 1427 1428 QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) { 1429 assert.expect(1); 1430 1431 var array = [1]; 1432 array[2] = 3; 1433 1434 assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 }); 1435 }); 1436 1437 QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) { 1438 assert.expect(1); 1439 1440 function Foo() {} 1441 Foo.prototype.a = 1; 1442 1443 assert.deepEqual(func({}, Foo.prototype), { 'a': 1 }); 1444 }); 1445 1446 QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) { 1447 assert.expect(1); 1448 1449 assert.deepEqual(func({}, 'a'), { '0': 'a' }); 1450 }); 1451 }); 1452 1453 /*--------------------------------------------------------------------------*/ 1454 1455 QUnit.module('lodash.assignInWith'); 1456 1457 (function() { 1458 QUnit.test('should be aliased', function(assert) { 1459 assert.expect(1); 1460 1461 assert.strictEqual(_.extendWith, _.assignInWith); 1462 }); 1463 }()); 1464 1465 /*--------------------------------------------------------------------------*/ 1466 1467 QUnit.module('lodash.assignWith and lodash.assignInWith'); 1468 1469 lodashStable.each(['assignWith', 'assignInWith'], function(methodName) { 1470 var func = _[methodName]; 1471 1472 QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) { 1473 assert.expect(1); 1474 1475 var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) { 1476 return a === undefined ? b : a; 1477 }); 1478 1479 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); 1480 }); 1481 1482 QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) { 1483 assert.expect(1); 1484 1485 var expected = { 'a': 1 }; 1486 assert.deepEqual(func({}, expected, noop), expected); 1487 }); 1488 }); 1489 1490 /*--------------------------------------------------------------------------*/ 1491 1492 QUnit.module('lodash.at'); 1493 1494 (function() { 1495 var array = ['a', 'b', 'c'], 1496 object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; 1497 1498 QUnit.test('should return the elements corresponding to the specified keys', function(assert) { 1499 assert.expect(1); 1500 1501 var actual = _.at(array, [0, 2]); 1502 assert.deepEqual(actual, ['a', 'c']); 1503 }); 1504 1505 QUnit.test('should return `undefined` for nonexistent keys', function(assert) { 1506 assert.expect(1); 1507 1508 var actual = _.at(array, [2, 4, 0]); 1509 assert.deepEqual(actual, ['c', undefined, 'a']); 1510 }); 1511 1512 QUnit.test('should work with non-index keys on array values', function(assert) { 1513 assert.expect(1); 1514 1515 var values = lodashStable.reject(empties, function(value) { 1516 return (value === 0) || lodashStable.isArray(value); 1517 }).concat(-1, 1.1); 1518 1519 var array = lodashStable.transform(values, function(result, value) { 1520 result[value] = 1; 1521 }, []); 1522 1523 var expected = lodashStable.map(values, stubOne), 1524 actual = _.at(array, values); 1525 1526 assert.deepEqual(actual, expected); 1527 }); 1528 1529 QUnit.test('should return an empty array when no keys are given', function(assert) { 1530 assert.expect(2); 1531 1532 assert.deepEqual(_.at(array), []); 1533 assert.deepEqual(_.at(array, [], []), []); 1534 }); 1535 1536 QUnit.test('should accept multiple key arguments', function(assert) { 1537 assert.expect(1); 1538 1539 var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2); 1540 assert.deepEqual(actual, ['d', 'a', 'c']); 1541 }); 1542 1543 QUnit.test('should work with a falsey `object` when keys are given', function(assert) { 1544 assert.expect(1); 1545 1546 var expected = lodashStable.map(falsey, lodashStable.constant(Array(4))); 1547 1548 var actual = lodashStable.map(falsey, function(object) { 1549 try { 1550 return _.at(object, 0, 1, 'pop', 'push'); 1551 } catch (e) {} 1552 }); 1553 1554 assert.deepEqual(actual, expected); 1555 }); 1556 1557 QUnit.test('should work with an `arguments` object for `object`', function(assert) { 1558 assert.expect(1); 1559 1560 var actual = _.at(args, [2, 0]); 1561 assert.deepEqual(actual, [3, 1]); 1562 }); 1563 1564 QUnit.test('should work with `arguments` object as secondary arguments', function(assert) { 1565 assert.expect(1); 1566 1567 var actual = _.at([1, 2, 3, 4, 5], args); 1568 assert.deepEqual(actual, [2, 3, 4]); 1569 }); 1570 1571 QUnit.test('should work with an object for `object`', function(assert) { 1572 assert.expect(1); 1573 1574 var actual = _.at(object, ['a[0].b.c', 'a[1]']); 1575 assert.deepEqual(actual, [3, 4]); 1576 }); 1577 1578 QUnit.test('should pluck inherited property values', function(assert) { 1579 assert.expect(1); 1580 1581 function Foo() { 1582 this.a = 1; 1583 } 1584 Foo.prototype.b = 2; 1585 1586 var actual = _.at(new Foo, 'b'); 1587 assert.deepEqual(actual, [2]); 1588 }); 1589 1590 QUnit.test('should work in a lazy sequence', function(assert) { 1591 assert.expect(6); 1592 1593 if (!isNpm) { 1594 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE), 1595 smallArray = array; 1596 1597 lodashStable.each([[2], ['2'], [2, 1]], function(paths) { 1598 lodashStable.times(2, function(index) { 1599 var array = index ? largeArray : smallArray, 1600 wrapped = _(array).map(identity).at(paths); 1601 1602 assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths)); 1603 }); 1604 }); 1605 } 1606 else { 1607 skipAssert(assert, 6); 1608 } 1609 }); 1610 1611 QUnit.test('should support shortcut fusion', function(assert) { 1612 assert.expect(8); 1613 1614 if (!isNpm) { 1615 var array = lodashStable.range(LARGE_ARRAY_SIZE), 1616 count = 0, 1617 iteratee = function(value) { count++; return square(value); }, 1618 lastIndex = LARGE_ARRAY_SIZE - 1; 1619 1620 lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) { 1621 count = 0; 1622 var actual = _(array).map(iteratee).at(n).value(), 1623 expected = index < 2 ? 1 : 0; 1624 1625 assert.strictEqual(count, expected); 1626 1627 expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)]; 1628 assert.deepEqual(actual, expected); 1629 }); 1630 } 1631 else { 1632 skipAssert(assert, 8); 1633 } 1634 }); 1635 1636 QUnit.test('work with an object for `object` when chaining', function(assert) { 1637 assert.expect(2); 1638 1639 if (!isNpm) { 1640 var paths = ['a[0].b.c', 'a[1]'], 1641 actual = _(object).map(identity).at(paths).value(); 1642 1643 assert.deepEqual(actual, _.at(_.map(object, identity), paths)); 1644 1645 var indexObject = { '0': 1 }; 1646 actual = _(indexObject).at(0).value(); 1647 assert.deepEqual(actual, _.at(indexObject, 0)); 1648 } 1649 else { 1650 skipAssert(assert, 2); 1651 } 1652 }); 1653 }()); 1654 1655 /*--------------------------------------------------------------------------*/ 1656 1657 QUnit.module('lodash.attempt'); 1658 1659 (function() { 1660 QUnit.test('should return the result of `func`', function(assert) { 1661 assert.expect(1); 1662 1663 assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x'); 1664 }); 1665 1666 QUnit.test('should provide additional arguments to `func`', function(assert) { 1667 assert.expect(1); 1668 1669 var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2); 1670 assert.deepEqual(actual, [1, 2]); 1671 }); 1672 1673 QUnit.test('should return the caught error', function(assert) { 1674 assert.expect(1); 1675 1676 var expected = lodashStable.map(errors, stubTrue); 1677 1678 var actual = lodashStable.map(errors, function(error) { 1679 return _.attempt(function() { throw error; }) === error; 1680 }); 1681 1682 assert.deepEqual(actual, expected); 1683 }); 1684 1685 QUnit.test('should coerce errors to error objects', function(assert) { 1686 assert.expect(1); 1687 1688 var actual = _.attempt(function() { throw 'x'; }); 1689 assert.ok(lodashStable.isEqual(actual, Error('x'))); 1690 }); 1691 1692 QUnit.test('should preserve custom errors', function(assert) { 1693 assert.expect(1); 1694 1695 var actual = _.attempt(function() { throw new CustomError('x'); }); 1696 assert.ok(actual instanceof CustomError); 1697 }); 1698 1699 QUnit.test('should work with an error object from another realm', function(assert) { 1700 assert.expect(1); 1701 1702 if (realm.errors) { 1703 var expected = lodashStable.map(realm.errors, stubTrue); 1704 1705 var actual = lodashStable.map(realm.errors, function(error) { 1706 return _.attempt(function() { throw error; }) === error; 1707 }); 1708 1709 assert.deepEqual(actual, expected); 1710 } 1711 else { 1712 skipAssert(assert); 1713 } 1714 }); 1715 1716 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 1717 assert.expect(1); 1718 1719 if (!isNpm) { 1720 assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x'); 1721 } 1722 else { 1723 skipAssert(assert); 1724 } 1725 }); 1726 1727 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 1728 assert.expect(1); 1729 1730 if (!isNpm) { 1731 assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _); 1732 } 1733 else { 1734 skipAssert(assert); 1735 } 1736 }); 1737 }()); 1738 1739 /*--------------------------------------------------------------------------*/ 1740 1741 QUnit.module('lodash.before'); 1742 1743 (function() { 1744 function before(n, times) { 1745 var count = 0; 1746 lodashStable.times(times, _.before(n, function() { count++; })); 1747 return count; 1748 } 1749 1750 QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) { 1751 assert.expect(4); 1752 1753 assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times'); 1754 assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times'); 1755 assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately'); 1756 assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called'); 1757 }); 1758 1759 QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) { 1760 assert.expect(1); 1761 1762 assert.strictEqual(before(NaN, 1), 0); 1763 }); 1764 1765 QUnit.test('should use `this` binding of function', function(assert) { 1766 assert.expect(2); 1767 1768 var before = _.before(2, function(assert) { return ++this.count; }), 1769 object = { 'before': before, 'count': 0 }; 1770 1771 object.before(); 1772 assert.strictEqual(object.before(), 1); 1773 assert.strictEqual(object.count, 1); 1774 }); 1775 }()); 1776 1777 /*--------------------------------------------------------------------------*/ 1778 1779 QUnit.module('lodash.bind'); 1780 1781 (function() { 1782 function fn() { 1783 var result = [this]; 1784 push.apply(result, arguments); 1785 return result; 1786 } 1787 1788 QUnit.test('should bind a function to an object', function(assert) { 1789 assert.expect(1); 1790 1791 var object = {}, 1792 bound = _.bind(fn, object); 1793 1794 assert.deepEqual(bound('a'), [object, 'a']); 1795 }); 1796 1797 QUnit.test('should accept a falsey `thisArg`', function(assert) { 1798 assert.expect(1); 1799 1800 var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }), 1801 expected = lodashStable.map(values, function(value) { return [value]; }); 1802 1803 var actual = lodashStable.map(values, function(value) { 1804 try { 1805 var bound = _.bind(fn, value); 1806 return bound(); 1807 } catch (e) {} 1808 }); 1809 1810 assert.ok(lodashStable.every(actual, function(value, index) { 1811 return lodashStable.isEqual(value, expected[index]); 1812 })); 1813 }); 1814 1815 QUnit.test('should bind a function to nullish values', function(assert) { 1816 assert.expect(6); 1817 1818 var bound = _.bind(fn, null), 1819 actual = bound('a'); 1820 1821 assert.ok((actual[0] === null) || (actual[0] && actual[0].Array)); 1822 assert.strictEqual(actual[1], 'a'); 1823 1824 lodashStable.times(2, function(index) { 1825 bound = index ? _.bind(fn, undefined) : _.bind(fn); 1826 actual = bound('b'); 1827 1828 assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array)); 1829 assert.strictEqual(actual[1], 'b'); 1830 }); 1831 }); 1832 1833 QUnit.test('should partially apply arguments ', function(assert) { 1834 assert.expect(4); 1835 1836 var object = {}, 1837 bound = _.bind(fn, object, 'a'); 1838 1839 assert.deepEqual(bound(), [object, 'a']); 1840 1841 bound = _.bind(fn, object, 'a'); 1842 assert.deepEqual(bound('b'), [object, 'a', 'b']); 1843 1844 bound = _.bind(fn, object, 'a', 'b'); 1845 assert.deepEqual(bound(), [object, 'a', 'b']); 1846 assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']); 1847 }); 1848 1849 QUnit.test('should support placeholders', function(assert) { 1850 assert.expect(4); 1851 1852 var object = {}, 1853 ph = _.bind.placeholder, 1854 bound = _.bind(fn, object, ph, 'b', ph); 1855 1856 assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']); 1857 assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]); 1858 assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']); 1859 assert.deepEqual(bound(), [object, undefined, 'b', undefined]); 1860 }); 1861 1862 QUnit.test('should use `_.placeholder` when set', function(assert) { 1863 assert.expect(1); 1864 1865 if (!isModularize) { 1866 var _ph = _.placeholder = {}, 1867 ph = _.bind.placeholder, 1868 object = {}, 1869 bound = _.bind(fn, object, _ph, 'b', ph); 1870 1871 assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']); 1872 delete _.placeholder; 1873 } 1874 else { 1875 skipAssert(assert); 1876 } 1877 }); 1878 1879 QUnit.test('should create a function with a `length` of `0`', function(assert) { 1880 assert.expect(2); 1881 1882 var fn = function(a, b, c) {}, 1883 bound = _.bind(fn, {}); 1884 1885 assert.strictEqual(bound.length, 0); 1886 1887 bound = _.bind(fn, {}, 1); 1888 assert.strictEqual(bound.length, 0); 1889 }); 1890 1891 QUnit.test('should ignore binding when called with the `new` operator', function(assert) { 1892 assert.expect(3); 1893 1894 function Foo() { 1895 return this; 1896 } 1897 1898 var bound = _.bind(Foo, { 'a': 1 }), 1899 newBound = new bound; 1900 1901 assert.strictEqual(bound().a, 1); 1902 assert.strictEqual(newBound.a, undefined); 1903 assert.ok(newBound instanceof Foo); 1904 }); 1905 1906 QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) { 1907 assert.expect(1); 1908 1909 function Foo() { 1910 return this; 1911 } 1912 1913 function Bar() {} 1914 1915 var thisArg = { 'a': 1 }, 1916 boundFoo = _.bind(Foo, thisArg), 1917 boundBar = _.bind(Bar, thisArg), 1918 count = 9, 1919 expected = lodashStable.times(count, lodashStable.constant([undefined, undefined])); 1920 1921 var actual = lodashStable.times(count, function(index) { 1922 try { 1923 switch (index) { 1924 case 0: return [new boundFoo().a, new boundBar().a]; 1925 case 1: return [new boundFoo(1).a, new boundBar(1).a]; 1926 case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a]; 1927 case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a]; 1928 case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a]; 1929 case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a]; 1930 case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a]; 1931 case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a]; 1932 case 8: return [new boundFoo(1, 2, 3, 4, 5, 6, 7, 8).a, new boundBar(1, 2, 3, 4, 5, 6, 7, 8).a]; 1933 } 1934 } catch (e) {} 1935 }); 1936 1937 assert.deepEqual(actual, expected); 1938 }); 1939 1940 QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) { 1941 assert.expect(2); 1942 1943 function Foo(value) { 1944 return value && object; 1945 } 1946 1947 var bound = _.bind(Foo), 1948 object = {}; 1949 1950 assert.ok(new bound instanceof Foo); 1951 assert.strictEqual(new bound(true), object); 1952 }); 1953 1954 QUnit.test('should append array arguments to partially applied arguments', function(assert) { 1955 assert.expect(1); 1956 1957 var object = {}, 1958 bound = _.bind(fn, object, 'a'); 1959 1960 assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']); 1961 }); 1962 1963 QUnit.test('should not rebind functions', function(assert) { 1964 assert.expect(3); 1965 1966 var object1 = {}, 1967 object2 = {}, 1968 object3 = {}; 1969 1970 var bound1 = _.bind(fn, object1), 1971 bound2 = _.bind(bound1, object2, 'a'), 1972 bound3 = _.bind(bound1, object3, 'b'); 1973 1974 assert.deepEqual(bound1(), [object1]); 1975 assert.deepEqual(bound2(), [object1, 'a']); 1976 assert.deepEqual(bound3(), [object1, 'b']); 1977 }); 1978 1979 QUnit.test('should not error when instantiating bound built-ins', function(assert) { 1980 assert.expect(2); 1981 1982 var Ctor = _.bind(Date, null), 1983 expected = new Date(2012, 4, 23, 0, 0, 0, 0); 1984 1985 try { 1986 var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0); 1987 } catch (e) {} 1988 1989 assert.deepEqual(actual, expected); 1990 1991 Ctor = _.bind(Date, null, 2012, 4, 23); 1992 1993 try { 1994 actual = new Ctor(0, 0, 0, 0); 1995 } catch (e) {} 1996 1997 assert.deepEqual(actual, expected); 1998 }); 1999 2000 QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) { 2001 assert.expect(1); 2002 2003 var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}'); 2004 2005 if (typeof createCtor == 'function') { 2006 var bound = _.bind(createCtor()), 2007 count = 8, 2008 expected = lodashStable.times(count, stubTrue); 2009 2010 var actual = lodashStable.times(count, function(index) { 2011 try { 2012 switch (index) { 2013 case 0: return !!(new bound); 2014 case 1: return !!(new bound(1)); 2015 case 2: return !!(new bound(1, 2)); 2016 case 3: return !!(new bound(1, 2, 3)); 2017 case 4: return !!(new bound(1, 2, 3, 4)); 2018 case 5: return !!(new bound(1, 2, 3, 4, 5)); 2019 case 6: return !!(new bound(1, 2, 3, 4, 5, 6)); 2020 case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7)); 2021 } 2022 } catch (e) {} 2023 }); 2024 2025 assert.deepEqual(actual, expected); 2026 } 2027 else { 2028 skipAssert(assert); 2029 } 2030 }); 2031 2032 QUnit.test('should return a wrapped value when chaining', function(assert) { 2033 assert.expect(2); 2034 2035 if (!isNpm) { 2036 var object = {}, 2037 bound = _(fn).bind({}, 'a', 'b'); 2038 2039 assert.ok(bound instanceof _); 2040 2041 var actual = bound.value()('c'); 2042 assert.deepEqual(actual, [object, 'a', 'b', 'c']); 2043 } 2044 else { 2045 skipAssert(assert, 2); 2046 } 2047 }); 2048 }()); 2049 2050 /*--------------------------------------------------------------------------*/ 2051 2052 QUnit.module('lodash.bindAll'); 2053 2054 (function() { 2055 var args = toArgs(['a']); 2056 2057 var source = { 2058 '_n0': -2, 2059 '_p0': -1, 2060 '_a': 1, 2061 '_b': 2, 2062 '_c': 3, 2063 '_d': 4, 2064 '-0': function() { return this._n0; }, 2065 '0': function() { return this._p0; }, 2066 'a': function() { return this._a; }, 2067 'b': function() { return this._b; }, 2068 'c': function() { return this._c; }, 2069 'd': function() { return this._d; } 2070 }; 2071 2072 QUnit.test('should accept individual method names', function(assert) { 2073 assert.expect(1); 2074 2075 var object = lodashStable.cloneDeep(source); 2076 _.bindAll(object, 'a', 'b'); 2077 2078 var actual = lodashStable.map(['a', 'b', 'c'], function(key) { 2079 return object[key].call({}); 2080 }); 2081 2082 assert.deepEqual(actual, [1, 2, undefined]); 2083 }); 2084 2085 QUnit.test('should accept arrays of method names', function(assert) { 2086 assert.expect(1); 2087 2088 var object = lodashStable.cloneDeep(source); 2089 _.bindAll(object, ['a', 'b'], ['c']); 2090 2091 var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) { 2092 return object[key].call({}); 2093 }); 2094 2095 assert.deepEqual(actual, [1, 2, 3, undefined]); 2096 }); 2097 2098 QUnit.test('should preserve the sign of `0`', function(assert) { 2099 assert.expect(1); 2100 2101 var props = [-0, Object(-0), 0, Object(0)]; 2102 2103 var actual = lodashStable.map(props, function(key) { 2104 var object = lodashStable.cloneDeep(source); 2105 _.bindAll(object, key); 2106 return object[lodashStable.toString(key)].call({}); 2107 }); 2108 2109 assert.deepEqual(actual, [-2, -2, -1, -1]); 2110 }); 2111 2112 QUnit.test('should work with an array `object`', function(assert) { 2113 assert.expect(1); 2114 2115 var array = ['push', 'pop']; 2116 _.bindAll(array); 2117 assert.strictEqual(array.pop, arrayProto.pop); 2118 }); 2119 2120 QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) { 2121 assert.expect(1); 2122 2123 var object = lodashStable.cloneDeep(source); 2124 _.bindAll(object, args); 2125 2126 var actual = lodashStable.map(args, function(key) { 2127 return object[key].call({}); 2128 }); 2129 2130 assert.deepEqual(actual, [1]); 2131 }); 2132 }()); 2133 2134 /*--------------------------------------------------------------------------*/ 2135 2136 QUnit.module('lodash.bindKey'); 2137 2138 (function() { 2139 QUnit.test('should work when the target function is overwritten', function(assert) { 2140 assert.expect(2); 2141 2142 var object = { 2143 'user': 'fred', 2144 'greet': function(greeting) { 2145 return this.user + ' says: ' + greeting; 2146 } 2147 }; 2148 2149 var bound = _.bindKey(object, 'greet', 'hi'); 2150 assert.strictEqual(bound(), 'fred says: hi'); 2151 2152 object.greet = function(greeting) { 2153 return this.user + ' says: ' + greeting + '!'; 2154 }; 2155 2156 assert.strictEqual(bound(), 'fred says: hi!'); 2157 }); 2158 2159 QUnit.test('should support placeholders', function(assert) { 2160 assert.expect(4); 2161 2162 var object = { 2163 'fn': function() { 2164 return slice.call(arguments); 2165 } 2166 }; 2167 2168 var ph = _.bindKey.placeholder, 2169 bound = _.bindKey(object, 'fn', ph, 'b', ph); 2170 2171 assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']); 2172 assert.deepEqual(bound('a'), ['a', 'b', undefined]); 2173 assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']); 2174 assert.deepEqual(bound(), [undefined, 'b', undefined]); 2175 }); 2176 2177 QUnit.test('should use `_.placeholder` when set', function(assert) { 2178 assert.expect(1); 2179 2180 if (!isModularize) { 2181 var object = { 2182 'fn': function() { 2183 return slice.call(arguments); 2184 } 2185 }; 2186 2187 var _ph = _.placeholder = {}, 2188 ph = _.bindKey.placeholder, 2189 bound = _.bindKey(object, 'fn', _ph, 'b', ph); 2190 2191 assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']); 2192 delete _.placeholder; 2193 } 2194 else { 2195 skipAssert(assert); 2196 } 2197 }); 2198 2199 QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) { 2200 assert.expect(2); 2201 2202 function Foo(value) { 2203 return value && object; 2204 } 2205 2206 var object = { 'Foo': Foo }, 2207 bound = _.bindKey(object, 'Foo'); 2208 2209 assert.ok(new bound instanceof Foo); 2210 assert.strictEqual(new bound(true), object); 2211 }); 2212 }()); 2213 2214 /*--------------------------------------------------------------------------*/ 2215 2216 QUnit.module('case methods'); 2217 2218 lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) { 2219 var methodName = caseName + 'Case', 2220 func = _[methodName]; 2221 2222 var strings = [ 2223 'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar', 2224 'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__' 2225 ]; 2226 2227 var converted = (function() { 2228 switch (caseName) { 2229 case 'camel': return 'fooBar'; 2230 case 'kebab': return 'foo-bar'; 2231 case 'lower': return 'foo bar'; 2232 case 'snake': return 'foo_bar'; 2233 case 'start': return 'Foo Bar'; 2234 case 'upper': return 'FOO BAR'; 2235 } 2236 }()); 2237 2238 QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) { 2239 assert.expect(1); 2240 2241 var actual = lodashStable.map(strings, function(string) { 2242 var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted; 2243 return func(string) === expected; 2244 }); 2245 2246 assert.deepEqual(actual, lodashStable.map(strings, stubTrue)); 2247 }); 2248 2249 QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) { 2250 assert.expect(1); 2251 2252 var actual = lodashStable.map(strings, function(string) { 2253 var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted; 2254 return func(func(string)) === expected; 2255 }); 2256 2257 assert.deepEqual(actual, lodashStable.map(strings, stubTrue)); 2258 }); 2259 2260 QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) { 2261 assert.expect(1); 2262 2263 var actual = lodashStable.map(burredLetters, function(burred, index) { 2264 var letter = deburredLetters[index].replace(/['\u2019]/g, ''); 2265 if (caseName == 'start') { 2266 letter = letter == 'IJ' ? letter : lodashStable.capitalize(letter); 2267 } else if (caseName == 'upper') { 2268 letter = letter.toUpperCase(); 2269 } else { 2270 letter = letter.toLowerCase(); 2271 } 2272 return func(burred) === letter; 2273 }); 2274 2275 assert.deepEqual(actual, lodashStable.map(burredLetters, stubTrue)); 2276 }); 2277 2278 QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) { 2279 assert.expect(2); 2280 2281 var postfixes = ['d', 'll', 'm', 're', 's', 't', 've']; 2282 2283 lodashStable.each(["'", '\u2019'], function(apos) { 2284 var actual = lodashStable.map(postfixes, function(postfix) { 2285 return func('a b' + apos + postfix + ' c'); 2286 }); 2287 2288 var expected = lodashStable.map(postfixes, function(postfix) { 2289 switch (caseName) { 2290 case 'camel': return 'aB' + postfix + 'C'; 2291 case 'kebab': return 'a-b' + postfix + '-c'; 2292 case 'lower': return 'a b' + postfix + ' c'; 2293 case 'snake': return 'a_b' + postfix + '_c'; 2294 case 'start': return 'A B' + postfix + ' C'; 2295 case 'upper': return 'A B' + postfix.toUpperCase() + ' C'; 2296 } 2297 }); 2298 2299 assert.deepEqual(actual, expected); 2300 }); 2301 }); 2302 2303 QUnit.test('`_.' + methodName + '` should remove Latin mathematical operators', function(assert) { 2304 assert.expect(1); 2305 2306 var actual = lodashStable.map(['\xd7', '\xf7'], func); 2307 assert.deepEqual(actual, ['', '']); 2308 }); 2309 2310 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) { 2311 assert.expect(2); 2312 2313 var string = 'foo bar'; 2314 assert.strictEqual(func(Object(string)), converted); 2315 assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted); 2316 }); 2317 2318 QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) { 2319 assert.expect(1); 2320 2321 if (!isNpm) { 2322 assert.strictEqual(_('foo bar')[methodName](), converted); 2323 } 2324 else { 2325 skipAssert(assert); 2326 } 2327 }); 2328 2329 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 2330 assert.expect(1); 2331 2332 if (!isNpm) { 2333 assert.ok(_('foo bar').chain()[methodName]() instanceof _); 2334 } 2335 else { 2336 skipAssert(assert); 2337 } 2338 }); 2339 }); 2340 2341 (function() { 2342 QUnit.test('should get the original value after cycling through all case methods', function(assert) { 2343 assert.expect(1); 2344 2345 var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase]; 2346 2347 var actual = lodashStable.reduce(funcs, function(result, func) { 2348 return func(result); 2349 }, 'enable 6h format'); 2350 2351 assert.strictEqual(actual, 'enable6HFormat'); 2352 }); 2353 }()); 2354 2355 /*--------------------------------------------------------------------------*/ 2356 2357 QUnit.module('lodash.camelCase'); 2358 2359 (function() { 2360 QUnit.test('should work with numbers', function(assert) { 2361 assert.expect(6); 2362 2363 assert.strictEqual(_.camelCase('12 feet'), '12Feet'); 2364 assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat'); 2365 assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat'); 2366 assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit'); 2367 assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles'); 2368 assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request'); 2369 }); 2370 2371 QUnit.test('should handle acronyms', function(assert) { 2372 assert.expect(6); 2373 2374 lodashStable.each(['safe HTML', 'safeHTML'], function(string) { 2375 assert.strictEqual(_.camelCase(string), 'safeHtml'); 2376 }); 2377 2378 lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) { 2379 assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities'); 2380 }); 2381 2382 lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) { 2383 assert.strictEqual(_.camelCase(string), 'xmlHttpRequest'); 2384 }); 2385 }); 2386 }()); 2387 2388 /*--------------------------------------------------------------------------*/ 2389 2390 QUnit.module('lodash.capitalize'); 2391 2392 (function() { 2393 QUnit.test('should capitalize the first character of a string', function(assert) { 2394 assert.expect(3); 2395 2396 assert.strictEqual(_.capitalize('fred'), 'Fred'); 2397 assert.strictEqual(_.capitalize('Fred'), 'Fred'); 2398 assert.strictEqual(_.capitalize(' fred'), ' fred'); 2399 }); 2400 }()); 2401 2402 /*--------------------------------------------------------------------------*/ 2403 2404 QUnit.module('lodash.castArray'); 2405 2406 (function() { 2407 QUnit.test('should wrap non-array items in an array', function(assert) { 2408 assert.expect(1); 2409 2410 var values = falsey.concat(true, 1, 'a', { 'a': 1 }), 2411 expected = lodashStable.map(values, function(value) { return [value]; }), 2412 actual = lodashStable.map(values, _.castArray); 2413 2414 assert.deepEqual(actual, expected); 2415 }); 2416 2417 QUnit.test('should return array values by reference', function(assert) { 2418 assert.expect(1); 2419 2420 var array = [1]; 2421 assert.strictEqual(_.castArray(array), array); 2422 }); 2423 2424 QUnit.test('should return an empty array when no arguments are given', function(assert) { 2425 assert.expect(1); 2426 2427 assert.deepEqual(_.castArray(), []); 2428 }); 2429 }()); 2430 2431 /*--------------------------------------------------------------------------*/ 2432 2433 QUnit.module('lodash.chain'); 2434 2435 (function() { 2436 QUnit.test('should return a wrapped value', function(assert) { 2437 assert.expect(1); 2438 2439 if (!isNpm) { 2440 var actual = _.chain({ 'a': 0 }); 2441 assert.ok(actual instanceof _); 2442 } 2443 else { 2444 skipAssert(assert); 2445 } 2446 }); 2447 2448 QUnit.test('should return existing wrapped values', function(assert) { 2449 assert.expect(2); 2450 2451 if (!isNpm) { 2452 var wrapped = _({ 'a': 0 }); 2453 assert.strictEqual(_.chain(wrapped), wrapped); 2454 assert.strictEqual(wrapped.chain(), wrapped); 2455 } 2456 else { 2457 skipAssert(assert, 2); 2458 } 2459 }); 2460 2461 QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) { 2462 assert.expect(6); 2463 2464 if (!isNpm) { 2465 var array = ['c', 'b', 'a']; 2466 2467 assert.ok(_.chain(array).head() instanceof _); 2468 assert.ok(_(array).chain().head() instanceof _); 2469 2470 assert.ok(_.chain(array).isArray() instanceof _); 2471 assert.ok(_(array).chain().isArray() instanceof _); 2472 2473 assert.ok(_.chain(array).sortBy().head() instanceof _); 2474 assert.ok(_(array).chain().sortBy().head() instanceof _); 2475 } 2476 else { 2477 skipAssert(assert, 6); 2478 } 2479 }); 2480 2481 QUnit.test('should chain multiple methods', function(assert) { 2482 assert.expect(6); 2483 2484 if (!isNpm) { 2485 lodashStable.times(2, function(index) { 2486 var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'], 2487 expected = { ' ': 9, 'e': 14, 'f': 2, 'g': 1, 'h': 2, 'i': 4, 'l': 2, 'n': 6, 'o': 3, 'r': 2, 's': 2, 't': 5, 'u': 1, 'v': 4, 'w': 2, 'x': 1 }, 2488 wrapped = index ? _(array).chain() : _.chain(array); 2489 2490 var actual = wrapped 2491 .chain() 2492 .map(function(value) { return value.split(''); }) 2493 .flatten() 2494 .reduce(function(object, chr) { 2495 object[chr] || (object[chr] = 0); 2496 object[chr]++; 2497 return object; 2498 }, {}) 2499 .value(); 2500 2501 assert.deepEqual(actual, expected); 2502 2503 array = [1, 2, 3, 4, 5, 6]; 2504 wrapped = index ? _(array).chain() : _.chain(array); 2505 actual = wrapped 2506 .chain() 2507 .filter(function(n) { return n % 2 != 0; }) 2508 .reject(function(n) { return n % 3 == 0; }) 2509 .sortBy(function(n) { return -n; }) 2510 .value(); 2511 2512 assert.deepEqual(actual, [5, 1]); 2513 2514 array = [3, 4]; 2515 wrapped = index ? _(array).chain() : _.chain(array); 2516 actual = wrapped 2517 .reverse() 2518 .concat([2, 1]) 2519 .unshift(5) 2520 .tap(function(value) { value.pop(); }) 2521 .map(square) 2522 .value(); 2523 2524 assert.deepEqual(actual, [25, 16, 9, 4]); 2525 }); 2526 } 2527 else { 2528 skipAssert(assert, 6); 2529 } 2530 }); 2531 }()); 2532 2533 /*--------------------------------------------------------------------------*/ 2534 2535 QUnit.module('lodash.chunk'); 2536 2537 (function() { 2538 var array = [0, 1, 2, 3, 4, 5]; 2539 2540 QUnit.test('should return chunked arrays', function(assert) { 2541 assert.expect(1); 2542 2543 var actual = _.chunk(array, 3); 2544 assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]); 2545 }); 2546 2547 QUnit.test('should return the last chunk as remaining elements', function(assert) { 2548 assert.expect(1); 2549 2550 var actual = _.chunk(array, 4); 2551 assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]); 2552 }); 2553 2554 QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) { 2555 assert.expect(1); 2556 2557 var expected = lodashStable.map(falsey, function(value) { 2558 return value === undefined ? [[0], [1], [2], [3], [4], [5]] : []; 2559 }); 2560 2561 var actual = lodashStable.map(falsey, function(size, index) { 2562 return index ? _.chunk(array, size) : _.chunk(array); 2563 }); 2564 2565 assert.deepEqual(actual, expected); 2566 }); 2567 2568 QUnit.test('should ensure the minimum `size` is `0`', function(assert) { 2569 assert.expect(1); 2570 2571 var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity), 2572 expected = lodashStable.map(values, stubArray); 2573 2574 var actual = lodashStable.map(values, function(n) { 2575 return _.chunk(array, n); 2576 }); 2577 2578 assert.deepEqual(actual, expected); 2579 }); 2580 2581 QUnit.test('should coerce `size` to an integer', function(assert) { 2582 assert.expect(1); 2583 2584 assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]); 2585 }); 2586 2587 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 2588 assert.expect(1); 2589 2590 var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk); 2591 assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]); 2592 }); 2593 }()); 2594 2595 /*--------------------------------------------------------------------------*/ 2596 2597 QUnit.module('lodash.clamp'); 2598 2599 (function() { 2600 QUnit.test('should work with a `max`', function(assert) { 2601 assert.expect(2); 2602 2603 assert.strictEqual(_.clamp(5, 3), 3); 2604 assert.strictEqual(_.clamp(1, 3), 1); 2605 }); 2606 2607 QUnit.test('should clamp negative numbers', function(assert) { 2608 assert.expect(3); 2609 2610 assert.strictEqual(_.clamp(-10, -5, 5), -5); 2611 assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5); 2612 assert.strictEqual(_.clamp(-Infinity, -5, 5), -5); 2613 }); 2614 2615 QUnit.test('should clamp positive numbers', function(assert) { 2616 assert.expect(3); 2617 2618 assert.strictEqual(_.clamp(10, -5, 5), 5); 2619 assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4); 2620 assert.strictEqual(_.clamp(Infinity, -5, 5), 5); 2621 }); 2622 2623 QUnit.test('should not alter negative numbers in range', function(assert) { 2624 assert.expect(3); 2625 2626 assert.strictEqual(_.clamp(-4, -5, 5), -4); 2627 assert.strictEqual(_.clamp(-5, -5, 5), -5); 2628 assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5); 2629 }); 2630 2631 QUnit.test('should not alter positive numbers in range', function(assert) { 2632 assert.expect(3); 2633 2634 assert.strictEqual(_.clamp(4, -5, 5), 4); 2635 assert.strictEqual(_.clamp(5, -5, 5), 5); 2636 assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5); 2637 }); 2638 2639 QUnit.test('should not alter `0` in range', function(assert) { 2640 assert.expect(1); 2641 2642 assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity); 2643 }); 2644 2645 QUnit.test('should clamp to `0`', function(assert) { 2646 assert.expect(1); 2647 2648 assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity); 2649 }); 2650 2651 QUnit.test('should not alter `-0` in range', function(assert) { 2652 assert.expect(1); 2653 2654 assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity); 2655 }); 2656 2657 QUnit.test('should clamp to `-0`', function(assert) { 2658 assert.expect(1); 2659 2660 assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity); 2661 }); 2662 2663 QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) { 2664 assert.expect(1); 2665 2666 assert.deepEqual(_.clamp(NaN, -5, 5), NaN); 2667 }); 2668 2669 QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) { 2670 assert.expect(2); 2671 2672 assert.deepEqual(_.clamp(1, -5, NaN), 0); 2673 assert.deepEqual(_.clamp(-1, NaN, 5), 0); 2674 }); 2675 }()); 2676 2677 /*--------------------------------------------------------------------------*/ 2678 2679 QUnit.module('clone methods'); 2680 2681 (function() { 2682 function Foo() { 2683 this.a = 1; 2684 } 2685 Foo.prototype.b = 1; 2686 Foo.c = function() {}; 2687 2688 if (Map) { 2689 var map = new Map; 2690 map.set('a', 1); 2691 map.set('b', 2); 2692 } 2693 if (Set) { 2694 var set = new Set; 2695 set.add(1); 2696 set.add(2); 2697 } 2698 var objects = { 2699 '`arguments` objects': arguments, 2700 'arrays': ['a', ''], 2701 'array-like objects': { '0': 'a', 'length': 1 }, 2702 'booleans': false, 2703 'boolean objects': Object(false), 2704 'date objects': new Date, 2705 'Foo instances': new Foo, 2706 'objects': { 'a': 0, 'b': 1, 'c': 2 }, 2707 'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } }, 2708 'objects from another document': realm.object || {}, 2709 'maps': map, 2710 'null values': null, 2711 'numbers': 0, 2712 'number objects': Object(0), 2713 'regexes': /a/gim, 2714 'sets': set, 2715 'strings': 'a', 2716 'string objects': Object('a'), 2717 'undefined values': undefined 2718 }; 2719 2720 objects.arrays.length = 3; 2721 2722 var uncloneable = { 2723 'DOM elements': body, 2724 'functions': Foo, 2725 'async functions': asyncFunc, 2726 'generator functions': genFunc, 2727 'the `Proxy` constructor': Proxy 2728 }; 2729 2730 lodashStable.each(errors, function(error) { 2731 uncloneable[error.name + 's'] = error; 2732 }); 2733 2734 QUnit.test('`_.clone` should perform a shallow clone', function(assert) { 2735 assert.expect(2); 2736 2737 var array = [{ 'a': 0 }, { 'b': 1 }], 2738 actual = _.clone(array); 2739 2740 assert.deepEqual(actual, array); 2741 assert.ok(actual !== array && actual[0] === array[0]); 2742 }); 2743 2744 QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) { 2745 assert.expect(1); 2746 2747 var object = { 2748 'foo': { 'b': { 'c': { 'd': {} } } }, 2749 'bar': {} 2750 }; 2751 2752 object.foo.b.c.d = object; 2753 object.bar.b = object.foo.b; 2754 2755 var actual = _.cloneDeep(object); 2756 assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object); 2757 }); 2758 2759 QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) { 2760 assert.expect(2); 2761 2762 var cyclical = {}; 2763 lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) { 2764 cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical]; 2765 }); 2766 2767 var clone = _.cloneDeep(cyclical), 2768 actual = clone['v' + LARGE_ARRAY_SIZE][0]; 2769 2770 assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]); 2771 assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]); 2772 }); 2773 2774 QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) { 2775 assert.expect(1); 2776 2777 var actual; 2778 2779 _.cloneDeepWith({ 'a': 1 }, function() { 2780 actual = _.last(arguments); 2781 }); 2782 2783 assert.ok(isNpm 2784 ? actual.constructor.name == 'Stack' 2785 : actual instanceof mapCaches.Stack 2786 ); 2787 }); 2788 2789 lodashStable.each(['clone', 'cloneDeep'], function(methodName) { 2790 var func = _[methodName], 2791 isDeep = methodName == 'cloneDeep'; 2792 2793 lodashStable.forOwn(objects, function(object, kind) { 2794 QUnit.test('`_.' + methodName + '` should clone ' + kind, function(assert) { 2795 assert.expect(2); 2796 2797 var actual = func(object); 2798 assert.ok(lodashStable.isEqual(actual, object)); 2799 2800 if (lodashStable.isObject(object)) { 2801 assert.notStrictEqual(actual, object); 2802 } else { 2803 assert.strictEqual(actual, object); 2804 } 2805 }); 2806 }); 2807 2808 QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) { 2809 assert.expect(2); 2810 2811 if (ArrayBuffer) { 2812 var actual = func(arrayBuffer); 2813 assert.strictEqual(actual.byteLength, arrayBuffer.byteLength); 2814 assert.notStrictEqual(actual, arrayBuffer); 2815 } 2816 else { 2817 skipAssert(assert, 2); 2818 } 2819 }); 2820 2821 QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) { 2822 assert.expect(4); 2823 2824 if (Buffer) { 2825 var buffer = new Buffer([1, 2]), 2826 actual = func(buffer); 2827 2828 assert.strictEqual(actual.byteLength, buffer.byteLength); 2829 assert.strictEqual(actual.inspect(), buffer.inspect()); 2830 assert.notStrictEqual(actual, buffer); 2831 2832 buffer[0] = 2; 2833 assert.strictEqual(actual[0], isDeep ? 2 : 1); 2834 } 2835 else { 2836 skipAssert(assert, 4); 2837 } 2838 }); 2839 2840 QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) { 2841 assert.expect(2); 2842 2843 var array = /c/.exec('abcde'), 2844 actual = func(array); 2845 2846 assert.strictEqual(actual.index, 2); 2847 assert.strictEqual(actual.input, 'abcde'); 2848 }); 2849 2850 QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) { 2851 assert.expect(1); 2852 2853 var regexp = /c/g; 2854 regexp.exec('abcde'); 2855 2856 assert.strictEqual(func(regexp).lastIndex, 3); 2857 }); 2858 2859 QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) { 2860 assert.expect(1); 2861 2862 var values = lodashStable.map([false, true, 1, 'a'], function(value) { 2863 var object = Object(value); 2864 object.a = 1; 2865 return object; 2866 }); 2867 2868 var expected = lodashStable.map(values, stubTrue); 2869 2870 var actual = lodashStable.map(values, function(value) { 2871 return func(value).a === 1; 2872 }); 2873 2874 assert.deepEqual(actual, expected); 2875 }); 2876 2877 QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) { 2878 assert.expect(2); 2879 2880 var actual = func(Foo.prototype); 2881 2882 assert.notOk(actual instanceof Foo); 2883 assert.deepEqual(actual, { 'b': 1 }); 2884 }); 2885 2886 QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) { 2887 assert.expect(1); 2888 2889 assert.ok(func(new Foo) instanceof Foo); 2890 }); 2891 2892 QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) { 2893 assert.expect(1); 2894 2895 Foo.prototype.constructor = Object; 2896 assert.ok(func(new Foo) instanceof Foo); 2897 Foo.prototype.constructor = Foo; 2898 }); 2899 2900 QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) { 2901 assert.expect(1); 2902 2903 Foo.prototype.constructor = null; 2904 assert.notOk(func(new Foo) instanceof Foo); 2905 Foo.prototype.constructor = Foo; 2906 }); 2907 2908 QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) { 2909 assert.expect(2); 2910 2911 var object = { 2912 'constructor': objectProto.constructor, 2913 'hasOwnProperty': objectProto.hasOwnProperty, 2914 'isPrototypeOf': objectProto.isPrototypeOf, 2915 'propertyIsEnumerable': objectProto.propertyIsEnumerable, 2916 'toLocaleString': objectProto.toLocaleString, 2917 'toString': objectProto.toString, 2918 'valueOf': objectProto.valueOf 2919 }; 2920 2921 var actual = func(object); 2922 2923 assert.deepEqual(actual, object); 2924 assert.notStrictEqual(actual, object); 2925 }); 2926 2927 QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) { 2928 assert.expect(7); 2929 2930 function Foo() { 2931 this[symbol] = { 'c': 1 }; 2932 } 2933 2934 if (Symbol) { 2935 var symbol2 = Symbol('b'); 2936 Foo.prototype[symbol2] = 2; 2937 2938 var symbol3 = Symbol('c'); 2939 defineProperty(Foo.prototype, symbol3, { 2940 'configurable': true, 2941 'enumerable': false, 2942 'writable': true, 2943 'value': 3 2944 }); 2945 2946 var object = { 'a': { 'b': new Foo } }; 2947 object[symbol] = { 'b': 1 }; 2948 2949 var actual = func(object); 2950 if (isDeep) { 2951 assert.notStrictEqual(actual[symbol], object[symbol]); 2952 assert.notStrictEqual(actual.a, object.a); 2953 } else { 2954 assert.strictEqual(actual[symbol], object[symbol]); 2955 assert.strictEqual(actual.a, object.a); 2956 } 2957 assert.deepEqual(actual[symbol], object[symbol]); 2958 assert.deepEqual(getSymbols(actual.a.b), [symbol]); 2959 assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]); 2960 assert.deepEqual(actual.a.b[symbol2], object.a.b[symbol2]); 2961 assert.deepEqual(actual.a.b[symbol3], object.a.b[symbol3]); 2962 } 2963 else { 2964 skipAssert(assert, 7); 2965 } 2966 }); 2967 2968 QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) { 2969 assert.expect(4); 2970 2971 if (Symbol) { 2972 assert.strictEqual(func(symbol), symbol); 2973 2974 var object = Object(symbol), 2975 actual = func(object); 2976 2977 assert.strictEqual(typeof actual, 'object'); 2978 assert.strictEqual(typeof actual.valueOf(), 'symbol'); 2979 assert.notStrictEqual(actual, object); 2980 } 2981 else { 2982 skipAssert(assert, 4); 2983 } 2984 }); 2985 2986 QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) { 2987 assert.expect(1); 2988 2989 if (Symbol) { 2990 assert.strictEqual(func(symbol), symbol); 2991 } 2992 else { 2993 skipAssert(assert); 2994 } 2995 }); 2996 2997 QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) { 2998 assert.expect(1); 2999 3000 if (document) { 3001 var element = document.createElement('div'); 3002 3003 try { 3004 assert.deepEqual(func(element), {}); 3005 } catch (e) { 3006 assert.ok(false, e.message); 3007 } 3008 } 3009 else { 3010 skipAssert(assert); 3011 } 3012 }); 3013 3014 QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) { 3015 assert.expect(1); 3016 3017 var props = []; 3018 3019 var objects = lodashStable.transform(_, function(result, value, key) { 3020 if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) && 3021 !lodashStable.isArguments(value) && !lodashStable.isElement(value) && 3022 !lodashStable.isFunction(value)) { 3023 props.push(lodashStable.capitalize(lodashStable.camelCase(key))); 3024 result.push(value); 3025 } 3026 }, []); 3027 3028 var expected = lodashStable.map(objects, stubTrue); 3029 3030 var actual = lodashStable.map(objects, function(object) { 3031 var Ctor = object.constructor, 3032 result = func(object); 3033 3034 return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor)); 3035 }); 3036 3037 assert.deepEqual(actual, expected, props.join(', ')); 3038 }); 3039 3040 QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) { 3041 assert.expect(2); 3042 3043 var expected = [{ 'a': [0] }, { 'b': [1] }], 3044 actual = lodashStable.map(expected, func); 3045 3046 assert.deepEqual(actual, expected); 3047 3048 if (isDeep) { 3049 assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b); 3050 } else { 3051 assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b); 3052 } 3053 }); 3054 3055 QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) { 3056 assert.expect(2); 3057 3058 if (!isNpm) { 3059 var object = objects.objects, 3060 actual = _(object)[methodName](); 3061 3062 assert.deepEqual(actual, object); 3063 assert.notStrictEqual(actual, object); 3064 } 3065 else { 3066 skipAssert(assert, 2); 3067 } 3068 }); 3069 3070 lodashStable.each(arrayViews, function(type) { 3071 QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) { 3072 assert.expect(10); 3073 3074 var Ctor = root[type]; 3075 3076 lodashStable.times(2, function(index) { 3077 if (Ctor) { 3078 var buffer = new ArrayBuffer(24), 3079 view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer), 3080 actual = func(view); 3081 3082 assert.deepEqual(actual, view); 3083 assert.notStrictEqual(actual, view); 3084 assert.strictEqual(actual.buffer === view.buffer, !isDeep); 3085 assert.strictEqual(actual.byteOffset, view.byteOffset); 3086 assert.strictEqual(actual.length, view.length); 3087 } 3088 else { 3089 skipAssert(assert, 5); 3090 } 3091 }); 3092 }); 3093 }); 3094 3095 lodashStable.forOwn(uncloneable, function(value, key) { 3096 QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) { 3097 assert.expect(3); 3098 3099 if (value) { 3100 var object = { 'a': value, 'b': { 'c': value } }, 3101 actual = func(object), 3102 expected = value === Foo ? { 'c': Foo.c } : {}; 3103 3104 assert.deepEqual(actual, object); 3105 assert.notStrictEqual(actual, object); 3106 assert.deepEqual(func(value), expected); 3107 } 3108 else { 3109 skipAssert(assert, 3); 3110 } 3111 }); 3112 }); 3113 }); 3114 3115 lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) { 3116 var func = _[methodName], 3117 isDeep = methodName == 'cloneDeepWith'; 3118 3119 QUnit.test('`_.' + methodName + '` should provide correct `customizer` arguments', function(assert) { 3120 assert.expect(1); 3121 3122 var argsList = [], 3123 object = new Foo; 3124 3125 func(object, function() { 3126 var length = arguments.length, 3127 args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0)); 3128 3129 argsList.push(args); 3130 }); 3131 3132 assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]); 3133 }); 3134 3135 QUnit.test('`_.' + methodName + '` should handle cloning when `customizer` returns `undefined`', function(assert) { 3136 assert.expect(1); 3137 3138 var actual = func({ 'a': { 'b': 'c' } }, noop); 3139 assert.deepEqual(actual, { 'a': { 'b': 'c' } }); 3140 }); 3141 3142 lodashStable.forOwn(uncloneable, function(value, key) { 3143 QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) { 3144 assert.expect(3); 3145 3146 var customizer = function(value) { 3147 return lodashStable.isPlainObject(value) ? undefined : value; 3148 }; 3149 3150 var actual = func(value, customizer); 3151 assert.strictEqual(actual, value); 3152 3153 var object = { 'a': value, 'b': { 'c': value } }; 3154 actual = func(object, customizer); 3155 3156 assert.deepEqual(actual, object); 3157 assert.notStrictEqual(actual, object); 3158 }); 3159 }); 3160 }); 3161 }()); 3162 3163 /*--------------------------------------------------------------------------*/ 3164 3165 QUnit.module('lodash.compact'); 3166 3167 (function() { 3168 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null); 3169 3170 QUnit.test('should filter falsey values', function(assert) { 3171 assert.expect(1); 3172 3173 var array = ['0', '1', '2']; 3174 assert.deepEqual(_.compact(falsey.concat(array)), array); 3175 }); 3176 3177 QUnit.test('should work when in-between lazy operators', function(assert) { 3178 assert.expect(2); 3179 3180 if (!isNpm) { 3181 var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value(); 3182 assert.deepEqual(actual, []); 3183 3184 actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value(); 3185 assert.deepEqual(actual, [true, 1, 'a']); 3186 } 3187 else { 3188 skipAssert(assert, 2); 3189 } 3190 }); 3191 3192 QUnit.test('should work in a lazy sequence', function(assert) { 3193 assert.expect(1); 3194 3195 if (!isNpm) { 3196 var actual = _(largeArray).slice(1).compact().reverse().take().value(); 3197 assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse())); 3198 } 3199 else { 3200 skipAssert(assert); 3201 } 3202 }); 3203 3204 QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) { 3205 assert.expect(1); 3206 3207 if (!isModularize) { 3208 var iteratee = _.iteratee, 3209 pass = false; 3210 3211 _.iteratee = identity; 3212 3213 try { 3214 var actual = _(largeArray).slice(1).compact().value(); 3215 pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1))); 3216 } catch (e) {console.log(e);} 3217 3218 assert.ok(pass); 3219 _.iteratee = iteratee; 3220 } 3221 else { 3222 skipAssert(assert); 3223 } 3224 }); 3225 }()); 3226 3227 /*--------------------------------------------------------------------------*/ 3228 3229 QUnit.module('lodash.concat'); 3230 3231 (function() { 3232 QUnit.test('should shallow clone `array`', function(assert) { 3233 assert.expect(2); 3234 3235 var array = [1, 2, 3], 3236 actual = _.concat(array); 3237 3238 assert.deepEqual(actual, array); 3239 assert.notStrictEqual(actual, array); 3240 }); 3241 3242 QUnit.test('should concat arrays and values', function(assert) { 3243 assert.expect(2); 3244 3245 var array = [1], 3246 actual = _.concat(array, 2, [3], [[4]]); 3247 3248 assert.deepEqual(actual, [1, 2, 3, [4]]); 3249 assert.deepEqual(array, [1]); 3250 }); 3251 3252 QUnit.test('should cast non-array `array` values to arrays', function(assert) { 3253 assert.expect(2); 3254 3255 var values = [, null, undefined, false, true, 1, NaN, 'a']; 3256 3257 var expected = lodashStable.map(values, function(value, index) { 3258 return index ? [value] : []; 3259 }); 3260 3261 var actual = lodashStable.map(values, function(value, index) { 3262 return index ? _.concat(value) : _.concat(); 3263 }); 3264 3265 assert.deepEqual(actual, expected); 3266 3267 expected = lodashStable.map(values, function(value) { 3268 return [value, 2, [3]]; 3269 }); 3270 3271 actual = lodashStable.map(values, function(value) { 3272 return _.concat(value, [2], [[3]]); 3273 }); 3274 3275 assert.deepEqual(actual, expected); 3276 }); 3277 3278 QUnit.test('should treat sparse arrays as dense', function(assert) { 3279 assert.expect(3); 3280 3281 var expected = [], 3282 actual = _.concat(Array(1), Array(1)); 3283 3284 expected.push(undefined, undefined); 3285 3286 assert.ok('0'in actual); 3287 assert.ok('1' in actual); 3288 assert.deepEqual(actual, expected); 3289 }); 3290 3291 QUnit.test('should return a new wrapped array', function(assert) { 3292 assert.expect(2); 3293 3294 if (!isNpm) { 3295 var array = [1], 3296 wrapped = _(array).concat([2, 3]), 3297 actual = wrapped.value(); 3298 3299 assert.deepEqual(array, [1]); 3300 assert.deepEqual(actual, [1, 2, 3]); 3301 } 3302 else { 3303 skipAssert(assert, 2); 3304 } 3305 }); 3306 }()); 3307 3308 /*--------------------------------------------------------------------------*/ 3309 3310 QUnit.module('lodash.cond'); 3311 3312 (function() { 3313 QUnit.test('should create a conditional function', function(assert) { 3314 assert.expect(3); 3315 3316 var cond = _.cond([ 3317 [lodashStable.matches({ 'a': 1 }), stubA], 3318 [lodashStable.matchesProperty('b', 1), stubB], 3319 [lodashStable.property('c'), stubC] 3320 ]); 3321 3322 assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a'); 3323 assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b'); 3324 assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c'); 3325 }); 3326 3327 QUnit.test('should provide arguments to functions', function(assert) { 3328 assert.expect(2); 3329 3330 var args1, 3331 args2, 3332 expected = ['a', 'b', 'c']; 3333 3334 var cond = _.cond([[ 3335 function() { args1 || (args1 = slice.call(arguments)); return true; }, 3336 function() { args2 || (args2 = slice.call(arguments)); } 3337 ]]); 3338 3339 cond('a', 'b', 'c'); 3340 3341 assert.deepEqual(args1, expected); 3342 assert.deepEqual(args2, expected); 3343 }); 3344 3345 QUnit.test('should work with predicate shorthands', function(assert) { 3346 assert.expect(3); 3347 3348 var cond = _.cond([ 3349 [{ 'a': 1 }, stubA], 3350 [['b', 1], stubB], 3351 ['c', stubC] 3352 ]); 3353 3354 assert.strictEqual(cond({ 'a': 1, 'b': 2, 'c': 3 }), 'a'); 3355 assert.strictEqual(cond({ 'a': 0, 'b': 1, 'c': 2 }), 'b'); 3356 assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c'); 3357 }); 3358 3359 QUnit.test('should return `undefined` when no condition is met', function(assert) { 3360 assert.expect(1); 3361 3362 var cond = _.cond([[stubFalse, stubA]]); 3363 assert.strictEqual(cond({ 'a': 1 }), undefined); 3364 }); 3365 3366 QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) { 3367 assert.expect(2); 3368 3369 lodashStable.each([false, true], function(value) { 3370 assert.raises(function() { _.cond([[stubTrue, value]])(); }, TypeError); 3371 }); 3372 }); 3373 3374 QUnit.test('should use `this` binding of function for `pairs`', function(assert) { 3375 assert.expect(1); 3376 3377 var cond = _.cond([ 3378 [function(a) { return this[a]; }, function(a, b) { return this[b]; }] 3379 ]); 3380 3381 var object = { 'cond': cond, 'a': 1, 'b': 2 }; 3382 assert.strictEqual(object.cond('a', 'b'), 2); 3383 }); 3384 }()); 3385 3386 /*--------------------------------------------------------------------------*/ 3387 3388 QUnit.module('lodash.conforms'); 3389 3390 (function() { 3391 QUnit.test('should not change behavior if `source` is modified', function(assert) { 3392 assert.expect(2); 3393 3394 var object = { 'a': 2 }, 3395 source = { 'a': function(value) { return value > 1; } }, 3396 par = _.conforms(source); 3397 3398 assert.strictEqual(par(object), true); 3399 3400 source.a = function(value) { return value < 2; }; 3401 assert.strictEqual(par(object), true); 3402 }); 3403 }()); 3404 3405 /*--------------------------------------------------------------------------*/ 3406 3407 QUnit.module('conforms methods'); 3408 3409 lodashStable.each(['conforms', 'conformsTo'], function(methodName) { 3410 var isConforms = methodName == 'conforms'; 3411 3412 function conforms(source) { 3413 return isConforms ? _.conforms(source) : function(object) { 3414 return _.conformsTo(object, source); 3415 }; 3416 } 3417 3418 QUnit.test('`_.' + methodName + '` should check if `object` conforms to `source`', function(assert) { 3419 assert.expect(2); 3420 3421 var objects = [ 3422 { 'a': 1, 'b': 8 }, 3423 { 'a': 2, 'b': 4 }, 3424 { 'a': 3, 'b': 16 } 3425 ]; 3426 3427 var par = conforms({ 3428 'b': function(value) { return value > 4; } 3429 }); 3430 3431 var actual = lodashStable.filter(objects, par); 3432 assert.deepEqual(actual, [objects[0], objects[2]]); 3433 3434 par = conforms({ 3435 'b': function(value) { return value > 8; }, 3436 'a': function(value) { return value > 1; } 3437 }); 3438 3439 actual = lodashStable.filter(objects, par); 3440 assert.deepEqual(actual, [objects[2]]); 3441 }); 3442 3443 QUnit.test('`_.' + methodName + '` should not match by inherited `source` properties', function(assert) { 3444 assert.expect(1); 3445 3446 function Foo() { 3447 this.a = function(value) { 3448 return value > 1; 3449 }; 3450 } 3451 Foo.prototype.b = function(value) { 3452 return value > 8; 3453 }; 3454 3455 var objects = [ 3456 { 'a': 1, 'b': 8 }, 3457 { 'a': 2, 'b': 4 }, 3458 { 'a': 3, 'b': 16 } 3459 ]; 3460 3461 var par = conforms(new Foo), 3462 actual = lodashStable.filter(objects, par); 3463 3464 assert.deepEqual(actual, [objects[1], objects[2]]); 3465 }); 3466 3467 QUnit.test('`_.' + methodName + '` should not invoke `source` predicates for missing `object` properties', function(assert) { 3468 assert.expect(2); 3469 3470 var count = 0; 3471 3472 var par = conforms({ 3473 'a': function() { count++; return true; } 3474 }); 3475 3476 assert.strictEqual(par({}), false); 3477 assert.strictEqual(count, 0); 3478 }); 3479 3480 QUnit.test('`_.' + methodName + '` should work with a function for `object`', function(assert) { 3481 assert.expect(2); 3482 3483 function Foo() {} 3484 Foo.a = 1; 3485 3486 function Bar() {} 3487 Bar.a = 2; 3488 3489 var par = conforms({ 3490 'a': function(value) { return value > 1; } 3491 }); 3492 3493 assert.strictEqual(par(Foo), false); 3494 assert.strictEqual(par(Bar), true); 3495 }); 3496 3497 QUnit.test('`_.' + methodName + '` should work with a function for `source`', function(assert) { 3498 assert.expect(1); 3499 3500 function Foo() {} 3501 Foo.a = function(value) { return value > 1; }; 3502 3503 var objects = [{ 'a': 1 }, { 'a': 2 }], 3504 actual = lodashStable.filter(objects, conforms(Foo)); 3505 3506 assert.deepEqual(actual, [objects[1]]); 3507 }); 3508 3509 QUnit.test('`_.' + methodName + '` should work with a non-plain `object`', function(assert) { 3510 assert.expect(1); 3511 3512 function Foo() { 3513 this.a = 1; 3514 } 3515 Foo.prototype.b = 2; 3516 3517 var par = conforms({ 3518 'b': function(value) { return value > 1; } 3519 }); 3520 3521 assert.strictEqual(par(new Foo), true); 3522 }); 3523 3524 QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) { 3525 assert.expect(1); 3526 3527 var values = [, null, undefined], 3528 expected = lodashStable.map(values, stubFalse); 3529 3530 var par = conforms({ 3531 'a': function(value) { return value > 1; } 3532 }); 3533 3534 var actual = lodashStable.map(values, function(value, index) { 3535 try { 3536 return index ? par(value) : par(); 3537 } catch (e) {} 3538 }); 3539 3540 assert.deepEqual(actual, expected); 3541 }); 3542 3543 QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source` to a nullish `object`', function(assert) { 3544 assert.expect(1); 3545 3546 var values = [, null, undefined], 3547 expected = lodashStable.map(values, stubTrue), 3548 par = conforms({}); 3549 3550 var actual = lodashStable.map(values, function(value, index) { 3551 try { 3552 return index ? par(value) : par(); 3553 } catch (e) {} 3554 }); 3555 3556 assert.deepEqual(actual, expected); 3557 }); 3558 3559 QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source`', function(assert) { 3560 assert.expect(1); 3561 3562 var object = { 'a': 1 }, 3563 expected = lodashStable.map(empties, stubTrue); 3564 3565 var actual = lodashStable.map(empties, function(value) { 3566 var par = conforms(value); 3567 return par(object); 3568 }); 3569 3570 assert.deepEqual(actual, expected); 3571 }); 3572 }); 3573 3574 /*--------------------------------------------------------------------------*/ 3575 3576 QUnit.module('lodash.constant'); 3577 3578 (function() { 3579 QUnit.test('should create a function that returns `value`', function(assert) { 3580 assert.expect(1); 3581 3582 var object = { 'a': 1 }, 3583 values = Array(2).concat(empties, true, 1, 'a'), 3584 constant = _.constant(object); 3585 3586 var results = lodashStable.map(values, function(value, index) { 3587 if (index < 2) { 3588 return index ? constant.call({}) : constant(); 3589 } 3590 return constant(value); 3591 }); 3592 3593 assert.ok(lodashStable.every(results, function(result) { 3594 return result === object; 3595 })); 3596 }); 3597 3598 QUnit.test('should work with falsey values', function(assert) { 3599 assert.expect(1); 3600 3601 var expected = lodashStable.map(falsey, stubTrue); 3602 3603 var actual = lodashStable.map(falsey, function(value, index) { 3604 var constant = index ? _.constant(value) : _.constant(), 3605 result = constant(); 3606 3607 return (result === value) || (result !== result && value !== value); 3608 }); 3609 3610 assert.deepEqual(actual, expected); 3611 }); 3612 3613 QUnit.test('should return a wrapped value when chaining', function(assert) { 3614 assert.expect(1); 3615 3616 if (!isNpm) { 3617 var wrapped = _(true).constant(); 3618 assert.ok(wrapped instanceof _); 3619 } 3620 else { 3621 skipAssert(assert); 3622 } 3623 }); 3624 }()); 3625 3626 /*--------------------------------------------------------------------------*/ 3627 3628 QUnit.module('lodash.countBy'); 3629 3630 (function() { 3631 var array = [6.1, 4.2, 6.3]; 3632 3633 QUnit.test('should transform keys by `iteratee`', function(assert) { 3634 assert.expect(1); 3635 3636 var actual = _.countBy(array, Math.floor); 3637 assert.deepEqual(actual, { '4': 1, '6': 2 }); 3638 }); 3639 3640 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 3641 assert.expect(1); 3642 3643 var array = [4, 6, 6], 3644 values = [, null, undefined], 3645 expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6': 2 })); 3646 3647 var actual = lodashStable.map(values, function(value, index) { 3648 return index ? _.countBy(array, value) : _.countBy(array); 3649 }); 3650 3651 assert.deepEqual(actual, expected); 3652 }); 3653 3654 QUnit.test('should work with `_.property` shorthands', function(assert) { 3655 assert.expect(1); 3656 3657 var actual = _.countBy(['one', 'two', 'three'], 'length'); 3658 assert.deepEqual(actual, { '3': 2, '5': 1 }); 3659 }); 3660 3661 QUnit.test('should only add values to own, not inherited, properties', function(assert) { 3662 assert.expect(2); 3663 3664 var actual = _.countBy(array, function(n) { 3665 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor'; 3666 }); 3667 3668 assert.deepEqual(actual.constructor, 1); 3669 assert.deepEqual(actual.hasOwnProperty, 2); 3670 }); 3671 3672 QUnit.test('should work with a number for `iteratee`', function(assert) { 3673 assert.expect(2); 3674 3675 var array = [ 3676 [1, 'a'], 3677 [2, 'a'], 3678 [2, 'b'] 3679 ]; 3680 3681 assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 }); 3682 assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 }); 3683 }); 3684 3685 QUnit.test('should work with an object for `collection`', function(assert) { 3686 assert.expect(1); 3687 3688 var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor); 3689 assert.deepEqual(actual, { '4': 1, '6': 2 }); 3690 }); 3691 3692 QUnit.test('should work in a lazy sequence', function(assert) { 3693 assert.expect(1); 3694 3695 if (!isNpm) { 3696 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat( 3697 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), 3698 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) 3699 ); 3700 3701 var actual = _(array).countBy().map(square).filter(isEven).take().value(); 3702 3703 assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven))); 3704 } 3705 else { 3706 skipAssert(assert); 3707 } 3708 }); 3709 }()); 3710 3711 /*--------------------------------------------------------------------------*/ 3712 3713 QUnit.module('lodash.create'); 3714 3715 (function() { 3716 function Shape() { 3717 this.x = 0; 3718 this.y = 0; 3719 } 3720 3721 function Circle() { 3722 Shape.call(this); 3723 } 3724 3725 QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) { 3726 assert.expect(3); 3727 3728 Circle.prototype = _.create(Shape.prototype); 3729 Circle.prototype.constructor = Circle; 3730 3731 var actual = new Circle; 3732 3733 assert.ok(actual instanceof Circle); 3734 assert.ok(actual instanceof Shape); 3735 assert.notStrictEqual(Circle.prototype, Shape.prototype); 3736 }); 3737 3738 QUnit.test('should assign `properties` to the created object', function(assert) { 3739 assert.expect(3); 3740 3741 var expected = { 'constructor': Circle, 'radius': 0 }; 3742 Circle.prototype = _.create(Shape.prototype, expected); 3743 3744 var actual = new Circle; 3745 3746 assert.ok(actual instanceof Circle); 3747 assert.ok(actual instanceof Shape); 3748 assert.deepEqual(Circle.prototype, expected); 3749 }); 3750 3751 QUnit.test('should assign own properties', function(assert) { 3752 assert.expect(1); 3753 3754 function Foo() { 3755 this.a = 1; 3756 this.c = 3; 3757 } 3758 Foo.prototype.b = 2; 3759 3760 assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 }); 3761 }); 3762 3763 QUnit.test('should assign properties that shadow those of `prototype`', function(assert) { 3764 assert.expect(1); 3765 3766 function Foo() { 3767 this.a = 1; 3768 } 3769 var object = _.create(new Foo, { 'a': 1 }); 3770 assert.deepEqual(lodashStable.keys(object), ['a']); 3771 }); 3772 3773 QUnit.test('should accept a falsey `prototype`', function(assert) { 3774 assert.expect(1); 3775 3776 var expected = lodashStable.map(falsey, stubObject); 3777 3778 var actual = lodashStable.map(falsey, function(prototype, index) { 3779 return index ? _.create(prototype) : _.create(); 3780 }); 3781 3782 assert.deepEqual(actual, expected); 3783 }); 3784 3785 QUnit.test('should ignore a primitive `prototype` and use an empty object instead', function(assert) { 3786 assert.expect(1); 3787 3788 var expected = lodashStable.map(primitives, stubTrue); 3789 3790 var actual = lodashStable.map(primitives, function(value, index) { 3791 return lodashStable.isPlainObject(index ? _.create(value) : _.create()); 3792 }); 3793 3794 assert.deepEqual(actual, expected); 3795 }); 3796 3797 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 3798 assert.expect(1); 3799 3800 var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }], 3801 expected = lodashStable.map(array, stubTrue), 3802 objects = lodashStable.map(array, _.create); 3803 3804 var actual = lodashStable.map(objects, function(object) { 3805 return object.a === 1 && !_.keys(object).length; 3806 }); 3807 3808 assert.deepEqual(actual, expected); 3809 }); 3810 }()); 3811 3812 /*--------------------------------------------------------------------------*/ 3813 3814 QUnit.module('lodash.curry'); 3815 3816 (function() { 3817 function fn(a, b, c, d) { 3818 return slice.call(arguments); 3819 } 3820 3821 QUnit.test('should curry based on the number of arguments given', function(assert) { 3822 assert.expect(3); 3823 3824 var curried = _.curry(fn), 3825 expected = [1, 2, 3, 4]; 3826 3827 assert.deepEqual(curried(1)(2)(3)(4), expected); 3828 assert.deepEqual(curried(1, 2)(3, 4), expected); 3829 assert.deepEqual(curried(1, 2, 3, 4), expected); 3830 }); 3831 3832 QUnit.test('should allow specifying `arity`', function(assert) { 3833 assert.expect(3); 3834 3835 var curried = _.curry(fn, 3), 3836 expected = [1, 2, 3]; 3837 3838 assert.deepEqual(curried(1)(2, 3), expected); 3839 assert.deepEqual(curried(1, 2)(3), expected); 3840 assert.deepEqual(curried(1, 2, 3), expected); 3841 }); 3842 3843 QUnit.test('should coerce `arity` to an integer', function(assert) { 3844 assert.expect(2); 3845 3846 var values = ['0', 0.6, 'xyz'], 3847 expected = lodashStable.map(values, stubArray); 3848 3849 var actual = lodashStable.map(values, function(arity) { 3850 return _.curry(fn, arity)(); 3851 }); 3852 3853 assert.deepEqual(actual, expected); 3854 assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]); 3855 }); 3856 3857 QUnit.test('should support placeholders', function(assert) { 3858 assert.expect(4); 3859 3860 var curried = _.curry(fn), 3861 ph = curried.placeholder; 3862 3863 assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]); 3864 assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]); 3865 assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]); 3866 assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]); 3867 }); 3868 3869 QUnit.test('should persist placeholders', function(assert) { 3870 assert.expect(1); 3871 3872 var curried = _.curry(fn), 3873 ph = curried.placeholder, 3874 actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c'); 3875 3876 assert.deepEqual(actual, ['a', 'b', 'c', 'd']); 3877 }); 3878 3879 QUnit.test('should use `_.placeholder` when set', function(assert) { 3880 assert.expect(1); 3881 3882 if (!isModularize) { 3883 var curried = _.curry(fn), 3884 _ph = _.placeholder = {}, 3885 ph = curried.placeholder; 3886 3887 assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]); 3888 delete _.placeholder; 3889 } 3890 else { 3891 skipAssert(assert); 3892 } 3893 }); 3894 3895 QUnit.test('should provide additional arguments after reaching the target arity', function(assert) { 3896 assert.expect(3); 3897 3898 var curried = _.curry(fn, 3); 3899 assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]); 3900 assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]); 3901 assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); 3902 }); 3903 3904 QUnit.test('should create a function with a `length` of `0`', function(assert) { 3905 assert.expect(6); 3906 3907 lodashStable.times(2, function(index) { 3908 var curried = index ? _.curry(fn, 4) : _.curry(fn); 3909 assert.strictEqual(curried.length, 0); 3910 assert.strictEqual(curried(1).length, 0); 3911 assert.strictEqual(curried(1, 2).length, 0); 3912 }); 3913 }); 3914 3915 QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) { 3916 assert.expect(2); 3917 3918 function Foo(value) { 3919 return value && object; 3920 } 3921 3922 var curried = _.curry(Foo), 3923 object = {}; 3924 3925 assert.ok(new curried(false) instanceof Foo); 3926 assert.strictEqual(new curried(true), object); 3927 }); 3928 3929 QUnit.test('should use `this` binding of function', function(assert) { 3930 assert.expect(9); 3931 3932 var fn = function(a, b, c) { 3933 var value = this || {}; 3934 return [value[a], value[b], value[c]]; 3935 }; 3936 3937 var object = { 'a': 1, 'b': 2, 'c': 3 }, 3938 expected = [1, 2, 3]; 3939 3940 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected); 3941 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected); 3942 assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected); 3943 3944 assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3)); 3945 assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3)); 3946 assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected); 3947 3948 object.curried = _.curry(fn); 3949 assert.deepEqual(object.curried('a')('b')('c'), Array(3)); 3950 assert.deepEqual(object.curried('a', 'b')('c'), Array(3)); 3951 assert.deepEqual(object.curried('a', 'b', 'c'), expected); 3952 }); 3953 3954 QUnit.test('should work with partialed methods', function(assert) { 3955 assert.expect(2); 3956 3957 var curried = _.curry(fn), 3958 expected = [1, 2, 3, 4]; 3959 3960 var a = _.partial(curried, 1), 3961 b = _.bind(a, null, 2), 3962 c = _.partialRight(b, 4), 3963 d = _.partialRight(b(3), 4); 3964 3965 assert.deepEqual(c(3), expected); 3966 assert.deepEqual(d(), expected); 3967 }); 3968 }()); 3969 3970 /*--------------------------------------------------------------------------*/ 3971 3972 QUnit.module('lodash.curryRight'); 3973 3974 (function() { 3975 function fn(a, b, c, d) { 3976 return slice.call(arguments); 3977 } 3978 3979 QUnit.test('should curry based on the number of arguments given', function(assert) { 3980 assert.expect(3); 3981 3982 var curried = _.curryRight(fn), 3983 expected = [1, 2, 3, 4]; 3984 3985 assert.deepEqual(curried(4)(3)(2)(1), expected); 3986 assert.deepEqual(curried(3, 4)(1, 2), expected); 3987 assert.deepEqual(curried(1, 2, 3, 4), expected); 3988 }); 3989 3990 QUnit.test('should allow specifying `arity`', function(assert) { 3991 assert.expect(3); 3992 3993 var curried = _.curryRight(fn, 3), 3994 expected = [1, 2, 3]; 3995 3996 assert.deepEqual(curried(3)(1, 2), expected); 3997 assert.deepEqual(curried(2, 3)(1), expected); 3998 assert.deepEqual(curried(1, 2, 3), expected); 3999 }); 4000 4001 QUnit.test('should coerce `arity` to an integer', function(assert) { 4002 assert.expect(2); 4003 4004 var values = ['0', 0.6, 'xyz'], 4005 expected = lodashStable.map(values, stubArray); 4006 4007 var actual = lodashStable.map(values, function(arity) { 4008 return _.curryRight(fn, arity)(); 4009 }); 4010 4011 assert.deepEqual(actual, expected); 4012 assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]); 4013 }); 4014 4015 QUnit.test('should support placeholders', function(assert) { 4016 assert.expect(4); 4017 4018 var curried = _.curryRight(fn), 4019 expected = [1, 2, 3, 4], 4020 ph = curried.placeholder; 4021 4022 assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected); 4023 assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected); 4024 assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected); 4025 assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected); 4026 }); 4027 4028 QUnit.test('should persist placeholders', function(assert) { 4029 assert.expect(1); 4030 4031 var curried = _.curryRight(fn), 4032 ph = curried.placeholder, 4033 actual = curried('a', ph, ph, ph)('b')(ph)('c')('d'); 4034 4035 assert.deepEqual(actual, ['a', 'b', 'c', 'd']); 4036 }); 4037 4038 QUnit.test('should use `_.placeholder` when set', function(assert) { 4039 assert.expect(1); 4040 4041 if (!isModularize) { 4042 var curried = _.curryRight(fn), 4043 _ph = _.placeholder = {}, 4044 ph = curried.placeholder; 4045 4046 assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]); 4047 delete _.placeholder; 4048 } 4049 else { 4050 skipAssert(assert); 4051 } 4052 }); 4053 4054 QUnit.test('should provide additional arguments after reaching the target arity', function(assert) { 4055 assert.expect(3); 4056 4057 var curried = _.curryRight(fn, 3); 4058 assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]); 4059 assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]); 4060 assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]); 4061 }); 4062 4063 QUnit.test('should create a function with a `length` of `0`', function(assert) { 4064 assert.expect(6); 4065 4066 lodashStable.times(2, function(index) { 4067 var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn); 4068 assert.strictEqual(curried.length, 0); 4069 assert.strictEqual(curried(4).length, 0); 4070 assert.strictEqual(curried(3, 4).length, 0); 4071 }); 4072 }); 4073 4074 QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) { 4075 assert.expect(2); 4076 4077 function Foo(value) { 4078 return value && object; 4079 } 4080 4081 var curried = _.curryRight(Foo), 4082 object = {}; 4083 4084 assert.ok(new curried(false) instanceof Foo); 4085 assert.strictEqual(new curried(true), object); 4086 }); 4087 4088 QUnit.test('should use `this` binding of function', function(assert) { 4089 assert.expect(9); 4090 4091 var fn = function(a, b, c) { 4092 var value = this || {}; 4093 return [value[a], value[b], value[c]]; 4094 }; 4095 4096 var object = { 'a': 1, 'b': 2, 'c': 3 }, 4097 expected = [1, 2, 3]; 4098 4099 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected); 4100 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected); 4101 assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected); 4102 4103 assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3)); 4104 assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3)); 4105 assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected); 4106 4107 object.curried = _.curryRight(fn); 4108 assert.deepEqual(object.curried('c')('b')('a'), Array(3)); 4109 assert.deepEqual(object.curried('b', 'c')('a'), Array(3)); 4110 assert.deepEqual(object.curried('a', 'b', 'c'), expected); 4111 }); 4112 4113 QUnit.test('should work with partialed methods', function(assert) { 4114 assert.expect(2); 4115 4116 var curried = _.curryRight(fn), 4117 expected = [1, 2, 3, 4]; 4118 4119 var a = _.partialRight(curried, 4), 4120 b = _.partialRight(a, 3), 4121 c = _.bind(b, null, 1), 4122 d = _.partial(b(2), 1); 4123 4124 assert.deepEqual(c(2), expected); 4125 assert.deepEqual(d(), expected); 4126 }); 4127 }()); 4128 4129 /*--------------------------------------------------------------------------*/ 4130 4131 QUnit.module('curry methods'); 4132 4133 lodashStable.each(['curry', 'curryRight'], function(methodName) { 4134 var func = _[methodName], 4135 fn = function(a, b) { return slice.call(arguments); }, 4136 isCurry = methodName == 'curry'; 4137 4138 QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) { 4139 assert.expect(1); 4140 4141 function run(a, b) { 4142 return a + b; 4143 } 4144 4145 var curried = func(run); 4146 4147 try { 4148 var actual = curried(1)(2); 4149 } catch (e) {} 4150 4151 assert.strictEqual(actual, 3); 4152 }); 4153 4154 QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) { 4155 assert.expect(1); 4156 4157 var curried = _.curry(function hasOwnProperty(a, b, c) { 4158 return [a, b, c]; 4159 }); 4160 4161 var expected = [1, 2, 3]; 4162 4163 assert.deepEqual(curried(1)(2)(3), expected); 4164 }); 4165 4166 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) { 4167 assert.expect(2); 4168 4169 var array = [fn, fn, fn], 4170 object = { 'a': fn, 'b': fn, 'c': fn }; 4171 4172 lodashStable.each([array, object], function(collection) { 4173 var curries = lodashStable.map(collection, func), 4174 expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a'])); 4175 4176 var actual = lodashStable.map(curries, function(curried) { 4177 return curried('a')('b'); 4178 }); 4179 4180 assert.deepEqual(actual, expected); 4181 }); 4182 }); 4183 }); 4184 4185 /*--------------------------------------------------------------------------*/ 4186 4187 QUnit.module('lodash.debounce'); 4188 4189 (function() { 4190 QUnit.test('should debounce a function', function(assert) { 4191 assert.expect(6); 4192 4193 var done = assert.async(); 4194 4195 var callCount = 0; 4196 4197 var debounced = _.debounce(function(value) { 4198 ++callCount; 4199 return value; 4200 }, 32); 4201 4202 var results = [debounced('a'), debounced('b'), debounced('c')]; 4203 assert.deepEqual(results, [undefined, undefined, undefined]); 4204 assert.strictEqual(callCount, 0); 4205 4206 setTimeout(function() { 4207 assert.strictEqual(callCount, 1); 4208 4209 var results = [debounced('d'), debounced('e'), debounced('f')]; 4210 assert.deepEqual(results, ['c', 'c', 'c']); 4211 assert.strictEqual(callCount, 1); 4212 }, 128); 4213 4214 setTimeout(function() { 4215 assert.strictEqual(callCount, 2); 4216 done(); 4217 }, 256); 4218 }); 4219 4220 QUnit.test('subsequent debounced calls return the last `func` result', function(assert) { 4221 assert.expect(2); 4222 4223 var done = assert.async(); 4224 4225 var debounced = _.debounce(identity, 32); 4226 debounced('a'); 4227 4228 setTimeout(function() { 4229 assert.notEqual(debounced('b'), 'b'); 4230 }, 64); 4231 4232 setTimeout(function() { 4233 assert.notEqual(debounced('c'), 'c'); 4234 done(); 4235 }, 128); 4236 }); 4237 4238 QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) { 4239 assert.expect(2); 4240 4241 var done = assert.async(); 4242 4243 var callCount = 0, 4244 debounced = _.debounce(function() { ++callCount; }, 0); 4245 4246 debounced(); 4247 debounced(); 4248 assert.strictEqual(callCount, 0); 4249 4250 setTimeout(function() { 4251 assert.strictEqual(callCount, 1); 4252 done(); 4253 }, 5); 4254 }); 4255 4256 QUnit.test('should apply default options', function(assert) { 4257 assert.expect(2); 4258 4259 var done = assert.async(); 4260 4261 var callCount = 0, 4262 debounced = _.debounce(function() { callCount++; }, 32, {}); 4263 4264 debounced(); 4265 assert.strictEqual(callCount, 0); 4266 4267 setTimeout(function() { 4268 assert.strictEqual(callCount, 1); 4269 done(); 4270 }, 64); 4271 }); 4272 4273 QUnit.test('should support a `leading` option', function(assert) { 4274 assert.expect(4); 4275 4276 var done = assert.async(); 4277 4278 var callCounts = [0, 0]; 4279 4280 var withLeading = _.debounce(function() { 4281 callCounts[0]++; 4282 }, 32, { 'leading': true }); 4283 4284 var withLeadingAndTrailing = _.debounce(function() { 4285 callCounts[1]++; 4286 }, 32, { 'leading': true }); 4287 4288 withLeading(); 4289 assert.strictEqual(callCounts[0], 1); 4290 4291 withLeadingAndTrailing(); 4292 withLeadingAndTrailing(); 4293 assert.strictEqual(callCounts[1], 1); 4294 4295 setTimeout(function() { 4296 assert.deepEqual(callCounts, [1, 2]); 4297 4298 withLeading(); 4299 assert.strictEqual(callCounts[0], 2); 4300 4301 done(); 4302 }, 64); 4303 }); 4304 4305 QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) { 4306 assert.expect(2); 4307 4308 var done = assert.async(); 4309 4310 var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }), 4311 results = [debounced('a'), debounced('b')]; 4312 4313 assert.deepEqual(results, ['a', 'a']); 4314 4315 setTimeout(function() { 4316 var results = [debounced('c'), debounced('d')]; 4317 assert.deepEqual(results, ['c', 'c']); 4318 done(); 4319 }, 64); 4320 }); 4321 4322 QUnit.test('should support a `trailing` option', function(assert) { 4323 assert.expect(4); 4324 4325 var done = assert.async(); 4326 4327 var withCount = 0, 4328 withoutCount = 0; 4329 4330 var withTrailing = _.debounce(function() { 4331 withCount++; 4332 }, 32, { 'trailing': true }); 4333 4334 var withoutTrailing = _.debounce(function() { 4335 withoutCount++; 4336 }, 32, { 'trailing': false }); 4337 4338 withTrailing(); 4339 assert.strictEqual(withCount, 0); 4340 4341 withoutTrailing(); 4342 assert.strictEqual(withoutCount, 0); 4343 4344 setTimeout(function() { 4345 assert.strictEqual(withCount, 1); 4346 assert.strictEqual(withoutCount, 0); 4347 done(); 4348 }, 64); 4349 }); 4350 4351 QUnit.test('should support a `maxWait` option', function(assert) { 4352 assert.expect(4); 4353 4354 var done = assert.async(); 4355 4356 var callCount = 0; 4357 4358 var debounced = _.debounce(function(value) { 4359 ++callCount; 4360 return value; 4361 }, 32, { 'maxWait': 64 }); 4362 4363 debounced(); 4364 debounced(); 4365 assert.strictEqual(callCount, 0); 4366 4367 setTimeout(function() { 4368 assert.strictEqual(callCount, 1); 4369 debounced(); 4370 debounced(); 4371 assert.strictEqual(callCount, 1); 4372 }, 128); 4373 4374 setTimeout(function() { 4375 assert.strictEqual(callCount, 2); 4376 done(); 4377 }, 256); 4378 }); 4379 4380 QUnit.test('should support `maxWait` in a tight loop', function(assert) { 4381 assert.expect(1); 4382 4383 var done = assert.async(); 4384 4385 var limit = (argv || isPhantom) ? 1000 : 320, 4386 withCount = 0, 4387 withoutCount = 0; 4388 4389 var withMaxWait = _.debounce(function() { 4390 withCount++; 4391 }, 64, { 'maxWait': 128 }); 4392 4393 var withoutMaxWait = _.debounce(function() { 4394 withoutCount++; 4395 }, 96); 4396 4397 var start = +new Date; 4398 while ((new Date - start) < limit) { 4399 withMaxWait(); 4400 withoutMaxWait(); 4401 } 4402 var actual = [Boolean(withoutCount), Boolean(withCount)]; 4403 setTimeout(function() { 4404 assert.deepEqual(actual, [false, true]); 4405 done(); 4406 }, 1); 4407 }); 4408 4409 QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) { 4410 assert.expect(1); 4411 4412 var done = assert.async(); 4413 4414 var callCount = 0; 4415 4416 var debounced = _.debounce(function() { 4417 ++callCount; 4418 }, 200, { 'maxWait': 200 }); 4419 4420 debounced(); 4421 4422 setTimeout(debounced, 190); 4423 setTimeout(debounced, 200); 4424 setTimeout(debounced, 210); 4425 4426 setTimeout(function() { 4427 assert.strictEqual(callCount, 2); 4428 done(); 4429 }, 500); 4430 }); 4431 4432 QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) { 4433 assert.expect(2); 4434 4435 var done = assert.async(); 4436 4437 var callCount = 0; 4438 4439 var debounced = _.debounce(function() { 4440 callCount++; 4441 }, 32, { 'maxWait': 64 }); 4442 4443 debounced(); 4444 4445 setTimeout(function() { 4446 debounced(); 4447 assert.strictEqual(callCount, 1); 4448 }, 128); 4449 4450 setTimeout(function() { 4451 assert.strictEqual(callCount, 2); 4452 done(); 4453 }, 192); 4454 }); 4455 4456 QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) { 4457 assert.expect(2); 4458 4459 var done = assert.async(); 4460 4461 var actual, 4462 callCount = 0, 4463 object = {}; 4464 4465 var debounced = _.debounce(function(value) { 4466 actual = [this]; 4467 push.apply(actual, arguments); 4468 return ++callCount != 2; 4469 }, 32, { 'leading': true, 'maxWait': 64 }); 4470 4471 while (true) { 4472 if (!debounced.call(object, 'a')) { 4473 break; 4474 } 4475 } 4476 setTimeout(function() { 4477 assert.strictEqual(callCount, 2); 4478 assert.deepEqual(actual, [object, 'a']); 4479 done(); 4480 }, 64); 4481 }); 4482 }()); 4483 4484 /*--------------------------------------------------------------------------*/ 4485 4486 QUnit.module('lodash.deburr'); 4487 4488 (function() { 4489 QUnit.test('should convert Latin Unicode letters to basic Latin', function(assert) { 4490 assert.expect(1); 4491 4492 var actual = lodashStable.map(burredLetters, _.deburr); 4493 assert.deepEqual(actual, deburredLetters); 4494 }); 4495 4496 QUnit.test('should not deburr Latin mathematical operators', function(assert) { 4497 assert.expect(1); 4498 4499 var operators = ['\xd7', '\xf7'], 4500 actual = lodashStable.map(operators, _.deburr); 4501 4502 assert.deepEqual(actual, operators); 4503 }); 4504 4505 QUnit.test('should deburr combining diacritical marks', function(assert) { 4506 assert.expect(1); 4507 4508 var expected = lodashStable.map(comboMarks, lodashStable.constant('ei')); 4509 4510 var actual = lodashStable.map(comboMarks, function(chr) { 4511 return _.deburr('e' + chr + 'i'); 4512 }); 4513 4514 assert.deepEqual(actual, expected); 4515 }); 4516 }()); 4517 4518 /*--------------------------------------------------------------------------*/ 4519 4520 QUnit.module('lodash.defaults'); 4521 4522 (function() { 4523 QUnit.test('should assign source properties if missing on `object`', function(assert) { 4524 assert.expect(1); 4525 4526 var actual = _.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }); 4527 assert.deepEqual(actual, { 'a': 1, 'b': 2 }); 4528 }); 4529 4530 QUnit.test('should accept multiple sources', function(assert) { 4531 assert.expect(2); 4532 4533 var expected = { 'a': 1, 'b': 2, 'c': 3 }, 4534 actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }); 4535 4536 assert.deepEqual(actual, expected); 4537 4538 actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }); 4539 assert.deepEqual(actual, expected); 4540 }); 4541 4542 QUnit.test('should not overwrite `null` values', function(assert) { 4543 assert.expect(1); 4544 4545 var actual = _.defaults({ 'a': null }, { 'a': 1 }); 4546 assert.strictEqual(actual.a, null); 4547 }); 4548 4549 QUnit.test('should overwrite `undefined` values', function(assert) { 4550 assert.expect(1); 4551 4552 var actual = _.defaults({ 'a': undefined }, { 'a': 1 }); 4553 assert.strictEqual(actual.a, 1); 4554 }); 4555 4556 QUnit.test('should assign `undefined` values', function(assert) { 4557 assert.expect(1); 4558 4559 var source = { 'a': undefined, 'b': 1 }, 4560 actual = _.defaults({}, source); 4561 4562 assert.deepEqual(actual, { 'a': undefined, 'b': 1 }); 4563 }); 4564 4565 QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) { 4566 assert.expect(2); 4567 4568 var object = { 4569 'constructor': objectProto.constructor, 4570 'hasOwnProperty': objectProto.hasOwnProperty, 4571 'isPrototypeOf': objectProto.isPrototypeOf, 4572 'propertyIsEnumerable': objectProto.propertyIsEnumerable, 4573 'toLocaleString': objectProto.toLocaleString, 4574 'toString': objectProto.toString, 4575 'valueOf': objectProto.valueOf 4576 }; 4577 4578 var source = { 4579 'constructor': 1, 4580 'hasOwnProperty': 2, 4581 'isPrototypeOf': 3, 4582 'propertyIsEnumerable': 4, 4583 'toLocaleString': 5, 4584 'toString': 6, 4585 'valueOf': 7 4586 }; 4587 4588 var expected = lodashStable.clone(source); 4589 assert.deepEqual(_.defaults({}, source), expected); 4590 4591 expected = lodashStable.clone(object); 4592 assert.deepEqual(_.defaults({}, object, source), expected); 4593 }); 4594 }()); 4595 4596 /*--------------------------------------------------------------------------*/ 4597 4598 QUnit.module('lodash.defaultsDeep'); 4599 4600 (function() { 4601 QUnit.test('should deep assign source properties if missing on `object`', function(assert) { 4602 assert.expect(1); 4603 4604 var object = { 'a': { 'b': 2 }, 'd': 4 }, 4605 source = { 'a': { 'b': 3, 'c': 3 }, 'e': 5 }, 4606 expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 }; 4607 4608 assert.deepEqual(_.defaultsDeep(object, source), expected); 4609 }); 4610 4611 QUnit.test('should accept multiple sources', function(assert) { 4612 assert.expect(2); 4613 4614 var source1 = { 'a': { 'b': 3 } }, 4615 source2 = { 'a': { 'c': 3 } }, 4616 source3 = { 'a': { 'b': 3, 'c': 3 } }, 4617 source4 = { 'a': { 'c': 4 } }, 4618 expected = { 'a': { 'b': 2, 'c': 3 } }; 4619 4620 assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected); 4621 assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected); 4622 }); 4623 4624 QUnit.test('should not overwrite `null` values', function(assert) { 4625 assert.expect(1); 4626 4627 var object = { 'a': { 'b': null } }, 4628 source = { 'a': { 'b': 2 } }, 4629 actual = _.defaultsDeep(object, source); 4630 4631 assert.strictEqual(actual.a.b, null); 4632 }); 4633 4634 QUnit.test('should not overwrite regexp values', function(assert) { 4635 assert.expect(1); 4636 4637 var object = { 'a': { 'b': /x/ } }, 4638 source = { 'a': { 'b': /y/ } }, 4639 actual = _.defaultsDeep(object, source); 4640 4641 assert.deepEqual(actual.a.b, /x/); 4642 }); 4643 4644 QUnit.test('should not convert function properties to objects', function(assert) { 4645 assert.expect(2); 4646 4647 var actual = _.defaultsDeep({}, { 'a': noop }); 4648 assert.strictEqual(actual.a, noop); 4649 4650 actual = _.defaultsDeep({}, { 'a': { 'b': noop } }); 4651 assert.strictEqual(actual.a.b, noop); 4652 }); 4653 4654 QUnit.test('should overwrite `undefined` values', function(assert) { 4655 assert.expect(1); 4656 4657 var object = { 'a': { 'b': undefined } }, 4658 source = { 'a': { 'b': 2 } }, 4659 actual = _.defaultsDeep(object, source); 4660 4661 assert.strictEqual(actual.a.b, 2); 4662 }); 4663 4664 QUnit.test('should assign `undefined` values', function(assert) { 4665 assert.expect(1); 4666 4667 var source = { 'a': undefined, 'b': { 'c': undefined, 'd': 1 } }, 4668 expected = lodashStable.cloneDeep(source), 4669 actual = _.defaultsDeep({}, source); 4670 4671 assert.deepEqual(actual, expected); 4672 }); 4673 4674 QUnit.test('should merge sources containing circular references', function(assert) { 4675 assert.expect(2); 4676 4677 var object = { 4678 'foo': { 'b': { 'c': { 'd': {} } } }, 4679 'bar': { 'a': 2 } 4680 }; 4681 4682 var source = { 4683 'foo': { 'b': { 'c': { 'd': {} } } }, 4684 'bar': {} 4685 }; 4686 4687 object.foo.b.c.d = object; 4688 source.foo.b.c.d = source; 4689 source.bar.b = source.foo.b; 4690 4691 var actual = _.defaultsDeep(object, source); 4692 4693 assert.strictEqual(actual.bar.b, actual.foo.b); 4694 assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d); 4695 }); 4696 4697 QUnit.test('should not modify sources', function(assert) { 4698 assert.expect(3); 4699 4700 var source1 = { 'a': 1, 'b': { 'c': 2 } }, 4701 source2 = { 'b': { 'c': 3, 'd': 3 } }, 4702 actual = _.defaultsDeep({}, source1, source2); 4703 4704 assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } }); 4705 assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } }); 4706 assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } }); 4707 }); 4708 4709 QUnit.test('should not attempt a merge of a string into an array', function(assert) { 4710 assert.expect(1); 4711 4712 var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' }); 4713 assert.deepEqual(actual.a, ['abc']); 4714 }); 4715 4716 QUnit.test('should not indirectly merge `Object` properties', function(assert) { 4717 assert.expect(1); 4718 4719 _.defaultsDeep({}, { 'constructor': { 'a': 1 } }); 4720 4721 var actual = 'a' in Object; 4722 delete Object.a; 4723 4724 assert.notOk(actual); 4725 }); 4726 }()); 4727 4728 /*--------------------------------------------------------------------------*/ 4729 4730 QUnit.module('lodash.defaultTo'); 4731 4732 (function() { 4733 QUnit.test('should return a default value if `value` is `NaN` or nullish', function(assert) { 4734 assert.expect(1); 4735 4736 var expected = lodashStable.map(falsey, function(value) { 4737 return (value == null || value !== value) ? 1 : value; 4738 }); 4739 4740 var actual = lodashStable.map(falsey, function(value) { 4741 return _.defaultTo(value, 1); 4742 }); 4743 4744 assert.deepEqual(actual, expected); 4745 }); 4746 }()); 4747 4748 /*--------------------------------------------------------------------------*/ 4749 4750 QUnit.module('lodash.defer'); 4751 4752 (function() { 4753 QUnit.test('should defer `func` execution', function(assert) { 4754 assert.expect(1); 4755 4756 var done = assert.async(); 4757 4758 var pass = false; 4759 _.defer(function() { pass = true; }); 4760 4761 setTimeout(function() { 4762 assert.ok(pass); 4763 done(); 4764 }, 32); 4765 }); 4766 4767 QUnit.test('should provide additional arguments to `func`', function(assert) { 4768 assert.expect(1); 4769 4770 var done = assert.async(); 4771 4772 var args; 4773 4774 _.defer(function() { 4775 args = slice.call(arguments); 4776 }, 1, 2); 4777 4778 setTimeout(function() { 4779 assert.deepEqual(args, [1, 2]); 4780 done(); 4781 }, 32); 4782 }); 4783 4784 QUnit.test('should be cancelable', function(assert) { 4785 assert.expect(1); 4786 4787 var done = assert.async(); 4788 4789 var pass = true, 4790 timerId = _.defer(function() { pass = false; }); 4791 4792 clearTimeout(timerId); 4793 4794 setTimeout(function() { 4795 assert.ok(pass); 4796 done(); 4797 }, 32); 4798 }); 4799 }()); 4800 4801 /*--------------------------------------------------------------------------*/ 4802 4803 QUnit.module('lodash.delay'); 4804 4805 (function() { 4806 QUnit.test('should delay `func` execution', function(assert) { 4807 assert.expect(2); 4808 4809 var done = assert.async(); 4810 4811 var pass = false; 4812 _.delay(function() { pass = true; }, 32); 4813 4814 setTimeout(function() { 4815 assert.notOk(pass); 4816 }, 1); 4817 4818 setTimeout(function() { 4819 assert.ok(pass); 4820 done(); 4821 }, 64); 4822 }); 4823 4824 QUnit.test('should provide additional arguments to `func`', function(assert) { 4825 assert.expect(1); 4826 4827 var done = assert.async(); 4828 4829 var args; 4830 4831 _.delay(function() { 4832 args = slice.call(arguments); 4833 }, 32, 1, 2); 4834 4835 setTimeout(function() { 4836 assert.deepEqual(args, [1, 2]); 4837 done(); 4838 }, 64); 4839 }); 4840 4841 QUnit.test('should use a default `wait` of `0`', function(assert) { 4842 assert.expect(2); 4843 4844 var done = assert.async(); 4845 4846 var pass = false; 4847 _.delay(function() { pass = true; }); 4848 4849 assert.notOk(pass); 4850 4851 setTimeout(function() { 4852 assert.ok(pass); 4853 done(); 4854 }, 0); 4855 }); 4856 4857 QUnit.test('should be cancelable', function(assert) { 4858 assert.expect(1); 4859 4860 var done = assert.async(); 4861 4862 var pass = true, 4863 timerId = _.delay(function() { pass = false; }, 32); 4864 4865 clearTimeout(timerId); 4866 4867 setTimeout(function() { 4868 assert.ok(pass); 4869 done(); 4870 }, 64); 4871 }); 4872 4873 QUnit.test('should work with mocked `setTimeout`', function(assert) { 4874 assert.expect(1); 4875 4876 if (!isPhantom) { 4877 var pass = false, 4878 setTimeout = root.setTimeout; 4879 4880 setProperty(root, 'setTimeout', function(func) { func(); }); 4881 _.delay(function() { pass = true; }, 32); 4882 setProperty(root, 'setTimeout', setTimeout); 4883 4884 assert.ok(pass); 4885 } 4886 else { 4887 skipAssert(assert); 4888 } 4889 }); 4890 }()); 4891 4892 /*--------------------------------------------------------------------------*/ 4893 4894 QUnit.module('difference methods'); 4895 4896 lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) { 4897 var func = _[methodName]; 4898 4899 QUnit.test('`_.' + methodName + '` should return the difference of two arrays', function(assert) { 4900 assert.expect(1); 4901 4902 var actual = func([2, 1], [2, 3]); 4903 assert.deepEqual(actual, [1]); 4904 }); 4905 4906 QUnit.test('`_.' + methodName + '` should return the difference of multiple arrays', function(assert) { 4907 assert.expect(1); 4908 4909 var actual = func([2, 1, 2, 3], [3, 4], [3, 2]); 4910 assert.deepEqual(actual, [1]); 4911 }); 4912 4913 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) { 4914 assert.expect(2); 4915 4916 var array = [-0, 0]; 4917 4918 var actual = lodashStable.map(array, function(value) { 4919 return func(array, [value]); 4920 }); 4921 4922 assert.deepEqual(actual, [[], []]); 4923 4924 actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString); 4925 assert.deepEqual(actual, ['0']); 4926 }); 4927 4928 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { 4929 assert.expect(1); 4930 4931 assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]); 4932 }); 4933 4934 QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) { 4935 assert.expect(1); 4936 4937 var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1), 4938 array2 = lodashStable.range(LARGE_ARRAY_SIZE), 4939 a = {}, 4940 b = {}, 4941 c = {}; 4942 4943 array1.push(a, b, c); 4944 array2.push(b, c, a); 4945 4946 assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]); 4947 }); 4948 4949 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) { 4950 assert.expect(2); 4951 4952 var array = [-0, 0]; 4953 4954 var actual = lodashStable.map(array, function(value) { 4955 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value)); 4956 return func(array, largeArray); 4957 }); 4958 4959 assert.deepEqual(actual, [[], []]); 4960 4961 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne); 4962 actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString); 4963 assert.deepEqual(actual, ['0']); 4964 }); 4965 4966 QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) { 4967 assert.expect(1); 4968 4969 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN); 4970 assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]); 4971 }); 4972 4973 QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) { 4974 assert.expect(1); 4975 4976 var object1 = {}, 4977 object2 = {}, 4978 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1)); 4979 4980 assert.deepEqual(func([object1, object2], largeArray), [object2]); 4981 }); 4982 4983 QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) { 4984 assert.expect(3); 4985 4986 var array = [1, null, 3]; 4987 4988 assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]); 4989 assert.deepEqual(func(null, array, 1), []); 4990 assert.deepEqual(func(array, args, null), [null]); 4991 }); 4992 }); 4993 4994 /*--------------------------------------------------------------------------*/ 4995 4996 QUnit.module('lodash.differenceBy'); 4997 4998 (function() { 4999 QUnit.test('should accept an `iteratee`', function(assert) { 5000 assert.expect(2); 5001 5002 var actual = _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); 5003 assert.deepEqual(actual, [1.2]); 5004 5005 actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); 5006 assert.deepEqual(actual, [{ 'x': 2 }]); 5007 }); 5008 5009 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 5010 assert.expect(1); 5011 5012 var args; 5013 5014 _.differenceBy([2.1, 1.2], [2.3, 3.4], function() { 5015 args || (args = slice.call(arguments)); 5016 }); 5017 5018 assert.deepEqual(args, [2.3]); 5019 }); 5020 }()); 5021 5022 /*--------------------------------------------------------------------------*/ 5023 5024 QUnit.module('lodash.differenceWith'); 5025 5026 (function() { 5027 QUnit.test('should work with a `comparator`', function(assert) { 5028 assert.expect(1); 5029 5030 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }], 5031 actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual); 5032 5033 assert.deepEqual(actual, [objects[1]]); 5034 }); 5035 5036 QUnit.test('should preserve the sign of `0`', function(assert) { 5037 assert.expect(1); 5038 5039 var array = [-0, 1], 5040 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubOne), 5041 others = [[1], largeArray], 5042 expected = lodashStable.map(others, lodashStable.constant(['-0'])); 5043 5044 var actual = lodashStable.map(others, function(other) { 5045 return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString); 5046 }); 5047 5048 assert.deepEqual(actual, expected); 5049 }); 5050 }()); 5051 5052 /*--------------------------------------------------------------------------*/ 5053 5054 QUnit.module('lodash.divide'); 5055 5056 (function() { 5057 QUnit.test('should divide two numbers', function(assert) { 5058 assert.expect(3); 5059 5060 assert.strictEqual(_.divide(6, 4), 1.5); 5061 assert.strictEqual(_.divide(-6, 4), -1.5); 5062 assert.strictEqual(_.divide(-6, -4), 1.5); 5063 }); 5064 5065 QUnit.test('should coerce arguments to numbers', function(assert) { 5066 assert.expect(2); 5067 5068 assert.strictEqual(_.divide('6', '4'), 1.5); 5069 assert.deepEqual(_.divide('x', 'y'), NaN); 5070 }); 5071 }()); 5072 5073 /*--------------------------------------------------------------------------*/ 5074 5075 QUnit.module('lodash.drop'); 5076 5077 (function() { 5078 var array = [1, 2, 3]; 5079 5080 QUnit.test('should drop the first two elements', function(assert) { 5081 assert.expect(1); 5082 5083 assert.deepEqual(_.drop(array, 2), [3]); 5084 }); 5085 5086 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) { 5087 assert.expect(1); 5088 5089 var expected = lodashStable.map(falsey, function(value) { 5090 return value === undefined ? [2, 3] : array; 5091 }); 5092 5093 var actual = lodashStable.map(falsey, function(n) { 5094 return _.drop(array, n); 5095 }); 5096 5097 assert.deepEqual(actual, expected); 5098 }); 5099 5100 QUnit.test('should return all elements when `n` < `1`', function(assert) { 5101 assert.expect(3); 5102 5103 lodashStable.each([0, -1, -Infinity], function(n) { 5104 assert.deepEqual(_.drop(array, n), array); 5105 }); 5106 }); 5107 5108 QUnit.test('should return an empty array when `n` >= `length`', function(assert) { 5109 assert.expect(4); 5110 5111 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { 5112 assert.deepEqual(_.drop(array, n), []); 5113 }); 5114 }); 5115 5116 QUnit.test('should coerce `n` to an integer', function(assert) { 5117 assert.expect(1); 5118 5119 assert.deepEqual(_.drop(array, 1.6), [2, 3]); 5120 }); 5121 5122 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 5123 assert.expect(1); 5124 5125 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 5126 actual = lodashStable.map(array, _.drop); 5127 5128 assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]); 5129 }); 5130 5131 QUnit.test('should work in a lazy sequence', function(assert) { 5132 assert.expect(6); 5133 5134 if (!isNpm) { 5135 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 5136 predicate = function(value) { values.push(value); return isEven(value); }, 5137 values = [], 5138 actual = _(array).drop(2).drop().value(); 5139 5140 assert.deepEqual(actual, array.slice(3)); 5141 5142 actual = _(array).filter(predicate).drop(2).drop().value(); 5143 assert.deepEqual(values, array); 5144 assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2))); 5145 5146 actual = _(array).drop(2).dropRight().drop().dropRight(2).value(); 5147 assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2)); 5148 5149 values = []; 5150 5151 actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value(); 5152 assert.deepEqual(values, array.slice(1)); 5153 assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2)); 5154 } 5155 else { 5156 skipAssert(assert, 6); 5157 } 5158 }); 5159 }()); 5160 5161 /*--------------------------------------------------------------------------*/ 5162 5163 QUnit.module('lodash.dropRight'); 5164 5165 (function() { 5166 var array = [1, 2, 3]; 5167 5168 QUnit.test('should drop the last two elements', function(assert) { 5169 assert.expect(1); 5170 5171 assert.deepEqual(_.dropRight(array, 2), [1]); 5172 }); 5173 5174 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) { 5175 assert.expect(1); 5176 5177 var expected = lodashStable.map(falsey, function(value) { 5178 return value === undefined ? [1, 2] : array; 5179 }); 5180 5181 var actual = lodashStable.map(falsey, function(n) { 5182 return _.dropRight(array, n); 5183 }); 5184 5185 assert.deepEqual(actual, expected); 5186 }); 5187 5188 QUnit.test('should return all elements when `n` < `1`', function(assert) { 5189 assert.expect(3); 5190 5191 lodashStable.each([0, -1, -Infinity], function(n) { 5192 assert.deepEqual(_.dropRight(array, n), array); 5193 }); 5194 }); 5195 5196 QUnit.test('should return an empty array when `n` >= `length`', function(assert) { 5197 assert.expect(4); 5198 5199 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { 5200 assert.deepEqual(_.dropRight(array, n), []); 5201 }); 5202 }); 5203 5204 QUnit.test('should coerce `n` to an integer', function(assert) { 5205 assert.expect(1); 5206 5207 assert.deepEqual(_.dropRight(array, 1.6), [1, 2]); 5208 }); 5209 5210 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 5211 assert.expect(1); 5212 5213 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 5214 actual = lodashStable.map(array, _.dropRight); 5215 5216 assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]); 5217 }); 5218 5219 QUnit.test('should work in a lazy sequence', function(assert) { 5220 assert.expect(6); 5221 5222 if (!isNpm) { 5223 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 5224 predicate = function(value) { values.push(value); return isEven(value); }, 5225 values = [], 5226 actual = _(array).dropRight(2).dropRight().value(); 5227 5228 assert.deepEqual(actual, array.slice(0, -3)); 5229 5230 actual = _(array).filter(predicate).dropRight(2).dropRight().value(); 5231 assert.deepEqual(values, array); 5232 assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2))); 5233 5234 actual = _(array).dropRight(2).drop().dropRight().drop(2).value(); 5235 assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2)); 5236 5237 values = []; 5238 5239 actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value(); 5240 assert.deepEqual(values, array.slice(0, -1)); 5241 assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2)); 5242 } 5243 else { 5244 skipAssert(assert, 6); 5245 } 5246 }); 5247 }()); 5248 5249 /*--------------------------------------------------------------------------*/ 5250 5251 QUnit.module('lodash.dropRightWhile'); 5252 5253 (function() { 5254 var array = [1, 2, 3, 4]; 5255 5256 var objects = [ 5257 { 'a': 0, 'b': 0 }, 5258 { 'a': 1, 'b': 1 }, 5259 { 'a': 2, 'b': 2 } 5260 ]; 5261 5262 QUnit.test('should drop elements while `predicate` returns truthy', function(assert) { 5263 assert.expect(1); 5264 5265 var actual = _.dropRightWhile(array, function(n) { 5266 return n > 2; 5267 }); 5268 5269 assert.deepEqual(actual, [1, 2]); 5270 }); 5271 5272 QUnit.test('should provide correct `predicate` arguments', function(assert) { 5273 assert.expect(1); 5274 5275 var args; 5276 5277 _.dropRightWhile(array, function() { 5278 args = slice.call(arguments); 5279 }); 5280 5281 assert.deepEqual(args, [4, 3, array]); 5282 }); 5283 5284 QUnit.test('should work with `_.matches` shorthands', function(assert) { 5285 assert.expect(1); 5286 5287 assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2)); 5288 }); 5289 5290 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 5291 assert.expect(1); 5292 5293 assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2)); 5294 }); 5295 5296 QUnit.test('should work with `_.property` shorthands', function(assert) { 5297 assert.expect(1); 5298 5299 assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1)); 5300 }); 5301 5302 QUnit.test('should return a wrapped value when chaining', function(assert) { 5303 assert.expect(2); 5304 5305 if (!isNpm) { 5306 var wrapped = _(array).dropRightWhile(function(n) { 5307 return n > 2; 5308 }); 5309 5310 assert.ok(wrapped instanceof _); 5311 assert.deepEqual(wrapped.value(), [1, 2]); 5312 } 5313 else { 5314 skipAssert(assert, 2); 5315 } 5316 }); 5317 }()); 5318 5319 /*--------------------------------------------------------------------------*/ 5320 5321 QUnit.module('lodash.dropWhile'); 5322 5323 (function() { 5324 var array = [1, 2, 3, 4]; 5325 5326 var objects = [ 5327 { 'a': 2, 'b': 2 }, 5328 { 'a': 1, 'b': 1 }, 5329 { 'a': 0, 'b': 0 } 5330 ]; 5331 5332 QUnit.test('should drop elements while `predicate` returns truthy', function(assert) { 5333 assert.expect(1); 5334 5335 var actual = _.dropWhile(array, function(n) { 5336 return n < 3; 5337 }); 5338 5339 assert.deepEqual(actual, [3, 4]); 5340 }); 5341 5342 QUnit.test('should provide correct `predicate` arguments', function(assert) { 5343 assert.expect(1); 5344 5345 var args; 5346 5347 _.dropWhile(array, function() { 5348 args = slice.call(arguments); 5349 }); 5350 5351 assert.deepEqual(args, [1, 0, array]); 5352 }); 5353 5354 QUnit.test('should work with `_.matches` shorthands', function(assert) { 5355 assert.expect(1); 5356 5357 assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1)); 5358 }); 5359 5360 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 5361 assert.expect(1); 5362 5363 assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1)); 5364 }); 5365 5366 QUnit.test('should work with `_.property` shorthands', function(assert) { 5367 assert.expect(1); 5368 5369 assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2)); 5370 }); 5371 5372 QUnit.test('should work in a lazy sequence', function(assert) { 5373 assert.expect(3); 5374 5375 if (!isNpm) { 5376 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3), 5377 predicate = function(n) { return n < 3; }, 5378 expected = _.dropWhile(array, predicate), 5379 wrapped = _(array).dropWhile(predicate); 5380 5381 assert.deepEqual(wrapped.value(), expected); 5382 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse()); 5383 assert.strictEqual(wrapped.last(), _.last(expected)); 5384 } 5385 else { 5386 skipAssert(assert, 3); 5387 } 5388 }); 5389 5390 QUnit.test('should work in a lazy sequence with `drop`', function(assert) { 5391 assert.expect(1); 5392 5393 if (!isNpm) { 5394 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3); 5395 5396 var actual = _(array) 5397 .dropWhile(function(n) { return n == 1; }) 5398 .drop() 5399 .dropWhile(function(n) { return n == 3; }) 5400 .value(); 5401 5402 assert.deepEqual(actual, array.slice(3)); 5403 } 5404 else { 5405 skipAssert(assert); 5406 } 5407 }); 5408 }()); 5409 5410 /*--------------------------------------------------------------------------*/ 5411 5412 QUnit.module('lodash.endsWith'); 5413 5414 (function() { 5415 var string = 'abc'; 5416 5417 QUnit.test('should return `true` if a string ends with `target`', function(assert) { 5418 assert.expect(1); 5419 5420 assert.strictEqual(_.endsWith(string, 'c'), true); 5421 }); 5422 5423 QUnit.test('should return `false` if a string does not end with `target`', function(assert) { 5424 assert.expect(1); 5425 5426 assert.strictEqual(_.endsWith(string, 'b'), false); 5427 }); 5428 5429 QUnit.test('should work with a `position`', function(assert) { 5430 assert.expect(1); 5431 5432 assert.strictEqual(_.endsWith(string, 'b', 2), true); 5433 }); 5434 5435 QUnit.test('should work with `position` >= `length`', function(assert) { 5436 assert.expect(4); 5437 5438 lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) { 5439 assert.strictEqual(_.endsWith(string, 'c', position), true); 5440 }); 5441 }); 5442 5443 QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) { 5444 assert.expect(1); 5445 5446 var expected = lodashStable.map(falsey, stubTrue); 5447 5448 var actual = lodashStable.map(falsey, function(position) { 5449 return _.endsWith(string, position === undefined ? 'c' : '', position); 5450 }); 5451 5452 assert.deepEqual(actual, expected); 5453 }); 5454 5455 QUnit.test('should treat a negative `position` as `0`', function(assert) { 5456 assert.expect(6); 5457 5458 lodashStable.each([-1, -3, -Infinity], function(position) { 5459 assert.ok(lodashStable.every(string, function(chr) { 5460 return !_.endsWith(string, chr, position); 5461 })); 5462 assert.strictEqual(_.endsWith(string, '', position), true); 5463 }); 5464 }); 5465 5466 QUnit.test('should coerce `position` to an integer', function(assert) { 5467 assert.expect(1); 5468 5469 assert.strictEqual(_.endsWith(string, 'ab', 2.2), true); 5470 }); 5471 }()); 5472 5473 /*--------------------------------------------------------------------------*/ 5474 5475 QUnit.module('lodash.eq'); 5476 5477 (function() { 5478 QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) { 5479 assert.expect(11); 5480 5481 assert.strictEqual(_.eq(), true); 5482 assert.strictEqual(_.eq(undefined), true); 5483 assert.strictEqual(_.eq(0, -0), true); 5484 assert.strictEqual(_.eq(NaN, NaN), true); 5485 assert.strictEqual(_.eq(1, 1), true); 5486 5487 assert.strictEqual(_.eq(null, undefined), false); 5488 assert.strictEqual(_.eq(1, Object(1)), false); 5489 assert.strictEqual(_.eq(1, '1'), false); 5490 assert.strictEqual(_.eq(1, '1'), false); 5491 5492 var object = { 'a': 1 }; 5493 assert.strictEqual(_.eq(object, object), true); 5494 assert.strictEqual(_.eq(object, { 'a': 1 }), false); 5495 }); 5496 }()); 5497 5498 /*--------------------------------------------------------------------------*/ 5499 5500 QUnit.module('lodash.escape'); 5501 5502 (function() { 5503 var escaped = '&<>"'/', 5504 unescaped = '&<>"\'/'; 5505 5506 escaped += escaped; 5507 unescaped += unescaped; 5508 5509 QUnit.test('should escape values', function(assert) { 5510 assert.expect(1); 5511 5512 assert.strictEqual(_.escape(unescaped), escaped); 5513 }); 5514 5515 QUnit.test('should handle strings with nothing to escape', function(assert) { 5516 assert.expect(1); 5517 5518 assert.strictEqual(_.escape('abc'), 'abc'); 5519 }); 5520 5521 QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) { 5522 assert.expect(1); 5523 5524 assert.strictEqual(_.escape(_.unescape(escaped)), escaped); 5525 }); 5526 5527 lodashStable.each(['`', '/'], function(chr) { 5528 QUnit.test('should not escape the "' + chr + '" character', function(assert) { 5529 assert.expect(1); 5530 5531 assert.strictEqual(_.escape(chr), chr); 5532 }); 5533 }); 5534 }()); 5535 5536 /*--------------------------------------------------------------------------*/ 5537 5538 QUnit.module('lodash.escapeRegExp'); 5539 5540 (function() { 5541 var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\', 5542 unescaped = '^$.*+?()[]{}|\\'; 5543 5544 QUnit.test('should escape values', function(assert) { 5545 assert.expect(1); 5546 5547 assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped); 5548 }); 5549 5550 QUnit.test('should handle strings with nothing to escape', function(assert) { 5551 assert.expect(1); 5552 5553 assert.strictEqual(_.escapeRegExp('abc'), 'abc'); 5554 }); 5555 5556 QUnit.test('should return an empty string for empty values', function(assert) { 5557 assert.expect(1); 5558 5559 var values = [, null, undefined, ''], 5560 expected = lodashStable.map(values, stubString); 5561 5562 var actual = lodashStable.map(values, function(value, index) { 5563 return index ? _.escapeRegExp(value) : _.escapeRegExp(); 5564 }); 5565 5566 assert.deepEqual(actual, expected); 5567 }); 5568 }()); 5569 5570 /*--------------------------------------------------------------------------*/ 5571 5572 QUnit.module('lodash.every'); 5573 5574 (function() { 5575 QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) { 5576 assert.expect(1); 5577 5578 assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true); 5579 }); 5580 5581 QUnit.test('should return `true` for empty collections', function(assert) { 5582 assert.expect(1); 5583 5584 var expected = lodashStable.map(empties, stubTrue); 5585 5586 var actual = lodashStable.map(empties, function(value) { 5587 try { 5588 return _.every(value, identity); 5589 } catch (e) {} 5590 }); 5591 5592 assert.deepEqual(actual, expected); 5593 }); 5594 5595 QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) { 5596 assert.expect(2); 5597 5598 var count = 0; 5599 5600 assert.strictEqual(_.every([true, null, true], function(value) { 5601 count++; 5602 return value; 5603 }), false); 5604 5605 assert.strictEqual(count, 2); 5606 }); 5607 5608 QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) { 5609 assert.expect(1); 5610 5611 assert.strictEqual(_.every([undefined, undefined, undefined], identity), false); 5612 }); 5613 5614 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) { 5615 assert.expect(2); 5616 5617 var values = [, null, undefined], 5618 expected = lodashStable.map(values, stubFalse); 5619 5620 var actual = lodashStable.map(values, function(value, index) { 5621 var array = [0]; 5622 return index ? _.every(array, value) : _.every(array); 5623 }); 5624 5625 assert.deepEqual(actual, expected); 5626 5627 expected = lodashStable.map(values, stubTrue); 5628 actual = lodashStable.map(values, function(value, index) { 5629 var array = [1]; 5630 return index ? _.every(array, value) : _.every(array); 5631 }); 5632 5633 assert.deepEqual(actual, expected); 5634 }); 5635 5636 QUnit.test('should work with `_.property` shorthands', function(assert) { 5637 assert.expect(2); 5638 5639 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }]; 5640 assert.strictEqual(_.every(objects, 'a'), false); 5641 assert.strictEqual(_.every(objects, 'b'), true); 5642 }); 5643 5644 QUnit.test('should work with `_.matches` shorthands', function(assert) { 5645 assert.expect(2); 5646 5647 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }]; 5648 assert.strictEqual(_.every(objects, { 'a': 0 }), true); 5649 assert.strictEqual(_.every(objects, { 'b': 1 }), false); 5650 }); 5651 5652 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 5653 assert.expect(1); 5654 5655 var actual = lodashStable.map([[1]], _.every); 5656 assert.deepEqual(actual, [true]); 5657 }); 5658 }()); 5659 5660 /*--------------------------------------------------------------------------*/ 5661 5662 QUnit.module('strict mode checks'); 5663 5664 lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults', 'defaultsDeep', 'merge'], function(methodName) { 5665 var func = _[methodName], 5666 isBindAll = methodName == 'bindAll'; 5667 5668 QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) { 5669 assert.expect(1); 5670 5671 var object = freeze({ 'a': undefined, 'b': function() {} }), 5672 pass = !isStrict; 5673 5674 try { 5675 func(object, isBindAll ? 'b' : { 'a': 1 }); 5676 } catch (e) { 5677 pass = !pass; 5678 } 5679 assert.ok(pass); 5680 }); 5681 }); 5682 5683 /*--------------------------------------------------------------------------*/ 5684 5685 QUnit.module('lodash.fill'); 5686 5687 (function() { 5688 QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) { 5689 assert.expect(1); 5690 5691 var array = [1, 2, 3]; 5692 assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']); 5693 }); 5694 5695 QUnit.test('should use `undefined` for `value` if not given', function(assert) { 5696 assert.expect(2); 5697 5698 var array = [1, 2, 3], 5699 actual = _.fill(array); 5700 5701 assert.deepEqual(actual, Array(3)); 5702 assert.ok(lodashStable.every(actual, function(value, index) { 5703 return index in actual; 5704 })); 5705 }); 5706 5707 QUnit.test('should work with a positive `start`', function(assert) { 5708 assert.expect(1); 5709 5710 var array = [1, 2, 3]; 5711 assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']); 5712 }); 5713 5714 QUnit.test('should work with a `start` >= `length`', function(assert) { 5715 assert.expect(4); 5716 5717 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) { 5718 var array = [1, 2, 3]; 5719 assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]); 5720 }); 5721 }); 5722 5723 QUnit.test('should treat falsey `start` values as `0`', function(assert) { 5724 assert.expect(1); 5725 5726 var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a'])); 5727 5728 var actual = lodashStable.map(falsey, function(start) { 5729 var array = [1, 2, 3]; 5730 return _.fill(array, 'a', start); 5731 }); 5732 5733 assert.deepEqual(actual, expected); 5734 }); 5735 5736 QUnit.test('should work with a negative `start`', function(assert) { 5737 assert.expect(1); 5738 5739 var array = [1, 2, 3]; 5740 assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']); 5741 }); 5742 5743 QUnit.test('should work with a negative `start` <= negative `length`', function(assert) { 5744 assert.expect(3); 5745 5746 lodashStable.each([-3, -4, -Infinity], function(start) { 5747 var array = [1, 2, 3]; 5748 assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']); 5749 }); 5750 }); 5751 5752 QUnit.test('should work with `start` >= `end`', function(assert) { 5753 assert.expect(2); 5754 5755 lodashStable.each([2, 3], function(start) { 5756 var array = [1, 2, 3]; 5757 assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]); 5758 }); 5759 }); 5760 5761 QUnit.test('should work with a positive `end`', function(assert) { 5762 assert.expect(1); 5763 5764 var array = [1, 2, 3]; 5765 assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]); 5766 }); 5767 5768 QUnit.test('should work with a `end` >= `length`', function(assert) { 5769 assert.expect(4); 5770 5771 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) { 5772 var array = [1, 2, 3]; 5773 assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']); 5774 }); 5775 }); 5776 5777 QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) { 5778 assert.expect(1); 5779 5780 var expected = lodashStable.map(falsey, function(value) { 5781 return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3]; 5782 }); 5783 5784 var actual = lodashStable.map(falsey, function(end) { 5785 var array = [1, 2, 3]; 5786 return _.fill(array, 'a', 0, end); 5787 }); 5788 5789 assert.deepEqual(actual, expected); 5790 }); 5791 5792 QUnit.test('should work with a negative `end`', function(assert) { 5793 assert.expect(1); 5794 5795 var array = [1, 2, 3]; 5796 assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]); 5797 }); 5798 5799 QUnit.test('should work with a negative `end` <= negative `length`', function(assert) { 5800 assert.expect(3); 5801 5802 lodashStable.each([-3, -4, -Infinity], function(end) { 5803 var array = [1, 2, 3]; 5804 assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]); 5805 }); 5806 }); 5807 5808 QUnit.test('should coerce `start` and `end` to integers', function(assert) { 5809 assert.expect(1); 5810 5811 var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]]; 5812 5813 var actual = lodashStable.map(positions, function(pos) { 5814 var array = [1, 2, 3]; 5815 return _.fill.apply(_, [array, 'a'].concat(pos)); 5816 }); 5817 5818 assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]); 5819 }); 5820 5821 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 5822 assert.expect(1); 5823 5824 var array = [[1, 2], [3, 4]], 5825 actual = lodashStable.map(array, _.fill); 5826 5827 assert.deepEqual(actual, [[0, 0], [1, 1]]); 5828 }); 5829 5830 QUnit.test('should return a wrapped value when chaining', function(assert) { 5831 assert.expect(3); 5832 5833 if (!isNpm) { 5834 var array = [1, 2, 3], 5835 wrapped = _(array).fill('a'), 5836 actual = wrapped.value(); 5837 5838 assert.ok(wrapped instanceof _); 5839 assert.strictEqual(actual, array); 5840 assert.deepEqual(actual, ['a', 'a', 'a']); 5841 } 5842 else { 5843 skipAssert(assert, 3); 5844 } 5845 }); 5846 }()); 5847 5848 /*--------------------------------------------------------------------------*/ 5849 5850 QUnit.module('lodash.filter'); 5851 5852 (function() { 5853 var array = [1, 2, 3]; 5854 5855 QUnit.test('should return elements `predicate` returns truthy for', function(assert) { 5856 assert.expect(1); 5857 5858 assert.deepEqual(_.filter(array, isEven), [2]); 5859 }); 5860 }()); 5861 5862 /*--------------------------------------------------------------------------*/ 5863 5864 lodashStable.each(['find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', 'findLastKey'], function(methodName) { 5865 QUnit.module('lodash.' + methodName); 5866 5867 var array = [1, 2, 3, 4], 5868 func = _[methodName]; 5869 5870 var objects = [ 5871 { 'a': 0, 'b': 0 }, 5872 { 'a': 1, 'b': 1 }, 5873 { 'a': 2, 'b': 2 } 5874 ]; 5875 5876 var expected = ({ 5877 'find': [objects[1], undefined, objects[2]], 5878 'findIndex': [1, -1, 2], 5879 'findKey': ['1', undefined, '2'], 5880 'findLast': [objects[2], undefined, objects[2]], 5881 'findLastIndex': [2, -1, 2], 5882 'findLastKey': ['2', undefined, '2'] 5883 })[methodName]; 5884 5885 QUnit.test('`_.' + methodName + '` should return the found value', function(assert) { 5886 assert.expect(1); 5887 5888 assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]); 5889 }); 5890 5891 QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) { 5892 assert.expect(1); 5893 5894 assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]); 5895 }); 5896 5897 QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) { 5898 assert.expect(1); 5899 5900 assert.strictEqual(func(objects, { 'b': 2 }), expected[2]); 5901 }); 5902 5903 QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) { 5904 assert.expect(1); 5905 5906 assert.strictEqual(func(objects, ['b', 2]), expected[2]); 5907 }); 5908 5909 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) { 5910 assert.expect(1); 5911 5912 assert.strictEqual(func(objects, 'b'), expected[0]); 5913 }); 5914 5915 QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) { 5916 assert.expect(1); 5917 5918 var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties, 5919 expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1])); 5920 5921 var actual = lodashStable.map(emptyValues, function(value) { 5922 try { 5923 return func(value, { 'a': 3 }); 5924 } catch (e) {} 5925 }); 5926 5927 assert.deepEqual(actual, expecting); 5928 }); 5929 5930 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 5931 assert.expect(1); 5932 5933 var expected = ({ 5934 'find': 1, 5935 'findIndex': 0, 5936 'findKey': '0', 5937 'findLast': 4, 5938 'findLastIndex': 3, 5939 'findLastKey': '3' 5940 })[methodName]; 5941 5942 if (!isNpm) { 5943 assert.strictEqual(_(array)[methodName](), expected); 5944 } 5945 else { 5946 skipAssert(assert); 5947 } 5948 }); 5949 5950 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 5951 assert.expect(1); 5952 5953 if (!isNpm) { 5954 assert.ok(_(array).chain()[methodName]() instanceof _); 5955 } 5956 else { 5957 skipAssert(assert); 5958 } 5959 }); 5960 5961 QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) { 5962 assert.expect(1); 5963 5964 if (!isNpm) { 5965 var wrapped = _(array).chain()[methodName](); 5966 assert.strictEqual(wrapped.__wrapped__, array); 5967 } 5968 else { 5969 skipAssert(assert); 5970 } 5971 }); 5972 5973 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) { 5974 assert.expect(2); 5975 5976 if (!isNpm) { 5977 var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 5978 smallArray = array; 5979 5980 lodashStable.times(2, function(index) { 5981 var array = index ? largeArray : smallArray, 5982 wrapped = _(array).filter(isEven); 5983 5984 assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven))); 5985 }); 5986 } 5987 else { 5988 skipAssert(assert, 2); 5989 } 5990 }); 5991 }); 5992 5993 _.each(['find', 'findIndex', 'findLast', 'findLastIndex'], function(methodName) { 5994 var func = _[methodName]; 5995 5996 QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for arrays', function(assert) { 5997 assert.expect(1); 5998 5999 var args, 6000 array = ['a']; 6001 6002 func(array, function() { 6003 args || (args = slice.call(arguments)); 6004 }); 6005 6006 assert.deepEqual(args, ['a', 0, array]); 6007 }); 6008 }); 6009 6010 _.each(['find', 'findKey', 'findLast', 'findLastKey'], function(methodName) { 6011 var func = _[methodName]; 6012 6013 QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) { 6014 assert.expect(1); 6015 6016 var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) { 6017 return n < 3; 6018 }); 6019 6020 var expected = ({ 6021 'find': 1, 6022 'findKey': 'a', 6023 'findLast': 2, 6024 'findLastKey': 'b' 6025 })[methodName]; 6026 6027 assert.strictEqual(actual, expected); 6028 }); 6029 6030 QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments for objects', function(assert) { 6031 assert.expect(1); 6032 6033 var args, 6034 object = { 'a': 1 }; 6035 6036 func(object, function() { 6037 args || (args = slice.call(arguments)); 6038 }); 6039 6040 assert.deepEqual(args, [1, 'a', object]); 6041 }); 6042 }); 6043 6044 /*--------------------------------------------------------------------------*/ 6045 6046 QUnit.module('lodash.find and lodash.findLast'); 6047 6048 lodashStable.each(['find', 'findLast'], function(methodName) { 6049 var isFind = methodName == 'find'; 6050 6051 QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) { 6052 assert.expect(3); 6053 6054 if (!isNpm) { 6055 var findCount = 0, 6056 mapCount = 0, 6057 array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 6058 iteratee = function(value) { mapCount++; return square(value); }, 6059 predicate = function(value) { findCount++; return isEven(value); }, 6060 actual = _(array).map(iteratee)[methodName](predicate); 6061 6062 assert.strictEqual(findCount, isFind ? 2 : 1); 6063 assert.strictEqual(mapCount, isFind ? 2 : 1); 6064 assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE)); 6065 } 6066 else { 6067 skipAssert(assert, 3); 6068 } 6069 }); 6070 }); 6071 6072 /*--------------------------------------------------------------------------*/ 6073 6074 QUnit.module('lodash.find and lodash.includes'); 6075 6076 lodashStable.each(['includes', 'find'], function(methodName) { 6077 var func = _[methodName], 6078 isIncludes = methodName == 'includes', 6079 resolve = methodName == 'find' ? lodashStable.curry(lodashStable.eq) : identity; 6080 6081 lodashStable.each({ 6082 'an `arguments` object': args, 6083 'an array': [1, 2, 3] 6084 }, 6085 function(collection, key) { 6086 var values = lodashStable.toArray(collection); 6087 6088 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a positive `fromIndex`', function(assert) { 6089 assert.expect(1); 6090 6091 var expected = [ 6092 isIncludes || values[2], 6093 isIncludes ? false : undefined 6094 ]; 6095 6096 var actual = [ 6097 func(collection, resolve(values[2]), 2), 6098 func(collection, resolve(values[1]), 2) 6099 ]; 6100 6101 assert.deepEqual(actual, expected); 6102 }); 6103 6104 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) { 6105 assert.expect(1); 6106 6107 var indexes = [4, 6, Math.pow(2, 32), Infinity]; 6108 6109 var expected = lodashStable.map(indexes, function() { 6110 var result = isIncludes ? false : undefined; 6111 return [result, result, result]; 6112 }); 6113 6114 var actual = lodashStable.map(indexes, function(fromIndex) { 6115 return [ 6116 func(collection, resolve(1), fromIndex), 6117 func(collection, resolve(undefined), fromIndex), 6118 func(collection, resolve(''), fromIndex) 6119 ]; 6120 }); 6121 6122 assert.deepEqual(actual, expected); 6123 }); 6124 6125 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) { 6126 assert.expect(1); 6127 6128 var expected = lodashStable.map(falsey, lodashStable.constant(isIncludes || values[0])); 6129 6130 var actual = lodashStable.map(falsey, function(fromIndex) { 6131 return func(collection, resolve(values[0]), fromIndex); 6132 }); 6133 6134 assert.deepEqual(actual, expected); 6135 }); 6136 6137 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) { 6138 assert.expect(1); 6139 6140 var expected = [ 6141 isIncludes || values[0], 6142 isIncludes || values[0], 6143 isIncludes ? false : undefined 6144 ]; 6145 6146 var actual = [ 6147 func(collection, resolve(values[0]), 0.1), 6148 func(collection, resolve(values[0]), NaN), 6149 func(collection, resolve(values[0]), '1') 6150 ]; 6151 6152 assert.deepEqual(actual, expected); 6153 }); 6154 6155 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex`', function(assert) { 6156 assert.expect(1); 6157 6158 var expected = [ 6159 isIncludes || values[2], 6160 isIncludes ? false : undefined 6161 ]; 6162 6163 var actual = [ 6164 func(collection, resolve(values[2]), -1), 6165 func(collection, resolve(values[1]), -1) 6166 ]; 6167 6168 assert.deepEqual(actual, expected); 6169 }); 6170 6171 QUnit.test('`_.' + methodName + '` should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) { 6172 assert.expect(1); 6173 6174 var indexes = [-4, -6, -Infinity], 6175 expected = lodashStable.map(indexes, lodashStable.constant(isIncludes || values[0])); 6176 6177 var actual = lodashStable.map(indexes, function(fromIndex) { 6178 return func(collection, resolve(values[0]), fromIndex); 6179 }); 6180 6181 assert.deepEqual(actual, expected); 6182 }); 6183 }); 6184 }); 6185 6186 /*--------------------------------------------------------------------------*/ 6187 6188 QUnit.module('lodash.findIndex and lodash.indexOf'); 6189 6190 lodashStable.each(['findIndex', 'indexOf'], function(methodName) { 6191 var array = [1, 2, 3, 1, 2, 3], 6192 func = _[methodName], 6193 resolve = methodName == 'findIndex' ? lodashStable.curry(lodashStable.eq) : identity; 6194 6195 QUnit.test('`_.' + methodName + '` should return the index of the first matched value', function(assert) { 6196 assert.expect(1); 6197 6198 assert.strictEqual(func(array, resolve(3)), 2); 6199 }); 6200 6201 QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) { 6202 assert.expect(1); 6203 6204 assert.strictEqual(func(array, resolve(1), 2), 3); 6205 }); 6206 6207 QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) { 6208 assert.expect(1); 6209 6210 var values = [6, 8, Math.pow(2, 32), Infinity], 6211 expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1])); 6212 6213 var actual = lodashStable.map(values, function(fromIndex) { 6214 return [ 6215 func(array, resolve(undefined), fromIndex), 6216 func(array, resolve(1), fromIndex), 6217 func(array, resolve(''), fromIndex) 6218 ]; 6219 }); 6220 6221 assert.deepEqual(actual, expected); 6222 }); 6223 6224 QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) { 6225 assert.expect(1); 6226 6227 assert.strictEqual(func(array, resolve(2), -3), 4); 6228 }); 6229 6230 QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) { 6231 assert.expect(1); 6232 6233 var values = [-6, -8, -Infinity], 6234 expected = lodashStable.map(values, stubZero); 6235 6236 var actual = lodashStable.map(values, function(fromIndex) { 6237 return func(array, resolve(1), fromIndex); 6238 }); 6239 6240 assert.deepEqual(actual, expected); 6241 }); 6242 6243 QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values as `0`', function(assert) { 6244 assert.expect(1); 6245 6246 var expected = lodashStable.map(falsey, stubZero); 6247 6248 var actual = lodashStable.map(falsey, function(fromIndex) { 6249 return func(array, resolve(1), fromIndex); 6250 }); 6251 6252 assert.deepEqual(actual, expected); 6253 }); 6254 6255 QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) { 6256 assert.expect(1); 6257 6258 assert.strictEqual(func(array, resolve(2), 1.2), 1); 6259 }); 6260 }); 6261 6262 /*--------------------------------------------------------------------------*/ 6263 6264 QUnit.module('lodash.findLast'); 6265 6266 (function() { 6267 var resolve = lodashStable.curry(lodashStable.eq); 6268 6269 lodashStable.each({ 6270 'an `arguments` object': args, 6271 'an array': [1, 2, 3] 6272 }, 6273 function(collection, key) { 6274 var values = lodashStable.toArray(collection); 6275 6276 QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) { 6277 assert.expect(1); 6278 6279 var expected = [ 6280 values[1], 6281 undefined 6282 ]; 6283 6284 var actual = [ 6285 _.findLast(collection, resolve(values[1]), 1), 6286 _.findLast(collection, resolve(values[2]), 1) 6287 ]; 6288 6289 assert.deepEqual(actual, expected); 6290 }); 6291 6292 QUnit.test('should work with ' + key + ' and a `fromIndex` >= `length`', function(assert) { 6293 assert.expect(1); 6294 6295 var indexes = [4, 6, Math.pow(2, 32), Infinity]; 6296 6297 var expected = lodashStable.map(indexes, lodashStable.constant([values[0], undefined, undefined])); 6298 6299 var actual = lodashStable.map(indexes, function(fromIndex) { 6300 return [ 6301 _.findLast(collection, resolve(1), fromIndex), 6302 _.findLast(collection, resolve(undefined), fromIndex), 6303 _.findLast(collection, resolve(''), fromIndex) 6304 ]; 6305 }); 6306 6307 assert.deepEqual(actual, expected); 6308 }); 6309 6310 QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values correctly', function(assert) { 6311 assert.expect(1); 6312 6313 var expected = lodashStable.map(falsey, function(value) { 6314 return value === undefined ? values[3] : undefined; 6315 }); 6316 6317 var actual = lodashStable.map(falsey, function(fromIndex) { 6318 return _.findLast(collection, resolve(values[3]), fromIndex); 6319 }); 6320 6321 assert.deepEqual(actual, expected); 6322 }); 6323 6324 QUnit.test('should work with ' + key + ' and coerce `fromIndex` to an integer', function(assert) { 6325 assert.expect(1); 6326 6327 var expected = [ 6328 values[0], 6329 values[0], 6330 undefined 6331 ]; 6332 6333 var actual = [ 6334 _.findLast(collection, resolve(values[0]), 0.1), 6335 _.findLast(collection, resolve(values[0]), NaN), 6336 _.findLast(collection, resolve(values[2]), '1') 6337 ]; 6338 6339 assert.deepEqual(actual, expected); 6340 }); 6341 6342 QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) { 6343 assert.expect(1); 6344 6345 var expected = [ 6346 values[1], 6347 undefined 6348 ]; 6349 6350 var actual = [ 6351 _.findLast(collection, resolve(values[1]), -2), 6352 _.findLast(collection, resolve(values[2]), -2) 6353 ]; 6354 6355 assert.deepEqual(actual, expected); 6356 }); 6357 6358 QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= `-length`', function(assert) { 6359 assert.expect(1); 6360 6361 var indexes = [-4, -6, -Infinity], 6362 expected = lodashStable.map(indexes, lodashStable.constant(values[0])); 6363 6364 var actual = lodashStable.map(indexes, function(fromIndex) { 6365 return _.findLast(collection, resolve(values[0]), fromIndex); 6366 }); 6367 6368 assert.deepEqual(actual, expected); 6369 }); 6370 }); 6371 }()); 6372 6373 /*--------------------------------------------------------------------------*/ 6374 6375 QUnit.module('lodash.flip'); 6376 6377 (function() { 6378 function fn() { 6379 return slice.call(arguments); 6380 } 6381 6382 QUnit.test('should flip arguments provided to `func`', function(assert) { 6383 assert.expect(1); 6384 6385 var flipped = _.flip(fn); 6386 assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']); 6387 }); 6388 }()); 6389 6390 /*--------------------------------------------------------------------------*/ 6391 6392 QUnit.module('lodash.flatMapDepth'); 6393 6394 (function() { 6395 var array = [1, [2, [3, [4]], 5]]; 6396 6397 QUnit.test('should use a default `depth` of `1`', function(assert) { 6398 assert.expect(1); 6399 6400 assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]); 6401 }); 6402 6403 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 6404 assert.expect(1); 6405 6406 var values = [, null, undefined], 6407 expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5])); 6408 6409 var actual = lodashStable.map(values, function(value, index) { 6410 return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array); 6411 }); 6412 6413 assert.deepEqual(actual, expected); 6414 }); 6415 6416 QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) { 6417 assert.expect(2); 6418 6419 lodashStable.each([-1, 0], function(depth) { 6420 assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]); 6421 }); 6422 }); 6423 6424 QUnit.test('should coerce `depth` to an integer', function(assert) { 6425 assert.expect(1); 6426 6427 assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]); 6428 }); 6429 }()); 6430 6431 /*--------------------------------------------------------------------------*/ 6432 6433 QUnit.module('flatMap methods'); 6434 6435 lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) { 6436 var func = _[methodName], 6437 array = [1, 2, 3, 4]; 6438 6439 function duplicate(n) { 6440 return [n, n]; 6441 } 6442 6443 QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) { 6444 assert.expect(1); 6445 6446 var actual = func(array, duplicate), 6447 expected = lodashStable.flatten(lodashStable.map(array, duplicate)); 6448 6449 assert.deepEqual(actual, expected); 6450 }); 6451 6452 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) { 6453 assert.expect(1); 6454 6455 var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }]; 6456 assert.deepEqual(func(objects, 'a'), array); 6457 }); 6458 6459 QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) { 6460 assert.expect(1); 6461 6462 function Foo() { 6463 this.a = [1, 2]; 6464 } 6465 Foo.prototype.b = [3, 4]; 6466 6467 var actual = func(new Foo, identity); 6468 assert.deepEqual(actual, [1, 2]); 6469 }); 6470 6471 QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) { 6472 assert.expect(2); 6473 6474 var array = [[1, 2], [3, 4]], 6475 object = { 'a': [1, 2], 'b': [3, 4] }, 6476 values = [, null, undefined], 6477 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4])); 6478 6479 lodashStable.each([array, object], function(collection) { 6480 var actual = lodashStable.map(values, function(value, index) { 6481 return index ? func(collection, value) : func(collection); 6482 }); 6483 6484 assert.deepEqual(actual, expected); 6485 }); 6486 }); 6487 6488 QUnit.test('`_.' + methodName + '` should accept a falsey `collection`', function(assert) { 6489 assert.expect(1); 6490 6491 var expected = lodashStable.map(falsey, stubArray); 6492 6493 var actual = lodashStable.map(falsey, function(collection, index) { 6494 try { 6495 return index ? func(collection) : func(); 6496 } catch (e) {} 6497 }); 6498 6499 assert.deepEqual(actual, expected); 6500 }); 6501 6502 QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) { 6503 assert.expect(1); 6504 6505 assert.deepEqual(func(1), []); 6506 }); 6507 6508 QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) { 6509 assert.expect(1); 6510 6511 var object = { 'length': [1, 2] }; 6512 assert.deepEqual(func(object, identity), [1, 2]); 6513 }); 6514 }); 6515 6516 /*--------------------------------------------------------------------------*/ 6517 6518 QUnit.module('lodash.flattenDepth'); 6519 6520 (function() { 6521 var array = [1, [2, [3, [4]], 5]]; 6522 6523 QUnit.test('should use a default `depth` of `1`', function(assert) { 6524 assert.expect(1); 6525 6526 assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]); 6527 }); 6528 6529 QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) { 6530 assert.expect(2); 6531 6532 lodashStable.each([-1, 0], function(depth) { 6533 assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]); 6534 }); 6535 }); 6536 6537 QUnit.test('should coerce `depth` to an integer', function(assert) { 6538 assert.expect(1); 6539 6540 assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]); 6541 }); 6542 }()); 6543 6544 /*--------------------------------------------------------------------------*/ 6545 6546 QUnit.module('flatten methods'); 6547 6548 (function() { 6549 var array = [1, [2, [3, [4]], 5]], 6550 methodNames = ['flatten', 'flattenDeep', 'flattenDepth']; 6551 6552 QUnit.test('should flatten `arguments` objects', function(assert) { 6553 assert.expect(3); 6554 6555 var array = [args, [args]]; 6556 6557 assert.deepEqual(_.flatten(array), [1, 2, 3, args]); 6558 assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]); 6559 assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]); 6560 }); 6561 6562 QUnit.test('should treat sparse arrays as dense', function(assert) { 6563 assert.expect(6); 6564 6565 var array = [[1, 2, 3], Array(3)], 6566 expected = [1, 2, 3]; 6567 6568 expected.push(undefined, undefined, undefined); 6569 6570 lodashStable.each(methodNames, function(methodName) { 6571 var actual = _[methodName](array); 6572 assert.deepEqual(actual, expected); 6573 assert.ok('4' in actual); 6574 }); 6575 }); 6576 6577 QUnit.test('should flatten objects with a truthy `Symbol.isConcatSpreadable` value', function(assert) { 6578 assert.expect(1); 6579 6580 if (Symbol && Symbol.isConcatSpreadable) { 6581 var object = { '0': 'a', 'length': 1 }, 6582 array = [object], 6583 expected = lodashStable.map(methodNames, lodashStable.constant(['a'])); 6584 6585 object[Symbol.isConcatSpreadable] = true; 6586 6587 var actual = lodashStable.map(methodNames, function(methodName) { 6588 return _[methodName](array); 6589 }); 6590 6591 assert.deepEqual(actual, expected); 6592 } 6593 else { 6594 skipAssert(assert); 6595 } 6596 }); 6597 6598 QUnit.test('should work with extremely large arrays', function(assert) { 6599 assert.expect(3); 6600 6601 lodashStable.times(3, function(index) { 6602 var expected = Array(5e5); 6603 try { 6604 var func = _.flatten; 6605 if (index == 1) { 6606 func = _.flattenDeep; 6607 } else if (index == 2) { 6608 func = _.flattenDepth; 6609 } 6610 assert.deepEqual(func([expected]), expected); 6611 } catch (e) { 6612 assert.ok(false, e.message); 6613 } 6614 }); 6615 }); 6616 6617 QUnit.test('should work with empty arrays', function(assert) { 6618 assert.expect(3); 6619 6620 var array = [[], [[]], [[], [[[]]]]]; 6621 6622 assert.deepEqual(_.flatten(array), [[], [], [[[]]]]); 6623 assert.deepEqual(_.flattenDeep(array), []); 6624 assert.deepEqual(_.flattenDepth(array, 2), [[[]]]); 6625 }); 6626 6627 QUnit.test('should support flattening of nested arrays', function(assert) { 6628 assert.expect(3); 6629 6630 assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]); 6631 assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]); 6632 assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]); 6633 }); 6634 6635 QUnit.test('should return an empty array for non array-like objects', function(assert) { 6636 assert.expect(3); 6637 6638 var expected = [], 6639 nonArray = { '0': 'a' }; 6640 6641 assert.deepEqual(_.flatten(nonArray), expected); 6642 assert.deepEqual(_.flattenDeep(nonArray), expected); 6643 assert.deepEqual(_.flattenDepth(nonArray, 2), expected); 6644 }); 6645 6646 QUnit.test('should return a wrapped value when chaining', function(assert) { 6647 assert.expect(6); 6648 6649 if (!isNpm) { 6650 var wrapped = _(array), 6651 actual = wrapped.flatten(); 6652 6653 assert.ok(actual instanceof _); 6654 assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]); 6655 6656 actual = wrapped.flattenDeep(); 6657 6658 assert.ok(actual instanceof _); 6659 assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]); 6660 6661 actual = wrapped.flattenDepth(2); 6662 6663 assert.ok(actual instanceof _); 6664 assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]); 6665 } 6666 else { 6667 skipAssert(assert, 6); 6668 } 6669 }); 6670 }()); 6671 6672 /*--------------------------------------------------------------------------*/ 6673 6674 QUnit.module('flow methods'); 6675 6676 lodashStable.each(['flow', 'flowRight'], function(methodName) { 6677 var func = _[methodName], 6678 isFlow = methodName == 'flow'; 6679 6680 QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) { 6681 assert.expect(1); 6682 6683 var fixed = function(n) { return n.toFixed(1); }, 6684 combined = isFlow ? func(add, square, fixed) : func(fixed, square, add); 6685 6686 assert.strictEqual(combined(1, 2), '9.0'); 6687 }); 6688 6689 QUnit.test('`_.' + methodName + '` should return a new function', function(assert) { 6690 assert.expect(1); 6691 6692 assert.notStrictEqual(func(noop), noop); 6693 }); 6694 6695 QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) { 6696 assert.expect(6); 6697 6698 _.times(2, function(index) { 6699 try { 6700 var combined = index ? func([]) : func(); 6701 assert.strictEqual(combined('a'), 'a'); 6702 } catch (e) { 6703 assert.ok(false, e.message); 6704 } 6705 assert.strictEqual(combined.length, 0); 6706 assert.notStrictEqual(combined, identity); 6707 }); 6708 }); 6709 6710 QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) { 6711 assert.expect(1); 6712 6713 var curried = _.curry(identity); 6714 6715 var combined = isFlow 6716 ? func(_.head, curried) 6717 : func(curried, _.head); 6718 6719 assert.strictEqual(combined([1]), 1); 6720 }); 6721 6722 QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) { 6723 assert.expect(6); 6724 6725 var filterCount, 6726 mapCount, 6727 array = lodashStable.range(LARGE_ARRAY_SIZE), 6728 iteratee = function(value) { mapCount++; return square(value); }, 6729 predicate = function(value) { filterCount++; return isEven(value); }; 6730 6731 lodashStable.times(2, function(index) { 6732 var filter1 = _.filter, 6733 filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2), 6734 filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate)); 6735 6736 var map1 = _.map, 6737 map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2), 6738 map3 = (_.map = index ? map2 : map1, map2(iteratee)); 6739 6740 var take1 = _.take, 6741 take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2), 6742 take3 = (_.take = index ? take2 : take1, take2(2)); 6743 6744 var combined = isFlow 6745 ? func(map3, filter3, _.compact, take3) 6746 : func(take3, _.compact, filter3, map3); 6747 6748 filterCount = mapCount = 0; 6749 assert.deepEqual(combined(array), [4, 16]); 6750 6751 if (!isNpm && WeakMap && WeakMap.name) { 6752 assert.strictEqual(filterCount, 5, 'filterCount'); 6753 assert.strictEqual(mapCount, 5, 'mapCount'); 6754 } 6755 else { 6756 skipAssert(assert, 2); 6757 } 6758 _.filter = filter1; 6759 _.map = map1; 6760 _.take = take1; 6761 }); 6762 }); 6763 6764 QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) { 6765 assert.expect(1); 6766 6767 var curried = _.curry(_.ary(_.map, 2), 2), 6768 getProp = curried(curried.placeholder, 'a'), 6769 objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }]; 6770 6771 var combined = isFlow 6772 ? func(getProp, _.uniq) 6773 : func(_.uniq, getProp); 6774 6775 assert.deepEqual(combined(objects), [1, 2]); 6776 }); 6777 6778 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) { 6779 assert.expect(1); 6780 6781 if (!isNpm) { 6782 var wrapped = _(noop)[methodName](); 6783 assert.ok(wrapped instanceof _); 6784 } 6785 else { 6786 skipAssert(assert); 6787 } 6788 }); 6789 }); 6790 6791 /*--------------------------------------------------------------------------*/ 6792 6793 QUnit.module('lodash.forEach'); 6794 6795 (function() { 6796 QUnit.test('should be aliased', function(assert) { 6797 assert.expect(1); 6798 6799 assert.strictEqual(_.each, _.forEach); 6800 }); 6801 }()); 6802 6803 /*--------------------------------------------------------------------------*/ 6804 6805 QUnit.module('lodash.forEachRight'); 6806 6807 (function() { 6808 QUnit.test('should be aliased', function(assert) { 6809 assert.expect(1); 6810 6811 assert.strictEqual(_.eachRight, _.forEachRight); 6812 }); 6813 }()); 6814 6815 /*--------------------------------------------------------------------------*/ 6816 6817 QUnit.module('forIn methods'); 6818 6819 lodashStable.each(['forIn', 'forInRight'], function(methodName) { 6820 var func = _[methodName]; 6821 6822 QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) { 6823 assert.expect(1); 6824 6825 function Foo() { 6826 this.a = 1; 6827 } 6828 Foo.prototype.b = 2; 6829 6830 var keys = []; 6831 func(new Foo, function(value, key) { keys.push(key); }); 6832 assert.deepEqual(keys.sort(), ['a', 'b']); 6833 }); 6834 }); 6835 6836 /*--------------------------------------------------------------------------*/ 6837 6838 QUnit.module('forOwn methods'); 6839 6840 lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) { 6841 var func = _[methodName]; 6842 6843 QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) { 6844 assert.expect(1); 6845 6846 var object = { '0': 'zero', '1': 'one', 'length': 2 }, 6847 props = []; 6848 6849 func(object, function(value, prop) { props.push(prop); }); 6850 assert.deepEqual(props.sort(), ['0', '1', 'length']); 6851 }); 6852 }); 6853 6854 /*--------------------------------------------------------------------------*/ 6855 6856 QUnit.module('iteration methods'); 6857 6858 (function() { 6859 var methods = [ 6860 '_baseEach', 6861 'countBy', 6862 'every', 6863 'filter', 6864 'find', 6865 'findIndex', 6866 'findKey', 6867 'findLast', 6868 'findLastIndex', 6869 'findLastKey', 6870 'forEach', 6871 'forEachRight', 6872 'forIn', 6873 'forInRight', 6874 'forOwn', 6875 'forOwnRight', 6876 'groupBy', 6877 'keyBy', 6878 'map', 6879 'mapKeys', 6880 'mapValues', 6881 'maxBy', 6882 'minBy', 6883 'omitBy', 6884 'partition', 6885 'pickBy', 6886 'reject', 6887 'some' 6888 ]; 6889 6890 var arrayMethods = [ 6891 'findIndex', 6892 'findLastIndex', 6893 'maxBy', 6894 'minBy' 6895 ]; 6896 6897 var collectionMethods = [ 6898 '_baseEach', 6899 'countBy', 6900 'every', 6901 'filter', 6902 'find', 6903 'findLast', 6904 'forEach', 6905 'forEachRight', 6906 'groupBy', 6907 'keyBy', 6908 'map', 6909 'partition', 6910 'reduce', 6911 'reduceRight', 6912 'reject', 6913 'some' 6914 ]; 6915 6916 var forInMethods = [ 6917 'forIn', 6918 'forInRight', 6919 'omitBy', 6920 'pickBy' 6921 ]; 6922 6923 var iterationMethods = [ 6924 '_baseEach', 6925 'forEach', 6926 'forEachRight', 6927 'forIn', 6928 'forInRight', 6929 'forOwn', 6930 'forOwnRight' 6931 ]; 6932 6933 var objectMethods = [ 6934 'findKey', 6935 'findLastKey', 6936 'forIn', 6937 'forInRight', 6938 'forOwn', 6939 'forOwnRight', 6940 'mapKeys', 6941 'mapValues', 6942 'omitBy', 6943 'pickBy' 6944 ]; 6945 6946 var rightMethods = [ 6947 'findLast', 6948 'findLastIndex', 6949 'findLastKey', 6950 'forEachRight', 6951 'forInRight', 6952 'forOwnRight' 6953 ]; 6954 6955 var unwrappedMethods = [ 6956 'each', 6957 'eachRight', 6958 'every', 6959 'find', 6960 'findIndex', 6961 'findKey', 6962 'findLast', 6963 'findLastIndex', 6964 'findLastKey', 6965 'forEach', 6966 'forEachRight', 6967 'forIn', 6968 'forInRight', 6969 'forOwn', 6970 'forOwnRight', 6971 'max', 6972 'maxBy', 6973 'min', 6974 'minBy', 6975 'some' 6976 ]; 6977 6978 lodashStable.each(methods, function(methodName) { 6979 var array = [1, 2, 3], 6980 func = _[methodName], 6981 isBy = /(^partition|By)$/.test(methodName), 6982 isFind = /^find/.test(methodName), 6983 isOmitPick = /^(?:omit|pick)By$/.test(methodName), 6984 isSome = methodName == 'some'; 6985 6986 QUnit.test('`_.' + methodName + '` should provide correct iteratee arguments', function(assert) { 6987 assert.expect(1); 6988 6989 if (func) { 6990 var args, 6991 expected = [1, 0, array]; 6992 6993 func(array, function() { 6994 args || (args = slice.call(arguments)); 6995 }); 6996 6997 if (lodashStable.includes(rightMethods, methodName)) { 6998 expected[0] = 3; 6999 expected[1] = 2; 7000 } 7001 if (lodashStable.includes(objectMethods, methodName)) { 7002 expected[1] += ''; 7003 } 7004 if (isBy) { 7005 expected.length = isOmitPick ? 2 : 1; 7006 } 7007 assert.deepEqual(args, expected); 7008 } 7009 else { 7010 skipAssert(assert); 7011 } 7012 }); 7013 7014 QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) { 7015 assert.expect(1); 7016 7017 if (func) { 7018 var array = [1]; 7019 array[2] = 3; 7020 7021 var expected = lodashStable.includes(objectMethods, methodName) 7022 ? [[1, '0', array], [undefined, '1', array], [3, '2', array]] 7023 : [[1, 0, array], [undefined, 1, array], [3, 2, array]]; 7024 7025 if (isBy) { 7026 expected = lodashStable.map(expected, function(args) { 7027 return args.slice(0, isOmitPick ? 2 : 1); 7028 }); 7029 } 7030 else if (lodashStable.includes(objectMethods, methodName)) { 7031 expected = lodashStable.map(expected, function(args) { 7032 args[1] += ''; 7033 return args; 7034 }); 7035 } 7036 if (lodashStable.includes(rightMethods, methodName)) { 7037 expected.reverse(); 7038 } 7039 var argsList = []; 7040 func(array, function() { 7041 argsList.push(slice.call(arguments)); 7042 return !(isFind || isSome); 7043 }); 7044 7045 assert.deepEqual(argsList, expected); 7046 } 7047 else { 7048 skipAssert(assert); 7049 } 7050 }); 7051 }); 7052 7053 lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) { 7054 var array = [1, 2, 3], 7055 func = _[methodName], 7056 isEvery = methodName == 'every'; 7057 7058 array.a = 1; 7059 7060 QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) { 7061 assert.expect(1); 7062 7063 if (func) { 7064 var keys = []; 7065 func(array, function(value, key) { 7066 keys.push(key); 7067 return isEvery; 7068 }); 7069 7070 assert.notOk(lodashStable.includes(keys, 'a')); 7071 } 7072 else { 7073 skipAssert(assert); 7074 } 7075 }); 7076 }); 7077 7078 lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) { 7079 var array = [1, 2, 3], 7080 isBaseEach = methodName == '_baseEach'; 7081 7082 QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) { 7083 assert.expect(1); 7084 7085 if (!(isBaseEach || isNpm)) { 7086 var wrapped = _(array)[methodName](noop); 7087 assert.ok(wrapped instanceof _); 7088 } 7089 else { 7090 skipAssert(assert); 7091 } 7092 }); 7093 }); 7094 7095 lodashStable.each(unwrappedMethods, function(methodName) { 7096 var array = [1, 2, 3]; 7097 7098 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 7099 assert.expect(1); 7100 7101 if (!isNpm) { 7102 var actual = _(array)[methodName](noop); 7103 assert.notOk(actual instanceof _); 7104 } 7105 else { 7106 skipAssert(assert); 7107 } 7108 }); 7109 7110 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 7111 assert.expect(2); 7112 7113 if (!isNpm) { 7114 var wrapped = _(array).chain(), 7115 actual = wrapped[methodName](noop); 7116 7117 assert.ok(actual instanceof _); 7118 assert.notStrictEqual(actual, wrapped); 7119 } 7120 else { 7121 skipAssert(assert, 2); 7122 } 7123 }); 7124 }); 7125 7126 lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) { 7127 var func = _[methodName]; 7128 7129 QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) { 7130 assert.expect(1); 7131 7132 function Foo() { 7133 this.a = 1; 7134 } 7135 Foo.prototype.b = 2; 7136 7137 if (func) { 7138 var values = []; 7139 func(new Foo, function(value) { values.push(value); }); 7140 assert.deepEqual(values, [1]); 7141 } 7142 else { 7143 skipAssert(assert); 7144 } 7145 }); 7146 }); 7147 7148 lodashStable.each(iterationMethods, function(methodName) { 7149 var array = [1, 2, 3], 7150 func = _[methodName]; 7151 7152 QUnit.test('`_.' + methodName + '` should return the collection', function(assert) { 7153 assert.expect(1); 7154 7155 if (func) { 7156 assert.strictEqual(func(array, Boolean), array); 7157 } 7158 else { 7159 skipAssert(assert); 7160 } 7161 }); 7162 }); 7163 7164 lodashStable.each(collectionMethods, function(methodName) { 7165 var func = _[methodName]; 7166 7167 QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) { 7168 assert.expect(3); 7169 7170 if (func) { 7171 var isIteratedAsObject = function(object) { 7172 var result = false; 7173 func(object, function() { result = true; }, 0); 7174 return result; 7175 }; 7176 7177 var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1], 7178 expected = lodashStable.map(values, stubTrue); 7179 7180 var actual = lodashStable.map(values, function(length) { 7181 return isIteratedAsObject({ 'length': length }); 7182 }); 7183 7184 var Foo = function(a) {}; 7185 Foo.a = 1; 7186 7187 assert.deepEqual(actual, expected); 7188 assert.ok(isIteratedAsObject(Foo)); 7189 assert.notOk(isIteratedAsObject({ 'length': 0 })); 7190 } 7191 else { 7192 skipAssert(assert, 3); 7193 } 7194 }); 7195 }); 7196 7197 lodashStable.each(methods, function(methodName) { 7198 var func = _[methodName], 7199 isFind = /^find/.test(methodName), 7200 isSome = methodName == 'some', 7201 isReduce = /^reduce/.test(methodName); 7202 7203 QUnit.test('`_.' + methodName + '` should ignore changes to `length`', function(assert) { 7204 assert.expect(1); 7205 7206 if (func) { 7207 var count = 0, 7208 array = [1]; 7209 7210 func(array, function() { 7211 if (++count == 1) { 7212 array.push(2); 7213 } 7214 return !(isFind || isSome); 7215 }, isReduce ? array : null); 7216 7217 assert.strictEqual(count, 1); 7218 } 7219 else { 7220 skipAssert(assert); 7221 } 7222 }); 7223 }); 7224 7225 lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) { 7226 var func = _[methodName], 7227 isFind = /^find/.test(methodName), 7228 isSome = methodName == 'some', 7229 isReduce = /^reduce/.test(methodName); 7230 7231 QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) { 7232 assert.expect(1); 7233 7234 if (func) { 7235 var count = 0, 7236 object = { 'a': 1 }; 7237 7238 func(object, function() { 7239 if (++count == 1) { 7240 object.b = 2; 7241 } 7242 return !(isFind || isSome); 7243 }, isReduce ? object : null); 7244 7245 assert.strictEqual(count, 1); 7246 } 7247 else { 7248 skipAssert(assert); 7249 } 7250 }); 7251 }); 7252 }()); 7253 7254 /*--------------------------------------------------------------------------*/ 7255 7256 QUnit.module('object assignments'); 7257 7258 lodashStable.each(['assign', 'assignIn', 'defaults', 'defaultsDeep', 'merge'], function(methodName) { 7259 var func = _[methodName], 7260 isAssign = methodName == 'assign', 7261 isDefaults = /^defaults/.test(methodName); 7262 7263 QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) { 7264 assert.expect(1); 7265 7266 var expected = lodashStable.map(primitives, function(value) { 7267 var object = Object(value); 7268 object.a = 1; 7269 return object; 7270 }); 7271 7272 var actual = lodashStable.map(primitives, function(value) { 7273 return func(value, { 'a': 1 }); 7274 }); 7275 7276 assert.deepEqual(actual, expected); 7277 }); 7278 7279 QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) { 7280 assert.expect(1); 7281 7282 function Foo() { 7283 this.a = 1; 7284 } 7285 Foo.prototype.b = 2; 7286 7287 var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 }; 7288 assert.deepEqual(func({}, new Foo), expected); 7289 }); 7290 7291 QUnit.test('`_.' + methodName + '` should not skip a trailing function source', function(assert) { 7292 assert.expect(1); 7293 7294 function fn() {} 7295 fn.b = 2; 7296 7297 assert.deepEqual(func({}, { 'a': 1 }, fn), { 'a': 1, 'b': 2 }); 7298 }); 7299 7300 QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) { 7301 assert.expect(1); 7302 7303 try { 7304 assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 }); 7305 } catch (e) { 7306 assert.ok(false, e.message); 7307 } 7308 }); 7309 7310 QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) { 7311 assert.expect(2); 7312 7313 var source = { 'a': 1 }, 7314 values = [null, undefined], 7315 expected = lodashStable.map(values, stubTrue); 7316 7317 var actual = lodashStable.map(values, function(value) { 7318 var object = func(value, source); 7319 return object !== source && lodashStable.isEqual(object, source); 7320 }); 7321 7322 assert.deepEqual(actual, expected); 7323 7324 actual = lodashStable.map(values, function(value) { 7325 return lodashStable.isEqual(func(value), {}); 7326 }); 7327 7328 assert.deepEqual(actual, expected); 7329 }); 7330 7331 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) { 7332 assert.expect(2); 7333 7334 var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }], 7335 expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 }; 7336 7337 function fn() {}; 7338 fn.a = array[0]; 7339 fn.b = array[1]; 7340 fn.c = array[2]; 7341 7342 assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected); 7343 assert.deepEqual(lodashStable.reduce(fn, func, { 'a': 0 }), expected); 7344 }); 7345 7346 QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) { 7347 assert.expect(1); 7348 7349 if (!isNpm) { 7350 var wrapped = _({ 'a': 1 }), 7351 actual = wrapped[methodName]({ 'b': 2 }); 7352 7353 assert.notStrictEqual(actual, wrapped); 7354 } 7355 else { 7356 skipAssert(assert); 7357 } 7358 }); 7359 }); 7360 7361 lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) { 7362 var func = _[methodName]; 7363 7364 QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) { 7365 assert.expect(1); 7366 7367 function Foo() {} 7368 Foo.prototype.a = 1; 7369 7370 var actual = func(new Foo, { 'b': 2 }); 7371 assert.notOk(_.has(actual, 'a')); 7372 }); 7373 }); 7374 7375 lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'defaultsDeep', 'merge', 'mergeWith'], function(methodName) { 7376 var func = _[methodName]; 7377 7378 QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) { 7379 assert.expect(4); 7380 7381 lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) { 7382 var object = {}, 7383 pass = true; 7384 7385 defineProperty(object, 'a', { 7386 'configurable': true, 7387 'enumerable': true, 7388 'get': lodashStable.constant(value), 7389 'set': function() { pass = false; } 7390 }); 7391 7392 func(object, { 'a': value }); 7393 assert.ok(pass); 7394 }); 7395 }); 7396 }); 7397 7398 lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) { 7399 var func = _[methodName], 7400 isMergeWith = methodName == 'mergeWith'; 7401 7402 QUnit.test('`_.' + methodName + '` should provide correct `customizer` arguments', function(assert) { 7403 assert.expect(3); 7404 7405 var args, 7406 object = { 'a': 1 }, 7407 source = { 'a': 2 }, 7408 expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep); 7409 7410 func(object, source, function() { 7411 args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep)); 7412 }); 7413 7414 assert.deepEqual(args, expected, 'primitive values'); 7415 7416 var argsList = [], 7417 objectValue = [1, 2], 7418 sourceValue = { 'b': 2 }; 7419 7420 object = { 'a': objectValue }; 7421 source = { 'a': sourceValue }; 7422 expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)]; 7423 7424 if (isMergeWith) { 7425 expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep)); 7426 } 7427 func(object, source, function() { 7428 argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep)); 7429 }); 7430 7431 assert.deepEqual(argsList, expected, 'object values'); 7432 7433 args = undefined; 7434 object = { 'a': 1 }; 7435 source = { 'b': 2 }; 7436 expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep); 7437 7438 func(object, source, function() { 7439 args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep)); 7440 }); 7441 7442 assert.deepEqual(args, expected, 'undefined properties'); 7443 }); 7444 7445 QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) { 7446 assert.expect(2); 7447 7448 function callback() {} 7449 callback.b = 2; 7450 7451 var actual = func({ 'a': 1 }, callback); 7452 assert.deepEqual(actual, { 'a': 1, 'b': 2 }); 7453 7454 actual = func({ 'a': 1 }, callback, { 'c': 3 }); 7455 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); 7456 }); 7457 }); 7458 7459 /*--------------------------------------------------------------------------*/ 7460 7461 QUnit.module('exit early'); 7462 7463 lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) { 7464 var func = _[methodName]; 7465 7466 QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) { 7467 assert.expect(1); 7468 7469 if (func) { 7470 var array = [1, 2, 3], 7471 values = []; 7472 7473 func(array, function(value, other) { 7474 values.push(lodashStable.isArray(value) ? other : value); 7475 return false; 7476 }); 7477 7478 assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]); 7479 } 7480 else { 7481 skipAssert(assert); 7482 } 7483 }); 7484 7485 QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) { 7486 assert.expect(1); 7487 7488 if (func) { 7489 var object = { 'a': 1, 'b': 2, 'c': 3 }, 7490 values = []; 7491 7492 func(object, function(value, other) { 7493 values.push(lodashStable.isArray(value) ? other : value); 7494 return false; 7495 }); 7496 7497 assert.strictEqual(values.length, 1); 7498 } 7499 else { 7500 skipAssert(assert); 7501 } 7502 }); 7503 }); 7504 7505 /*--------------------------------------------------------------------------*/ 7506 7507 QUnit.module('`__proto__` property bugs'); 7508 7509 (function() { 7510 QUnit.test('should work with the "__proto__" key in internal data objects', function(assert) { 7511 assert.expect(4); 7512 7513 var stringLiteral = '__proto__', 7514 stringObject = Object(stringLiteral), 7515 expected = [stringLiteral, stringObject]; 7516 7517 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) { 7518 return isEven(count) ? stringLiteral : stringObject; 7519 }); 7520 7521 assert.deepEqual(_.difference(largeArray, largeArray), []); 7522 assert.deepEqual(_.intersection(largeArray, largeArray), expected); 7523 assert.deepEqual(_.uniq(largeArray), expected); 7524 assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []); 7525 }); 7526 7527 QUnit.test('should treat "__proto__" as a regular key in assignments', function(assert) { 7528 assert.expect(2); 7529 7530 var methods = [ 7531 'assign', 7532 'assignIn', 7533 'defaults', 7534 'defaultsDeep', 7535 'merge' 7536 ]; 7537 7538 var source = create(null); 7539 source.__proto__ = []; 7540 7541 var expected = lodashStable.map(methods, stubFalse); 7542 7543 var actual = lodashStable.map(methods, function(methodName) { 7544 var result = _[methodName]({}, source); 7545 return result instanceof Array; 7546 }); 7547 7548 assert.deepEqual(actual, expected); 7549 7550 actual = _.groupBy([{ 'a': '__proto__' }], 'a'); 7551 assert.notOk(actual instanceof Array); 7552 }); 7553 7554 QUnit.test('should not merge "__proto__" properties', function(assert) { 7555 assert.expect(1); 7556 7557 if (JSON) { 7558 _.merge({}, JSON.parse('{"__proto__":{"a":1}}')); 7559 7560 var actual = 'a' in objectProto; 7561 delete objectProto.a; 7562 7563 assert.notOk(actual); 7564 } else { 7565 skipAssert(assert); 7566 } 7567 }); 7568 7569 QUnit.test('should not indirectly merge builtin prototype properties', function(assert) { 7570 assert.expect(2); 7571 7572 _.merge({}, { 'toString': { 'constructor': { 'prototype': { 'a': 1 } } } }); 7573 7574 var actual = 'a' in funcProto; 7575 delete funcProto.a; 7576 7577 assert.notOk(actual); 7578 7579 _.merge({}, { 'constructor': { 'prototype': { 'a': 1 } } }); 7580 7581 actual = 'a' in objectProto; 7582 delete objectProto.a; 7583 7584 assert.notOk(actual); 7585 }); 7586 7587 QUnit.test('should not indirectly merge `Object` properties', function(assert) { 7588 assert.expect(1); 7589 7590 _.merge({}, { 'constructor': { 'a': 1 } }); 7591 7592 var actual = 'a' in Object; 7593 delete Object.a; 7594 7595 assert.notOk(actual); 7596 }); 7597 }()); 7598 7599 /*--------------------------------------------------------------------------*/ 7600 7601 QUnit.module('lodash.fromPairs'); 7602 7603 (function() { 7604 QUnit.test('should accept a two dimensional array', function(assert) { 7605 assert.expect(1); 7606 7607 var array = [['a', 1], ['b', 2]], 7608 object = { 'a': 1, 'b': 2 }, 7609 actual = _.fromPairs(array); 7610 7611 assert.deepEqual(actual, object); 7612 }); 7613 7614 QUnit.test('should accept a falsey `array`', function(assert) { 7615 assert.expect(1); 7616 7617 var expected = lodashStable.map(falsey, stubObject); 7618 7619 var actual = lodashStable.map(falsey, function(array, index) { 7620 try { 7621 return index ? _.fromPairs(array) : _.fromPairs(); 7622 } catch (e) {} 7623 }); 7624 7625 assert.deepEqual(actual, expected); 7626 }); 7627 7628 QUnit.test('should not support deep paths', function(assert) { 7629 assert.expect(1); 7630 7631 var actual = _.fromPairs([['a.b', 1]]); 7632 assert.deepEqual(actual, { 'a.b': 1 }); 7633 }); 7634 7635 QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) { 7636 assert.expect(1); 7637 7638 var object = { 'a.b': 1 }; 7639 assert.deepEqual(_.fromPairs(_.toPairs(object)), object); 7640 }); 7641 7642 QUnit.test('should work in a lazy sequence', function(assert) { 7643 assert.expect(1); 7644 7645 if (!isNpm) { 7646 var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 7647 return ['key' + index, index]; 7648 }); 7649 7650 var actual = _(array).fromPairs().map(square).filter(isEven).take().value(); 7651 7652 assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven))); 7653 } 7654 else { 7655 skipAssert(assert); 7656 } 7657 }); 7658 }()); 7659 7660 /*--------------------------------------------------------------------------*/ 7661 7662 QUnit.module('lodash.functions'); 7663 7664 (function() { 7665 QUnit.test('should return the function names of an object', function(assert) { 7666 assert.expect(1); 7667 7668 var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop }, 7669 actual = _.functions(object).sort(); 7670 7671 assert.deepEqual(actual, ['b', 'd']); 7672 }); 7673 7674 QUnit.test('should not include inherited functions', function(assert) { 7675 assert.expect(1); 7676 7677 function Foo() { 7678 this.a = identity; 7679 this.b = 'b'; 7680 } 7681 Foo.prototype.c = noop; 7682 7683 assert.deepEqual(_.functions(new Foo), ['a']); 7684 }); 7685 }()); 7686 7687 /*--------------------------------------------------------------------------*/ 7688 7689 QUnit.module('lodash.groupBy'); 7690 7691 (function() { 7692 var array = [6.1, 4.2, 6.3]; 7693 7694 QUnit.test('should transform keys by `iteratee`', function(assert) { 7695 assert.expect(1); 7696 7697 var actual = _.groupBy(array, Math.floor); 7698 assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] }); 7699 }); 7700 7701 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 7702 assert.expect(1); 7703 7704 var array = [6, 4, 6], 7705 values = [, null, undefined], 7706 expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6': [6, 6] })); 7707 7708 var actual = lodashStable.map(values, function(value, index) { 7709 return index ? _.groupBy(array, value) : _.groupBy(array); 7710 }); 7711 7712 assert.deepEqual(actual, expected); 7713 }); 7714 7715 QUnit.test('should work with `_.property` shorthands', function(assert) { 7716 assert.expect(1); 7717 7718 var actual = _.groupBy(['one', 'two', 'three'], 'length'); 7719 assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] }); 7720 }); 7721 7722 QUnit.test('should only add values to own, not inherited, properties', function(assert) { 7723 assert.expect(2); 7724 7725 var actual = _.groupBy(array, function(n) { 7726 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor'; 7727 }); 7728 7729 assert.deepEqual(actual.constructor, [4.2]); 7730 assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]); 7731 }); 7732 7733 QUnit.test('should work with a number for `iteratee`', function(assert) { 7734 assert.expect(2); 7735 7736 var array = [ 7737 [1, 'a'], 7738 [2, 'a'], 7739 [2, 'b'] 7740 ]; 7741 7742 assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] }); 7743 assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] }); 7744 }); 7745 7746 QUnit.test('should work with an object for `collection`', function(assert) { 7747 assert.expect(1); 7748 7749 var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor); 7750 assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] }); 7751 }); 7752 7753 QUnit.test('should work in a lazy sequence', function(assert) { 7754 assert.expect(1); 7755 7756 if (!isNpm) { 7757 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat( 7758 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), 7759 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) 7760 ); 7761 7762 var iteratee = function(value) { value.push(value[0]); return value; }, 7763 predicate = function(value) { return isEven(value[0]); }, 7764 actual = _(array).groupBy().map(iteratee).filter(predicate).take().value(); 7765 7766 assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate))); 7767 } 7768 else { 7769 skipAssert(assert); 7770 } 7771 }); 7772 }()); 7773 7774 /*--------------------------------------------------------------------------*/ 7775 7776 QUnit.module('lodash.gt'); 7777 7778 (function() { 7779 QUnit.test('should return `true` if `value` > `other`', function(assert) { 7780 assert.expect(2); 7781 7782 assert.strictEqual(_.gt(3, 1), true); 7783 assert.strictEqual(_.gt('def', 'abc'), true); 7784 }); 7785 7786 QUnit.test('should return `false` if `value` is <= `other`', function(assert) { 7787 assert.expect(4); 7788 7789 assert.strictEqual(_.gt(1, 3), false); 7790 assert.strictEqual(_.gt(3, 3), false); 7791 assert.strictEqual(_.gt('abc', 'def'), false); 7792 assert.strictEqual(_.gt('def', 'def'), false); 7793 }); 7794 }()); 7795 7796 /*--------------------------------------------------------------------------*/ 7797 7798 QUnit.module('lodash.gte'); 7799 7800 (function() { 7801 QUnit.test('should return `true` if `value` >= `other`', function(assert) { 7802 assert.expect(4); 7803 7804 assert.strictEqual(_.gte(3, 1), true); 7805 assert.strictEqual(_.gte(3, 3), true); 7806 assert.strictEqual(_.gte('def', 'abc'), true); 7807 assert.strictEqual(_.gte('def', 'def'), true); 7808 }); 7809 7810 QUnit.test('should return `false` if `value` is less than `other`', function(assert) { 7811 assert.expect(2); 7812 7813 assert.strictEqual(_.gte(1, 3), false); 7814 assert.strictEqual(_.gte('abc', 'def'), false); 7815 }); 7816 }()); 7817 7818 /*--------------------------------------------------------------------------*/ 7819 7820 QUnit.module('has methods'); 7821 7822 lodashStable.each(['has', 'hasIn'], function(methodName) { 7823 var func = _[methodName], 7824 isHas = methodName == 'has', 7825 sparseArgs = toArgs([1]), 7826 sparseArray = Array(1), 7827 sparseString = Object('a'); 7828 7829 delete sparseArgs[0]; 7830 delete sparseString[0]; 7831 7832 QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) { 7833 assert.expect(2); 7834 7835 var object = { 'a': 1 }; 7836 7837 lodashStable.each(['a', ['a']], function(path) { 7838 assert.strictEqual(func(object, path), true); 7839 }); 7840 }); 7841 7842 QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of `object`', function(assert) { 7843 assert.expect(1); 7844 7845 var object = { 'hasOwnProperty': null, 'a': 1 }; 7846 assert.strictEqual(func(object, 'a'), true); 7847 }); 7848 7849 QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) { 7850 assert.expect(4); 7851 7852 var object = { 'a': { 'b': 2 } }; 7853 7854 lodashStable.each(['a.b', ['a', 'b']], function(path) { 7855 assert.strictEqual(func(object, path), true); 7856 }); 7857 7858 lodashStable.each(['a.a', ['a', 'a']], function(path) { 7859 assert.strictEqual(func(object, path), false); 7860 }); 7861 }); 7862 7863 QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) { 7864 assert.expect(2); 7865 7866 function fn() {} 7867 fn.toString = lodashStable.constant('fn'); 7868 7869 var object = { 'null': 1 , 'undefined': 2, 'fn': 3, '[object Object]': 4 }, 7870 paths = [null, undefined, fn, {}], 7871 expected = lodashStable.map(paths, stubTrue); 7872 7873 lodashStable.times(2, function(index) { 7874 var actual = lodashStable.map(paths, function(path) { 7875 return func(object, index ? [path] : path); 7876 }); 7877 7878 assert.deepEqual(actual, expected); 7879 }); 7880 }); 7881 7882 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) { 7883 assert.expect(1); 7884 7885 assert.strictEqual(func(args, 1), true); 7886 }); 7887 7888 QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) { 7889 assert.expect(2); 7890 7891 var array = [1, 2, 3]; 7892 7893 lodashStable.each([1, [1]], function(path) { 7894 assert.strictEqual(func(array, path), true); 7895 }); 7896 }); 7897 7898 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 7899 assert.expect(1); 7900 7901 var object = { '-0': 'a', '0': 'b' }, 7902 props = [-0, Object(-0), 0, Object(0)], 7903 expected = lodashStable.map(props, stubTrue); 7904 7905 var actual = lodashStable.map(props, function(key) { 7906 return func(object, key); 7907 }); 7908 7909 assert.deepEqual(actual, expected); 7910 }); 7911 7912 QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) { 7913 assert.expect(2); 7914 7915 function Foo() {} 7916 7917 if (Symbol) { 7918 Foo.prototype[symbol] = 1; 7919 7920 var symbol2 = Symbol('b'); 7921 defineProperty(Foo.prototype, symbol2, { 7922 'configurable': true, 7923 'enumerable': false, 7924 'writable': true, 7925 'value': 2 7926 }); 7927 7928 var object = isHas ? Foo.prototype : new Foo; 7929 assert.strictEqual(func(object, symbol), true); 7930 assert.strictEqual(func(object, symbol2), true); 7931 } 7932 else { 7933 skipAssert(assert, 2); 7934 } 7935 }); 7936 7937 QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) { 7938 assert.expect(2); 7939 7940 var object = { 'a.b': 1 }; 7941 7942 lodashStable.each(['a.b', ['a.b']], function(path) { 7943 assert.strictEqual(func(object, path), true); 7944 }); 7945 }); 7946 7947 QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values', function(assert) { 7948 assert.expect(1); 7949 7950 var values = [sparseArgs, sparseArray, sparseString], 7951 expected = lodashStable.map(values, stubTrue); 7952 7953 var actual = lodashStable.map(values, function(value) { 7954 return func(value, 0); 7955 }); 7956 7957 assert.deepEqual(actual, expected); 7958 }); 7959 7960 QUnit.test('`_.' + methodName + '` should return `true` for indexes of sparse values with deep paths', function(assert) { 7961 assert.expect(1); 7962 7963 var values = [sparseArgs, sparseArray, sparseString], 7964 expected = lodashStable.map(values, lodashStable.constant([true, true])); 7965 7966 var actual = lodashStable.map(values, function(value) { 7967 return lodashStable.map(['a[0]', ['a', '0']], function(path) { 7968 return func({ 'a': value }, path); 7969 }); 7970 }); 7971 7972 assert.deepEqual(actual, expected); 7973 }); 7974 7975 QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) { 7976 assert.expect(2); 7977 7978 function Foo() {} 7979 Foo.prototype.a = 1; 7980 7981 lodashStable.each(['a', ['a']], function(path) { 7982 assert.strictEqual(func(new Foo, path), !isHas); 7983 }); 7984 }); 7985 7986 QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) { 7987 assert.expect(2); 7988 7989 function Foo() {} 7990 Foo.prototype.a = { 'b': 1 }; 7991 7992 lodashStable.each(['a.b', ['a', 'b']], function(path) { 7993 assert.strictEqual(func(new Foo, path), !isHas); 7994 }); 7995 }); 7996 7997 QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) { 7998 assert.expect(2); 7999 8000 var values = [null, undefined], 8001 expected = lodashStable.map(values, stubFalse); 8002 8003 lodashStable.each(['constructor', ['constructor']], function(path) { 8004 var actual = lodashStable.map(values, function(value) { 8005 return func(value, path); 8006 }); 8007 8008 assert.deepEqual(actual, expected); 8009 }); 8010 }); 8011 8012 QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) { 8013 assert.expect(2); 8014 8015 var values = [null, undefined], 8016 expected = lodashStable.map(values, stubFalse); 8017 8018 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 8019 var actual = lodashStable.map(values, function(value) { 8020 return func(value, path); 8021 }); 8022 8023 assert.deepEqual(actual, expected); 8024 }); 8025 }); 8026 8027 QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) { 8028 assert.expect(2); 8029 8030 var values = [, null, undefined], 8031 expected = lodashStable.map(values, stubFalse); 8032 8033 lodashStable.each(['a.b', ['a', 'b']], function(path) { 8034 var actual = lodashStable.map(values, function(value, index) { 8035 var object = index ? { 'a': value } : {}; 8036 return func(object, path); 8037 }); 8038 8039 assert.deepEqual(actual, expected); 8040 }); 8041 }); 8042 8043 QUnit.test('`_.' + methodName + '` should return `false` over sparse values of deep paths', function(assert) { 8044 assert.expect(1); 8045 8046 var values = [sparseArgs, sparseArray, sparseString], 8047 expected = lodashStable.map(values, lodashStable.constant([false, false])); 8048 8049 var actual = lodashStable.map(values, function(value) { 8050 return lodashStable.map(['a[0].b', ['a', '0', 'b']], function(path) { 8051 return func({ 'a': value }, path); 8052 }); 8053 }); 8054 8055 assert.deepEqual(actual, expected); 8056 }); 8057 }); 8058 8059 /*--------------------------------------------------------------------------*/ 8060 8061 QUnit.module('lodash.head'); 8062 8063 (function() { 8064 var array = [1, 2, 3, 4]; 8065 8066 QUnit.test('should return the first element', function(assert) { 8067 assert.expect(1); 8068 8069 assert.strictEqual(_.head(array), 1); 8070 }); 8071 8072 QUnit.test('should return `undefined` when querying empty arrays', function(assert) { 8073 assert.expect(1); 8074 8075 arrayProto[0] = 1; 8076 assert.strictEqual(_.head([]), undefined); 8077 arrayProto.length = 0; 8078 }); 8079 8080 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 8081 assert.expect(1); 8082 8083 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 8084 actual = lodashStable.map(array, _.head); 8085 8086 assert.deepEqual(actual, [1, 4, 7]); 8087 }); 8088 8089 QUnit.test('should be aliased', function(assert) { 8090 assert.expect(1); 8091 8092 assert.strictEqual(_.first, _.head); 8093 }); 8094 8095 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 8096 assert.expect(2); 8097 8098 if (!isNpm) { 8099 var wrapped = _(array); 8100 assert.strictEqual(wrapped.head(), 1); 8101 assert.strictEqual(wrapped.first(), 1); 8102 } 8103 else { 8104 skipAssert(assert, 2); 8105 } 8106 }); 8107 8108 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 8109 assert.expect(2); 8110 8111 if (!isNpm) { 8112 var wrapped = _(array).chain(); 8113 assert.ok(wrapped.head() instanceof _); 8114 assert.ok(wrapped.first() instanceof _); 8115 } 8116 else { 8117 skipAssert(assert, 2); 8118 } 8119 }); 8120 8121 QUnit.test('should not execute immediately when explicitly chaining', function(assert) { 8122 assert.expect(2); 8123 8124 if (!isNpm) { 8125 var wrapped = _(array).chain(); 8126 assert.strictEqual(wrapped.head().__wrapped__, array); 8127 assert.strictEqual(wrapped.first().__wrapped__, array); 8128 } 8129 else { 8130 skipAssert(assert, 2); 8131 } 8132 }); 8133 8134 QUnit.test('should work in a lazy sequence', function(assert) { 8135 assert.expect(4); 8136 8137 if (!isNpm) { 8138 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE), 8139 smallArray = array; 8140 8141 lodashStable.each(['head', 'first'], function(methodName) { 8142 lodashStable.times(2, function(index) { 8143 var array = index ? largeArray : smallArray, 8144 actual = _(array).filter(isEven)[methodName](); 8145 8146 assert.strictEqual(actual, _[methodName](_.filter(array, isEven))); 8147 }); 8148 }); 8149 } 8150 else { 8151 skipAssert(assert, 4); 8152 } 8153 }); 8154 }()); 8155 8156 /*--------------------------------------------------------------------------*/ 8157 8158 QUnit.module('lodash.identity'); 8159 8160 (function() { 8161 QUnit.test('should return the first argument given', function(assert) { 8162 assert.expect(1); 8163 8164 var object = { 'name': 'fred' }; 8165 assert.strictEqual(_.identity(object), object); 8166 }); 8167 }()); 8168 8169 /*--------------------------------------------------------------------------*/ 8170 8171 QUnit.module('lodash.includes'); 8172 8173 (function() { 8174 lodashStable.each({ 8175 'an `arguments` object': arguments, 8176 'an array': [1, 2, 3, 4], 8177 'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, 8178 'a string': '1234' 8179 }, 8180 function(collection, key) { 8181 QUnit.test('should work with ' + key + ' and return `true` for matched values', function(assert) { 8182 assert.expect(1); 8183 8184 assert.strictEqual(_.includes(collection, 3), true); 8185 }); 8186 8187 QUnit.test('should work with ' + key + ' and return `false` for unmatched values', function(assert) { 8188 assert.expect(1); 8189 8190 assert.strictEqual(_.includes(collection, 5), false); 8191 }); 8192 8193 QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) { 8194 assert.expect(1); 8195 8196 assert.strictEqual(_.includes(collection, 2, 1.2), true); 8197 }); 8198 8199 QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) { 8200 assert.expect(1); 8201 8202 if (!isNpm) { 8203 assert.strictEqual(_(collection).includes(3), true); 8204 } 8205 else { 8206 skipAssert(assert); 8207 } 8208 }); 8209 8210 QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) { 8211 assert.expect(1); 8212 8213 if (!isNpm) { 8214 assert.ok(_(collection).chain().includes(3) instanceof _); 8215 } 8216 else { 8217 skipAssert(assert); 8218 } 8219 }); 8220 }); 8221 8222 lodashStable.each({ 8223 'literal': 'abc', 8224 'object': Object('abc') 8225 }, 8226 function(collection, key) { 8227 QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) { 8228 assert.expect(2); 8229 8230 assert.strictEqual(_.includes(collection, 'bc'), true); 8231 assert.strictEqual(_.includes(collection, 'd'), false); 8232 }); 8233 }); 8234 8235 QUnit.test('should return `false` for empty collections', function(assert) { 8236 assert.expect(1); 8237 8238 var expected = lodashStable.map(empties, stubFalse); 8239 8240 var actual = lodashStable.map(empties, function(value) { 8241 try { 8242 return _.includes(value); 8243 } catch (e) {} 8244 }); 8245 8246 assert.deepEqual(actual, expected); 8247 }); 8248 8249 QUnit.test('should work with a string and a `fromIndex` >= `length`', function(assert) { 8250 assert.expect(1); 8251 8252 var string = '1234', 8253 length = string.length, 8254 indexes = [4, 6, Math.pow(2, 32), Infinity]; 8255 8256 var expected = lodashStable.map(indexes, function(index) { 8257 return [false, false, index == length]; 8258 }); 8259 8260 var actual = lodashStable.map(indexes, function(fromIndex) { 8261 return [ 8262 _.includes(string, 1, fromIndex), 8263 _.includes(string, undefined, fromIndex), 8264 _.includes(string, '', fromIndex) 8265 ]; 8266 }); 8267 8268 assert.deepEqual(actual, expected); 8269 }); 8270 8271 QUnit.test('should match `NaN`', function(assert) { 8272 assert.expect(1); 8273 8274 assert.strictEqual(_.includes([1, NaN, 3], NaN), true); 8275 }); 8276 8277 QUnit.test('should match `-0` as `0`', function(assert) { 8278 assert.expect(2); 8279 8280 assert.strictEqual(_.includes([-0], 0), true); 8281 assert.strictEqual(_.includes([0], -0), true); 8282 }); 8283 8284 QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) { 8285 assert.expect(1); 8286 8287 var array = [2, 3, 1], 8288 values = [1, 2, 3]; 8289 8290 assert.ok(lodashStable.every(values, lodashStable.partial(_.includes, array))); 8291 }); 8292 }(1, 2, 3, 4)); 8293 8294 /*--------------------------------------------------------------------------*/ 8295 8296 QUnit.module('lodash.initial'); 8297 8298 (function() { 8299 var array = [1, 2, 3]; 8300 8301 QUnit.test('should accept a falsey `array`', function(assert) { 8302 assert.expect(1); 8303 8304 var expected = lodashStable.map(falsey, stubArray); 8305 8306 var actual = lodashStable.map(falsey, function(array, index) { 8307 try { 8308 return index ? _.initial(array) : _.initial(); 8309 } catch (e) {} 8310 }); 8311 8312 assert.deepEqual(actual, expected); 8313 }); 8314 8315 QUnit.test('should exclude last element', function(assert) { 8316 assert.expect(1); 8317 8318 assert.deepEqual(_.initial(array), [1, 2]); 8319 }); 8320 8321 QUnit.test('should return an empty when querying empty arrays', function(assert) { 8322 assert.expect(1); 8323 8324 assert.deepEqual(_.initial([]), []); 8325 }); 8326 8327 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 8328 assert.expect(1); 8329 8330 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 8331 actual = lodashStable.map(array, _.initial); 8332 8333 assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]); 8334 }); 8335 8336 QUnit.test('should work in a lazy sequence', function(assert) { 8337 assert.expect(4); 8338 8339 if (!isNpm) { 8340 var array = lodashStable.range(LARGE_ARRAY_SIZE), 8341 values = []; 8342 8343 var actual = _(array).initial().filter(function(value) { 8344 values.push(value); 8345 return false; 8346 }) 8347 .value(); 8348 8349 assert.deepEqual(actual, []); 8350 assert.deepEqual(values, _.initial(array)); 8351 8352 values = []; 8353 8354 actual = _(array).filter(function(value) { 8355 values.push(value); 8356 return isEven(value); 8357 }) 8358 .initial() 8359 .value(); 8360 8361 assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven))); 8362 assert.deepEqual(values, array); 8363 } 8364 else { 8365 skipAssert(assert, 4); 8366 } 8367 }); 8368 }()); 8369 8370 /*--------------------------------------------------------------------------*/ 8371 8372 QUnit.module('lodash.inRange'); 8373 8374 (function() { 8375 QUnit.test('should work with an `end`', function(assert) { 8376 assert.expect(3); 8377 8378 assert.strictEqual(_.inRange(3, 5), true); 8379 assert.strictEqual(_.inRange(5, 5), false); 8380 assert.strictEqual(_.inRange(6, 5), false); 8381 }); 8382 8383 QUnit.test('should work with a `start` and `end`', function(assert) { 8384 assert.expect(4); 8385 8386 assert.strictEqual(_.inRange(1, 1, 5), true); 8387 assert.strictEqual(_.inRange(3, 1, 5), true); 8388 assert.strictEqual(_.inRange(0, 1, 5), false); 8389 assert.strictEqual(_.inRange(5, 1, 5), false); 8390 }); 8391 8392 QUnit.test('should treat falsey `start` as `0`', function(assert) { 8393 assert.expect(13); 8394 8395 lodashStable.each(falsey, function(value, index) { 8396 if (index) { 8397 assert.strictEqual(_.inRange(0, value), false); 8398 assert.strictEqual(_.inRange(0, value, 1), true); 8399 } else { 8400 assert.strictEqual(_.inRange(0), false); 8401 } 8402 }); 8403 }); 8404 8405 QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) { 8406 assert.expect(2); 8407 8408 assert.strictEqual(_.inRange(2, 5, 1), true); 8409 assert.strictEqual(_.inRange(-3, -2, -6), true); 8410 }); 8411 8412 QUnit.test('should work with a floating point `n` value', function(assert) { 8413 assert.expect(4); 8414 8415 assert.strictEqual(_.inRange(0.5, 5), true); 8416 assert.strictEqual(_.inRange(1.2, 1, 5), true); 8417 assert.strictEqual(_.inRange(5.2, 5), false); 8418 assert.strictEqual(_.inRange(0.5, 1, 5), false); 8419 }); 8420 8421 QUnit.test('should coerce arguments to finite numbers', function(assert) { 8422 assert.expect(1); 8423 8424 var actual = [ 8425 _.inRange(0, '1'), 8426 _.inRange(0, '0', 1), 8427 _.inRange(0, 0, '1'), 8428 _.inRange(0, NaN, 1), 8429 _.inRange(-1, -1, NaN) 8430 ]; 8431 8432 assert.deepEqual(actual, lodashStable.map(actual, stubTrue)); 8433 }); 8434 }()); 8435 8436 /*--------------------------------------------------------------------------*/ 8437 8438 QUnit.module('intersection methods'); 8439 8440 lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) { 8441 var func = _[methodName]; 8442 8443 QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) { 8444 assert.expect(1); 8445 8446 var actual = func([2, 1], [2, 3]); 8447 assert.deepEqual(actual, [2]); 8448 }); 8449 8450 QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) { 8451 assert.expect(1); 8452 8453 var actual = func([2, 1, 2, 3], [3, 4], [3, 2]); 8454 assert.deepEqual(actual, [3]); 8455 }); 8456 8457 QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) { 8458 assert.expect(1); 8459 8460 var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]); 8461 assert.deepEqual(actual, [1, 2]); 8462 }); 8463 8464 QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) { 8465 assert.expect(1); 8466 8467 var actual = func([1, 1, 3, 2, 2]); 8468 assert.deepEqual(actual, [1, 3, 2]); 8469 }); 8470 8471 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) { 8472 assert.expect(2); 8473 8474 var array = [0, 1, null, 3], 8475 expected = [1, 3]; 8476 8477 assert.deepEqual(func(array, args), expected); 8478 assert.deepEqual(func(args, array), expected); 8479 }); 8480 8481 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) { 8482 assert.expect(1); 8483 8484 var values = [-0, 0], 8485 expected = lodashStable.map(values, lodashStable.constant(['0'])); 8486 8487 var actual = lodashStable.map(values, function(value) { 8488 return lodashStable.map(func(values, [value]), lodashStable.toString); 8489 }); 8490 8491 assert.deepEqual(actual, expected); 8492 }); 8493 8494 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { 8495 assert.expect(1); 8496 8497 var actual = func([1, NaN, 3], [NaN, 5, NaN]); 8498 assert.deepEqual(actual, [NaN]); 8499 }); 8500 8501 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) { 8502 assert.expect(1); 8503 8504 var values = [-0, 0], 8505 expected = lodashStable.map(values, lodashStable.constant(['0'])); 8506 8507 var actual = lodashStable.map(values, function(value) { 8508 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value)); 8509 return lodashStable.map(func(values, largeArray), lodashStable.toString); 8510 }); 8511 8512 assert.deepEqual(actual, expected); 8513 }); 8514 8515 QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) { 8516 assert.expect(1); 8517 8518 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubNaN); 8519 assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]); 8520 }); 8521 8522 QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) { 8523 assert.expect(2); 8524 8525 var object = {}, 8526 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object)); 8527 8528 assert.deepEqual(func([object], largeArray), [object]); 8529 assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]); 8530 }); 8531 8532 QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) { 8533 assert.expect(3); 8534 8535 var array = [0, 1, null, 3]; 8536 assert.deepEqual(func(array, 3, { '0': 1 }, null), []); 8537 assert.deepEqual(func(null, array, null, [2, 3]), []); 8538 assert.deepEqual(func(array, null, args, null), []); 8539 }); 8540 8541 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) { 8542 assert.expect(2); 8543 8544 if (!isNpm) { 8545 var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]); 8546 assert.ok(wrapped instanceof _); 8547 assert.deepEqual(wrapped.value(), [1, 2]); 8548 } 8549 else { 8550 skipAssert(assert, 2); 8551 } 8552 }); 8553 }); 8554 8555 /*--------------------------------------------------------------------------*/ 8556 8557 QUnit.module('lodash.intersectionBy'); 8558 8559 (function() { 8560 QUnit.test('should accept an `iteratee`', function(assert) { 8561 assert.expect(2); 8562 8563 var actual = _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); 8564 assert.deepEqual(actual, [2.1]); 8565 8566 actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); 8567 assert.deepEqual(actual, [{ 'x': 1 }]); 8568 }); 8569 8570 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 8571 assert.expect(1); 8572 8573 var args; 8574 8575 _.intersectionBy([2.1, 1.2], [2.3, 3.4], function() { 8576 args || (args = slice.call(arguments)); 8577 }); 8578 8579 assert.deepEqual(args, [2.3]); 8580 }); 8581 }()); 8582 8583 /*--------------------------------------------------------------------------*/ 8584 8585 QUnit.module('lodash.intersectionWith'); 8586 8587 (function() { 8588 QUnit.test('should work with a `comparator`', function(assert) { 8589 assert.expect(1); 8590 8591 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }], 8592 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }], 8593 actual = _.intersectionWith(objects, others, lodashStable.isEqual); 8594 8595 assert.deepEqual(actual, [objects[0]]); 8596 }); 8597 8598 QUnit.test('should preserve the sign of `0`', function(assert) { 8599 assert.expect(1); 8600 8601 var array = [-0], 8602 largeArray = lodashStable.times(LARGE_ARRAY_SIZE, stubZero), 8603 others = [[0], largeArray], 8604 expected = lodashStable.map(others, lodashStable.constant(['-0'])); 8605 8606 var actual = lodashStable.map(others, function(other) { 8607 return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString); 8608 }); 8609 8610 assert.deepEqual(actual, expected); 8611 }); 8612 }()); 8613 8614 /*--------------------------------------------------------------------------*/ 8615 8616 QUnit.module('lodash.invert'); 8617 8618 (function() { 8619 QUnit.test('should invert an object', function(assert) { 8620 assert.expect(2); 8621 8622 var object = { 'a': 1, 'b': 2 }, 8623 actual = _.invert(object); 8624 8625 assert.deepEqual(actual, { '1': 'a', '2': 'b' }); 8626 assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' }); 8627 }); 8628 8629 QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) { 8630 assert.expect(1); 8631 8632 var object = { 'a': 'hasOwnProperty', 'b': 'constructor' }; 8633 assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' }); 8634 }); 8635 8636 QUnit.test('should work with an object that has a `length` property', function(assert) { 8637 assert.expect(1); 8638 8639 var object = { '0': 'a', '1': 'b', 'length': 2 }; 8640 assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' }); 8641 }); 8642 8643 QUnit.test('should return a wrapped value when chaining', function(assert) { 8644 assert.expect(2); 8645 8646 if (!isNpm) { 8647 var object = { 'a': 1, 'b': 2 }, 8648 wrapped = _(object).invert(); 8649 8650 assert.ok(wrapped instanceof _); 8651 assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' }); 8652 } 8653 else { 8654 skipAssert(assert, 2); 8655 } 8656 }); 8657 }()); 8658 8659 /*--------------------------------------------------------------------------*/ 8660 8661 QUnit.module('lodash.invertBy'); 8662 8663 (function() { 8664 var object = { 'a': 1, 'b': 2, 'c': 1 }; 8665 8666 QUnit.test('should transform keys by `iteratee`', function(assert) { 8667 assert.expect(1); 8668 8669 var expected = { 'group1': ['a', 'c'], 'group2': ['b'] }; 8670 8671 var actual = _.invertBy(object, function(value) { 8672 return 'group' + value; 8673 }); 8674 8675 assert.deepEqual(actual, expected); 8676 }); 8677 8678 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 8679 assert.expect(1); 8680 8681 var values = [, null, undefined], 8682 expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] })); 8683 8684 var actual = lodashStable.map(values, function(value, index) { 8685 return index ? _.invertBy(object, value) : _.invertBy(object); 8686 }); 8687 8688 assert.deepEqual(actual, expected); 8689 }); 8690 8691 QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) { 8692 assert.expect(1); 8693 8694 var object = { 'a': 'hasOwnProperty', 'b': 'constructor' }, 8695 expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] }; 8696 8697 assert.ok(lodashStable.isEqual(_.invertBy(object), expected)); 8698 }); 8699 8700 QUnit.test('should return a wrapped value when chaining', function(assert) { 8701 assert.expect(2); 8702 8703 if (!isNpm) { 8704 var wrapped = _(object).invertBy(); 8705 8706 assert.ok(wrapped instanceof _); 8707 assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] }); 8708 } 8709 else { 8710 skipAssert(assert, 2); 8711 } 8712 }); 8713 }()); 8714 8715 /*--------------------------------------------------------------------------*/ 8716 8717 QUnit.module('lodash.invoke'); 8718 8719 (function() { 8720 QUnit.test('should invoke a method on `object`', function(assert) { 8721 assert.expect(1); 8722 8723 var object = { 'a': lodashStable.constant('A') }, 8724 actual = _.invoke(object, 'a'); 8725 8726 assert.strictEqual(actual, 'A'); 8727 }); 8728 8729 QUnit.test('should support invoking with arguments', function(assert) { 8730 assert.expect(1); 8731 8732 var object = { 'a': function(a, b) { return [a, b]; } }, 8733 actual = _.invoke(object, 'a', 1, 2); 8734 8735 assert.deepEqual(actual, [1, 2]); 8736 }); 8737 8738 QUnit.test('should not error on nullish elements', function(assert) { 8739 assert.expect(1); 8740 8741 var values = [null, undefined], 8742 expected = lodashStable.map(values, noop); 8743 8744 var actual = lodashStable.map(values, function(value) { 8745 try { 8746 return _.invoke(value, 'a.b', 1, 2); 8747 } catch (e) {} 8748 }); 8749 8750 assert.deepEqual(actual, expected); 8751 }); 8752 8753 QUnit.test('should preserve the sign of `0`', function(assert) { 8754 assert.expect(1); 8755 8756 var object = { '-0': stubA, '0': stubB }, 8757 props = [-0, Object(-0), 0, Object(0)]; 8758 8759 var actual = lodashStable.map(props, function(key) { 8760 return _.invoke(object, key); 8761 }); 8762 8763 assert.deepEqual(actual, ['a', 'a', 'b', 'b']); 8764 }); 8765 8766 QUnit.test('should support deep paths', function(assert) { 8767 assert.expect(2); 8768 8769 var object = { 'a': { 'b': function(a, b) { return [a, b]; } } }; 8770 8771 lodashStable.each(['a.b', ['a', 'b']], function(path) { 8772 var actual = _.invoke(object, path, 1, 2); 8773 assert.deepEqual(actual, [1, 2]); 8774 }); 8775 }); 8776 8777 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) { 8778 assert.expect(2); 8779 8780 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } }; 8781 8782 lodashStable.each(['a.b', ['a', 'b']], function(path) { 8783 assert.deepEqual(_.invoke(object, path), 1); 8784 }); 8785 }); 8786 8787 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 8788 assert.expect(1); 8789 8790 if (!isNpm) { 8791 var object = { 'a': stubOne }; 8792 assert.strictEqual(_(object).invoke('a'), 1); 8793 } 8794 else { 8795 skipAssert(assert); 8796 } 8797 }); 8798 8799 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 8800 assert.expect(1); 8801 8802 if (!isNpm) { 8803 var object = { 'a': stubOne }; 8804 assert.ok(_(object).chain().invoke('a') instanceof _); 8805 } 8806 else { 8807 skipAssert(assert); 8808 } 8809 }); 8810 }()); 8811 8812 /*--------------------------------------------------------------------------*/ 8813 8814 QUnit.module('lodash.invokeMap'); 8815 8816 (function() { 8817 QUnit.test('should invoke a methods on each element of `collection`', function(assert) { 8818 assert.expect(1); 8819 8820 var array = ['a', 'b', 'c'], 8821 actual = _.invokeMap(array, 'toUpperCase'); 8822 8823 assert.deepEqual(actual, ['A', 'B', 'C']); 8824 }); 8825 8826 QUnit.test('should support invoking with arguments', function(assert) { 8827 assert.expect(1); 8828 8829 var array = [function() { return slice.call(arguments); }], 8830 actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c'); 8831 8832 assert.deepEqual(actual, [['a', 'b', 'c']]); 8833 }); 8834 8835 QUnit.test('should work with a function for `methodName`', function(assert) { 8836 assert.expect(1); 8837 8838 var array = ['a', 'b', 'c']; 8839 8840 var actual = _.invokeMap(array, function(left, right) { 8841 return left + this.toUpperCase() + right; 8842 }, '(', ')'); 8843 8844 assert.deepEqual(actual, ['(A)', '(B)', '(C)']); 8845 }); 8846 8847 QUnit.test('should work with an object for `collection`', function(assert) { 8848 assert.expect(1); 8849 8850 var object = { 'a': 1, 'b': 2, 'c': 3 }, 8851 actual = _.invokeMap(object, 'toFixed', 1); 8852 8853 assert.deepEqual(actual, ['1.0', '2.0', '3.0']); 8854 }); 8855 8856 QUnit.test('should treat number values for `collection` as empty', function(assert) { 8857 assert.expect(1); 8858 8859 assert.deepEqual(_.invokeMap(1), []); 8860 }); 8861 8862 QUnit.test('should not error on nullish elements', function(assert) { 8863 assert.expect(1); 8864 8865 var array = ['a', null, undefined, 'd']; 8866 8867 try { 8868 var actual = _.invokeMap(array, 'toUpperCase'); 8869 } catch (e) {} 8870 8871 assert.deepEqual(actual, ['A', undefined, undefined, 'D']); 8872 }); 8873 8874 QUnit.test('should not error on elements with missing properties', function(assert) { 8875 assert.expect(1); 8876 8877 var objects = lodashStable.map([null, undefined, stubOne], function(value) { 8878 return { 'a': value }; 8879 }); 8880 8881 var expected = lodashStable.map(objects, function(object) { 8882 return object.a ? object.a() : undefined; 8883 }); 8884 8885 try { 8886 var actual = _.invokeMap(objects, 'a'); 8887 } catch (e) {} 8888 8889 assert.deepEqual(actual, expected); 8890 }); 8891 8892 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) { 8893 assert.expect(2); 8894 8895 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } }; 8896 8897 lodashStable.each(['a.b', ['a', 'b']], function(path) { 8898 assert.deepEqual(_.invokeMap([object], path), [1]); 8899 }); 8900 }); 8901 8902 QUnit.test('should return a wrapped value when chaining', function(assert) { 8903 assert.expect(4); 8904 8905 if (!isNpm) { 8906 var array = ['a', 'b', 'c'], 8907 wrapped = _(array), 8908 actual = wrapped.invokeMap('toUpperCase'); 8909 8910 assert.ok(actual instanceof _); 8911 assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']); 8912 8913 actual = wrapped.invokeMap(function(left, right) { 8914 return left + this.toUpperCase() + right; 8915 }, '(', ')'); 8916 8917 assert.ok(actual instanceof _); 8918 assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']); 8919 } 8920 else { 8921 skipAssert(assert, 4); 8922 } 8923 }); 8924 8925 QUnit.test('should support shortcut fusion', function(assert) { 8926 assert.expect(2); 8927 8928 if (!isNpm) { 8929 var count = 0, 8930 method = function() { count++; return this.index; }; 8931 8932 var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 8933 return { 'index': index, 'method': method }; 8934 }); 8935 8936 var actual = _(array).invokeMap('method').take(1).value(); 8937 8938 assert.strictEqual(count, 1); 8939 assert.deepEqual(actual, [0]); 8940 } 8941 else { 8942 skipAssert(assert, 2); 8943 } 8944 }); 8945 }()); 8946 8947 /*--------------------------------------------------------------------------*/ 8948 8949 QUnit.module('lodash.isArguments'); 8950 8951 (function() { 8952 QUnit.test('should return `true` for `arguments` objects', function(assert) { 8953 assert.expect(2); 8954 8955 assert.strictEqual(_.isArguments(args), true); 8956 assert.strictEqual(_.isArguments(strictArgs), true); 8957 }); 8958 8959 QUnit.test('should return `false` for non `arguments` objects', function(assert) { 8960 assert.expect(12); 8961 8962 var expected = lodashStable.map(falsey, stubFalse); 8963 8964 var actual = lodashStable.map(falsey, function(value, index) { 8965 return index ? _.isArguments(value) : _.isArguments(); 8966 }); 8967 8968 assert.deepEqual(actual, expected); 8969 8970 assert.strictEqual(_.isArguments([1, 2, 3]), false); 8971 assert.strictEqual(_.isArguments(true), false); 8972 assert.strictEqual(_.isArguments(new Date), false); 8973 assert.strictEqual(_.isArguments(new Error), false); 8974 assert.strictEqual(_.isArguments(_), false); 8975 assert.strictEqual(_.isArguments(slice), false); 8976 assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false); 8977 assert.strictEqual(_.isArguments(1), false); 8978 assert.strictEqual(_.isArguments(/x/), false); 8979 assert.strictEqual(_.isArguments('a'), false); 8980 assert.strictEqual(_.isArguments(symbol), false); 8981 }); 8982 8983 QUnit.test('should work with an `arguments` object from another realm', function(assert) { 8984 assert.expect(1); 8985 8986 if (realm.arguments) { 8987 assert.strictEqual(_.isArguments(realm.arguments), true); 8988 } 8989 else { 8990 skipAssert(assert); 8991 } 8992 }); 8993 }()); 8994 8995 /*--------------------------------------------------------------------------*/ 8996 8997 QUnit.module('lodash.isArray'); 8998 8999 (function() { 9000 QUnit.test('should return `true` for arrays', function(assert) { 9001 assert.expect(1); 9002 9003 assert.strictEqual(_.isArray([1, 2, 3]), true); 9004 }); 9005 9006 QUnit.test('should return `false` for non-arrays', function(assert) { 9007 assert.expect(12); 9008 9009 var expected = lodashStable.map(falsey, stubFalse); 9010 9011 var actual = lodashStable.map(falsey, function(value, index) { 9012 return index ? _.isArray(value) : _.isArray(); 9013 }); 9014 9015 assert.deepEqual(actual, expected); 9016 9017 assert.strictEqual(_.isArray(args), false); 9018 assert.strictEqual(_.isArray(true), false); 9019 assert.strictEqual(_.isArray(new Date), false); 9020 assert.strictEqual(_.isArray(new Error), false); 9021 assert.strictEqual(_.isArray(_), false); 9022 assert.strictEqual(_.isArray(slice), false); 9023 assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false); 9024 assert.strictEqual(_.isArray(1), false); 9025 assert.strictEqual(_.isArray(/x/), false); 9026 assert.strictEqual(_.isArray('a'), false); 9027 assert.strictEqual(_.isArray(symbol), false); 9028 }); 9029 9030 QUnit.test('should work with an array from another realm', function(assert) { 9031 assert.expect(1); 9032 9033 if (realm.array) { 9034 assert.strictEqual(_.isArray(realm.array), true); 9035 } 9036 else { 9037 skipAssert(assert); 9038 } 9039 }); 9040 }()); 9041 9042 /*--------------------------------------------------------------------------*/ 9043 9044 QUnit.module('lodash.isArrayBuffer'); 9045 9046 (function() { 9047 QUnit.test('should return `true` for array buffers', function(assert) { 9048 assert.expect(1); 9049 9050 if (ArrayBuffer) { 9051 assert.strictEqual(_.isArrayBuffer(arrayBuffer), true); 9052 } 9053 else { 9054 skipAssert(assert); 9055 } 9056 }); 9057 9058 QUnit.test('should return `false` for non array buffers', function(assert) { 9059 assert.expect(13); 9060 9061 var expected = lodashStable.map(falsey, stubFalse); 9062 9063 var actual = lodashStable.map(falsey, function(value, index) { 9064 return index ? _.isArrayBuffer(value) : _.isArrayBuffer(); 9065 }); 9066 9067 assert.deepEqual(actual, expected); 9068 9069 assert.strictEqual(_.isArrayBuffer(args), false); 9070 assert.strictEqual(_.isArrayBuffer([1]), false); 9071 assert.strictEqual(_.isArrayBuffer(true), false); 9072 assert.strictEqual(_.isArrayBuffer(new Date), false); 9073 assert.strictEqual(_.isArrayBuffer(new Error), false); 9074 assert.strictEqual(_.isArrayBuffer(_), false); 9075 assert.strictEqual(_.isArrayBuffer(slice), false); 9076 assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false); 9077 assert.strictEqual(_.isArrayBuffer(1), false); 9078 assert.strictEqual(_.isArrayBuffer(/x/), false); 9079 assert.strictEqual(_.isArrayBuffer('a'), false); 9080 assert.strictEqual(_.isArrayBuffer(symbol), false); 9081 }); 9082 9083 QUnit.test('should work with array buffers from another realm', function(assert) { 9084 assert.expect(1); 9085 9086 if (realm.arrayBuffer) { 9087 assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true); 9088 } 9089 else { 9090 skipAssert(assert); 9091 } 9092 }); 9093 }()); 9094 9095 /*--------------------------------------------------------------------------*/ 9096 9097 QUnit.module('lodash.isArrayLike'); 9098 9099 (function() { 9100 QUnit.test('should return `true` for array-like values', function(assert) { 9101 assert.expect(1); 9102 9103 var values = [args, [1, 2, 3], { '0': 'a', 'length': 1 }, 'a'], 9104 expected = lodashStable.map(values, stubTrue), 9105 actual = lodashStable.map(values, _.isArrayLike); 9106 9107 assert.deepEqual(actual, expected); 9108 }); 9109 9110 QUnit.test('should return `false` for non-arrays', function(assert) { 9111 assert.expect(12); 9112 9113 var expected = lodashStable.map(falsey, function(value) { 9114 return value === ''; 9115 }); 9116 9117 var actual = lodashStable.map(falsey, function(value, index) { 9118 return index ? _.isArrayLike(value) : _.isArrayLike(); 9119 }); 9120 9121 assert.deepEqual(actual, expected); 9122 9123 assert.strictEqual(_.isArrayLike(true), false); 9124 assert.strictEqual(_.isArrayLike(new Date), false); 9125 assert.strictEqual(_.isArrayLike(new Error), false); 9126 assert.strictEqual(_.isArrayLike(_), false); 9127 assert.strictEqual(_.isArrayLike(asyncFunc), false); 9128 assert.strictEqual(_.isArrayLike(genFunc), false); 9129 assert.strictEqual(_.isArrayLike(slice), false); 9130 assert.strictEqual(_.isArrayLike({ 'a': 1 }), false); 9131 assert.strictEqual(_.isArrayLike(1), false); 9132 assert.strictEqual(_.isArrayLike(/x/), false); 9133 assert.strictEqual(_.isArrayLike(symbol), false); 9134 }); 9135 9136 QUnit.test('should work with an array from another realm', function(assert) { 9137 assert.expect(1); 9138 9139 if (realm.object) { 9140 var values = [realm.arguments, realm.array, realm.string], 9141 expected = lodashStable.map(values, stubTrue), 9142 actual = lodashStable.map(values, _.isArrayLike); 9143 9144 assert.deepEqual(actual, expected); 9145 } 9146 else { 9147 skipAssert(assert); 9148 } 9149 }); 9150 }()); 9151 9152 /*--------------------------------------------------------------------------*/ 9153 9154 QUnit.module('lodash.isBoolean'); 9155 9156 (function() { 9157 QUnit.test('should return `true` for booleans', function(assert) { 9158 assert.expect(4); 9159 9160 assert.strictEqual(_.isBoolean(true), true); 9161 assert.strictEqual(_.isBoolean(false), true); 9162 assert.strictEqual(_.isBoolean(Object(true)), true); 9163 assert.strictEqual(_.isBoolean(Object(false)), true); 9164 }); 9165 9166 QUnit.test('should return `false` for non-booleans', function(assert) { 9167 assert.expect(12); 9168 9169 var expected = lodashStable.map(falsey, function(value) { 9170 return value === false; 9171 }); 9172 9173 var actual = lodashStable.map(falsey, function(value, index) { 9174 return index ? _.isBoolean(value) : _.isBoolean(); 9175 }); 9176 9177 assert.deepEqual(actual, expected); 9178 9179 assert.strictEqual(_.isBoolean(args), false); 9180 assert.strictEqual(_.isBoolean([1, 2, 3]), false); 9181 assert.strictEqual(_.isBoolean(new Date), false); 9182 assert.strictEqual(_.isBoolean(new Error), false); 9183 assert.strictEqual(_.isBoolean(_), false); 9184 assert.strictEqual(_.isBoolean(slice), false); 9185 assert.strictEqual(_.isBoolean({ 'a': 1 }), false); 9186 assert.strictEqual(_.isBoolean(1), false); 9187 assert.strictEqual(_.isBoolean(/x/), false); 9188 assert.strictEqual(_.isBoolean('a'), false); 9189 assert.strictEqual(_.isBoolean(symbol), false); 9190 }); 9191 9192 QUnit.test('should work with a boolean from another realm', function(assert) { 9193 assert.expect(1); 9194 9195 if (realm.boolean) { 9196 assert.strictEqual(_.isBoolean(realm.boolean), true); 9197 } 9198 else { 9199 skipAssert(assert); 9200 } 9201 }); 9202 }()); 9203 9204 /*--------------------------------------------------------------------------*/ 9205 9206 QUnit.module('lodash.isBuffer'); 9207 9208 (function() { 9209 QUnit.test('should return `true` for buffers', function(assert) { 9210 assert.expect(1); 9211 9212 if (Buffer) { 9213 assert.strictEqual(_.isBuffer(new Buffer(2)), true); 9214 } 9215 else { 9216 skipAssert(assert); 9217 } 9218 }); 9219 9220 QUnit.test('should return `false` for non-buffers', function(assert) { 9221 assert.expect(13); 9222 9223 var expected = lodashStable.map(falsey, stubFalse); 9224 9225 var actual = lodashStable.map(falsey, function(value, index) { 9226 return index ? _.isBuffer(value) : _.isBuffer(); 9227 }); 9228 9229 assert.deepEqual(actual, expected); 9230 9231 assert.strictEqual(_.isBuffer(args), false); 9232 assert.strictEqual(_.isBuffer([1]), false); 9233 assert.strictEqual(_.isBuffer(true), false); 9234 assert.strictEqual(_.isBuffer(new Date), false); 9235 assert.strictEqual(_.isBuffer(new Error), false); 9236 assert.strictEqual(_.isBuffer(_), false); 9237 assert.strictEqual(_.isBuffer(slice), false); 9238 assert.strictEqual(_.isBuffer({ 'a': 1 }), false); 9239 assert.strictEqual(_.isBuffer(1), false); 9240 assert.strictEqual(_.isBuffer(/x/), false); 9241 assert.strictEqual(_.isBuffer('a'), false); 9242 assert.strictEqual(_.isBuffer(symbol), false); 9243 }); 9244 9245 QUnit.test('should return `false` if `Buffer` is not defined', function(assert) { 9246 assert.expect(1); 9247 9248 if (!isStrict && Buffer && lodashBizarro) { 9249 assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false); 9250 } 9251 else { 9252 skipAssert(assert); 9253 } 9254 }); 9255 }()); 9256 9257 /*--------------------------------------------------------------------------*/ 9258 9259 QUnit.module('lodash.isDate'); 9260 9261 (function() { 9262 QUnit.test('should return `true` for dates', function(assert) { 9263 assert.expect(1); 9264 9265 assert.strictEqual(_.isDate(new Date), true); 9266 }); 9267 9268 QUnit.test('should return `false` for non-dates', function(assert) { 9269 assert.expect(12); 9270 9271 var expected = lodashStable.map(falsey, stubFalse); 9272 9273 var actual = lodashStable.map(falsey, function(value, index) { 9274 return index ? _.isDate(value) : _.isDate(); 9275 }); 9276 9277 assert.deepEqual(actual, expected); 9278 9279 assert.strictEqual(_.isDate(args), false); 9280 assert.strictEqual(_.isDate([1, 2, 3]), false); 9281 assert.strictEqual(_.isDate(true), false); 9282 assert.strictEqual(_.isDate(new Error), false); 9283 assert.strictEqual(_.isDate(_), false); 9284 assert.strictEqual(_.isDate(slice), false); 9285 assert.strictEqual(_.isDate({ 'a': 1 }), false); 9286 assert.strictEqual(_.isDate(1), false); 9287 assert.strictEqual(_.isDate(/x/), false); 9288 assert.strictEqual(_.isDate('a'), false); 9289 assert.strictEqual(_.isDate(symbol), false); 9290 }); 9291 9292 QUnit.test('should work with a date object from another realm', function(assert) { 9293 assert.expect(1); 9294 9295 if (realm.date) { 9296 assert.strictEqual(_.isDate(realm.date), true); 9297 } 9298 else { 9299 skipAssert(assert); 9300 } 9301 }); 9302 }()); 9303 9304 /*--------------------------------------------------------------------------*/ 9305 9306 QUnit.module('lodash.isElement'); 9307 9308 (function() { 9309 QUnit.test('should return `true` for elements', function(assert) { 9310 assert.expect(1); 9311 9312 if (document) { 9313 assert.strictEqual(_.isElement(body), true); 9314 } 9315 else { 9316 skipAssert(assert); 9317 } 9318 }); 9319 9320 QUnit.test('should return `true` for non-plain objects', function(assert) { 9321 assert.expect(1); 9322 9323 function Foo() { 9324 this.nodeType = 1; 9325 } 9326 9327 assert.strictEqual(_.isElement(new Foo), true); 9328 }); 9329 9330 QUnit.test('should return `false` for non DOM elements', function(assert) { 9331 assert.expect(13); 9332 9333 var expected = lodashStable.map(falsey, stubFalse); 9334 9335 var actual = lodashStable.map(falsey, function(value, index) { 9336 return index ? _.isElement(value) : _.isElement(); 9337 }); 9338 9339 assert.deepEqual(actual, expected); 9340 9341 assert.strictEqual(_.isElement(args), false); 9342 assert.strictEqual(_.isElement([1, 2, 3]), false); 9343 assert.strictEqual(_.isElement(true), false); 9344 assert.strictEqual(_.isElement(new Date), false); 9345 assert.strictEqual(_.isElement(new Error), false); 9346 assert.strictEqual(_.isElement(_), false); 9347 assert.strictEqual(_.isElement(slice), false); 9348 assert.strictEqual(_.isElement({ 'a': 1 }), false); 9349 assert.strictEqual(_.isElement(1), false); 9350 assert.strictEqual(_.isElement(/x/), false); 9351 assert.strictEqual(_.isElement('a'), false); 9352 assert.strictEqual(_.isElement(symbol), false); 9353 }); 9354 9355 QUnit.test('should return `false` for plain objects', function(assert) { 9356 assert.expect(6); 9357 9358 assert.strictEqual(_.isElement({ 'nodeType': 1 }), false); 9359 assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false); 9360 assert.strictEqual(_.isElement({ 'nodeType': true }), false); 9361 assert.strictEqual(_.isElement({ 'nodeType': [1] }), false); 9362 assert.strictEqual(_.isElement({ 'nodeType': '1' }), false); 9363 assert.strictEqual(_.isElement({ 'nodeType': '001' }), false); 9364 }); 9365 9366 QUnit.test('should work with a DOM element from another realm', function(assert) { 9367 assert.expect(1); 9368 9369 if (realm.element) { 9370 assert.strictEqual(_.isElement(realm.element), true); 9371 } 9372 else { 9373 skipAssert(assert); 9374 } 9375 }); 9376 }()); 9377 9378 /*--------------------------------------------------------------------------*/ 9379 9380 QUnit.module('lodash.isEmpty'); 9381 9382 (function() { 9383 QUnit.test('should return `true` for empty values', function(assert) { 9384 assert.expect(10); 9385 9386 var expected = lodashStable.map(empties, stubTrue), 9387 actual = lodashStable.map(empties, _.isEmpty); 9388 9389 assert.deepEqual(actual, expected); 9390 9391 assert.strictEqual(_.isEmpty(true), true); 9392 assert.strictEqual(_.isEmpty(slice), true); 9393 assert.strictEqual(_.isEmpty(1), true); 9394 assert.strictEqual(_.isEmpty(NaN), true); 9395 assert.strictEqual(_.isEmpty(/x/), true); 9396 assert.strictEqual(_.isEmpty(symbol), true); 9397 assert.strictEqual(_.isEmpty(), true); 9398 9399 if (Buffer) { 9400 assert.strictEqual(_.isEmpty(new Buffer(0)), true); 9401 assert.strictEqual(_.isEmpty(new Buffer(1)), false); 9402 } 9403 else { 9404 skipAssert(assert, 2); 9405 } 9406 }); 9407 9408 QUnit.test('should return `false` for non-empty values', function(assert) { 9409 assert.expect(3); 9410 9411 assert.strictEqual(_.isEmpty([0]), false); 9412 assert.strictEqual(_.isEmpty({ 'a': 0 }), false); 9413 assert.strictEqual(_.isEmpty('a'), false); 9414 }); 9415 9416 QUnit.test('should work with an object that has a `length` property', function(assert) { 9417 assert.expect(1); 9418 9419 assert.strictEqual(_.isEmpty({ 'length': 0 }), false); 9420 }); 9421 9422 QUnit.test('should work with `arguments` objects', function(assert) { 9423 assert.expect(1); 9424 9425 assert.strictEqual(_.isEmpty(args), false); 9426 }); 9427 9428 QUnit.test('should work with prototytpe objects', function(assert) { 9429 assert.expect(2); 9430 9431 function Foo() {} 9432 Foo.prototype = { 'constructor': Foo }; 9433 9434 assert.strictEqual(_.isEmpty(Foo.prototype), true); 9435 9436 Foo.prototype.a = 1; 9437 assert.strictEqual(_.isEmpty(Foo.prototype), false); 9438 }); 9439 9440 QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) { 9441 assert.expect(1); 9442 9443 function Foo(elements) { 9444 push.apply(this, elements); 9445 } 9446 Foo.prototype = { 'length': 0, 'splice': arrayProto.splice }; 9447 9448 assert.strictEqual(_.isEmpty(new Foo([])), true); 9449 }); 9450 9451 QUnit.test('should work with maps', function(assert) { 9452 assert.expect(4); 9453 9454 if (Map) { 9455 lodashStable.each([new Map, realm.map], function(map) { 9456 assert.strictEqual(_.isEmpty(map), true); 9457 map.set('a', 1); 9458 assert.strictEqual(_.isEmpty(map), false); 9459 map.clear(); 9460 }); 9461 } 9462 else { 9463 skipAssert(assert, 4); 9464 } 9465 }); 9466 9467 QUnit.test('should work with sets', function(assert) { 9468 assert.expect(4); 9469 9470 if (Set) { 9471 lodashStable.each([new Set, realm.set], function(set) { 9472 assert.strictEqual(_.isEmpty(set), true); 9473 set.add(1); 9474 assert.strictEqual(_.isEmpty(set), false); 9475 set.clear(); 9476 }); 9477 } 9478 else { 9479 skipAssert(assert, 4); 9480 } 9481 }); 9482 9483 QUnit.test('should not treat objects with negative lengths as array-like', function(assert) { 9484 assert.expect(1); 9485 9486 function Foo() {} 9487 Foo.prototype.length = -1; 9488 9489 assert.strictEqual(_.isEmpty(new Foo), true); 9490 }); 9491 9492 QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) { 9493 assert.expect(1); 9494 9495 function Foo() {} 9496 Foo.prototype.length = MAX_SAFE_INTEGER + 1; 9497 9498 assert.strictEqual(_.isEmpty(new Foo), true); 9499 }); 9500 9501 QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) { 9502 assert.expect(1); 9503 9504 assert.strictEqual(_.isEmpty({ 'length': '0' }), false); 9505 }); 9506 9507 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 9508 assert.expect(1); 9509 9510 if (!isNpm) { 9511 assert.strictEqual(_({}).isEmpty(), true); 9512 } 9513 else { 9514 skipAssert(assert); 9515 } 9516 }); 9517 9518 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 9519 assert.expect(1); 9520 9521 if (!isNpm) { 9522 assert.ok(_({}).chain().isEmpty() instanceof _); 9523 } 9524 else { 9525 skipAssert(assert); 9526 } 9527 }); 9528 }()); 9529 9530 /*--------------------------------------------------------------------------*/ 9531 9532 QUnit.module('lodash.isEqual'); 9533 9534 (function() { 9535 var symbol1 = Symbol ? Symbol('a') : true, 9536 symbol2 = Symbol ? Symbol('b') : false; 9537 9538 QUnit.test('should compare primitives', function(assert) { 9539 assert.expect(1); 9540 9541 var pairs = [ 9542 [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false], 9543 [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false], 9544 [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false], 9545 ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false], 9546 [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false], 9547 [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false], 9548 [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false], 9549 [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false], 9550 [undefined, undefined, true], [undefined, null, false], [undefined, '', false] 9551 ]; 9552 9553 var expected = lodashStable.map(pairs, function(pair) { 9554 return pair[2]; 9555 }); 9556 9557 var actual = lodashStable.map(pairs, function(pair) { 9558 return _.isEqual(pair[0], pair[1]); 9559 }); 9560 9561 assert.deepEqual(actual, expected); 9562 }); 9563 9564 QUnit.test('should compare arrays', function(assert) { 9565 assert.expect(6); 9566 9567 var array1 = [true, null, 1, 'a', undefined], 9568 array2 = [true, null, 1, 'a', undefined]; 9569 9570 assert.strictEqual(_.isEqual(array1, array2), true); 9571 9572 array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }]; 9573 array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }]; 9574 9575 assert.strictEqual(_.isEqual(array1, array2), true); 9576 9577 array1 = [1]; 9578 array1[2] = 3; 9579 9580 array2 = [1]; 9581 array2[1] = undefined; 9582 array2[2] = 3; 9583 9584 assert.strictEqual(_.isEqual(array1, array2), true); 9585 9586 array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }]; 9587 array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }]; 9588 9589 assert.strictEqual(_.isEqual(array1, array2), true); 9590 9591 array1 = [1, 2, 3]; 9592 array2 = [3, 2, 1]; 9593 9594 assert.strictEqual(_.isEqual(array1, array2), false); 9595 9596 array1 = [1, 2]; 9597 array2 = [1, 2, 3]; 9598 9599 assert.strictEqual(_.isEqual(array1, array2), false); 9600 }); 9601 9602 QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) { 9603 assert.expect(3); 9604 9605 var array1 = [1, 2, 3], 9606 array2 = [1, 2, 3]; 9607 9608 array1.every = array1.filter = array1.forEach = 9609 array1.indexOf = array1.lastIndexOf = array1.map = 9610 array1.some = array1.reduce = array1.reduceRight = null; 9611 9612 array2.concat = array2.join = array2.pop = 9613 array2.reverse = array2.shift = array2.slice = 9614 array2.sort = array2.splice = array2.unshift = null; 9615 9616 assert.strictEqual(_.isEqual(array1, array2), true); 9617 9618 array1 = [1, 2, 3]; 9619 array1.a = 1; 9620 9621 array2 = [1, 2, 3]; 9622 array2.b = 1; 9623 9624 assert.strictEqual(_.isEqual(array1, array2), true); 9625 9626 array1 = /c/.exec('abcde'); 9627 array2 = ['c']; 9628 9629 assert.strictEqual(_.isEqual(array1, array2), true); 9630 }); 9631 9632 QUnit.test('should compare sparse arrays', function(assert) { 9633 assert.expect(3); 9634 9635 var array = Array(1); 9636 9637 assert.strictEqual(_.isEqual(array, Array(1)), true); 9638 assert.strictEqual(_.isEqual(array, [undefined]), true); 9639 assert.strictEqual(_.isEqual(array, Array(2)), false); 9640 }); 9641 9642 QUnit.test('should compare plain objects', function(assert) { 9643 assert.expect(5); 9644 9645 var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined }, 9646 object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined }; 9647 9648 assert.strictEqual(_.isEqual(object1, object2), true); 9649 9650 object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } }; 9651 object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } }; 9652 9653 assert.strictEqual(_.isEqual(object1, object2), true); 9654 9655 object1 = { 'a': 1, 'b': 2, 'c': 3 }; 9656 object2 = { 'a': 3, 'b': 2, 'c': 1 }; 9657 9658 assert.strictEqual(_.isEqual(object1, object2), false); 9659 9660 object1 = { 'a': 1, 'b': 2, 'c': 3 }; 9661 object2 = { 'd': 1, 'e': 2, 'f': 3 }; 9662 9663 assert.strictEqual(_.isEqual(object1, object2), false); 9664 9665 object1 = { 'a': 1, 'b': 2 }; 9666 object2 = { 'a': 1, 'b': 2, 'c': 3 }; 9667 9668 assert.strictEqual(_.isEqual(object1, object2), false); 9669 }); 9670 9671 QUnit.test('should compare objects regardless of key order', function(assert) { 9672 assert.expect(1); 9673 9674 var object1 = { 'a': 1, 'b': 2, 'c': 3 }, 9675 object2 = { 'c': 3, 'a': 1, 'b': 2 }; 9676 9677 assert.strictEqual(_.isEqual(object1, object2), true); 9678 }); 9679 9680 QUnit.test('should compare nested objects', function(assert) { 9681 assert.expect(1); 9682 9683 var object1 = { 9684 'a': [1, 2, 3], 9685 'b': true, 9686 'c': Object(1), 9687 'd': 'a', 9688 'e': { 9689 'f': ['a', Object('b'), 'c'], 9690 'g': Object(false), 9691 'h': new Date(2012, 4, 23), 9692 'i': noop, 9693 'j': 'a' 9694 } 9695 }; 9696 9697 var object2 = { 9698 'a': [1, Object(2), 3], 9699 'b': Object(true), 9700 'c': 1, 9701 'd': Object('a'), 9702 'e': { 9703 'f': ['a', 'b', 'c'], 9704 'g': false, 9705 'h': new Date(2012, 4, 23), 9706 'i': noop, 9707 'j': 'a' 9708 } 9709 }; 9710 9711 assert.strictEqual(_.isEqual(object1, object2), true); 9712 }); 9713 9714 QUnit.test('should compare object instances', function(assert) { 9715 assert.expect(4); 9716 9717 function Foo() { 9718 this.a = 1; 9719 } 9720 Foo.prototype.a = 1; 9721 9722 function Bar() { 9723 this.a = 1; 9724 } 9725 Bar.prototype.a = 2; 9726 9727 assert.strictEqual(_.isEqual(new Foo, new Foo), true); 9728 assert.strictEqual(_.isEqual(new Foo, new Bar), false); 9729 assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false); 9730 assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false); 9731 }); 9732 9733 QUnit.test('should compare objects with constructor properties', function(assert) { 9734 assert.expect(5); 9735 9736 assert.strictEqual(_.isEqual({ 'constructor': 1 }, { 'constructor': 1 }), true); 9737 assert.strictEqual(_.isEqual({ 'constructor': 1 }, { 'constructor': '1' }), false); 9738 assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true); 9739 assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false); 9740 assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false); 9741 }); 9742 9743 QUnit.test('should compare arrays with circular references', function(assert) { 9744 assert.expect(4); 9745 9746 var array1 = [], 9747 array2 = []; 9748 9749 array1.push(array1); 9750 array2.push(array2); 9751 9752 assert.strictEqual(_.isEqual(array1, array2), true); 9753 9754 array1.push('b'); 9755 array2.push('b'); 9756 9757 assert.strictEqual(_.isEqual(array1, array2), true); 9758 9759 array1.push('c'); 9760 array2.push('d'); 9761 9762 assert.strictEqual(_.isEqual(array1, array2), false); 9763 9764 array1 = ['a', 'b', 'c']; 9765 array1[1] = array1; 9766 array2 = ['a', ['a', 'b', 'c'], 'c']; 9767 9768 assert.strictEqual(_.isEqual(array1, array2), false); 9769 }); 9770 9771 QUnit.test('should have transitive equivalence for circular references of arrays', function(assert) { 9772 assert.expect(3); 9773 9774 var array1 = [], 9775 array2 = [array1], 9776 array3 = [array2]; 9777 9778 array1[0] = array1; 9779 9780 assert.strictEqual(_.isEqual(array1, array2), true); 9781 assert.strictEqual(_.isEqual(array2, array3), true); 9782 assert.strictEqual(_.isEqual(array1, array3), true); 9783 }); 9784 9785 QUnit.test('should compare objects with circular references', function(assert) { 9786 assert.expect(4); 9787 9788 var object1 = {}, 9789 object2 = {}; 9790 9791 object1.a = object1; 9792 object2.a = object2; 9793 9794 assert.strictEqual(_.isEqual(object1, object2), true); 9795 9796 object1.b = 0; 9797 object2.b = Object(0); 9798 9799 assert.strictEqual(_.isEqual(object1, object2), true); 9800 9801 object1.c = Object(1); 9802 object2.c = Object(2); 9803 9804 assert.strictEqual(_.isEqual(object1, object2), false); 9805 9806 object1 = { 'a': 1, 'b': 2, 'c': 3 }; 9807 object1.b = object1; 9808 object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 }; 9809 9810 assert.strictEqual(_.isEqual(object1, object2), false); 9811 }); 9812 9813 QUnit.test('should have transitive equivalence for circular references of objects', function(assert) { 9814 assert.expect(3); 9815 9816 var object1 = {}, 9817 object2 = { 'a': object1 }, 9818 object3 = { 'a': object2 }; 9819 9820 object1.a = object1; 9821 9822 assert.strictEqual(_.isEqual(object1, object2), true); 9823 assert.strictEqual(_.isEqual(object2, object3), true); 9824 assert.strictEqual(_.isEqual(object1, object3), true); 9825 }); 9826 9827 QUnit.test('should compare objects with multiple circular references', function(assert) { 9828 assert.expect(3); 9829 9830 var array1 = [{}], 9831 array2 = [{}]; 9832 9833 (array1[0].a = array1).push(array1); 9834 (array2[0].a = array2).push(array2); 9835 9836 assert.strictEqual(_.isEqual(array1, array2), true); 9837 9838 array1[0].b = 0; 9839 array2[0].b = Object(0); 9840 9841 assert.strictEqual(_.isEqual(array1, array2), true); 9842 9843 array1[0].c = Object(1); 9844 array2[0].c = Object(2); 9845 9846 assert.strictEqual(_.isEqual(array1, array2), false); 9847 }); 9848 9849 QUnit.test('should compare objects with complex circular references', function(assert) { 9850 assert.expect(1); 9851 9852 var object1 = { 9853 'foo': { 'b': { 'c': { 'd': {} } } }, 9854 'bar': { 'a': 2 } 9855 }; 9856 9857 var object2 = { 9858 'foo': { 'b': { 'c': { 'd': {} } } }, 9859 'bar': { 'a': 2 } 9860 }; 9861 9862 object1.foo.b.c.d = object1; 9863 object1.bar.b = object1.foo.b; 9864 9865 object2.foo.b.c.d = object2; 9866 object2.bar.b = object2.foo.b; 9867 9868 assert.strictEqual(_.isEqual(object1, object2), true); 9869 }); 9870 9871 QUnit.test('should compare objects with shared property values', function(assert) { 9872 assert.expect(1); 9873 9874 var object1 = { 9875 'a': [1, 2] 9876 }; 9877 9878 var object2 = { 9879 'a': [1, 2], 9880 'b': [1, 2] 9881 }; 9882 9883 object1.b = object1.a; 9884 9885 assert.strictEqual(_.isEqual(object1, object2), true); 9886 }); 9887 9888 QUnit.test('should treat objects created by `Object.create(null)` like plain objects', function(assert) { 9889 assert.expect(2); 9890 9891 function Foo() { 9892 this.a = 1; 9893 } 9894 Foo.prototype.constructor = null; 9895 9896 var object1 = create(null); 9897 object1.a = 1; 9898 9899 var object2 = { 'a': 1 }; 9900 9901 assert.strictEqual(_.isEqual(object1, object2), true); 9902 assert.strictEqual(_.isEqual(new Foo, object2), false); 9903 }); 9904 9905 QUnit.test('should avoid common type coercions', function(assert) { 9906 assert.expect(9); 9907 9908 assert.strictEqual(_.isEqual(true, Object(false)), false); 9909 assert.strictEqual(_.isEqual(Object(false), Object(0)), false); 9910 assert.strictEqual(_.isEqual(false, Object('')), false); 9911 assert.strictEqual(_.isEqual(Object(36), Object('36')), false); 9912 assert.strictEqual(_.isEqual(0, ''), false); 9913 assert.strictEqual(_.isEqual(1, true), false); 9914 assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false); 9915 assert.strictEqual(_.isEqual('36', 36), false); 9916 assert.strictEqual(_.isEqual(36, '36'), false); 9917 }); 9918 9919 QUnit.test('should compare `arguments` objects', function(assert) { 9920 assert.expect(2); 9921 9922 var args1 = (function() { return arguments; }()), 9923 args2 = (function() { return arguments; }()), 9924 args3 = (function() { return arguments; }(1, 2)); 9925 9926 assert.strictEqual(_.isEqual(args1, args2), true); 9927 assert.strictEqual(_.isEqual(args1, args3), false); 9928 }); 9929 9930 QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) { 9931 assert.expect(4); 9932 9933 var object = { '0': 1, '1': 2, '2': 3 }; 9934 9935 function Foo() {} 9936 Foo.prototype = object; 9937 9938 assert.strictEqual(_.isEqual(args, object), true); 9939 assert.strictEqual(_.isEqual(object, args), true); 9940 assert.strictEqual(_.isEqual(args, new Foo), false); 9941 assert.strictEqual(_.isEqual(new Foo, args), false); 9942 }); 9943 9944 QUnit.test('should compare array buffers', function(assert) { 9945 assert.expect(2); 9946 9947 if (ArrayBuffer) { 9948 var buffer = new Int8Array([-1]).buffer; 9949 9950 assert.strictEqual(_.isEqual(buffer, new Uint8Array([255]).buffer), true); 9951 assert.strictEqual(_.isEqual(buffer, new ArrayBuffer(1)), false); 9952 } 9953 else { 9954 skipAssert(assert, 2); 9955 } 9956 }); 9957 9958 QUnit.test('should compare array views', function(assert) { 9959 assert.expect(2); 9960 9961 lodashStable.times(2, function(index) { 9962 var ns = index ? realm : root; 9963 9964 var pairs = lodashStable.map(arrayViews, function(type, viewIndex) { 9965 var otherType = arrayViews[(viewIndex + 1) % arrayViews.length], 9966 CtorA = ns[type] || function(n) { this.n = n; }, 9967 CtorB = ns[otherType] || function(n) { this.n = n; }, 9968 bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8, 9969 bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8, 9970 bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16; 9971 9972 return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)]; 9973 }); 9974 9975 var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false])); 9976 9977 var actual = lodashStable.map(pairs, function(pair) { 9978 return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])]; 9979 }); 9980 9981 assert.deepEqual(actual, expected); 9982 }); 9983 }); 9984 9985 QUnit.test('should compare buffers', function(assert) { 9986 assert.expect(3); 9987 9988 if (Buffer) { 9989 var buffer = new Buffer([1]); 9990 9991 assert.strictEqual(_.isEqual(buffer, new Buffer([1])), true); 9992 assert.strictEqual(_.isEqual(buffer, new Buffer([2])), false); 9993 assert.strictEqual(_.isEqual(buffer, new Uint8Array([1])), false); 9994 } 9995 else { 9996 skipAssert(assert, 3); 9997 } 9998 }); 9999 10000 QUnit.test('should compare date objects', function(assert) { 10001 assert.expect(4); 10002 10003 var date = new Date(2012, 4, 23); 10004 10005 assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true); 10006 assert.strictEqual(_.isEqual(new Date('a'), new Date('b')), true); 10007 assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false); 10008 assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false); 10009 }); 10010 10011 QUnit.test('should compare error objects', function(assert) { 10012 assert.expect(1); 10013 10014 var pairs = lodashStable.map([ 10015 'Error', 10016 'EvalError', 10017 'RangeError', 10018 'ReferenceError', 10019 'SyntaxError', 10020 'TypeError', 10021 'URIError' 10022 ], function(type, index, errorTypes) { 10023 var otherType = errorTypes[++index % errorTypes.length], 10024 CtorA = root[type], 10025 CtorB = root[otherType]; 10026 10027 return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')]; 10028 }); 10029 10030 var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false])); 10031 10032 var actual = lodashStable.map(pairs, function(pair) { 10033 return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])]; 10034 }); 10035 10036 assert.deepEqual(actual, expected); 10037 }); 10038 10039 QUnit.test('should compare functions', function(assert) { 10040 assert.expect(2); 10041 10042 function a() { return 1 + 2; } 10043 function b() { return 1 + 2; } 10044 10045 assert.strictEqual(_.isEqual(a, a), true); 10046 assert.strictEqual(_.isEqual(a, b), false); 10047 }); 10048 10049 QUnit.test('should compare maps', function(assert) { 10050 assert.expect(8); 10051 10052 if (Map) { 10053 lodashStable.each([[map, new Map], [map, realm.map]], function(maps) { 10054 var map1 = maps[0], 10055 map2 = maps[1]; 10056 10057 map1.set('a', 1); 10058 map2.set('b', 2); 10059 assert.strictEqual(_.isEqual(map1, map2), false); 10060 10061 map1.set('b', 2); 10062 map2.set('a', 1); 10063 assert.strictEqual(_.isEqual(map1, map2), true); 10064 10065 map1.delete('a'); 10066 map1.set('a', 1); 10067 assert.strictEqual(_.isEqual(map1, map2), true); 10068 10069 map2.delete('a'); 10070 assert.strictEqual(_.isEqual(map1, map2), false); 10071 10072 map1.clear(); 10073 map2.clear(); 10074 }); 10075 } 10076 else { 10077 skipAssert(assert, 8); 10078 } 10079 }); 10080 10081 QUnit.test('should compare maps with circular references', function(assert) { 10082 assert.expect(2); 10083 10084 if (Map) { 10085 var map1 = new Map, 10086 map2 = new Map; 10087 10088 map1.set('a', map1); 10089 map2.set('a', map2); 10090 assert.strictEqual(_.isEqual(map1, map2), true); 10091 10092 map1.set('b', 1); 10093 map2.set('b', 2); 10094 assert.strictEqual(_.isEqual(map1, map2), false); 10095 } 10096 else { 10097 skipAssert(assert, 2); 10098 } 10099 }); 10100 10101 QUnit.test('should compare promises by reference', function(assert) { 10102 assert.expect(4); 10103 10104 if (promise) { 10105 lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) { 10106 var promise1 = promises[0], 10107 promise2 = promises[1]; 10108 10109 assert.strictEqual(_.isEqual(promise1, promise2), false); 10110 assert.strictEqual(_.isEqual(promise1, promise1), true); 10111 }); 10112 } 10113 else { 10114 skipAssert(assert, 4); 10115 } 10116 }); 10117 10118 QUnit.test('should compare regexes', function(assert) { 10119 assert.expect(5); 10120 10121 assert.strictEqual(_.isEqual(/x/gim, /x/gim), true); 10122 assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true); 10123 assert.strictEqual(_.isEqual(/x/gi, /x/g), false); 10124 assert.strictEqual(_.isEqual(/x/, /y/), false); 10125 assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false); 10126 }); 10127 10128 QUnit.test('should compare sets', function(assert) { 10129 assert.expect(8); 10130 10131 if (Set) { 10132 lodashStable.each([[set, new Set], [set, realm.set]], function(sets) { 10133 var set1 = sets[0], 10134 set2 = sets[1]; 10135 10136 set1.add(1); 10137 set2.add(2); 10138 assert.strictEqual(_.isEqual(set1, set2), false); 10139 10140 set1.add(2); 10141 set2.add(1); 10142 assert.strictEqual(_.isEqual(set1, set2), true); 10143 10144 set1.delete(1); 10145 set1.add(1); 10146 assert.strictEqual(_.isEqual(set1, set2), true); 10147 10148 set2.delete(1); 10149 assert.strictEqual(_.isEqual(set1, set2), false); 10150 10151 set1.clear(); 10152 set2.clear(); 10153 }); 10154 } 10155 else { 10156 skipAssert(assert, 8); 10157 } 10158 }); 10159 10160 QUnit.test('should compare sets with circular references', function(assert) { 10161 assert.expect(2); 10162 10163 if (Set) { 10164 var set1 = new Set, 10165 set2 = new Set; 10166 10167 set1.add(set1); 10168 set2.add(set2); 10169 assert.strictEqual(_.isEqual(set1, set2), true); 10170 10171 set1.add(1); 10172 set2.add(2); 10173 assert.strictEqual(_.isEqual(set1, set2), false); 10174 } 10175 else { 10176 skipAssert(assert, 2); 10177 } 10178 }); 10179 10180 QUnit.test('should compare symbol properties', function(assert) { 10181 assert.expect(3); 10182 10183 if (Symbol) { 10184 var object1 = { 'a': 1 }, 10185 object2 = { 'a': 1 }; 10186 10187 object1[symbol1] = { 'a': { 'b': 2 } }; 10188 object2[symbol1] = { 'a': { 'b': 2 } }; 10189 10190 defineProperty(object2, symbol2, { 10191 'configurable': true, 10192 'enumerable': false, 10193 'writable': true, 10194 'value': 2 10195 }); 10196 10197 assert.strictEqual(_.isEqual(object1, object2), true); 10198 10199 object2[symbol1] = { 'a': 1 }; 10200 assert.strictEqual(_.isEqual(object1, object2), false); 10201 10202 delete object2[symbol1]; 10203 object2[Symbol('a')] = { 'a': { 'b': 2 } }; 10204 assert.strictEqual(_.isEqual(object1, object2), false); 10205 } 10206 else { 10207 skipAssert(assert, 3); 10208 } 10209 }); 10210 10211 QUnit.test('should compare wrapped values', function(assert) { 10212 assert.expect(32); 10213 10214 var stamp = +new Date; 10215 10216 var values = [ 10217 [[1, 2], [1, 2], [1, 2, 3]], 10218 [true, true, false], 10219 [new Date(stamp), new Date(stamp), new Date(stamp - 100)], 10220 [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }], 10221 [1, 1, 2], 10222 [NaN, NaN, Infinity], 10223 [/x/, /x/, /x/i], 10224 ['a', 'a', 'A'] 10225 ]; 10226 10227 lodashStable.each(values, function(vals) { 10228 if (!isNpm) { 10229 var wrapped1 = _(vals[0]), 10230 wrapped2 = _(vals[1]), 10231 actual = wrapped1.isEqual(wrapped2); 10232 10233 assert.strictEqual(actual, true); 10234 assert.strictEqual(_.isEqual(_(actual), _(true)), true); 10235 10236 wrapped1 = _(vals[0]); 10237 wrapped2 = _(vals[2]); 10238 10239 actual = wrapped1.isEqual(wrapped2); 10240 assert.strictEqual(actual, false); 10241 assert.strictEqual(_.isEqual(_(actual), _(false)), true); 10242 } 10243 else { 10244 skipAssert(assert, 4); 10245 } 10246 }); 10247 }); 10248 10249 QUnit.test('should compare wrapped and non-wrapped values', function(assert) { 10250 assert.expect(4); 10251 10252 if (!isNpm) { 10253 var object1 = _({ 'a': 1, 'b': 2 }), 10254 object2 = { 'a': 1, 'b': 2 }; 10255 10256 assert.strictEqual(object1.isEqual(object2), true); 10257 assert.strictEqual(_.isEqual(object1, object2), true); 10258 10259 object1 = _({ 'a': 1, 'b': 2 }); 10260 object2 = { 'a': 1, 'b': 1 }; 10261 10262 assert.strictEqual(object1.isEqual(object2), false); 10263 assert.strictEqual(_.isEqual(object1, object2), false); 10264 } 10265 else { 10266 skipAssert(assert, 4); 10267 } 10268 }); 10269 10270 QUnit.test('should work as an iteratee for `_.every`', function(assert) { 10271 assert.expect(1); 10272 10273 var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1)); 10274 assert.ok(actual); 10275 }); 10276 10277 QUnit.test('should not error on DOM elements', function(assert) { 10278 assert.expect(1); 10279 10280 if (document) { 10281 var element1 = document.createElement('div'), 10282 element2 = element1.cloneNode(true); 10283 10284 try { 10285 assert.strictEqual(_.isEqual(element1, element2), false); 10286 } catch (e) { 10287 assert.ok(false, e.message); 10288 } 10289 } 10290 else { 10291 skipAssert(assert); 10292 } 10293 }); 10294 10295 QUnit.test('should return `true` for like-objects from different documents', function(assert) { 10296 assert.expect(4); 10297 10298 if (realm.object) { 10299 assert.strictEqual(_.isEqual([1], realm.array), true); 10300 assert.strictEqual(_.isEqual([2], realm.array), false); 10301 assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true); 10302 assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false); 10303 } 10304 else { 10305 skipAssert(assert, 4); 10306 } 10307 }); 10308 10309 QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) { 10310 assert.expect(1); 10311 10312 var primitive, 10313 object = { 'toString': function() { return primitive; } }, 10314 values = [true, null, 1, 'a', undefined], 10315 expected = lodashStable.map(values, stubFalse); 10316 10317 var actual = lodashStable.map(values, function(value) { 10318 primitive = value; 10319 return _.isEqual(object, value); 10320 }); 10321 10322 assert.deepEqual(actual, expected); 10323 }); 10324 10325 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 10326 assert.expect(1); 10327 10328 if (!isNpm) { 10329 assert.strictEqual(_('a').isEqual('a'), true); 10330 } 10331 else { 10332 skipAssert(assert); 10333 } 10334 }); 10335 10336 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 10337 assert.expect(1); 10338 10339 if (!isNpm) { 10340 assert.ok(_('a').chain().isEqual('a') instanceof _); 10341 } 10342 else { 10343 skipAssert(assert); 10344 } 10345 }); 10346 }()); 10347 10348 /*--------------------------------------------------------------------------*/ 10349 10350 QUnit.module('lodash.isEqualWith'); 10351 10352 (function() { 10353 QUnit.test('should provide correct `customizer` arguments', function(assert) { 10354 assert.expect(1); 10355 10356 var argsList = [], 10357 object1 = { 'a': [1, 2], 'b': null }, 10358 object2 = { 'a': [1, 2], 'b': null }; 10359 10360 object1.b = object2; 10361 object2.b = object1; 10362 10363 var expected = [ 10364 [object1, object2], 10365 [object1.a, object2.a, 'a', object1, object2], 10366 [object1.a[0], object2.a[0], 0, object1.a, object2.a], 10367 [object1.a[1], object2.a[1], 1, object1.a, object2.a], 10368 [object1.b, object2.b, 'b', object1.b, object2.b] 10369 ]; 10370 10371 _.isEqualWith(object1, object2, function(assert) { 10372 var length = arguments.length, 10373 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0)); 10374 10375 argsList.push(args); 10376 }); 10377 10378 assert.deepEqual(argsList, expected); 10379 }); 10380 10381 QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) { 10382 assert.expect(3); 10383 10384 assert.strictEqual(_.isEqualWith('a', 'a', noop), true); 10385 assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true); 10386 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true); 10387 }); 10388 10389 QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) { 10390 assert.expect(3); 10391 10392 var customizer = function(value) { 10393 return _.isString(value) || undefined; 10394 }; 10395 10396 assert.strictEqual(_.isEqualWith('a', 'b', customizer), true); 10397 assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true); 10398 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true); 10399 }); 10400 10401 QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) { 10402 assert.expect(3); 10403 10404 var customizer = function(value) { 10405 return _.isString(value) ? false : undefined; 10406 }; 10407 10408 assert.strictEqual(_.isEqualWith('a', 'a', customizer), false); 10409 assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false); 10410 assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false); 10411 }); 10412 10413 QUnit.test('should return a boolean value even when `customizer` does not', function(assert) { 10414 assert.expect(2); 10415 10416 var actual = _.isEqualWith('a', 'b', stubC); 10417 assert.strictEqual(actual, true); 10418 10419 var values = _.without(falsey, undefined), 10420 expected = lodashStable.map(values, stubFalse); 10421 10422 actual = []; 10423 lodashStable.each(values, function(value) { 10424 actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value))); 10425 }); 10426 10427 assert.deepEqual(actual, expected); 10428 }); 10429 10430 QUnit.test('should ensure `customizer` is a function', function(assert) { 10431 assert.expect(1); 10432 10433 var array = [1, 2, 3], 10434 eq = _.partial(_.isEqualWith, array), 10435 actual = lodashStable.map([array, [1, 0, 3]], eq); 10436 10437 assert.deepEqual(actual, [true, false]); 10438 }); 10439 10440 QUnit.test('should call `customizer` for values maps and sets', function(assert) { 10441 assert.expect(2); 10442 10443 var value = { 'a': { 'b': 2 } }; 10444 10445 if (Map) { 10446 var map1 = new Map; 10447 map1.set('a', value); 10448 10449 var map2 = new Map; 10450 map2.set('a', value); 10451 } 10452 if (Set) { 10453 var set1 = new Set; 10454 set1.add(value); 10455 10456 var set2 = new Set; 10457 set2.add(value); 10458 } 10459 lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) { 10460 if (pair[0]) { 10461 var argsList = [], 10462 array = lodashStable.toArray(pair[0]); 10463 10464 var expected = [ 10465 [pair[0], pair[1]], 10466 [array[0], array[0], 0, array, array], 10467 [array[0][0], array[0][0], 0, array[0], array[0]], 10468 [array[0][1], array[0][1], 1, array[0], array[0]] 10469 ]; 10470 10471 if (index) { 10472 expected.length = 2; 10473 } 10474 _.isEqualWith(pair[0], pair[1], function() { 10475 var length = arguments.length, 10476 args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0)); 10477 10478 argsList.push(args); 10479 }); 10480 10481 assert.deepEqual(argsList, expected, index ? 'Set' : 'Map'); 10482 } 10483 else { 10484 skipAssert(assert); 10485 } 10486 }); 10487 }); 10488 }()); 10489 10490 /*--------------------------------------------------------------------------*/ 10491 10492 QUnit.module('lodash.isError'); 10493 10494 (function() { 10495 QUnit.test('should return `true` for error objects', function(assert) { 10496 assert.expect(1); 10497 10498 var expected = lodashStable.map(errors, stubTrue); 10499 10500 var actual = lodashStable.map(errors, function(error) { 10501 return _.isError(error) === true; 10502 }); 10503 10504 assert.deepEqual(actual, expected); 10505 }); 10506 10507 QUnit.test('should return `true` for subclassed values', function(assert) { 10508 assert.expect(1); 10509 10510 assert.strictEqual(_.isError(new CustomError('x')), true); 10511 }); 10512 10513 QUnit.test('should return `false` for non error objects', function(assert) { 10514 assert.expect(12); 10515 10516 var expected = lodashStable.map(falsey, stubFalse); 10517 10518 var actual = lodashStable.map(falsey, function(value, index) { 10519 return index ? _.isError(value) : _.isError(); 10520 }); 10521 10522 assert.deepEqual(actual, expected); 10523 10524 assert.strictEqual(_.isError(args), false); 10525 assert.strictEqual(_.isError([1, 2, 3]), false); 10526 assert.strictEqual(_.isError(true), false); 10527 assert.strictEqual(_.isError(new Date), false); 10528 assert.strictEqual(_.isError(_), false); 10529 assert.strictEqual(_.isError(slice), false); 10530 assert.strictEqual(_.isError({ 'a': 1 }), false); 10531 assert.strictEqual(_.isError(1), false); 10532 assert.strictEqual(_.isError(/x/), false); 10533 assert.strictEqual(_.isError('a'), false); 10534 assert.strictEqual(_.isError(symbol), false); 10535 }); 10536 10537 QUnit.test('should return `false` for plain objects', function(assert) { 10538 assert.expect(1); 10539 10540 assert.strictEqual(_.isError({ 'name': 'Error', 'message': '' }), false); 10541 }); 10542 10543 QUnit.test('should work with an error object from another realm', function(assert) { 10544 assert.expect(1); 10545 10546 if (realm.errors) { 10547 var expected = lodashStable.map(realm.errors, stubTrue); 10548 10549 var actual = lodashStable.map(realm.errors, function(error) { 10550 return _.isError(error) === true; 10551 }); 10552 10553 assert.deepEqual(actual, expected); 10554 } 10555 else { 10556 skipAssert(assert); 10557 } 10558 }); 10559 }()); 10560 10561 /*--------------------------------------------------------------------------*/ 10562 10563 QUnit.module('lodash.isFinite'); 10564 10565 (function() { 10566 QUnit.test('should return `true` for finite values', function(assert) { 10567 assert.expect(1); 10568 10569 var values = [0, 1, 3.14, -1], 10570 expected = lodashStable.map(values, stubTrue), 10571 actual = lodashStable.map(values, _.isFinite); 10572 10573 assert.deepEqual(actual, expected); 10574 }); 10575 10576 QUnit.test('should return `false` for non-finite values', function(assert) { 10577 assert.expect(1); 10578 10579 var values = [NaN, Infinity, -Infinity, Object(1)], 10580 expected = lodashStable.map(values, stubFalse), 10581 actual = lodashStable.map(values, _.isFinite); 10582 10583 assert.deepEqual(actual, expected); 10584 }); 10585 10586 QUnit.test('should return `false` for non-numeric values', function(assert) { 10587 assert.expect(10); 10588 10589 var values = [undefined, [], true, '', ' ', '2px'], 10590 expected = lodashStable.map(values, stubFalse), 10591 actual = lodashStable.map(values, _.isFinite); 10592 10593 assert.deepEqual(actual, expected); 10594 10595 assert.strictEqual(_.isFinite(args), false); 10596 assert.strictEqual(_.isFinite([1, 2, 3]), false); 10597 assert.strictEqual(_.isFinite(true), false); 10598 assert.strictEqual(_.isFinite(new Date), false); 10599 assert.strictEqual(_.isFinite(new Error), false); 10600 assert.strictEqual(_.isFinite({ 'a': 1 }), false); 10601 assert.strictEqual(_.isFinite(/x/), false); 10602 assert.strictEqual(_.isFinite('a'), false); 10603 assert.strictEqual(_.isFinite(symbol), false); 10604 }); 10605 10606 QUnit.test('should return `false` for numeric string values', function(assert) { 10607 assert.expect(1); 10608 10609 var values = ['2', '0', '08'], 10610 expected = lodashStable.map(values, stubFalse), 10611 actual = lodashStable.map(values, _.isFinite); 10612 10613 assert.deepEqual(actual, expected); 10614 }); 10615 }()); 10616 10617 /*--------------------------------------------------------------------------*/ 10618 10619 QUnit.module('lodash.isFunction'); 10620 10621 (function() { 10622 QUnit.test('should return `true` for functions', function(assert) { 10623 assert.expect(2); 10624 10625 assert.strictEqual(_.isFunction(_), true); 10626 assert.strictEqual(_.isFunction(slice), true); 10627 }); 10628 10629 QUnit.test('should return `true` for async functions', function(assert) { 10630 assert.expect(1); 10631 10632 assert.strictEqual(_.isFunction(asyncFunc), typeof asyncFunc == 'function'); 10633 }); 10634 10635 QUnit.test('should return `true` for generator functions', function(assert) { 10636 assert.expect(1); 10637 10638 assert.strictEqual(_.isFunction(genFunc), typeof genFunc == 'function'); 10639 }); 10640 10641 QUnit.test('should return `true` for the `Proxy` constructor', function(assert) { 10642 assert.expect(1); 10643 10644 if (Proxy) { 10645 assert.strictEqual(_.isFunction(Proxy), true); 10646 } 10647 else { 10648 skipAssert(assert); 10649 } 10650 }); 10651 10652 QUnit.test('should return `true` for array view constructors', function(assert) { 10653 assert.expect(1); 10654 10655 var expected = lodashStable.map(arrayViews, function(type) { 10656 return objToString.call(root[type]) == funcTag; 10657 }); 10658 10659 var actual = lodashStable.map(arrayViews, function(type) { 10660 return _.isFunction(root[type]); 10661 }); 10662 10663 assert.deepEqual(actual, expected); 10664 }); 10665 10666 QUnit.test('should return `false` for non-functions', function(assert) { 10667 assert.expect(12); 10668 10669 var expected = lodashStable.map(falsey, stubFalse); 10670 10671 var actual = lodashStable.map(falsey, function(value, index) { 10672 return index ? _.isFunction(value) : _.isFunction(); 10673 }); 10674 10675 assert.deepEqual(actual, expected); 10676 10677 assert.strictEqual(_.isFunction(args), false); 10678 assert.strictEqual(_.isFunction([1, 2, 3]), false); 10679 assert.strictEqual(_.isFunction(true), false); 10680 assert.strictEqual(_.isFunction(new Date), false); 10681 assert.strictEqual(_.isFunction(new Error), false); 10682 assert.strictEqual(_.isFunction({ 'a': 1 }), false); 10683 assert.strictEqual(_.isFunction(1), false); 10684 assert.strictEqual(_.isFunction(/x/), false); 10685 assert.strictEqual(_.isFunction('a'), false); 10686 assert.strictEqual(_.isFunction(symbol), false); 10687 10688 if (document) { 10689 assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false); 10690 } 10691 else { 10692 skipAssert(assert); 10693 } 10694 }); 10695 10696 QUnit.test('should work with a function from another realm', function(assert) { 10697 assert.expect(1); 10698 10699 if (realm.function) { 10700 assert.strictEqual(_.isFunction(realm.function), true); 10701 } 10702 else { 10703 skipAssert(assert); 10704 } 10705 }); 10706 }()); 10707 10708 /*--------------------------------------------------------------------------*/ 10709 10710 QUnit.module('isInteger methods'); 10711 10712 lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) { 10713 var func = _[methodName], 10714 isSafe = methodName == 'isSafeInteger'; 10715 10716 QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) { 10717 assert.expect(2); 10718 10719 var values = [-1, 0, 1], 10720 expected = lodashStable.map(values, stubTrue); 10721 10722 var actual = lodashStable.map(values, function(value) { 10723 return func(value); 10724 }); 10725 10726 assert.deepEqual(actual, expected); 10727 assert.strictEqual(func(MAX_INTEGER), !isSafe); 10728 }); 10729 10730 QUnit.test('should return `false` for non-integer number values', function(assert) { 10731 assert.expect(1); 10732 10733 var values = [NaN, Infinity, -Infinity, Object(1), 3.14], 10734 expected = lodashStable.map(values, stubFalse); 10735 10736 var actual = lodashStable.map(values, function(value) { 10737 return func(value); 10738 }); 10739 10740 assert.deepEqual(actual, expected); 10741 }); 10742 10743 QUnit.test('should return `false` for non-numeric values', function(assert) { 10744 assert.expect(10); 10745 10746 var expected = lodashStable.map(falsey, function(value) { 10747 return value === 0; 10748 }); 10749 10750 var actual = lodashStable.map(falsey, function(value, index) { 10751 return index ? func(value) : func(); 10752 }); 10753 10754 assert.deepEqual(actual, expected); 10755 10756 assert.strictEqual(func(args), false); 10757 assert.strictEqual(func([1, 2, 3]), false); 10758 assert.strictEqual(func(true), false); 10759 assert.strictEqual(func(new Date), false); 10760 assert.strictEqual(func(new Error), false); 10761 assert.strictEqual(func({ 'a': 1 }), false); 10762 assert.strictEqual(func(/x/), false); 10763 assert.strictEqual(func('a'), false); 10764 assert.strictEqual(func(symbol), false); 10765 }); 10766 }); 10767 10768 /*--------------------------------------------------------------------------*/ 10769 10770 QUnit.module('lodash.isLength'); 10771 10772 (function() { 10773 QUnit.test('should return `true` for lengths', function(assert) { 10774 assert.expect(1); 10775 10776 var values = [0, 3, MAX_SAFE_INTEGER], 10777 expected = lodashStable.map(values, stubTrue), 10778 actual = lodashStable.map(values, _.isLength); 10779 10780 assert.deepEqual(actual, expected); 10781 }); 10782 10783 QUnit.test('should return `false` for non-lengths', function(assert) { 10784 assert.expect(1); 10785 10786 var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1], 10787 expected = lodashStable.map(values, stubFalse), 10788 actual = lodashStable.map(values, _.isLength); 10789 10790 assert.deepEqual(actual, expected); 10791 }); 10792 }()); 10793 10794 /*--------------------------------------------------------------------------*/ 10795 10796 QUnit.module('lodash.isMap'); 10797 10798 (function() { 10799 QUnit.test('should return `true` for maps', function(assert) { 10800 assert.expect(1); 10801 10802 if (Map) { 10803 assert.strictEqual(_.isMap(map), true); 10804 } 10805 else { 10806 skipAssert(assert); 10807 } 10808 }); 10809 10810 QUnit.test('should return `false` for non-maps', function(assert) { 10811 assert.expect(14); 10812 10813 var expected = lodashStable.map(falsey, stubFalse); 10814 10815 var actual = lodashStable.map(falsey, function(value, index) { 10816 return index ? _.isMap(value) : _.isMap(); 10817 }); 10818 10819 assert.deepEqual(actual, expected); 10820 10821 assert.strictEqual(_.isMap(args), false); 10822 assert.strictEqual(_.isMap([1, 2, 3]), false); 10823 assert.strictEqual(_.isMap(true), false); 10824 assert.strictEqual(_.isMap(new Date), false); 10825 assert.strictEqual(_.isMap(new Error), false); 10826 assert.strictEqual(_.isMap(_), false); 10827 assert.strictEqual(_.isMap(slice), false); 10828 assert.strictEqual(_.isMap({ 'a': 1 }), false); 10829 assert.strictEqual(_.isMap(1), false); 10830 assert.strictEqual(_.isMap(/x/), false); 10831 assert.strictEqual(_.isMap('a'), false); 10832 assert.strictEqual(_.isMap(symbol), false); 10833 assert.strictEqual(_.isMap(weakMap), false); 10834 }); 10835 10836 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) { 10837 assert.expect(1); 10838 10839 var values = [false, true], 10840 expected = lodashStable.map(values, stubFalse); 10841 10842 var actual = lodashStable.map(values, function(value) { 10843 return _.isMap({ 'constructor': value }); 10844 }); 10845 10846 assert.deepEqual(actual, expected); 10847 }); 10848 10849 QUnit.test('should work with maps from another realm', function(assert) { 10850 assert.expect(1); 10851 10852 if (realm.map) { 10853 assert.strictEqual(_.isMap(realm.map), true); 10854 } 10855 else { 10856 skipAssert(assert); 10857 } 10858 }); 10859 }()); 10860 10861 /*--------------------------------------------------------------------------*/ 10862 10863 QUnit.module('lodash.isMatchWith'); 10864 10865 (function() { 10866 QUnit.test('should provide correct `customizer` arguments', function(assert) { 10867 assert.expect(1); 10868 10869 var argsList = [], 10870 object1 = { 'a': [1, 2], 'b': null }, 10871 object2 = { 'a': [1, 2], 'b': null }; 10872 10873 object1.b = object2; 10874 object2.b = object1; 10875 10876 var expected = [ 10877 [object1.a, object2.a, 'a', object1, object2], 10878 [object1.a[0], object2.a[0], 0, object1.a, object2.a], 10879 [object1.a[1], object2.a[1], 1, object1.a, object2.a], 10880 [object1.b, object2.b, 'b', object1, object2], 10881 [object1.b.a, object2.b.a, 'a', object1.b, object2.b], 10882 [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a], 10883 [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a], 10884 [object1.b.b, object2.b.b, 'b', object1.b, object2.b] 10885 ]; 10886 10887 _.isMatchWith(object1, object2, function(assert) { 10888 argsList.push(slice.call(arguments, 0, -1)); 10889 }); 10890 10891 assert.deepEqual(argsList, expected); 10892 }); 10893 10894 QUnit.test('should handle comparisons when `customizer` returns `undefined`', function(assert) { 10895 assert.expect(1); 10896 10897 assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true); 10898 }); 10899 10900 QUnit.test('should not handle comparisons when `customizer` returns `true`', function(assert) { 10901 assert.expect(2); 10902 10903 var customizer = function(value) { 10904 return _.isString(value) || undefined; 10905 }; 10906 10907 assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true); 10908 assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true); 10909 }); 10910 10911 QUnit.test('should not handle comparisons when `customizer` returns `false`', function(assert) { 10912 assert.expect(2); 10913 10914 var customizer = function(value) { 10915 return _.isString(value) ? false : undefined; 10916 }; 10917 10918 assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false); 10919 assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false); 10920 }); 10921 10922 QUnit.test('should return a boolean value even when `customizer` does not', function(assert) { 10923 assert.expect(2); 10924 10925 var object = { 'a': 1 }, 10926 actual = _.isMatchWith(object, { 'a': 1 }, stubA); 10927 10928 assert.strictEqual(actual, true); 10929 10930 var expected = lodashStable.map(falsey, stubFalse); 10931 10932 actual = []; 10933 lodashStable.each(falsey, function(value) { 10934 actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value))); 10935 }); 10936 10937 assert.deepEqual(actual, expected); 10938 }); 10939 10940 QUnit.test('should provide `stack` to `customizer`', function(assert) { 10941 assert.expect(1); 10942 10943 var actual; 10944 10945 _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() { 10946 actual = _.last(arguments); 10947 }); 10948 10949 assert.ok(isNpm 10950 ? actual.constructor.name == 'Stack' 10951 : actual instanceof mapCaches.Stack 10952 ); 10953 }); 10954 10955 QUnit.test('should ensure `customizer` is a function', function(assert) { 10956 assert.expect(1); 10957 10958 var object = { 'a': 1 }, 10959 matches = _.partial(_.isMatchWith, object), 10960 actual = lodashStable.map([object, { 'a': 2 }], matches); 10961 10962 assert.deepEqual(actual, [true, false]); 10963 }); 10964 10965 QUnit.test('should call `customizer` for values maps and sets', function(assert) { 10966 assert.expect(2); 10967 10968 var value = { 'a': { 'b': 2 } }; 10969 10970 if (Map) { 10971 var map1 = new Map; 10972 map1.set('a', value); 10973 10974 var map2 = new Map; 10975 map2.set('a', value); 10976 } 10977 if (Set) { 10978 var set1 = new Set; 10979 set1.add(value); 10980 10981 var set2 = new Set; 10982 set2.add(value); 10983 } 10984 lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) { 10985 if (pair[0]) { 10986 var argsList = [], 10987 array = lodashStable.toArray(pair[0]), 10988 object1 = { 'a': pair[0] }, 10989 object2 = { 'a': pair[1] }; 10990 10991 var expected = [ 10992 [pair[0], pair[1], 'a', object1, object2], 10993 [array[0], array[0], 0, array, array], 10994 [array[0][0], array[0][0], 0, array[0], array[0]], 10995 [array[0][1], array[0][1], 1, array[0], array[0]] 10996 ]; 10997 10998 if (index) { 10999 expected.length = 2; 11000 } 11001 _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() { 11002 argsList.push(slice.call(arguments, 0, -1)); 11003 }); 11004 11005 assert.deepEqual(argsList, expected, index ? 'Set' : 'Map'); 11006 } 11007 else { 11008 skipAssert(assert); 11009 } 11010 }); 11011 }); 11012 }()); 11013 11014 /*--------------------------------------------------------------------------*/ 11015 11016 QUnit.module('lodash.isNaN'); 11017 11018 (function() { 11019 QUnit.test('should return `true` for NaNs', function(assert) { 11020 assert.expect(2); 11021 11022 assert.strictEqual(_.isNaN(NaN), true); 11023 assert.strictEqual(_.isNaN(Object(NaN)), true); 11024 }); 11025 11026 QUnit.test('should return `false` for non-NaNs', function(assert) { 11027 assert.expect(14); 11028 11029 var expected = lodashStable.map(falsey, function(value) { 11030 return value !== value; 11031 }); 11032 11033 var actual = lodashStable.map(falsey, function(value, index) { 11034 return index ? _.isNaN(value) : _.isNaN(); 11035 }); 11036 11037 assert.deepEqual(actual, expected); 11038 11039 assert.strictEqual(_.isNaN(args), false); 11040 assert.strictEqual(_.isNaN([1, 2, 3]), false); 11041 assert.strictEqual(_.isNaN(true), false); 11042 assert.strictEqual(_.isNaN(new Date), false); 11043 assert.strictEqual(_.isNaN(new Error), false); 11044 assert.strictEqual(_.isNaN(_), false); 11045 assert.strictEqual(_.isNaN(slice), false); 11046 assert.strictEqual(_.isNaN({ 'a': 1 }), false); 11047 assert.strictEqual(_.isNaN(1), false); 11048 assert.strictEqual(_.isNaN(Object(1)), false); 11049 assert.strictEqual(_.isNaN(/x/), false); 11050 assert.strictEqual(_.isNaN('a'), false); 11051 assert.strictEqual(_.isNaN(symbol), false); 11052 }); 11053 11054 QUnit.test('should work with `NaN` from another realm', function(assert) { 11055 assert.expect(1); 11056 11057 if (realm.object) { 11058 assert.strictEqual(_.isNaN(realm.nan), true); 11059 } 11060 else { 11061 skipAssert(assert); 11062 } 11063 }); 11064 }()); 11065 11066 /*--------------------------------------------------------------------------*/ 11067 11068 QUnit.module('lodash.isNative'); 11069 11070 (function() { 11071 QUnit.test('should return `true` for native methods', function(assert) { 11072 assert.expect(1); 11073 11074 var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array], 11075 expected = lodashStable.map(values, Boolean), 11076 actual = lodashStable.map(values, _.isNative); 11077 11078 assert.deepEqual(actual, expected); 11079 }); 11080 11081 QUnit.test('should return `false` for non-native methods', function(assert) { 11082 assert.expect(12); 11083 11084 var expected = lodashStable.map(falsey, stubFalse); 11085 11086 var actual = lodashStable.map(falsey, function(value, index) { 11087 return index ? _.isNative(value) : _.isNative(); 11088 }); 11089 11090 assert.deepEqual(actual, expected); 11091 11092 assert.strictEqual(_.isNative(args), false); 11093 assert.strictEqual(_.isNative([1, 2, 3]), false); 11094 assert.strictEqual(_.isNative(true), false); 11095 assert.strictEqual(_.isNative(new Date), false); 11096 assert.strictEqual(_.isNative(new Error), false); 11097 assert.strictEqual(_.isNative(_), false); 11098 assert.strictEqual(_.isNative({ 'a': 1 }), false); 11099 assert.strictEqual(_.isNative(1), false); 11100 assert.strictEqual(_.isNative(/x/), false); 11101 assert.strictEqual(_.isNative('a'), false); 11102 assert.strictEqual(_.isNative(symbol), false); 11103 }); 11104 11105 QUnit.test('should work with native functions from another realm', function(assert) { 11106 assert.expect(2); 11107 11108 if (realm.element) { 11109 assert.strictEqual(_.isNative(realm.element.cloneNode), true); 11110 } 11111 else { 11112 skipAssert(assert); 11113 } 11114 if (realm.object) { 11115 assert.strictEqual(_.isNative(realm.object.valueOf), true); 11116 } 11117 else { 11118 skipAssert(assert); 11119 } 11120 }); 11121 11122 QUnit.test('should throw an error if core-js is detected', function(assert) { 11123 assert.expect(1); 11124 11125 if (!isModularize) { 11126 var lodash = _.runInContext({ 11127 '__core-js_shared__': {} 11128 }); 11129 11130 assert.raises(function() { lodash.isNative(noop); }); 11131 } 11132 else { 11133 skipAssert(assert); 11134 } 11135 }); 11136 11137 QUnit.test('should detect methods masquerading as native (test in Node.js)', function(assert) { 11138 assert.expect(2); 11139 11140 if (!amd && _._baseEach) { 11141 var path = require('path'), 11142 basePath = path.dirname(filePath), 11143 uid = 'e0gvgyrad1jor', 11144 coreKey = '__core-js_shared__', 11145 fakeSrcKey = 'Symbol(src)_1.' + uid; 11146 11147 root[coreKey] = { 'keys': { 'IE_PROTO': 'Symbol(IE_PROTO)_3.' + uid } }; 11148 emptyObject(require.cache); 11149 11150 var baseIsNative = interopRequire(path.join(basePath, '_baseIsNative')); 11151 assert.strictEqual(baseIsNative(slice), true); 11152 11153 slice[fakeSrcKey] = slice + ''; 11154 assert.strictEqual(baseIsNative(slice), false); 11155 11156 delete slice[fakeSrcKey]; 11157 delete root[coreKey]; 11158 } 11159 else { 11160 skipAssert(assert, 2); 11161 } 11162 }); 11163 }()); 11164 11165 /*--------------------------------------------------------------------------*/ 11166 11167 QUnit.module('lodash.isNil'); 11168 11169 (function() { 11170 QUnit.test('should return `true` for nullish values', function(assert) { 11171 assert.expect(3); 11172 11173 assert.strictEqual(_.isNil(null), true); 11174 assert.strictEqual(_.isNil(), true); 11175 assert.strictEqual(_.isNil(undefined), true); 11176 }); 11177 11178 QUnit.test('should return `false` for non-nullish values', function(assert) { 11179 assert.expect(13); 11180 11181 var expected = lodashStable.map(falsey, function(value) { 11182 return value == null; 11183 }); 11184 11185 var actual = lodashStable.map(falsey, function(value, index) { 11186 return index ? _.isNil(value) : _.isNil(); 11187 }); 11188 11189 assert.deepEqual(actual, expected); 11190 11191 assert.strictEqual(_.isNil(args), false); 11192 assert.strictEqual(_.isNil([1, 2, 3]), false); 11193 assert.strictEqual(_.isNil(true), false); 11194 assert.strictEqual(_.isNil(new Date), false); 11195 assert.strictEqual(_.isNil(new Error), false); 11196 assert.strictEqual(_.isNil(_), false); 11197 assert.strictEqual(_.isNil(slice), false); 11198 assert.strictEqual(_.isNil({ 'a': 1 }), false); 11199 assert.strictEqual(_.isNil(1), false); 11200 assert.strictEqual(_.isNil(/x/), false); 11201 assert.strictEqual(_.isNil('a'), false); 11202 11203 if (Symbol) { 11204 assert.strictEqual(_.isNil(symbol), false); 11205 } 11206 else { 11207 skipAssert(assert); 11208 } 11209 }); 11210 11211 QUnit.test('should work with nils from another realm', function(assert) { 11212 assert.expect(2); 11213 11214 if (realm.object) { 11215 assert.strictEqual(_.isNil(realm.null), true); 11216 assert.strictEqual(_.isNil(realm.undefined), true); 11217 } 11218 else { 11219 skipAssert(assert, 2); 11220 } 11221 }); 11222 }()); 11223 11224 /*--------------------------------------------------------------------------*/ 11225 11226 QUnit.module('lodash.isNull'); 11227 11228 (function() { 11229 QUnit.test('should return `true` for `null` values', function(assert) { 11230 assert.expect(1); 11231 11232 assert.strictEqual(_.isNull(null), true); 11233 }); 11234 11235 QUnit.test('should return `false` for non `null` values', function(assert) { 11236 assert.expect(13); 11237 11238 var expected = lodashStable.map(falsey, function(value) { 11239 return value === null; 11240 }); 11241 11242 var actual = lodashStable.map(falsey, function(value, index) { 11243 return index ? _.isNull(value) : _.isNull(); 11244 }); 11245 11246 assert.deepEqual(actual, expected); 11247 11248 assert.strictEqual(_.isNull(args), false); 11249 assert.strictEqual(_.isNull([1, 2, 3]), false); 11250 assert.strictEqual(_.isNull(true), false); 11251 assert.strictEqual(_.isNull(new Date), false); 11252 assert.strictEqual(_.isNull(new Error), false); 11253 assert.strictEqual(_.isNull(_), false); 11254 assert.strictEqual(_.isNull(slice), false); 11255 assert.strictEqual(_.isNull({ 'a': 1 }), false); 11256 assert.strictEqual(_.isNull(1), false); 11257 assert.strictEqual(_.isNull(/x/), false); 11258 assert.strictEqual(_.isNull('a'), false); 11259 assert.strictEqual(_.isNull(symbol), false); 11260 }); 11261 11262 QUnit.test('should work with nulls from another realm', function(assert) { 11263 assert.expect(1); 11264 11265 if (realm.object) { 11266 assert.strictEqual(_.isNull(realm.null), true); 11267 } 11268 else { 11269 skipAssert(assert); 11270 } 11271 }); 11272 }()); 11273 11274 /*--------------------------------------------------------------------------*/ 11275 11276 QUnit.module('lodash.isNumber'); 11277 11278 (function() { 11279 QUnit.test('should return `true` for numbers', function(assert) { 11280 assert.expect(3); 11281 11282 assert.strictEqual(_.isNumber(0), true); 11283 assert.strictEqual(_.isNumber(Object(0)), true); 11284 assert.strictEqual(_.isNumber(NaN), true); 11285 }); 11286 11287 QUnit.test('should return `false` for non-numbers', function(assert) { 11288 assert.expect(12); 11289 11290 var expected = lodashStable.map(falsey, function(value) { 11291 return typeof value == 'number'; 11292 }); 11293 11294 var actual = lodashStable.map(falsey, function(value, index) { 11295 return index ? _.isNumber(value) : _.isNumber(); 11296 }); 11297 11298 assert.deepEqual(actual, expected); 11299 11300 assert.strictEqual(_.isNumber(args), false); 11301 assert.strictEqual(_.isNumber([1, 2, 3]), false); 11302 assert.strictEqual(_.isNumber(true), false); 11303 assert.strictEqual(_.isNumber(new Date), false); 11304 assert.strictEqual(_.isNumber(new Error), false); 11305 assert.strictEqual(_.isNumber(_), false); 11306 assert.strictEqual(_.isNumber(slice), false); 11307 assert.strictEqual(_.isNumber({ 'a': 1 }), false); 11308 assert.strictEqual(_.isNumber(/x/), false); 11309 assert.strictEqual(_.isNumber('a'), false); 11310 assert.strictEqual(_.isNumber(symbol), false); 11311 }); 11312 11313 QUnit.test('should work with numbers from another realm', function(assert) { 11314 assert.expect(1); 11315 11316 if (realm.number) { 11317 assert.strictEqual(_.isNumber(realm.number), true); 11318 } 11319 else { 11320 skipAssert(assert); 11321 } 11322 }); 11323 }()); 11324 11325 /*--------------------------------------------------------------------------*/ 11326 11327 QUnit.module('lodash.isObject'); 11328 11329 (function() { 11330 QUnit.test('should return `true` for objects', function(assert) { 11331 assert.expect(13); 11332 11333 assert.strictEqual(_.isObject(args), true); 11334 assert.strictEqual(_.isObject([1, 2, 3]), true); 11335 assert.strictEqual(_.isObject(Object(false)), true); 11336 assert.strictEqual(_.isObject(new Date), true); 11337 assert.strictEqual(_.isObject(new Error), true); 11338 assert.strictEqual(_.isObject(_), true); 11339 assert.strictEqual(_.isObject(slice), true); 11340 assert.strictEqual(_.isObject({ 'a': 1 }), true); 11341 assert.strictEqual(_.isObject(Object(0)), true); 11342 assert.strictEqual(_.isObject(/x/), true); 11343 assert.strictEqual(_.isObject(Object('a')), true); 11344 11345 if (document) { 11346 assert.strictEqual(_.isObject(body), true); 11347 } 11348 else { 11349 skipAssert(assert); 11350 } 11351 if (Symbol) { 11352 assert.strictEqual(_.isObject(Object(symbol)), true); 11353 } 11354 else { 11355 skipAssert(assert); 11356 } 11357 }); 11358 11359 QUnit.test('should return `false` for non-objects', function(assert) { 11360 assert.expect(1); 11361 11362 var values = falsey.concat(true, 1, 'a', symbol), 11363 expected = lodashStable.map(values, stubFalse); 11364 11365 var actual = lodashStable.map(values, function(value, index) { 11366 return index ? _.isObject(value) : _.isObject(); 11367 }); 11368 11369 assert.deepEqual(actual, expected); 11370 }); 11371 11372 QUnit.test('should work with objects from another realm', function(assert) { 11373 assert.expect(8); 11374 11375 if (realm.element) { 11376 assert.strictEqual(_.isObject(realm.element), true); 11377 } 11378 else { 11379 skipAssert(assert); 11380 } 11381 if (realm.object) { 11382 assert.strictEqual(_.isObject(realm.boolean), true); 11383 assert.strictEqual(_.isObject(realm.date), true); 11384 assert.strictEqual(_.isObject(realm.function), true); 11385 assert.strictEqual(_.isObject(realm.number), true); 11386 assert.strictEqual(_.isObject(realm.object), true); 11387 assert.strictEqual(_.isObject(realm.regexp), true); 11388 assert.strictEqual(_.isObject(realm.string), true); 11389 } 11390 else { 11391 skipAssert(assert, 7); 11392 } 11393 }); 11394 }()); 11395 11396 /*--------------------------------------------------------------------------*/ 11397 11398 QUnit.module('lodash.isObjectLike'); 11399 11400 (function() { 11401 QUnit.test('should return `true` for objects', function(assert) { 11402 assert.expect(9); 11403 11404 assert.strictEqual(_.isObjectLike(args), true); 11405 assert.strictEqual(_.isObjectLike([1, 2, 3]), true); 11406 assert.strictEqual(_.isObjectLike(Object(false)), true); 11407 assert.strictEqual(_.isObjectLike(new Date), true); 11408 assert.strictEqual(_.isObjectLike(new Error), true); 11409 assert.strictEqual(_.isObjectLike({ 'a': 1 }), true); 11410 assert.strictEqual(_.isObjectLike(Object(0)), true); 11411 assert.strictEqual(_.isObjectLike(/x/), true); 11412 assert.strictEqual(_.isObjectLike(Object('a')), true); 11413 }); 11414 11415 QUnit.test('should return `false` for non-objects', function(assert) { 11416 assert.expect(1); 11417 11418 var values = falsey.concat(true, _, slice, 1, 'a', symbol), 11419 expected = lodashStable.map(values, stubFalse); 11420 11421 var actual = lodashStable.map(values, function(value, index) { 11422 return index ? _.isObjectLike(value) : _.isObjectLike(); 11423 }); 11424 11425 assert.deepEqual(actual, expected); 11426 }); 11427 11428 QUnit.test('should work with objects from another realm', function(assert) { 11429 assert.expect(6); 11430 11431 if (realm.object) { 11432 assert.strictEqual(_.isObjectLike(realm.boolean), true); 11433 assert.strictEqual(_.isObjectLike(realm.date), true); 11434 assert.strictEqual(_.isObjectLike(realm.number), true); 11435 assert.strictEqual(_.isObjectLike(realm.object), true); 11436 assert.strictEqual(_.isObjectLike(realm.regexp), true); 11437 assert.strictEqual(_.isObjectLike(realm.string), true); 11438 } 11439 else { 11440 skipAssert(assert, 6); 11441 } 11442 }); 11443 }()); 11444 11445 /*--------------------------------------------------------------------------*/ 11446 11447 QUnit.module('lodash.isPlainObject'); 11448 11449 (function() { 11450 var element = document && document.createElement('div'); 11451 11452 QUnit.test('should detect plain objects', function(assert) { 11453 assert.expect(5); 11454 11455 function Foo(a) { 11456 this.a = 1; 11457 } 11458 11459 assert.strictEqual(_.isPlainObject({}), true); 11460 assert.strictEqual(_.isPlainObject({ 'a': 1 }), true); 11461 assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true); 11462 assert.strictEqual(_.isPlainObject([1, 2, 3]), false); 11463 assert.strictEqual(_.isPlainObject(new Foo(1)), false); 11464 }); 11465 11466 QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) { 11467 assert.expect(2); 11468 11469 var object = create(null); 11470 assert.strictEqual(_.isPlainObject(object), true); 11471 11472 object.constructor = objectProto.constructor; 11473 assert.strictEqual(_.isPlainObject(object), true); 11474 }); 11475 11476 QUnit.test('should return `true` for objects with a `valueOf` property', function(assert) { 11477 assert.expect(1); 11478 11479 assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true); 11480 }); 11481 11482 QUnit.test('should return `true` for objects with a writable `Symbol.toStringTag` property', function(assert) { 11483 assert.expect(1); 11484 11485 if (Symbol && Symbol.toStringTag) { 11486 var object = {}; 11487 object[Symbol.toStringTag] = 'X'; 11488 11489 assert.deepEqual(_.isPlainObject(object), true); 11490 } 11491 else { 11492 skipAssert(assert); 11493 } 11494 }); 11495 11496 QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) { 11497 assert.expect(1); 11498 11499 var object = create({ 'a': 1 }); 11500 assert.strictEqual(_.isPlainObject(object), false); 11501 }); 11502 11503 QUnit.test('should return `false` for DOM elements', function(assert) { 11504 assert.expect(1); 11505 11506 if (element) { 11507 assert.strictEqual(_.isPlainObject(element), false); 11508 } else { 11509 skipAssert(assert); 11510 } 11511 }); 11512 11513 QUnit.test('should return `false` for non-Object objects', function(assert) { 11514 assert.expect(3); 11515 11516 assert.strictEqual(_.isPlainObject(arguments), false); 11517 assert.strictEqual(_.isPlainObject(Error), false); 11518 assert.strictEqual(_.isPlainObject(Math), false); 11519 }); 11520 11521 QUnit.test('should return `false` for non-objects', function(assert) { 11522 assert.expect(4); 11523 11524 var expected = lodashStable.map(falsey, stubFalse); 11525 11526 var actual = lodashStable.map(falsey, function(value, index) { 11527 return index ? _.isPlainObject(value) : _.isPlainObject(); 11528 }); 11529 11530 assert.deepEqual(actual, expected); 11531 11532 assert.strictEqual(_.isPlainObject(true), false); 11533 assert.strictEqual(_.isPlainObject('a'), false); 11534 assert.strictEqual(_.isPlainObject(symbol), false); 11535 }); 11536 11537 QUnit.test('should return `false` for objects with a read-only `Symbol.toStringTag` property', function(assert) { 11538 assert.expect(1); 11539 11540 if (Symbol && Symbol.toStringTag) { 11541 var object = {}; 11542 defineProperty(object, Symbol.toStringTag, { 11543 'configurable': true, 11544 'enumerable': false, 11545 'writable': false, 11546 'value': 'X' 11547 }); 11548 11549 assert.deepEqual(_.isPlainObject(object), false); 11550 } 11551 else { 11552 skipAssert(assert); 11553 } 11554 }); 11555 11556 QUnit.test('should not mutate `value`', function(assert) { 11557 assert.expect(2); 11558 11559 if (Symbol && Symbol.toStringTag) { 11560 var proto = {}; 11561 proto[Symbol.toStringTag] = undefined; 11562 var object = create(proto); 11563 11564 assert.strictEqual(_.isPlainObject(object), false); 11565 assert.notOk(lodashStable.has(object, Symbol.toStringTag)); 11566 } 11567 else { 11568 skipAssert(assert, 2); 11569 } 11570 }); 11571 11572 QUnit.test('should work with objects from another realm', function(assert) { 11573 assert.expect(1); 11574 11575 if (realm.object) { 11576 assert.strictEqual(_.isPlainObject(realm.object), true); 11577 } 11578 else { 11579 skipAssert(assert); 11580 } 11581 }); 11582 }()); 11583 11584 /*--------------------------------------------------------------------------*/ 11585 11586 QUnit.module('lodash.isRegExp'); 11587 11588 (function() { 11589 QUnit.test('should return `true` for regexes', function(assert) { 11590 assert.expect(2); 11591 11592 assert.strictEqual(_.isRegExp(/x/), true); 11593 assert.strictEqual(_.isRegExp(RegExp('x')), true); 11594 }); 11595 11596 QUnit.test('should return `false` for non-regexes', function(assert) { 11597 assert.expect(12); 11598 11599 var expected = lodashStable.map(falsey, stubFalse); 11600 11601 var actual = lodashStable.map(falsey, function(value, index) { 11602 return index ? _.isRegExp(value) : _.isRegExp(); 11603 }); 11604 11605 assert.deepEqual(actual, expected); 11606 11607 assert.strictEqual(_.isRegExp(args), false); 11608 assert.strictEqual(_.isRegExp([1, 2, 3]), false); 11609 assert.strictEqual(_.isRegExp(true), false); 11610 assert.strictEqual(_.isRegExp(new Date), false); 11611 assert.strictEqual(_.isRegExp(new Error), false); 11612 assert.strictEqual(_.isRegExp(_), false); 11613 assert.strictEqual(_.isRegExp(slice), false); 11614 assert.strictEqual(_.isRegExp({ 'a': 1 }), false); 11615 assert.strictEqual(_.isRegExp(1), false); 11616 assert.strictEqual(_.isRegExp('a'), false); 11617 assert.strictEqual(_.isRegExp(symbol), false); 11618 }); 11619 11620 QUnit.test('should work with regexes from another realm', function(assert) { 11621 assert.expect(1); 11622 11623 if (realm.regexp) { 11624 assert.strictEqual(_.isRegExp(realm.regexp), true); 11625 } 11626 else { 11627 skipAssert(assert); 11628 } 11629 }); 11630 }()); 11631 11632 /*--------------------------------------------------------------------------*/ 11633 11634 QUnit.module('lodash.isSet'); 11635 11636 (function() { 11637 QUnit.test('should return `true` for sets', function(assert) { 11638 assert.expect(1); 11639 11640 if (Set) { 11641 assert.strictEqual(_.isSet(set), true); 11642 } 11643 else { 11644 skipAssert(assert); 11645 } 11646 }); 11647 11648 QUnit.test('should return `false` for non-sets', function(assert) { 11649 assert.expect(14); 11650 11651 var expected = lodashStable.map(falsey, stubFalse); 11652 11653 var actual = lodashStable.map(falsey, function(value, index) { 11654 return index ? _.isSet(value) : _.isSet(); 11655 }); 11656 11657 assert.deepEqual(actual, expected); 11658 11659 assert.strictEqual(_.isSet(args), false); 11660 assert.strictEqual(_.isSet([1, 2, 3]), false); 11661 assert.strictEqual(_.isSet(true), false); 11662 assert.strictEqual(_.isSet(new Date), false); 11663 assert.strictEqual(_.isSet(new Error), false); 11664 assert.strictEqual(_.isSet(_), false); 11665 assert.strictEqual(_.isSet(slice), false); 11666 assert.strictEqual(_.isSet({ 'a': 1 }), false); 11667 assert.strictEqual(_.isSet(1), false); 11668 assert.strictEqual(_.isSet(/x/), false); 11669 assert.strictEqual(_.isSet('a'), false); 11670 assert.strictEqual(_.isSet(symbol), false); 11671 assert.strictEqual(_.isSet(weakSet), false); 11672 }); 11673 11674 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) { 11675 assert.expect(1); 11676 11677 var values = [false, true], 11678 expected = lodashStable.map(values, stubFalse); 11679 11680 var actual = lodashStable.map(values, function(value) { 11681 return _.isSet({ 'constructor': value }); 11682 }); 11683 11684 assert.deepEqual(actual, expected); 11685 }); 11686 11687 QUnit.test('should work with weak sets from another realm', function(assert) { 11688 assert.expect(1); 11689 11690 if (realm.set) { 11691 assert.strictEqual(_.isSet(realm.set), true); 11692 } 11693 else { 11694 skipAssert(assert); 11695 } 11696 }); 11697 }()); 11698 11699 /*--------------------------------------------------------------------------*/ 11700 11701 QUnit.module('lodash.isString'); 11702 11703 (function() { 11704 QUnit.test('should return `true` for strings', function(assert) { 11705 assert.expect(2); 11706 11707 assert.strictEqual(_.isString('a'), true); 11708 assert.strictEqual(_.isString(Object('a')), true); 11709 }); 11710 11711 QUnit.test('should return `false` for non-strings', function(assert) { 11712 assert.expect(12); 11713 11714 var expected = lodashStable.map(falsey, function(value) { 11715 return value === ''; 11716 }); 11717 11718 var actual = lodashStable.map(falsey, function(value, index) { 11719 return index ? _.isString(value) : _.isString(); 11720 }); 11721 11722 assert.deepEqual(actual, expected); 11723 11724 assert.strictEqual(_.isString(args), false); 11725 assert.strictEqual(_.isString([1, 2, 3]), false); 11726 assert.strictEqual(_.isString(true), false); 11727 assert.strictEqual(_.isString(new Date), false); 11728 assert.strictEqual(_.isString(new Error), false); 11729 assert.strictEqual(_.isString(_), false); 11730 assert.strictEqual(_.isString(slice), false); 11731 assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false); 11732 assert.strictEqual(_.isString(1), false); 11733 assert.strictEqual(_.isString(/x/), false); 11734 assert.strictEqual(_.isString(symbol), false); 11735 }); 11736 11737 QUnit.test('should work with strings from another realm', function(assert) { 11738 assert.expect(1); 11739 11740 if (realm.string) { 11741 assert.strictEqual(_.isString(realm.string), true); 11742 } 11743 else { 11744 skipAssert(assert); 11745 } 11746 }); 11747 }()); 11748 11749 /*--------------------------------------------------------------------------*/ 11750 11751 QUnit.module('lodash.isSymbol'); 11752 11753 (function() { 11754 QUnit.test('should return `true` for symbols', function(assert) { 11755 assert.expect(2); 11756 11757 if (Symbol) { 11758 assert.strictEqual(_.isSymbol(symbol), true); 11759 assert.strictEqual(_.isSymbol(Object(symbol)), true); 11760 } 11761 else { 11762 skipAssert(assert, 2); 11763 } 11764 }); 11765 11766 QUnit.test('should return `false` for non-symbols', function(assert) { 11767 assert.expect(12); 11768 11769 var expected = lodashStable.map(falsey, stubFalse); 11770 11771 var actual = lodashStable.map(falsey, function(value, index) { 11772 return index ? _.isSymbol(value) : _.isSymbol(); 11773 }); 11774 11775 assert.deepEqual(actual, expected); 11776 11777 assert.strictEqual(_.isSymbol(args), false); 11778 assert.strictEqual(_.isSymbol([1, 2, 3]), false); 11779 assert.strictEqual(_.isSymbol(true), false); 11780 assert.strictEqual(_.isSymbol(new Date), false); 11781 assert.strictEqual(_.isSymbol(new Error), false); 11782 assert.strictEqual(_.isSymbol(_), false); 11783 assert.strictEqual(_.isSymbol(slice), false); 11784 assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false); 11785 assert.strictEqual(_.isSymbol(1), false); 11786 assert.strictEqual(_.isSymbol(/x/), false); 11787 assert.strictEqual(_.isSymbol('a'), false); 11788 }); 11789 11790 QUnit.test('should work with symbols from another realm', function(assert) { 11791 assert.expect(1); 11792 11793 if (Symbol && realm.symbol) { 11794 assert.strictEqual(_.isSymbol(realm.symbol), true); 11795 } 11796 else { 11797 skipAssert(assert); 11798 } 11799 }); 11800 }()); 11801 11802 /*--------------------------------------------------------------------------*/ 11803 11804 QUnit.module('lodash.isTypedArray'); 11805 11806 (function() { 11807 QUnit.test('should return `true` for typed arrays', function(assert) { 11808 assert.expect(1); 11809 11810 var expected = lodashStable.map(typedArrays, function(type) { 11811 return type in root; 11812 }); 11813 11814 var actual = lodashStable.map(typedArrays, function(type) { 11815 var Ctor = root[type]; 11816 return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false; 11817 }); 11818 11819 assert.deepEqual(actual, expected); 11820 }); 11821 11822 QUnit.test('should return `false` for non typed arrays', function(assert) { 11823 assert.expect(13); 11824 11825 var expected = lodashStable.map(falsey, stubFalse); 11826 11827 var actual = lodashStable.map(falsey, function(value, index) { 11828 return index ? _.isTypedArray(value) : _.isTypedArray(); 11829 }); 11830 11831 assert.deepEqual(actual, expected); 11832 11833 assert.strictEqual(_.isTypedArray(args), false); 11834 assert.strictEqual(_.isTypedArray([1, 2, 3]), false); 11835 assert.strictEqual(_.isTypedArray(true), false); 11836 assert.strictEqual(_.isTypedArray(new Date), false); 11837 assert.strictEqual(_.isTypedArray(new Error), false); 11838 assert.strictEqual(_.isTypedArray(_), false); 11839 assert.strictEqual(_.isTypedArray(slice), false); 11840 assert.strictEqual(_.isTypedArray({ 'a': 1 }), false); 11841 assert.strictEqual(_.isTypedArray(1), false); 11842 assert.strictEqual(_.isTypedArray(/x/), false); 11843 assert.strictEqual(_.isTypedArray('a'), false); 11844 assert.strictEqual(_.isTypedArray(symbol), false); 11845 }); 11846 11847 QUnit.test('should work with typed arrays from another realm', function(assert) { 11848 assert.expect(1); 11849 11850 if (realm.object) { 11851 var props = lodashStable.invokeMap(typedArrays, 'toLowerCase'); 11852 11853 var expected = lodashStable.map(props, function(key) { 11854 return realm[key] !== undefined; 11855 }); 11856 11857 var actual = lodashStable.map(props, function(key) { 11858 var value = realm[key]; 11859 return value ? _.isTypedArray(value) : false; 11860 }); 11861 11862 assert.deepEqual(actual, expected); 11863 } 11864 else { 11865 skipAssert(assert); 11866 } 11867 }); 11868 }()); 11869 11870 /*--------------------------------------------------------------------------*/ 11871 11872 QUnit.module('lodash.isUndefined'); 11873 11874 (function() { 11875 QUnit.test('should return `true` for `undefined` values', function(assert) { 11876 assert.expect(2); 11877 11878 assert.strictEqual(_.isUndefined(), true); 11879 assert.strictEqual(_.isUndefined(undefined), true); 11880 }); 11881 11882 QUnit.test('should return `false` for non `undefined` values', function(assert) { 11883 assert.expect(13); 11884 11885 var expected = lodashStable.map(falsey, function(value) { 11886 return value === undefined; 11887 }); 11888 11889 var actual = lodashStable.map(falsey, function(value, index) { 11890 return index ? _.isUndefined(value) : _.isUndefined(); 11891 }); 11892 11893 assert.deepEqual(actual, expected); 11894 11895 assert.strictEqual(_.isUndefined(args), false); 11896 assert.strictEqual(_.isUndefined([1, 2, 3]), false); 11897 assert.strictEqual(_.isUndefined(true), false); 11898 assert.strictEqual(_.isUndefined(new Date), false); 11899 assert.strictEqual(_.isUndefined(new Error), false); 11900 assert.strictEqual(_.isUndefined(_), false); 11901 assert.strictEqual(_.isUndefined(slice), false); 11902 assert.strictEqual(_.isUndefined({ 'a': 1 }), false); 11903 assert.strictEqual(_.isUndefined(1), false); 11904 assert.strictEqual(_.isUndefined(/x/), false); 11905 assert.strictEqual(_.isUndefined('a'), false); 11906 11907 if (Symbol) { 11908 assert.strictEqual(_.isUndefined(symbol), false); 11909 } 11910 else { 11911 skipAssert(assert); 11912 } 11913 }); 11914 11915 QUnit.test('should work with `undefined` from another realm', function(assert) { 11916 assert.expect(1); 11917 11918 if (realm.object) { 11919 assert.strictEqual(_.isUndefined(realm.undefined), true); 11920 } 11921 else { 11922 skipAssert(assert); 11923 } 11924 }); 11925 }()); 11926 11927 /*--------------------------------------------------------------------------*/ 11928 11929 QUnit.module('lodash.isWeakMap'); 11930 11931 (function() { 11932 QUnit.test('should return `true` for weak maps', function(assert) { 11933 assert.expect(1); 11934 11935 if (WeakMap) { 11936 assert.strictEqual(_.isWeakMap(weakMap), true); 11937 } 11938 else { 11939 skipAssert(assert); 11940 } 11941 }); 11942 11943 QUnit.test('should return `false` for non weak maps', function(assert) { 11944 assert.expect(14); 11945 11946 var expected = lodashStable.map(falsey, stubFalse); 11947 11948 var actual = lodashStable.map(falsey, function(value, index) { 11949 return index ? _.isWeakMap(value) : _.isWeakMap(); 11950 }); 11951 11952 assert.deepEqual(actual, expected); 11953 11954 assert.strictEqual(_.isWeakMap(args), false); 11955 assert.strictEqual(_.isWeakMap([1, 2, 3]), false); 11956 assert.strictEqual(_.isWeakMap(true), false); 11957 assert.strictEqual(_.isWeakMap(new Date), false); 11958 assert.strictEqual(_.isWeakMap(new Error), false); 11959 assert.strictEqual(_.isWeakMap(_), false); 11960 assert.strictEqual(_.isWeakMap(slice), false); 11961 assert.strictEqual(_.isWeakMap({ 'a': 1 }), false); 11962 assert.strictEqual(_.isWeakMap(map), false); 11963 assert.strictEqual(_.isWeakMap(1), false); 11964 assert.strictEqual(_.isWeakMap(/x/), false); 11965 assert.strictEqual(_.isWeakMap('a'), false); 11966 assert.strictEqual(_.isWeakMap(symbol), false); 11967 }); 11968 11969 QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) { 11970 assert.expect(1); 11971 11972 var values = [false, true], 11973 expected = lodashStable.map(values, stubFalse); 11974 11975 var actual = lodashStable.map(values, function(value) { 11976 return _.isWeakMap({ 'constructor': value }); 11977 }); 11978 11979 assert.deepEqual(actual, expected); 11980 }); 11981 11982 QUnit.test('should work with weak maps from another realm', function(assert) { 11983 assert.expect(1); 11984 11985 if (realm.weakMap) { 11986 assert.strictEqual(_.isWeakMap(realm.weakMap), true); 11987 } 11988 else { 11989 skipAssert(assert); 11990 } 11991 }); 11992 }()); 11993 11994 /*--------------------------------------------------------------------------*/ 11995 11996 QUnit.module('lodash.isWeakSet'); 11997 11998 (function() { 11999 QUnit.test('should return `true` for weak sets', function(assert) { 12000 assert.expect(1); 12001 12002 if (WeakSet) { 12003 assert.strictEqual(_.isWeakSet(weakSet), true); 12004 } 12005 else { 12006 skipAssert(assert); 12007 } 12008 }); 12009 12010 QUnit.test('should return `false` for non weak sets', function(assert) { 12011 assert.expect(14); 12012 12013 var expected = lodashStable.map(falsey, stubFalse); 12014 12015 var actual = lodashStable.map(falsey, function(value, index) { 12016 return index ? _.isWeakSet(value) : _.isWeakSet(); 12017 }); 12018 12019 assert.deepEqual(actual, expected); 12020 12021 assert.strictEqual(_.isWeakSet(args), false); 12022 assert.strictEqual(_.isWeakSet([1, 2, 3]), false); 12023 assert.strictEqual(_.isWeakSet(true), false); 12024 assert.strictEqual(_.isWeakSet(new Date), false); 12025 assert.strictEqual(_.isWeakSet(new Error), false); 12026 assert.strictEqual(_.isWeakSet(_), false); 12027 assert.strictEqual(_.isWeakSet(slice), false); 12028 assert.strictEqual(_.isWeakSet({ 'a': 1 }), false); 12029 assert.strictEqual(_.isWeakSet(1), false); 12030 assert.strictEqual(_.isWeakSet(/x/), false); 12031 assert.strictEqual(_.isWeakSet('a'), false); 12032 assert.strictEqual(_.isWeakSet(set), false); 12033 assert.strictEqual(_.isWeakSet(symbol), false); 12034 }); 12035 12036 QUnit.test('should work with weak sets from another realm', function(assert) { 12037 assert.expect(1); 12038 12039 if (realm.weakSet) { 12040 assert.strictEqual(_.isWeakSet(realm.weakSet), true); 12041 } 12042 else { 12043 skipAssert(assert); 12044 } 12045 }); 12046 }()); 12047 12048 /*--------------------------------------------------------------------------*/ 12049 12050 QUnit.module('isType checks'); 12051 12052 (function() { 12053 QUnit.test('should return `false` for subclassed values', function(assert) { 12054 assert.expect(7); 12055 12056 var funcs = [ 12057 'isArray', 'isBoolean', 'isDate', 'isFunction', 12058 'isNumber', 'isRegExp', 'isString' 12059 ]; 12060 12061 lodashStable.each(funcs, function(methodName) { 12062 function Foo() {} 12063 Foo.prototype = root[methodName.slice(2)].prototype; 12064 12065 var object = new Foo; 12066 if (objToString.call(object) == objectTag) { 12067 assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`'); 12068 } 12069 else { 12070 skipAssert(assert); 12071 } 12072 }); 12073 }); 12074 12075 QUnit.test('should not error on host objects (test in IE)', function(assert) { 12076 assert.expect(26); 12077 12078 var funcs = [ 12079 'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean', 12080 'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction', 12081 'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject', 12082 'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString', 12083 'isUndefined', 'isWeakMap', 'isWeakSet' 12084 ]; 12085 12086 lodashStable.each(funcs, function(methodName) { 12087 if (xml) { 12088 _[methodName](xml); 12089 assert.ok(true, '`_.' + methodName + '` should not error'); 12090 } 12091 else { 12092 skipAssert(assert); 12093 } 12094 }); 12095 }); 12096 }()); 12097 12098 /*--------------------------------------------------------------------------*/ 12099 12100 QUnit.module('lodash.iteratee'); 12101 12102 (function() { 12103 QUnit.test('should provide arguments to `func`', function(assert) { 12104 assert.expect(1); 12105 12106 var fn = function() { return slice.call(arguments); }, 12107 iteratee = _.iteratee(fn), 12108 actual = iteratee('a', 'b', 'c', 'd', 'e', 'f'); 12109 12110 assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']); 12111 }); 12112 12113 QUnit.test('should return `_.identity` when `func` is nullish', function(assert) { 12114 assert.expect(1); 12115 12116 var object = {}, 12117 values = [, null, undefined], 12118 expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object])); 12119 12120 var actual = lodashStable.map(values, function(value, index) { 12121 var identity = index ? _.iteratee(value) : _.iteratee(); 12122 return [!isNpm && identity, identity(object)]; 12123 }); 12124 12125 assert.deepEqual(actual, expected); 12126 }); 12127 12128 QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) { 12129 assert.expect(2); 12130 12131 var matches = _.iteratee({ 'a': 1, 'b': 2 }); 12132 assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true); 12133 assert.strictEqual(matches({ 'b': 2 }), false); 12134 }); 12135 12136 QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) { 12137 assert.expect(9); 12138 12139 var sources = [ 12140 { 'a': { 'b': 2, 'c': 3 } }, 12141 { 'a': 1, 'b': 2 }, 12142 { 'a': 1 } 12143 ]; 12144 12145 lodashStable.each(sources, function(source, index) { 12146 var object = lodashStable.cloneDeep(source), 12147 matches = _.iteratee(source); 12148 12149 assert.strictEqual(matches(object), true); 12150 12151 if (index) { 12152 source.a = 2; 12153 source.b = 1; 12154 source.c = 3; 12155 } else { 12156 source.a.b = 1; 12157 source.a.c = 2; 12158 source.a.d = 3; 12159 } 12160 assert.strictEqual(matches(object), true); 12161 assert.strictEqual(matches(source), false); 12162 }); 12163 }); 12164 12165 QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) { 12166 assert.expect(3); 12167 12168 var array = ['a', undefined], 12169 matches = _.iteratee([0, 'a']); 12170 12171 assert.strictEqual(matches(array), true); 12172 12173 matches = _.iteratee(['0', 'a']); 12174 assert.strictEqual(matches(array), true); 12175 12176 matches = _.iteratee([1, undefined]); 12177 assert.strictEqual(matches(array), true); 12178 }); 12179 12180 QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) { 12181 assert.expect(1); 12182 12183 var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } }, 12184 matches = _.iteratee(['a.b', { 'c': 1 }]); 12185 12186 assert.strictEqual(matches(object), true); 12187 }); 12188 12189 QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) { 12190 assert.expect(9); 12191 12192 var sources = [ 12193 { 'a': { 'b': 2, 'c': 3 } }, 12194 { 'a': 1, 'b': 2 }, 12195 { 'a': 1 } 12196 ]; 12197 12198 lodashStable.each(sources, function(source, index) { 12199 var object = { 'a': lodashStable.cloneDeep(source) }, 12200 matches = _.iteratee(['a', source]); 12201 12202 assert.strictEqual(matches(object), true); 12203 12204 if (index) { 12205 source.a = 2; 12206 source.b = 1; 12207 source.c = 3; 12208 } else { 12209 source.a.b = 1; 12210 source.a.c = 2; 12211 source.a.d = 3; 12212 } 12213 assert.strictEqual(matches(object), true); 12214 assert.strictEqual(matches({ 'a': source }), false); 12215 }); 12216 }); 12217 12218 QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) { 12219 assert.expect(2); 12220 12221 var array = ['a'], 12222 prop = _.iteratee(0); 12223 12224 assert.strictEqual(prop(array), 'a'); 12225 12226 prop = _.iteratee('0'); 12227 assert.strictEqual(prop(array), 'a'); 12228 }); 12229 12230 QUnit.test('should support deep paths for `_.property` shorthands', function(assert) { 12231 assert.expect(1); 12232 12233 var object = { 'a': { 'b': 2 } }, 12234 prop = _.iteratee('a.b'); 12235 12236 assert.strictEqual(prop(object), 2); 12237 }); 12238 12239 QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) { 12240 assert.expect(2); 12241 12242 var fn = function() { 12243 var result = [this.a]; 12244 push.apply(result, arguments); 12245 return result; 12246 }; 12247 12248 var expected = [1, 2, 3], 12249 object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) }; 12250 12251 assert.deepEqual(object.iteratee(3), expected); 12252 12253 object.iteratee = _.iteratee(_.partialRight(fn, 3)); 12254 assert.deepEqual(object.iteratee(2), expected); 12255 }); 12256 12257 QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) { 12258 assert.expect(1); 12259 12260 var iteratee = _.iteratee; 12261 delete _.iteratee; 12262 12263 assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]); 12264 12265 _.iteratee = iteratee; 12266 }); 12267 12268 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 12269 assert.expect(1); 12270 12271 var fn = function() { return this instanceof Number; }, 12272 array = [fn, fn, fn], 12273 iteratees = lodashStable.map(array, _.iteratee), 12274 expected = lodashStable.map(array, stubFalse); 12275 12276 var actual = lodashStable.map(iteratees, function(iteratee) { 12277 return iteratee(); 12278 }); 12279 12280 assert.deepEqual(actual, expected); 12281 }); 12282 }()); 12283 12284 /*--------------------------------------------------------------------------*/ 12285 12286 QUnit.module('custom `_.iteratee` methods'); 12287 12288 (function() { 12289 var array = ['one', 'two', 'three'], 12290 getPropA = _.partial(_.property, 'a'), 12291 getPropB = _.partial(_.property, 'b'), 12292 getLength = _.partial(_.property, 'length'), 12293 iteratee = _.iteratee; 12294 12295 var getSum = function() { 12296 return function(result, object) { 12297 return result + object.a; 12298 }; 12299 }; 12300 12301 var objects = [ 12302 { 'a': 0, 'b': 0 }, 12303 { 'a': 1, 'b': 0 }, 12304 { 'a': 1, 'b': 1 } 12305 ]; 12306 12307 QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) { 12308 assert.expect(1); 12309 12310 if (!isModularize) { 12311 _.iteratee = getLength; 12312 assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 }); 12313 _.iteratee = iteratee; 12314 } 12315 else { 12316 skipAssert(assert); 12317 } 12318 }); 12319 12320 QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) { 12321 assert.expect(1); 12322 12323 if (!isModularize) { 12324 _.iteratee = getPropA; 12325 assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]); 12326 _.iteratee = iteratee; 12327 } 12328 else { 12329 skipAssert(assert); 12330 } 12331 }); 12332 12333 QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) { 12334 assert.expect(1); 12335 12336 if (!isModularize) { 12337 _.iteratee = getPropB; 12338 assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2)); 12339 _.iteratee = iteratee; 12340 } 12341 else { 12342 skipAssert(assert); 12343 } 12344 }); 12345 12346 QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) { 12347 assert.expect(1); 12348 12349 if (!isModularize) { 12350 _.iteratee = getPropB; 12351 assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2)); 12352 _.iteratee = iteratee; 12353 } 12354 else { 12355 skipAssert(assert); 12356 } 12357 }); 12358 12359 QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) { 12360 assert.expect(1); 12361 12362 if (!isModularize) { 12363 _.iteratee = getPropA; 12364 assert.strictEqual(_.every(objects.slice(1)), true); 12365 _.iteratee = iteratee; 12366 } 12367 else { 12368 skipAssert(assert); 12369 } 12370 }); 12371 12372 QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) { 12373 assert.expect(1); 12374 12375 if (!isModularize) { 12376 var objects = [{ 'a': 0 }, { 'a': 1 }]; 12377 12378 _.iteratee = getPropA; 12379 assert.deepEqual(_.filter(objects), [objects[1]]); 12380 _.iteratee = iteratee; 12381 } 12382 else { 12383 skipAssert(assert); 12384 } 12385 }); 12386 12387 QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) { 12388 assert.expect(1); 12389 12390 if (!isModularize) { 12391 _.iteratee = getPropA; 12392 assert.strictEqual(_.find(objects), objects[1]); 12393 _.iteratee = iteratee; 12394 } 12395 else { 12396 skipAssert(assert); 12397 } 12398 }); 12399 12400 QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) { 12401 assert.expect(1); 12402 12403 if (!isModularize) { 12404 _.iteratee = getPropA; 12405 assert.strictEqual(_.findIndex(objects), 1); 12406 _.iteratee = iteratee; 12407 } 12408 else { 12409 skipAssert(assert); 12410 } 12411 }); 12412 12413 QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) { 12414 assert.expect(1); 12415 12416 if (!isModularize) { 12417 _.iteratee = getPropA; 12418 assert.strictEqual(_.findLast(objects), objects[2]); 12419 _.iteratee = iteratee; 12420 } 12421 else { 12422 skipAssert(assert); 12423 } 12424 }); 12425 12426 QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) { 12427 assert.expect(1); 12428 12429 if (!isModularize) { 12430 _.iteratee = getPropA; 12431 assert.strictEqual(_.findLastIndex(objects), 2); 12432 _.iteratee = iteratee; 12433 } 12434 else { 12435 skipAssert(assert); 12436 } 12437 }); 12438 12439 QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) { 12440 assert.expect(1); 12441 12442 if (!isModularize) { 12443 _.iteratee = getPropB; 12444 assert.strictEqual(_.findKey(objects), '2'); 12445 _.iteratee = iteratee; 12446 } 12447 else { 12448 skipAssert(assert); 12449 } 12450 }); 12451 12452 QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) { 12453 assert.expect(1); 12454 12455 if (!isModularize) { 12456 _.iteratee = getPropB; 12457 assert.strictEqual(_.findLastKey(objects), '2'); 12458 _.iteratee = iteratee; 12459 } 12460 else { 12461 skipAssert(assert); 12462 } 12463 }); 12464 12465 QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) { 12466 assert.expect(1); 12467 12468 if (!isModularize) { 12469 _.iteratee = getLength; 12470 assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] }); 12471 _.iteratee = iteratee; 12472 } 12473 else { 12474 skipAssert(assert); 12475 } 12476 }); 12477 12478 QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) { 12479 assert.expect(1); 12480 12481 if (!isModularize) { 12482 _.iteratee = getPropA; 12483 assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]); 12484 _.iteratee = iteratee; 12485 } 12486 else { 12487 skipAssert(assert); 12488 } 12489 }); 12490 12491 QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) { 12492 assert.expect(1); 12493 12494 if (!isModularize) { 12495 _.iteratee = getLength; 12496 assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' }); 12497 _.iteratee = iteratee; 12498 } 12499 else { 12500 skipAssert(assert); 12501 } 12502 }); 12503 12504 QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) { 12505 assert.expect(1); 12506 12507 if (!isModularize) { 12508 _.iteratee = getPropA; 12509 assert.deepEqual(_.map(objects), [0, 1, 1]); 12510 _.iteratee = iteratee; 12511 } 12512 else { 12513 skipAssert(assert); 12514 } 12515 }); 12516 12517 QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) { 12518 assert.expect(1); 12519 12520 if (!isModularize) { 12521 _.iteratee = getPropB; 12522 assert.deepEqual(_.mapKeys({ 'a': { 'b': 2 } }), { '2': { 'b': 2 } }); 12523 _.iteratee = iteratee; 12524 } 12525 else { 12526 skipAssert(assert); 12527 } 12528 }); 12529 12530 QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) { 12531 assert.expect(1); 12532 12533 if (!isModularize) { 12534 _.iteratee = getPropB; 12535 assert.deepEqual(_.mapValues({ 'a': { 'b': 2 } }), { 'a': 2 }); 12536 _.iteratee = iteratee; 12537 } 12538 else { 12539 skipAssert(assert); 12540 } 12541 }); 12542 12543 QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) { 12544 assert.expect(1); 12545 12546 if (!isModularize) { 12547 _.iteratee = getPropB; 12548 assert.deepEqual(_.maxBy(objects), objects[2]); 12549 _.iteratee = iteratee; 12550 } 12551 else { 12552 skipAssert(assert); 12553 } 12554 }); 12555 12556 QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) { 12557 assert.expect(1); 12558 12559 if (!isModularize) { 12560 _.iteratee = getPropA; 12561 assert.strictEqual(_.meanBy(objects), 2 / 3); 12562 _.iteratee = iteratee; 12563 } 12564 else { 12565 skipAssert(assert); 12566 } 12567 }); 12568 12569 QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) { 12570 assert.expect(1); 12571 12572 if (!isModularize) { 12573 _.iteratee = getPropB; 12574 assert.deepEqual(_.minBy(objects), objects[0]); 12575 _.iteratee = iteratee; 12576 } 12577 else { 12578 skipAssert(assert); 12579 } 12580 }); 12581 12582 QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) { 12583 assert.expect(1); 12584 12585 if (!isModularize) { 12586 var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }]; 12587 12588 _.iteratee = getPropA; 12589 assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]); 12590 _.iteratee = iteratee; 12591 } 12592 else { 12593 skipAssert(assert); 12594 } 12595 }); 12596 12597 QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) { 12598 assert.expect(1); 12599 12600 if (!isModularize) { 12601 _.iteratee = getPropA; 12602 assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]); 12603 _.iteratee = iteratee; 12604 } 12605 else { 12606 skipAssert(assert); 12607 } 12608 }); 12609 12610 QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) { 12611 assert.expect(1); 12612 12613 if (!isModularize) { 12614 _.iteratee = getSum; 12615 assert.strictEqual(_.reduce(objects, undefined, 0), 2); 12616 _.iteratee = iteratee; 12617 } 12618 else { 12619 skipAssert(assert); 12620 } 12621 }); 12622 12623 QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) { 12624 assert.expect(1); 12625 12626 if (!isModularize) { 12627 _.iteratee = getSum; 12628 assert.strictEqual(_.reduceRight(objects, undefined, 0), 2); 12629 _.iteratee = iteratee; 12630 } 12631 else { 12632 skipAssert(assert); 12633 } 12634 }); 12635 12636 QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) { 12637 assert.expect(1); 12638 12639 if (!isModularize) { 12640 var objects = [{ 'a': 0 }, { 'a': 1 }]; 12641 12642 _.iteratee = getPropA; 12643 assert.deepEqual(_.reject(objects), [objects[0]]); 12644 _.iteratee = iteratee; 12645 } 12646 else { 12647 skipAssert(assert); 12648 } 12649 }); 12650 12651 QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) { 12652 assert.expect(1); 12653 12654 if (!isModularize) { 12655 var objects = [{ 'a': 0 }, { 'a': 1 }]; 12656 12657 _.iteratee = getPropA; 12658 _.remove(objects); 12659 assert.deepEqual(objects, [{ 'a': 0 }]); 12660 _.iteratee = iteratee; 12661 } 12662 else { 12663 skipAssert(assert); 12664 } 12665 }); 12666 12667 QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) { 12668 assert.expect(1); 12669 12670 if (!isModularize) { 12671 _.iteratee = getPropB; 12672 assert.strictEqual(_.some(objects), true); 12673 _.iteratee = iteratee; 12674 } 12675 else { 12676 skipAssert(assert); 12677 } 12678 }); 12679 12680 QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) { 12681 assert.expect(1); 12682 12683 if (!isModularize) { 12684 _.iteratee = getPropA; 12685 assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]); 12686 _.iteratee = iteratee; 12687 } 12688 else { 12689 skipAssert(assert); 12690 } 12691 }); 12692 12693 QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) { 12694 assert.expect(1); 12695 12696 if (!isModularize) { 12697 var objects = [{ 'a': 30 }, { 'a': 50 }]; 12698 12699 _.iteratee = getPropA; 12700 assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1); 12701 _.iteratee = iteratee; 12702 } 12703 else { 12704 skipAssert(assert); 12705 } 12706 }); 12707 12708 QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) { 12709 assert.expect(1); 12710 12711 if (!isModularize) { 12712 var objects = [{ 'a': 30 }, { 'a': 50 }]; 12713 12714 _.iteratee = getPropA; 12715 assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1); 12716 _.iteratee = iteratee; 12717 } 12718 else { 12719 skipAssert(assert); 12720 } 12721 }); 12722 12723 QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) { 12724 assert.expect(1); 12725 12726 if (!isModularize) { 12727 _.iteratee = getPropB; 12728 assert.strictEqual(_.sumBy(objects), 1); 12729 _.iteratee = iteratee; 12730 } 12731 else { 12732 skipAssert(assert); 12733 } 12734 }); 12735 12736 QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) { 12737 assert.expect(1); 12738 12739 if (!isModularize) { 12740 _.iteratee = getPropB; 12741 assert.deepEqual(_.takeRightWhile(objects), objects.slice(2)); 12742 _.iteratee = iteratee; 12743 } 12744 else { 12745 skipAssert(assert); 12746 } 12747 }); 12748 12749 QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) { 12750 assert.expect(1); 12751 12752 if (!isModularize) { 12753 _.iteratee = getPropB; 12754 assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2)); 12755 _.iteratee = iteratee; 12756 } 12757 else { 12758 skipAssert(assert); 12759 } 12760 }); 12761 12762 QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) { 12763 assert.expect(1); 12764 12765 if (!isModularize) { 12766 _.iteratee = function() { 12767 return function(result, object) { 12768 result.sum += object.a; 12769 }; 12770 }; 12771 12772 assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 }); 12773 _.iteratee = iteratee; 12774 } 12775 else { 12776 skipAssert(assert); 12777 } 12778 }); 12779 12780 QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) { 12781 assert.expect(1); 12782 12783 if (!isModularize) { 12784 _.iteratee = getPropB; 12785 assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]); 12786 _.iteratee = iteratee; 12787 } 12788 else { 12789 skipAssert(assert); 12790 } 12791 }); 12792 12793 QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) { 12794 assert.expect(1); 12795 12796 if (!isModularize) { 12797 _.iteratee = getPropB; 12798 assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]); 12799 _.iteratee = iteratee; 12800 } 12801 else { 12802 skipAssert(assert); 12803 } 12804 }); 12805 12806 QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) { 12807 assert.expect(1); 12808 12809 if (!isModularize) { 12810 _.iteratee = getPropA; 12811 assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]); 12812 _.iteratee = iteratee; 12813 } 12814 else { 12815 skipAssert(assert); 12816 } 12817 }); 12818 }()); 12819 12820 /*--------------------------------------------------------------------------*/ 12821 12822 QUnit.module('lodash.join'); 12823 12824 (function() { 12825 var array = ['a', 'b', 'c']; 12826 12827 QUnit.test('should return join all array elements into a string', function(assert) { 12828 assert.expect(1); 12829 12830 assert.strictEqual(_.join(array, '~'), 'a~b~c'); 12831 }); 12832 12833 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 12834 assert.expect(2); 12835 12836 if (!isNpm) { 12837 var wrapped = _(array); 12838 assert.strictEqual(wrapped.join('~'), 'a~b~c'); 12839 assert.strictEqual(wrapped.value(), array); 12840 } 12841 else { 12842 skipAssert(assert, 2); 12843 } 12844 }); 12845 12846 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 12847 assert.expect(1); 12848 12849 if (!isNpm) { 12850 assert.ok(_(array).chain().join('~') instanceof _); 12851 } 12852 else { 12853 skipAssert(assert); 12854 } 12855 }); 12856 }()); 12857 12858 /*--------------------------------------------------------------------------*/ 12859 12860 QUnit.module('lodash.keyBy'); 12861 12862 (function() { 12863 var array = [ 12864 { 'dir': 'left', 'code': 97 }, 12865 { 'dir': 'right', 'code': 100 } 12866 ]; 12867 12868 QUnit.test('should transform keys by `iteratee`', function(assert) { 12869 assert.expect(1); 12870 12871 var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }; 12872 12873 var actual = _.keyBy(array, function(object) { 12874 return String.fromCharCode(object.code); 12875 }); 12876 12877 assert.deepEqual(actual, expected); 12878 }); 12879 12880 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 12881 assert.expect(1); 12882 12883 var array = [4, 6, 6], 12884 values = [, null, undefined], 12885 expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 })); 12886 12887 var actual = lodashStable.map(values, function(value, index) { 12888 return index ? _.keyBy(array, value) : _.keyBy(array); 12889 }); 12890 12891 assert.deepEqual(actual, expected); 12892 }); 12893 12894 QUnit.test('should work with `_.property` shorthands', function(assert) { 12895 assert.expect(1); 12896 12897 var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }, 12898 actual = _.keyBy(array, 'dir'); 12899 12900 assert.deepEqual(actual, expected); 12901 }); 12902 12903 QUnit.test('should only add values to own, not inherited, properties', function(assert) { 12904 assert.expect(2); 12905 12906 var actual = _.keyBy([6.1, 4.2, 6.3], function(n) { 12907 return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor'; 12908 }); 12909 12910 assert.deepEqual(actual.constructor, 4.2); 12911 assert.deepEqual(actual.hasOwnProperty, 6.3); 12912 }); 12913 12914 QUnit.test('should work with a number for `iteratee`', function(assert) { 12915 assert.expect(2); 12916 12917 var array = [ 12918 [1, 'a'], 12919 [2, 'a'], 12920 [2, 'b'] 12921 ]; 12922 12923 assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] }); 12924 assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] }); 12925 }); 12926 12927 QUnit.test('should work with an object for `collection`', function(assert) { 12928 assert.expect(1); 12929 12930 var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor); 12931 assert.deepEqual(actual, { '4': 4.2, '6': 6.3 }); 12932 }); 12933 12934 QUnit.test('should work in a lazy sequence', function(assert) { 12935 assert.expect(1); 12936 12937 if (!isNpm) { 12938 var array = lodashStable.range(LARGE_ARRAY_SIZE).concat( 12939 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE), 12940 lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE) 12941 ); 12942 12943 var actual = _(array).keyBy().map(square).filter(isEven).take().value(); 12944 12945 assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven))); 12946 } 12947 else { 12948 skipAssert(assert); 12949 } 12950 }); 12951 }()); 12952 12953 /*--------------------------------------------------------------------------*/ 12954 12955 QUnit.module('keys methods'); 12956 12957 lodashStable.each(['keys', 'keysIn'], function(methodName) { 12958 var func = _[methodName], 12959 isKeys = methodName == 'keys'; 12960 12961 QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) { 12962 assert.expect(1); 12963 12964 var actual = func({ 'a': 1, 'b': 1 }).sort(); 12965 12966 assert.deepEqual(actual, ['a', 'b']); 12967 }); 12968 12969 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) { 12970 assert.expect(1); 12971 12972 function Foo() { 12973 this.a = 1; 12974 } 12975 Foo.prototype.b = 2; 12976 12977 var expected = isKeys ? ['a'] : ['a', 'b'], 12978 actual = func(new Foo).sort(); 12979 12980 assert.deepEqual(actual, expected); 12981 }); 12982 12983 QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) { 12984 assert.expect(1); 12985 12986 var array = [1]; 12987 array[2] = 3; 12988 12989 var actual = func(array).sort(); 12990 12991 assert.deepEqual(actual, ['0', '1', '2']); 12992 }); 12993 12994 QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) { 12995 assert.expect(1); 12996 12997 var array = [1]; 12998 array.a = 1; 12999 13000 var actual = func(array).sort(); 13001 13002 assert.deepEqual(actual, ['0', 'a']); 13003 }); 13004 13005 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) { 13006 assert.expect(1); 13007 13008 arrayProto.a = 1; 13009 13010 var expected = isKeys ? ['0'] : ['0', 'a'], 13011 actual = func([1]).sort(); 13012 13013 assert.deepEqual(actual, expected); 13014 13015 delete arrayProto.a; 13016 }); 13017 13018 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) { 13019 assert.expect(1); 13020 13021 var values = [args, strictArgs], 13022 expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2'])); 13023 13024 var actual = lodashStable.map(values, function(value) { 13025 return func(value).sort(); 13026 }); 13027 13028 assert.deepEqual(actual, expected); 13029 }); 13030 13031 QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) { 13032 assert.expect(1); 13033 13034 var values = [args, strictArgs], 13035 expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a'])); 13036 13037 var actual = lodashStable.map(values, function(value) { 13038 value.a = 1; 13039 var result = func(value).sort(); 13040 delete value.a; 13041 return result; 13042 }); 13043 13044 assert.deepEqual(actual, expected); 13045 }); 13046 13047 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) { 13048 assert.expect(1); 13049 13050 var values = [args, strictArgs], 13051 expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a'])); 13052 13053 var actual = lodashStable.map(values, function(value) { 13054 objectProto.a = 1; 13055 var result = func(value).sort(); 13056 delete objectProto.a; 13057 return result; 13058 }); 13059 13060 assert.deepEqual(actual, expected); 13061 }); 13062 13063 QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) { 13064 assert.expect(1); 13065 13066 var actual = func(Object('abc')).sort(); 13067 13068 assert.deepEqual(actual, ['0', '1', '2']); 13069 }); 13070 13071 QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) { 13072 assert.expect(1); 13073 13074 var object = Object('a'); 13075 object.a = 1; 13076 13077 var actual = func(object).sort(); 13078 13079 assert.deepEqual(actual, ['0', 'a']); 13080 }); 13081 13082 QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) { 13083 assert.expect(1); 13084 13085 stringProto.a = 1; 13086 13087 var expected = isKeys ? ['0'] : ['0', 'a'], 13088 actual = func(Object('a')).sort(); 13089 13090 assert.deepEqual(actual, expected); 13091 13092 delete stringProto.a; 13093 }); 13094 13095 QUnit.test('`_.' + methodName + '` should work with array-like objects', function(assert) { 13096 assert.expect(1); 13097 13098 var object = { '0': 'a', 'length': 1 }, 13099 actual = func(object).sort(); 13100 13101 assert.deepEqual(actual, ['0', 'length']); 13102 }); 13103 13104 QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) { 13105 assert.expect(2); 13106 13107 var expected = lodashStable.map(primitives, function(value) { 13108 return typeof value == 'string' ? ['0'] : []; 13109 }); 13110 13111 var actual = lodashStable.map(primitives, func); 13112 assert.deepEqual(actual, expected); 13113 13114 // IE 9 doesn't box numbers in for-in loops. 13115 numberProto.a = 1; 13116 assert.deepEqual(func(0), isKeys ? [] : ['a']); 13117 delete numberProto.a; 13118 }); 13119 13120 QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) { 13121 assert.expect(3); 13122 13123 function Foo() {} 13124 Foo.prototype.a = 1; 13125 13126 var expected = ['a']; 13127 assert.deepEqual(func(Foo.prototype), expected); 13128 13129 Foo.prototype = { 'constructor': Foo, 'a': 1 }; 13130 assert.deepEqual(func(Foo.prototype), expected); 13131 13132 var Fake = { 'prototype': {} }; 13133 Fake.prototype.constructor = Fake; 13134 assert.deepEqual(func(Fake.prototype), ['constructor']); 13135 }); 13136 13137 QUnit.test('`_.' + methodName + '` should return an empty array when `object` is nullish', function(assert) { 13138 var values = [, null, undefined], 13139 expected = lodashStable.map(values, stubArray); 13140 13141 var actual = lodashStable.map(values, function(value, index) { 13142 objectProto.a = 1; 13143 var result = index ? func(value) : func(); 13144 delete objectProto.a; 13145 return result; 13146 }); 13147 13148 assert.deepEqual(actual, expected); 13149 }); 13150 }); 13151 13152 /*--------------------------------------------------------------------------*/ 13153 13154 QUnit.module('lodash.last'); 13155 13156 (function() { 13157 var array = [1, 2, 3, 4]; 13158 13159 QUnit.test('should return the last element', function(assert) { 13160 assert.expect(1); 13161 13162 assert.strictEqual(_.last(array), 4); 13163 }); 13164 13165 QUnit.test('should return `undefined` when querying empty arrays', function(assert) { 13166 assert.expect(1); 13167 13168 var array = []; 13169 array['-1'] = 1; 13170 13171 assert.strictEqual(_.last([]), undefined); 13172 }); 13173 13174 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 13175 assert.expect(1); 13176 13177 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 13178 actual = lodashStable.map(array, _.last); 13179 13180 assert.deepEqual(actual, [3, 6, 9]); 13181 }); 13182 13183 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 13184 assert.expect(1); 13185 13186 if (!isNpm) { 13187 assert.strictEqual(_(array).last(), 4); 13188 } 13189 else { 13190 skipAssert(assert); 13191 } 13192 }); 13193 13194 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 13195 assert.expect(1); 13196 13197 if (!isNpm) { 13198 assert.ok(_(array).chain().last() instanceof _); 13199 } 13200 else { 13201 skipAssert(assert); 13202 } 13203 }); 13204 13205 QUnit.test('should not execute immediately when explicitly chaining', function(assert) { 13206 assert.expect(1); 13207 13208 if (!isNpm) { 13209 var wrapped = _(array).chain().last(); 13210 assert.strictEqual(wrapped.__wrapped__, array); 13211 } 13212 else { 13213 skipAssert(assert); 13214 } 13215 }); 13216 13217 QUnit.test('should work in a lazy sequence', function(assert) { 13218 assert.expect(2); 13219 13220 if (!isNpm) { 13221 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE), 13222 smallArray = array; 13223 13224 lodashStable.times(2, function(index) { 13225 var array = index ? largeArray : smallArray, 13226 wrapped = _(array).filter(isEven); 13227 13228 assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven))); 13229 }); 13230 } 13231 else { 13232 skipAssert(assert, 2); 13233 } 13234 }); 13235 }()); 13236 13237 /*--------------------------------------------------------------------------*/ 13238 13239 QUnit.module('lodash.lowerCase'); 13240 13241 (function() { 13242 QUnit.test('should lowercase as space-separated words', function(assert) { 13243 assert.expect(3); 13244 13245 assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar'); 13246 assert.strictEqual(_.lowerCase('fooBar'), 'foo bar'); 13247 assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar'); 13248 }); 13249 }()); 13250 13251 /*--------------------------------------------------------------------------*/ 13252 13253 QUnit.module('lodash.lowerFirst'); 13254 13255 (function() { 13256 QUnit.test('should lowercase only the first character', function(assert) { 13257 assert.expect(3); 13258 13259 assert.strictEqual(_.lowerFirst('fred'), 'fred'); 13260 assert.strictEqual(_.lowerFirst('Fred'), 'fred'); 13261 assert.strictEqual(_.lowerFirst('FRED'), 'fRED'); 13262 }); 13263 }()); 13264 13265 /*--------------------------------------------------------------------------*/ 13266 13267 QUnit.module('lodash.lt'); 13268 13269 (function() { 13270 QUnit.test('should return `true` if `value` is less than `other`', function(assert) { 13271 assert.expect(2); 13272 13273 assert.strictEqual(_.lt(1, 3), true); 13274 assert.strictEqual(_.lt('abc', 'def'), true); 13275 }); 13276 13277 QUnit.test('should return `false` if `value` >= `other`', function(assert) { 13278 assert.expect(4); 13279 13280 assert.strictEqual(_.lt(3, 1), false); 13281 assert.strictEqual(_.lt(3, 3), false); 13282 assert.strictEqual(_.lt('def', 'abc'), false); 13283 assert.strictEqual(_.lt('def', 'def'), false); 13284 }); 13285 }()); 13286 13287 /*--------------------------------------------------------------------------*/ 13288 13289 QUnit.module('lodash.lte'); 13290 13291 (function() { 13292 QUnit.test('should return `true` if `value` is <= `other`', function(assert) { 13293 assert.expect(4); 13294 13295 assert.strictEqual(_.lte(1, 3), true); 13296 assert.strictEqual(_.lte(3, 3), true); 13297 assert.strictEqual(_.lte('abc', 'def'), true); 13298 assert.strictEqual(_.lte('def', 'def'), true); 13299 }); 13300 13301 QUnit.test('should return `false` if `value` > `other`', function(assert) { 13302 assert.expect(2); 13303 13304 assert.strictEqual(_.lt(3, 1), false); 13305 assert.strictEqual(_.lt('def', 'abc'), false); 13306 }); 13307 }()); 13308 13309 /*--------------------------------------------------------------------------*/ 13310 13311 QUnit.module('lodash.findLastIndex and lodash.lastIndexOf'); 13312 13313 lodashStable.each(['findLastIndex', 'lastIndexOf'], function(methodName) { 13314 var array = [1, 2, 3, 1, 2, 3], 13315 func = _[methodName], 13316 resolve = methodName == 'findLastIndex' ? lodashStable.curry(lodashStable.eq) : identity; 13317 13318 QUnit.test('`_.' + methodName + '` should return the index of the last matched value', function(assert) { 13319 assert.expect(1); 13320 13321 assert.strictEqual(func(array, resolve(3)), 5); 13322 }); 13323 13324 QUnit.test('`_.' + methodName + '` should work with a positive `fromIndex`', function(assert) { 13325 assert.expect(1); 13326 13327 assert.strictEqual(func(array, resolve(1), 2), 0); 13328 }); 13329 13330 QUnit.test('`_.' + methodName + '` should work with a `fromIndex` >= `length`', function(assert) { 13331 assert.expect(1); 13332 13333 var values = [6, 8, Math.pow(2, 32), Infinity], 13334 expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1])); 13335 13336 var actual = lodashStable.map(values, function(fromIndex) { 13337 return [ 13338 func(array, resolve(undefined), fromIndex), 13339 func(array, resolve(1), fromIndex), 13340 func(array, resolve(''), fromIndex) 13341 ]; 13342 }); 13343 13344 assert.deepEqual(actual, expected); 13345 }); 13346 13347 QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex`', function(assert) { 13348 assert.expect(1); 13349 13350 assert.strictEqual(func(array, resolve(2), -3), 1); 13351 }); 13352 13353 QUnit.test('`_.' + methodName + '` should work with a negative `fromIndex` <= `-length`', function(assert) { 13354 assert.expect(1); 13355 13356 var values = [-6, -8, -Infinity], 13357 expected = lodashStable.map(values, stubZero); 13358 13359 var actual = lodashStable.map(values, function(fromIndex) { 13360 return func(array, resolve(1), fromIndex); 13361 }); 13362 13363 assert.deepEqual(actual, expected); 13364 }); 13365 13366 QUnit.test('`_.' + methodName + '` should treat falsey `fromIndex` values correctly', function(assert) { 13367 assert.expect(1); 13368 13369 var expected = lodashStable.map(falsey, function(value) { 13370 return value === undefined ? 5 : -1; 13371 }); 13372 13373 var actual = lodashStable.map(falsey, function(fromIndex) { 13374 return func(array, resolve(3), fromIndex); 13375 }); 13376 13377 assert.deepEqual(actual, expected); 13378 }); 13379 13380 QUnit.test('`_.' + methodName + '` should coerce `fromIndex` to an integer', function(assert) { 13381 assert.expect(1); 13382 13383 assert.strictEqual(func(array, resolve(2), 4.2), 4); 13384 }); 13385 }); 13386 13387 /*--------------------------------------------------------------------------*/ 13388 13389 QUnit.module('indexOf methods'); 13390 13391 lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) { 13392 var func = _[methodName], 13393 isIndexOf = !/last/i.test(methodName), 13394 isSorted = /^sorted/.test(methodName); 13395 13396 QUnit.test('`_.' + methodName + '` should accept a falsey `array`', function(assert) { 13397 assert.expect(1); 13398 13399 var expected = lodashStable.map(falsey, lodashStable.constant(-1)); 13400 13401 var actual = lodashStable.map(falsey, function(array, index) { 13402 try { 13403 return index ? func(array) : func(); 13404 } catch (e) {} 13405 }); 13406 13407 assert.deepEqual(actual, expected); 13408 }); 13409 13410 QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) { 13411 assert.expect(5); 13412 13413 var array = [1, 2, 3], 13414 empty = []; 13415 13416 assert.strictEqual(func(array, 4), -1); 13417 assert.strictEqual(func(array, 4, true), -1); 13418 assert.strictEqual(func(array, undefined, true), -1); 13419 13420 assert.strictEqual(func(empty, undefined), -1); 13421 assert.strictEqual(func(empty, undefined, true), -1); 13422 }); 13423 13424 QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) { 13425 assert.expect(2); 13426 13427 var array = []; 13428 array[-1] = 0; 13429 13430 assert.strictEqual(func(array, undefined), -1); 13431 assert.strictEqual(func(array, 0, true), -1); 13432 }); 13433 13434 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { 13435 assert.expect(3); 13436 13437 var array = isSorted 13438 ? [1, 2, NaN, NaN] 13439 : [1, NaN, 3, NaN, 5, NaN]; 13440 13441 if (isSorted) { 13442 assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3); 13443 skipAssert(assert, 2); 13444 } 13445 else { 13446 assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5); 13447 assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1); 13448 assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3); 13449 } 13450 }); 13451 13452 QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) { 13453 assert.expect(2); 13454 13455 assert.strictEqual(func([-0], 0), 0); 13456 assert.strictEqual(func([0], -0), 0); 13457 }); 13458 }); 13459 13460 /*--------------------------------------------------------------------------*/ 13461 13462 QUnit.module('lodash.map'); 13463 13464 (function() { 13465 var array = [1, 2]; 13466 13467 QUnit.test('should map values in `collection` to a new array', function(assert) { 13468 assert.expect(2); 13469 13470 var object = { 'a': 1, 'b': 2 }, 13471 expected = ['1', '2']; 13472 13473 assert.deepEqual(_.map(array, String), expected); 13474 assert.deepEqual(_.map(object, String), expected); 13475 }); 13476 13477 QUnit.test('should work with `_.property` shorthands', function(assert) { 13478 assert.expect(1); 13479 13480 var objects = [{ 'a': 'x' }, { 'a': 'y' }]; 13481 assert.deepEqual(_.map(objects, 'a'), ['x', 'y']); 13482 }); 13483 13484 QUnit.test('should iterate over own string keyed properties of objects', function(assert) { 13485 assert.expect(1); 13486 13487 function Foo() { 13488 this.a = 1; 13489 } 13490 Foo.prototype.b = 2; 13491 13492 var actual = _.map(new Foo, identity); 13493 assert.deepEqual(actual, [1]); 13494 }); 13495 13496 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 13497 assert.expect(2); 13498 13499 var object = { 'a': 1, 'b': 2 }, 13500 values = [, null, undefined], 13501 expected = lodashStable.map(values, lodashStable.constant([1, 2])); 13502 13503 lodashStable.each([array, object], function(collection) { 13504 var actual = lodashStable.map(values, function(value, index) { 13505 return index ? _.map(collection, value) : _.map(collection); 13506 }); 13507 13508 assert.deepEqual(actual, expected); 13509 }); 13510 }); 13511 13512 QUnit.test('should accept a falsey `collection`', function(assert) { 13513 assert.expect(1); 13514 13515 var expected = lodashStable.map(falsey, stubArray); 13516 13517 var actual = lodashStable.map(falsey, function(collection, index) { 13518 try { 13519 return index ? _.map(collection) : _.map(); 13520 } catch (e) {} 13521 }); 13522 13523 assert.deepEqual(actual, expected); 13524 }); 13525 13526 QUnit.test('should treat number values for `collection` as empty', function(assert) { 13527 assert.expect(1); 13528 13529 assert.deepEqual(_.map(1), []); 13530 }); 13531 13532 QUnit.test('should treat a nodelist as an array-like object', function(assert) { 13533 assert.expect(1); 13534 13535 if (document) { 13536 var actual = _.map(document.getElementsByTagName('body'), function(element) { 13537 return element.nodeName.toLowerCase(); 13538 }); 13539 13540 assert.deepEqual(actual, ['body']); 13541 } 13542 else { 13543 skipAssert(assert); 13544 } 13545 }); 13546 13547 QUnit.test('should work with objects with non-number length properties', function(assert) { 13548 assert.expect(1); 13549 13550 var value = { 'value': 'x' }, 13551 object = { 'length': { 'value': 'x' } }; 13552 13553 assert.deepEqual(_.map(object, identity), [value]); 13554 }); 13555 13556 QUnit.test('should return a wrapped value when chaining', function(assert) { 13557 assert.expect(1); 13558 13559 if (!isNpm) { 13560 assert.ok(_(array).map(noop) instanceof _); 13561 } 13562 else { 13563 skipAssert(assert); 13564 } 13565 }); 13566 13567 QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) { 13568 assert.expect(5); 13569 13570 if (!isNpm) { 13571 var args, 13572 array = lodashStable.range(LARGE_ARRAY_SIZE + 1), 13573 expected = [1, 0, _.map(array.slice(1), square)]; 13574 13575 _(array).slice(1).map(function(value, index, array) { 13576 args || (args = slice.call(arguments)); 13577 }).value(); 13578 13579 assert.deepEqual(args, [1, 0, array.slice(1)]); 13580 13581 args = undefined; 13582 _(array).slice(1).map(square).map(function(value, index, array) { 13583 args || (args = slice.call(arguments)); 13584 }).value(); 13585 13586 assert.deepEqual(args, expected); 13587 13588 args = undefined; 13589 _(array).slice(1).map(square).map(function(value, index) { 13590 args || (args = slice.call(arguments)); 13591 }).value(); 13592 13593 assert.deepEqual(args, expected); 13594 13595 args = undefined; 13596 _(array).slice(1).map(square).map(function(value) { 13597 args || (args = slice.call(arguments)); 13598 }).value(); 13599 13600 assert.deepEqual(args, [1]); 13601 13602 args = undefined; 13603 _(array).slice(1).map(square).map(function() { 13604 args || (args = slice.call(arguments)); 13605 }).value(); 13606 13607 assert.deepEqual(args, expected); 13608 } 13609 else { 13610 skipAssert(assert, 5); 13611 } 13612 }); 13613 }()); 13614 13615 /*--------------------------------------------------------------------------*/ 13616 13617 QUnit.module('lodash.mapKeys'); 13618 13619 (function() { 13620 var array = [1, 2], 13621 object = { 'a': 1, 'b': 2 }; 13622 13623 QUnit.test('should map keys in `object` to a new object', function(assert) { 13624 assert.expect(1); 13625 13626 var actual = _.mapKeys(object, String); 13627 assert.deepEqual(actual, { '1': 1, '2': 2 }); 13628 }); 13629 13630 QUnit.test('should treat arrays like objects', function(assert) { 13631 assert.expect(1); 13632 13633 var actual = _.mapKeys(array, String); 13634 assert.deepEqual(actual, { '1': 1, '2': 2 }); 13635 }); 13636 13637 QUnit.test('should work with `_.property` shorthands', function(assert) { 13638 assert.expect(1); 13639 13640 var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b'); 13641 assert.deepEqual(actual, { 'c': { 'b': 'c' } }); 13642 }); 13643 13644 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 13645 assert.expect(1); 13646 13647 var object = { 'a': 1, 'b': 2 }, 13648 values = [, null, undefined], 13649 expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 })); 13650 13651 var actual = lodashStable.map(values, function(value, index) { 13652 return index ? _.mapKeys(object, value) : _.mapKeys(object); 13653 }); 13654 13655 assert.deepEqual(actual, expected); 13656 }); 13657 }()); 13658 13659 /*--------------------------------------------------------------------------*/ 13660 13661 QUnit.module('lodash.mapValues'); 13662 13663 (function() { 13664 var array = [1, 2], 13665 object = { 'a': 1, 'b': 2 }; 13666 13667 QUnit.test('should map values in `object` to a new object', function(assert) { 13668 assert.expect(1); 13669 13670 var actual = _.mapValues(object, String); 13671 assert.deepEqual(actual, { 'a': '1', 'b': '2' }); 13672 }); 13673 13674 QUnit.test('should treat arrays like objects', function(assert) { 13675 assert.expect(1); 13676 13677 var actual = _.mapValues(array, String); 13678 assert.deepEqual(actual, { '0': '1', '1': '2' }); 13679 }); 13680 13681 QUnit.test('should work with `_.property` shorthands', function(assert) { 13682 assert.expect(1); 13683 13684 var actual = _.mapValues({ 'a': { 'b': 2 } }, 'b'); 13685 assert.deepEqual(actual, { 'a': 2 }); 13686 }); 13687 13688 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 13689 assert.expect(1); 13690 13691 var object = { 'a': 1, 'b': 2 }, 13692 values = [, null, undefined], 13693 expected = lodashStable.map(values, lodashStable.constant([true, false])); 13694 13695 var actual = lodashStable.map(values, function(value, index) { 13696 var result = index ? _.mapValues(object, value) : _.mapValues(object); 13697 return [lodashStable.isEqual(result, object), result === object]; 13698 }); 13699 13700 assert.deepEqual(actual, expected); 13701 }); 13702 }()); 13703 13704 /*--------------------------------------------------------------------------*/ 13705 13706 QUnit.module('lodash.mapKeys and lodash.mapValues'); 13707 13708 lodashStable.each(['mapKeys', 'mapValues'], function(methodName) { 13709 var func = _[methodName], 13710 object = { 'a': 1, 'b': 2 }; 13711 13712 QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) { 13713 assert.expect(1); 13714 13715 function Foo() { 13716 this.a = 'a'; 13717 } 13718 Foo.prototype.b = 'b'; 13719 13720 var actual = func(new Foo, function(value, key) { return key; }); 13721 assert.deepEqual(actual, { 'a': 'a' }); 13722 }); 13723 13724 QUnit.test('`_.' + methodName + '` should accept a falsey `object`', function(assert) { 13725 assert.expect(1); 13726 13727 var expected = lodashStable.map(falsey, stubObject); 13728 13729 var actual = lodashStable.map(falsey, function(object, index) { 13730 try { 13731 return index ? func(object) : func(); 13732 } catch (e) {} 13733 }); 13734 13735 assert.deepEqual(actual, expected); 13736 }); 13737 13738 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) { 13739 assert.expect(1); 13740 13741 if (!isNpm) { 13742 assert.ok(_(object)[methodName](noop) instanceof _); 13743 } 13744 else { 13745 skipAssert(assert); 13746 } 13747 }); 13748 }); 13749 13750 QUnit.module('lodash.matches'); 13751 13752 (function() { 13753 QUnit.test('should not change behavior if `source` is modified', function(assert) { 13754 assert.expect(9); 13755 13756 var sources = [ 13757 { 'a': { 'b': 2, 'c': 3 } }, 13758 { 'a': 1, 'b': 2 }, 13759 { 'a': 1 } 13760 ]; 13761 13762 lodashStable.each(sources, function(source, index) { 13763 var object = lodashStable.cloneDeep(source), 13764 par = _.matches(source); 13765 13766 assert.strictEqual(par(object), true); 13767 13768 if (index) { 13769 source.a = 2; 13770 source.b = 1; 13771 source.c = 3; 13772 } else { 13773 source.a.b = 1; 13774 source.a.c = 2; 13775 source.a.d = 3; 13776 } 13777 assert.strictEqual(par(object), true); 13778 assert.strictEqual(par(source), false); 13779 }); 13780 }); 13781 }()); 13782 13783 /*--------------------------------------------------------------------------*/ 13784 13785 QUnit.module('matches methods'); 13786 13787 lodashStable.each(['matches', 'isMatch'], function(methodName) { 13788 var isMatches = methodName == 'matches'; 13789 13790 function matches(source) { 13791 return isMatches ? _.matches(source) : function(object) { 13792 return _.isMatch(object, source); 13793 }; 13794 } 13795 13796 QUnit.test('`_.' + methodName + '` should perform a deep comparison between `source` and `object`', function(assert) { 13797 assert.expect(5); 13798 13799 var object = { 'a': 1, 'b': 2, 'c': 3 }, 13800 par = matches({ 'a': 1 }); 13801 13802 assert.strictEqual(par(object), true); 13803 13804 par = matches({ 'b': 1 }); 13805 assert.strictEqual(par(object), false); 13806 13807 par = matches({ 'a': 1, 'c': 3 }); 13808 assert.strictEqual(par(object), true); 13809 13810 par = matches({ 'c': 3, 'd': 4 }); 13811 assert.strictEqual(par(object), false); 13812 13813 object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 }; 13814 par = matches({ 'a': { 'b': { 'c': 1 } } }); 13815 13816 assert.strictEqual(par(object), true); 13817 }); 13818 13819 QUnit.test('`_.' + methodName + '` should match inherited string keyed `object` properties', function(assert) { 13820 assert.expect(1); 13821 13822 function Foo() { 13823 this.a = 1; 13824 } 13825 Foo.prototype.b = 2; 13826 13827 var object = { 'a': new Foo }, 13828 par = matches({ 'a': { 'b': 2 } }); 13829 13830 assert.strictEqual(par(object), true); 13831 }); 13832 13833 QUnit.test('`_.' + methodName + '` should not match by inherited `source` properties', function(assert) { 13834 assert.expect(1); 13835 13836 function Foo() { 13837 this.a = 1; 13838 } 13839 Foo.prototype.b = 2; 13840 13841 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }], 13842 source = new Foo, 13843 actual = lodashStable.map(objects, matches(source)), 13844 expected = lodashStable.map(objects, stubTrue); 13845 13846 assert.deepEqual(actual, expected); 13847 }); 13848 13849 QUnit.test('`_.' + methodName + '` should compare a variety of `source` property values', function(assert) { 13850 assert.expect(2); 13851 13852 var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } }, 13853 object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } }, 13854 par = matches(object1); 13855 13856 assert.strictEqual(par(object1), true); 13857 assert.strictEqual(par(object2), false); 13858 }); 13859 13860 QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) { 13861 assert.expect(2); 13862 13863 var object1 = { 'a': -0 }, 13864 object2 = { 'a': 0 }, 13865 par = matches(object1); 13866 13867 assert.strictEqual(par(object2), true); 13868 13869 par = matches(object2); 13870 assert.strictEqual(par(object1), true); 13871 }); 13872 13873 QUnit.test('`_.' + methodName + '` should compare functions by reference', function(assert) { 13874 assert.expect(3); 13875 13876 var object1 = { 'a': lodashStable.noop }, 13877 object2 = { 'a': noop }, 13878 object3 = { 'a': {} }, 13879 par = matches(object1); 13880 13881 assert.strictEqual(par(object1), true); 13882 assert.strictEqual(par(object2), false); 13883 assert.strictEqual(par(object3), false); 13884 }); 13885 13886 QUnit.test('`_.' + methodName + '` should work with a function for `object`', function(assert) { 13887 assert.expect(1); 13888 13889 function Foo() {} 13890 Foo.a = { 'b': 2, 'c': 3 }; 13891 13892 var par = matches({ 'a': { 'b': 2 } }); 13893 assert.strictEqual(par(Foo), true); 13894 }); 13895 13896 QUnit.test('`_.' + methodName + '` should work with a function for `source`', function(assert) { 13897 assert.expect(1); 13898 13899 function Foo() {} 13900 Foo.a = 1; 13901 Foo.b = function() {}; 13902 Foo.c = 3; 13903 13904 var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }], 13905 actual = lodashStable.map(objects, matches(Foo)); 13906 13907 assert.deepEqual(actual, [false, true]); 13908 }); 13909 13910 QUnit.test('`_.' + methodName + '` should work with a non-plain `object`', function(assert) { 13911 assert.expect(1); 13912 13913 function Foo(object) { lodashStable.assign(this, object); } 13914 13915 var object = new Foo({ 'a': new Foo({ 'b': 2, 'c': 3 }) }), 13916 par = matches({ 'a': { 'b': 2 } }); 13917 13918 assert.strictEqual(par(object), true); 13919 }); 13920 13921 QUnit.test('`_.' + methodName + '` should partial match arrays', function(assert) { 13922 assert.expect(3); 13923 13924 var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }], 13925 actual = lodashStable.filter(objects, matches({ 'a': ['d'] })); 13926 13927 assert.deepEqual(actual, [objects[1]]); 13928 13929 actual = lodashStable.filter(objects, matches({ 'a': ['b', 'd'] })); 13930 assert.deepEqual(actual, []); 13931 13932 actual = lodashStable.filter(objects, matches({ 'a': ['d', 'b'] })); 13933 assert.deepEqual(actual, []); 13934 }); 13935 13936 QUnit.test('`_.' + methodName + '` should partial match arrays with duplicate values', function(assert) { 13937 assert.expect(1); 13938 13939 var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }], 13940 actual = lodashStable.filter(objects, matches({ 'a': [2, 2] })); 13941 13942 assert.deepEqual(actual, [objects[1]]); 13943 }); 13944 13945 QUnit.test('should partial match arrays of objects', function(assert) { 13946 assert.expect(1); 13947 13948 var objects = [ 13949 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] }, 13950 { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] } 13951 ]; 13952 13953 var actual = lodashStable.filter(objects, matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] })); 13954 assert.deepEqual(actual, [objects[0]]); 13955 }); 13956 13957 QUnit.test('`_.' + methodName + '` should partial match maps', function(assert) { 13958 assert.expect(3); 13959 13960 if (Map) { 13961 var objects = [{ 'a': new Map }, { 'a': new Map }]; 13962 objects[0].a.set('a', 1); 13963 objects[1].a.set('a', 1); 13964 objects[1].a.set('b', 2); 13965 13966 var map = new Map; 13967 map.set('b', 2); 13968 var actual = lodashStable.filter(objects, matches({ 'a': map })); 13969 13970 assert.deepEqual(actual, [objects[1]]); 13971 13972 map.delete('b'); 13973 actual = lodashStable.filter(objects, matches({ 'a': map })); 13974 13975 assert.deepEqual(actual, objects); 13976 13977 map.set('c', 3); 13978 actual = lodashStable.filter(objects, matches({ 'a': map })); 13979 13980 assert.deepEqual(actual, []); 13981 } 13982 else { 13983 skipAssert(assert, 3); 13984 } 13985 }); 13986 13987 QUnit.test('`_.' + methodName + '` should partial match sets', function(assert) { 13988 assert.expect(3); 13989 13990 if (Set) { 13991 var objects = [{ 'a': new Set }, { 'a': new Set }]; 13992 objects[0].a.add(1); 13993 objects[1].a.add(1); 13994 objects[1].a.add(2); 13995 13996 var set = new Set; 13997 set.add(2); 13998 var actual = lodashStable.filter(objects, matches({ 'a': set })); 13999 14000 assert.deepEqual(actual, [objects[1]]); 14001 14002 set.delete(2); 14003 actual = lodashStable.filter(objects, matches({ 'a': set })); 14004 14005 assert.deepEqual(actual, objects); 14006 14007 set.add(3); 14008 actual = lodashStable.filter(objects, matches({ 'a': set })); 14009 14010 assert.deepEqual(actual, []); 14011 } 14012 else { 14013 skipAssert(assert, 3); 14014 } 14015 }); 14016 14017 QUnit.test('`_.' + methodName + '` should match `undefined` values', function(assert) { 14018 assert.expect(3); 14019 14020 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }], 14021 actual = lodashStable.map(objects, matches({ 'b': undefined })), 14022 expected = [false, false, true]; 14023 14024 assert.deepEqual(actual, expected); 14025 14026 actual = lodashStable.map(objects, matches({ 'a': 1, 'b': undefined })); 14027 14028 assert.deepEqual(actual, expected); 14029 14030 objects = [{ 'a': { 'b': 2 } }, { 'a': { 'b': 2, 'c': 3 } }, { 'a': { 'b': 2, 'c': undefined } }]; 14031 actual = lodashStable.map(objects, matches({ 'a': { 'c': undefined } })); 14032 14033 assert.deepEqual(actual, expected); 14034 }); 14035 14036 QUnit.test('`_.' + methodName + '` should match `undefined` values on primitives', function(assert) { 14037 assert.expect(3); 14038 14039 numberProto.a = 1; 14040 numberProto.b = undefined; 14041 14042 try { 14043 var par = matches({ 'b': undefined }); 14044 assert.strictEqual(par(1), true); 14045 } catch (e) { 14046 assert.ok(false, e.message); 14047 } 14048 try { 14049 par = matches({ 'a': 1, 'b': undefined }); 14050 assert.strictEqual(par(1), true); 14051 } catch (e) { 14052 assert.ok(false, e.message); 14053 } 14054 numberProto.a = { 'b': 1, 'c': undefined }; 14055 try { 14056 par = matches({ 'a': { 'c': undefined } }); 14057 assert.strictEqual(par(1), true); 14058 } catch (e) { 14059 assert.ok(false, e.message); 14060 } 14061 delete numberProto.a; 14062 delete numberProto.b; 14063 }); 14064 14065 QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) { 14066 assert.expect(1); 14067 14068 var values = [, null, undefined], 14069 expected = lodashStable.map(values, stubFalse), 14070 par = matches({ 'a': 1 }); 14071 14072 var actual = lodashStable.map(values, function(value, index) { 14073 try { 14074 return index ? par(value) : par(); 14075 } catch (e) {} 14076 }); 14077 14078 assert.deepEqual(actual, expected); 14079 }); 14080 14081 QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source`', function(assert) { 14082 assert.expect(1); 14083 14084 var object = { 'a': 1 }, 14085 expected = lodashStable.map(empties, stubTrue); 14086 14087 var actual = lodashStable.map(empties, function(value) { 14088 var par = matches(value); 14089 return par(object); 14090 }); 14091 14092 assert.deepEqual(actual, expected); 14093 }); 14094 14095 QUnit.test('`_.' + methodName + '` should return `true` when comparing an empty `source` to a nullish `object`', function(assert) { 14096 assert.expect(1); 14097 14098 var values = [, null, undefined], 14099 expected = lodashStable.map(values, stubTrue), 14100 par = matches({}); 14101 14102 var actual = lodashStable.map(values, function(value, index) { 14103 try { 14104 return index ? par(value) : par(); 14105 } catch (e) {} 14106 }); 14107 14108 assert.deepEqual(actual, expected); 14109 }); 14110 14111 QUnit.test('`_.' + methodName + '` should return `true` when comparing a `source` of empty arrays and objects', function(assert) { 14112 assert.expect(1); 14113 14114 var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }], 14115 actual = lodashStable.filter(objects, matches({ 'a': [], 'b': {} })); 14116 14117 assert.deepEqual(actual, objects); 14118 }); 14119 }); 14120 14121 /*--------------------------------------------------------------------------*/ 14122 14123 QUnit.module('lodash.matchesProperty'); 14124 14125 (function() { 14126 QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) { 14127 assert.expect(6); 14128 14129 var object = { 'a': 1, 'b': 2, 'c': 3 }, 14130 matches = _.matchesProperty('a', 1); 14131 14132 assert.strictEqual(matches.length, 1); 14133 assert.strictEqual(matches(object), true); 14134 14135 matches = _.matchesProperty('b', 3); 14136 assert.strictEqual(matches(object), false); 14137 14138 matches = _.matchesProperty('a', { 'a': 1, 'c': 3 }); 14139 assert.strictEqual(matches({ 'a': object }), true); 14140 14141 matches = _.matchesProperty('a', { 'c': 3, 'd': 4 }); 14142 assert.strictEqual(matches(object), false); 14143 14144 object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 }; 14145 matches = _.matchesProperty('a', { 'b': { 'c': 1 } }); 14146 14147 assert.strictEqual(matches(object), true); 14148 }); 14149 14150 QUnit.test('should support deep paths', function(assert) { 14151 assert.expect(2); 14152 14153 var object = { 'a': { 'b': 2 } }; 14154 14155 lodashStable.each(['a.b', ['a', 'b']], function(path) { 14156 var matches = _.matchesProperty(path, 2); 14157 assert.strictEqual(matches(object), true); 14158 }); 14159 }); 14160 14161 QUnit.test('should work with a non-string `path`', function(assert) { 14162 assert.expect(2); 14163 14164 var array = [1, 2, 3]; 14165 14166 lodashStable.each([1, [1]], function(path) { 14167 var matches = _.matchesProperty(path, 2); 14168 assert.strictEqual(matches(array), true); 14169 }); 14170 }); 14171 14172 QUnit.test('should preserve the sign of `0`', function(assert) { 14173 assert.expect(1); 14174 14175 var object1 = { '-0': 'a' }, 14176 object2 = { '0': 'b' }, 14177 pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]], 14178 props = [-0, Object(-0), 0, Object(0)], 14179 values = ['a', 'a', 'b', 'b'], 14180 expected = lodashStable.map(props, lodashStable.constant([true, false])); 14181 14182 var actual = lodashStable.map(props, function(key, index) { 14183 var matches = _.matchesProperty(key, values[index]), 14184 pair = pairs[index]; 14185 14186 return [matches(pair[0]), matches(pair[1])]; 14187 }); 14188 14189 assert.deepEqual(actual, expected); 14190 }); 14191 14192 QUnit.test('should coerce `path` to a string', function(assert) { 14193 assert.expect(2); 14194 14195 function fn() {} 14196 fn.toString = lodashStable.constant('fn'); 14197 14198 var object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 }, 14199 paths = [null, undefined, fn, {}], 14200 expected = lodashStable.map(paths, stubTrue); 14201 14202 lodashStable.times(2, function(index) { 14203 var actual = lodashStable.map(paths, function(path) { 14204 var matches = _.matchesProperty(index ? [path] : path, object[path]); 14205 return matches(object); 14206 }); 14207 14208 assert.deepEqual(actual, expected); 14209 }); 14210 }); 14211 14212 QUnit.test('should match a key over a path', function(assert) { 14213 assert.expect(2); 14214 14215 var object = { 'a.b': 1, 'a': { 'b': 2 } }; 14216 14217 lodashStable.each(['a.b', ['a.b']], function(path) { 14218 var matches = _.matchesProperty(path, 1); 14219 assert.strictEqual(matches(object), true); 14220 }); 14221 }); 14222 14223 QUnit.test('should return `false` when `object` is nullish', function(assert) { 14224 assert.expect(2); 14225 14226 var values = [, null, undefined], 14227 expected = lodashStable.map(values, stubFalse); 14228 14229 lodashStable.each(['constructor', ['constructor']], function(path) { 14230 var matches = _.matchesProperty(path, 1); 14231 14232 var actual = lodashStable.map(values, function(value, index) { 14233 try { 14234 return index ? matches(value) : matches(); 14235 } catch (e) {} 14236 }); 14237 14238 assert.deepEqual(actual, expected); 14239 }); 14240 }); 14241 14242 QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) { 14243 assert.expect(2); 14244 14245 var values = [, null, undefined], 14246 expected = lodashStable.map(values, stubFalse); 14247 14248 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 14249 var matches = _.matchesProperty(path, 1); 14250 14251 var actual = lodashStable.map(values, function(value, index) { 14252 try { 14253 return index ? matches(value) : matches(); 14254 } catch (e) {} 14255 }); 14256 14257 assert.deepEqual(actual, expected); 14258 }); 14259 }); 14260 14261 QUnit.test('should return `false` if parts of `path` are missing', function(assert) { 14262 assert.expect(4); 14263 14264 var object = {}; 14265 14266 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) { 14267 var matches = _.matchesProperty(path, 1); 14268 assert.strictEqual(matches(object), false); 14269 }); 14270 }); 14271 14272 QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) { 14273 assert.expect(2); 14274 14275 function Foo() {} 14276 Foo.prototype.b = 2; 14277 14278 var object = { 'a': new Foo }; 14279 14280 lodashStable.each(['a', ['a']], function(path) { 14281 var matches = _.matchesProperty(path, { 'b': 2 }); 14282 assert.strictEqual(matches(object), true); 14283 }); 14284 }); 14285 14286 QUnit.test('should not match by inherited `srcValue` properties', function(assert) { 14287 assert.expect(2); 14288 14289 function Foo() { 14290 this.a = 1; 14291 } 14292 Foo.prototype.b = 2; 14293 14294 var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }], 14295 expected = lodashStable.map(objects, stubTrue); 14296 14297 lodashStable.each(['a', ['a']], function(path) { 14298 assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected); 14299 }); 14300 }); 14301 14302 QUnit.test('should compare a variety of values', function(assert) { 14303 assert.expect(2); 14304 14305 var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } }, 14306 object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } }, 14307 matches = _.matchesProperty('a', object1); 14308 14309 assert.strictEqual(matches({ 'a': object1 }), true); 14310 assert.strictEqual(matches({ 'a': object2 }), false); 14311 }); 14312 14313 QUnit.test('should match `-0` as `0`', function(assert) { 14314 assert.expect(2); 14315 14316 var matches = _.matchesProperty('a', -0); 14317 assert.strictEqual(matches({ 'a': 0 }), true); 14318 14319 matches = _.matchesProperty('a', 0); 14320 assert.strictEqual(matches({ 'a': -0 }), true); 14321 }); 14322 14323 QUnit.test('should compare functions by reference', function(assert) { 14324 assert.expect(3); 14325 14326 var object1 = { 'a': lodashStable.noop }, 14327 object2 = { 'a': noop }, 14328 object3 = { 'a': {} }, 14329 matches = _.matchesProperty('a', object1); 14330 14331 assert.strictEqual(matches({ 'a': object1 }), true); 14332 assert.strictEqual(matches({ 'a': object2 }), false); 14333 assert.strictEqual(matches({ 'a': object3 }), false); 14334 }); 14335 14336 QUnit.test('should work with a function for `srcValue`', function(assert) { 14337 assert.expect(1); 14338 14339 function Foo() {} 14340 Foo.a = 1; 14341 Foo.b = function() {}; 14342 Foo.c = 3; 14343 14344 var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }], 14345 actual = lodashStable.map(objects, _.matchesProperty('a', Foo)); 14346 14347 assert.deepEqual(actual, [false, true]); 14348 }); 14349 14350 QUnit.test('should work with a non-plain `srcValue`', function(assert) { 14351 assert.expect(1); 14352 14353 function Foo(object) { lodashStable.assign(this, object); } 14354 14355 var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }), 14356 matches = _.matchesProperty('a', { 'b': 1 }); 14357 14358 assert.strictEqual(matches(object), true); 14359 }); 14360 14361 QUnit.test('should partial match arrays', function(assert) { 14362 assert.expect(3); 14363 14364 var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }], 14365 actual = lodashStable.filter(objects, _.matchesProperty('a', ['d'])); 14366 14367 assert.deepEqual(actual, [objects[1]]); 14368 14369 actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd'])); 14370 assert.deepEqual(actual, []); 14371 14372 actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b'])); 14373 assert.deepEqual(actual, []); 14374 }); 14375 14376 QUnit.test('should partial match arrays with duplicate values', function(assert) { 14377 assert.expect(1); 14378 14379 var objects = [{ 'a': [1, 2] }, { 'a': [2, 2] }], 14380 actual = lodashStable.filter(objects, _.matchesProperty('a', [2, 2])); 14381 14382 assert.deepEqual(actual, [objects[1]]); 14383 }); 14384 14385 QUnit.test('should partial match arrays of objects', function(assert) { 14386 assert.expect(1); 14387 14388 var objects = [ 14389 { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] }, 14390 { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] } 14391 ]; 14392 14393 var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }])); 14394 assert.deepEqual(actual, [objects[0]]); 14395 }); 14396 QUnit.test('should partial match maps', function(assert) { 14397 assert.expect(3); 14398 14399 if (Map) { 14400 var objects = [{ 'a': new Map }, { 'a': new Map }]; 14401 objects[0].a.set('a', 1); 14402 objects[1].a.set('a', 1); 14403 objects[1].a.set('b', 2); 14404 14405 var map = new Map; 14406 map.set('b', 2); 14407 var actual = lodashStable.filter(objects, _.matchesProperty('a', map)); 14408 14409 assert.deepEqual(actual, [objects[1]]); 14410 14411 map.delete('b'); 14412 actual = lodashStable.filter(objects, _.matchesProperty('a', map)); 14413 14414 assert.deepEqual(actual, objects); 14415 14416 map.set('c', 3); 14417 actual = lodashStable.filter(objects, _.matchesProperty('a', map)); 14418 14419 assert.deepEqual(actual, []); 14420 } 14421 else { 14422 skipAssert(assert, 3); 14423 } 14424 }); 14425 14426 QUnit.test('should partial match sets', function(assert) { 14427 assert.expect(3); 14428 14429 if (Set) { 14430 var objects = [{ 'a': new Set }, { 'a': new Set }]; 14431 objects[0].a.add(1); 14432 objects[1].a.add(1); 14433 objects[1].a.add(2); 14434 14435 var set = new Set; 14436 set.add(2); 14437 var actual = lodashStable.filter(objects, _.matchesProperty('a', set)); 14438 14439 assert.deepEqual(actual, [objects[1]]); 14440 14441 set.delete(2); 14442 actual = lodashStable.filter(objects, _.matchesProperty('a', set)); 14443 14444 assert.deepEqual(actual, objects); 14445 14446 set.add(3); 14447 actual = lodashStable.filter(objects, _.matchesProperty('a', set)); 14448 14449 assert.deepEqual(actual, []); 14450 } 14451 else { 14452 skipAssert(assert, 3); 14453 } 14454 }); 14455 14456 QUnit.test('should match `undefined` values', function(assert) { 14457 assert.expect(2); 14458 14459 var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }], 14460 actual = lodashStable.map(objects, _.matchesProperty('b', undefined)), 14461 expected = [false, false, true]; 14462 14463 assert.deepEqual(actual, expected); 14464 14465 objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }]; 14466 actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined })); 14467 14468 assert.deepEqual(actual, expected); 14469 }); 14470 14471 QUnit.test('should match `undefined` values of nested objects', function(assert) { 14472 assert.expect(4); 14473 14474 var object = { 'a': { 'b': undefined } }; 14475 14476 lodashStable.each(['a.b', ['a', 'b']], function(path) { 14477 var matches = _.matchesProperty(path, undefined); 14478 assert.strictEqual(matches(object), true); 14479 }); 14480 14481 lodashStable.each(['a.a', ['a', 'a']], function(path) { 14482 var matches = _.matchesProperty(path, undefined); 14483 assert.strictEqual(matches(object), false); 14484 }); 14485 }); 14486 14487 QUnit.test('should match `undefined` values on primitives', function(assert) { 14488 assert.expect(2); 14489 14490 numberProto.a = 1; 14491 numberProto.b = undefined; 14492 14493 try { 14494 var matches = _.matchesProperty('b', undefined); 14495 assert.strictEqual(matches(1), true); 14496 } catch (e) { 14497 assert.ok(false, e.message); 14498 } 14499 numberProto.a = { 'b': 1, 'c': undefined }; 14500 try { 14501 matches = _.matchesProperty('a', { 'c': undefined }); 14502 assert.strictEqual(matches(1), true); 14503 } catch (e) { 14504 assert.ok(false, e.message); 14505 } 14506 delete numberProto.a; 14507 delete numberProto.b; 14508 }); 14509 14510 QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) { 14511 assert.expect(1); 14512 14513 var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }], 14514 matches = _.matchesProperty('a', { 'a': [], 'b': {} }); 14515 14516 var actual = lodashStable.filter(objects, function(object) { 14517 return matches({ 'a': object }); 14518 }); 14519 14520 assert.deepEqual(actual, objects); 14521 }); 14522 14523 QUnit.test('should not change behavior if `srcValue` is modified', function(assert) { 14524 assert.expect(9); 14525 14526 lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) { 14527 var object = lodashStable.cloneDeep(source), 14528 matches = _.matchesProperty('a', source); 14529 14530 assert.strictEqual(matches({ 'a': object }), true); 14531 14532 if (index) { 14533 source.a = 2; 14534 source.b = 1; 14535 source.c = 3; 14536 } else { 14537 source.a.b = 1; 14538 source.a.c = 2; 14539 source.a.d = 3; 14540 } 14541 assert.strictEqual(matches({ 'a': object }), true); 14542 assert.strictEqual(matches({ 'a': source }), false); 14543 }); 14544 }); 14545 }()); 14546 14547 /*--------------------------------------------------------------------------*/ 14548 14549 QUnit.module('lodash.max'); 14550 14551 (function() { 14552 QUnit.test('should return the largest value from a collection', function(assert) { 14553 assert.expect(1); 14554 14555 assert.strictEqual(_.max([1, 2, 3]), 3); 14556 }); 14557 14558 QUnit.test('should return `undefined` for empty collections', function(assert) { 14559 assert.expect(1); 14560 14561 var values = falsey.concat([[]]), 14562 expected = lodashStable.map(values, noop); 14563 14564 var actual = lodashStable.map(values, function(value, index) { 14565 try { 14566 return index ? _.max(value) : _.max(); 14567 } catch (e) {} 14568 }); 14569 14570 assert.deepEqual(actual, expected); 14571 }); 14572 14573 QUnit.test('should work with non-numeric collection values', function(assert) { 14574 assert.expect(1); 14575 14576 assert.strictEqual(_.max(['a', 'b']), 'b'); 14577 }); 14578 }()); 14579 14580 /*--------------------------------------------------------------------------*/ 14581 14582 QUnit.module('lodash.mean'); 14583 14584 (function() { 14585 QUnit.test('should return the mean of an array of numbers', function(assert) { 14586 assert.expect(1); 14587 14588 var array = [4, 2, 8, 6]; 14589 assert.strictEqual(_.mean(array), 5); 14590 }); 14591 14592 QUnit.test('should return `NaN` when passing empty `array` values', function(assert) { 14593 assert.expect(1); 14594 14595 var expected = lodashStable.map(empties, stubNaN), 14596 actual = lodashStable.map(empties, _.mean); 14597 14598 assert.deepEqual(actual, expected); 14599 }); 14600 }()); 14601 14602 /*--------------------------------------------------------------------------*/ 14603 14604 QUnit.module('lodash.meanBy'); 14605 14606 (function() { 14607 var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; 14608 14609 QUnit.test('should work with an `iteratee`', function(assert) { 14610 assert.expect(1); 14611 14612 var actual = _.meanBy(objects, function(object) { 14613 return object.a; 14614 }); 14615 14616 assert.deepEqual(actual, 2); 14617 }); 14618 14619 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 14620 assert.expect(1); 14621 14622 var args; 14623 14624 _.meanBy(objects, function() { 14625 args || (args = slice.call(arguments)); 14626 }); 14627 14628 assert.deepEqual(args, [{ 'a': 2 }]); 14629 }); 14630 14631 QUnit.test('should work with `_.property` shorthands', function(assert) { 14632 assert.expect(2); 14633 14634 var arrays = [[2], [3], [1]]; 14635 assert.strictEqual(_.meanBy(arrays, 0), 2); 14636 assert.strictEqual(_.meanBy(objects, 'a'), 2); 14637 }); 14638 }()); 14639 14640 /*--------------------------------------------------------------------------*/ 14641 14642 QUnit.module('lodash.memoize'); 14643 14644 (function() { 14645 function CustomCache() { 14646 this.clear(); 14647 } 14648 14649 CustomCache.prototype = { 14650 'clear': function() { 14651 this.__data__ = []; 14652 return this; 14653 }, 14654 'get': function(key) { 14655 var entry = lodashStable.find(this.__data__, ['key', key]); 14656 return entry && entry.value; 14657 }, 14658 'has': function(key) { 14659 return lodashStable.some(this.__data__, ['key', key]); 14660 }, 14661 'set': function(key, value) { 14662 this.__data__.push({ 'key': key, 'value': value }); 14663 return this; 14664 } 14665 }; 14666 14667 function ImmutableCache() { 14668 this.__data__ = []; 14669 } 14670 14671 ImmutableCache.prototype = lodashStable.create(CustomCache.prototype, { 14672 'constructor': ImmutableCache, 14673 'clear': function() { 14674 return new ImmutableCache; 14675 }, 14676 'set': function(key, value) { 14677 var result = new ImmutableCache; 14678 result.__data__ = this.__data__.concat({ 'key': key, 'value': value }); 14679 return result; 14680 } 14681 }); 14682 14683 QUnit.test('should memoize results based on the first argument given', function(assert) { 14684 assert.expect(2); 14685 14686 var memoized = _.memoize(function(a, b, c) { 14687 return a + b + c; 14688 }); 14689 14690 assert.strictEqual(memoized(1, 2, 3), 6); 14691 assert.strictEqual(memoized(1, 3, 5), 6); 14692 }); 14693 14694 QUnit.test('should support a `resolver`', function(assert) { 14695 assert.expect(2); 14696 14697 var fn = function(a, b, c) { return a + b + c; }, 14698 memoized = _.memoize(fn, fn); 14699 14700 assert.strictEqual(memoized(1, 2, 3), 6); 14701 assert.strictEqual(memoized(1, 3, 5), 9); 14702 }); 14703 14704 QUnit.test('should use `this` binding of function for `resolver`', function(assert) { 14705 assert.expect(2); 14706 14707 var fn = function(a, b, c) { return a + this.b + this.c; }, 14708 memoized = _.memoize(fn, fn); 14709 14710 var object = { 'memoized': memoized, 'b': 2, 'c': 3 }; 14711 assert.strictEqual(object.memoized(1), 6); 14712 14713 object.b = 3; 14714 object.c = 5; 14715 assert.strictEqual(object.memoized(1), 9); 14716 }); 14717 14718 QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) { 14719 assert.expect(1); 14720 14721 assert.raises(function() { _.memoize(noop, true); }, TypeError); 14722 }); 14723 14724 QUnit.test('should not error if `resolver` is nullish', function(assert) { 14725 assert.expect(1); 14726 14727 var values = [, null, undefined], 14728 expected = lodashStable.map(values, stubTrue); 14729 14730 var actual = lodashStable.map(values, function(resolver, index) { 14731 try { 14732 return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop)); 14733 } catch (e) {} 14734 }); 14735 14736 assert.deepEqual(actual, expected); 14737 }); 14738 14739 QUnit.test('should check cache for own properties', function(assert) { 14740 assert.expect(1); 14741 14742 var props = [ 14743 'constructor', 14744 'hasOwnProperty', 14745 'isPrototypeOf', 14746 'propertyIsEnumerable', 14747 'toLocaleString', 14748 'toString', 14749 'valueOf' 14750 ]; 14751 14752 var memoized = _.memoize(identity); 14753 14754 var actual = lodashStable.map(props, function(value) { 14755 return memoized(value); 14756 }); 14757 14758 assert.deepEqual(actual, props); 14759 }); 14760 14761 QUnit.test('should cache the `__proto__` key', function(assert) { 14762 assert.expect(8); 14763 14764 var array = [], 14765 key = '__proto__'; 14766 14767 lodashStable.times(2, function(index) { 14768 var count = 0, 14769 resolver = index ? identity : undefined; 14770 14771 var memoized = _.memoize(function() { 14772 count++; 14773 return array; 14774 }, resolver); 14775 14776 var cache = memoized.cache; 14777 14778 memoized(key); 14779 memoized(key); 14780 14781 assert.strictEqual(count, 1); 14782 assert.strictEqual(cache.get(key), array); 14783 assert.notOk(cache.__data__ instanceof Array); 14784 assert.strictEqual(cache.delete(key), true); 14785 }); 14786 }); 14787 14788 QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) { 14789 assert.expect(4); 14790 14791 var oldCache = _.memoize.Cache; 14792 _.memoize.Cache = CustomCache; 14793 14794 var memoized = _.memoize(function(object) { 14795 return object.id; 14796 }); 14797 14798 var cache = memoized.cache, 14799 key1 = { 'id': 'a' }, 14800 key2 = { 'id': 'b' }; 14801 14802 assert.strictEqual(memoized(key1), 'a'); 14803 assert.strictEqual(cache.has(key1), true); 14804 14805 assert.strictEqual(memoized(key2), 'b'); 14806 assert.strictEqual(cache.has(key2), true); 14807 14808 _.memoize.Cache = oldCache; 14809 }); 14810 14811 QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) { 14812 assert.expect(2); 14813 14814 var oldCache = _.memoize.Cache; 14815 _.memoize.Cache = ImmutableCache; 14816 14817 var memoized = _.memoize(function(object) { 14818 return object.id; 14819 }); 14820 14821 var key1 = { 'id': 'a' }, 14822 key2 = { 'id': 'b' }; 14823 14824 memoized(key1); 14825 memoized(key2); 14826 14827 var cache = memoized.cache; 14828 assert.strictEqual(cache.has(key1), true); 14829 assert.strictEqual(cache.has(key2), true); 14830 14831 _.memoize.Cache = oldCache; 14832 }); 14833 }()); 14834 14835 /*--------------------------------------------------------------------------*/ 14836 14837 QUnit.module('memoizeCapped'); 14838 14839 (function() { 14840 var func = _._memoizeCapped; 14841 14842 QUnit.test('should enforce a max cache size of `MAX_MEMOIZE_SIZE`', function(assert) { 14843 assert.expect(2); 14844 14845 if (func) { 14846 var memoized = func(identity), 14847 cache = memoized.cache; 14848 14849 lodashStable.times(MAX_MEMOIZE_SIZE, memoized); 14850 assert.strictEqual(cache.size, MAX_MEMOIZE_SIZE); 14851 14852 memoized(MAX_MEMOIZE_SIZE); 14853 assert.strictEqual(cache.size, 1); 14854 } 14855 else { 14856 skipAssert(assert, 2); 14857 } 14858 }); 14859 }()); 14860 14861 /*--------------------------------------------------------------------------*/ 14862 14863 QUnit.module('lodash.merge'); 14864 14865 (function() { 14866 QUnit.test('should merge `source` into `object`', function(assert) { 14867 assert.expect(1); 14868 14869 var names = { 14870 'characters': [ 14871 { 'name': 'barney' }, 14872 { 'name': 'fred' } 14873 ] 14874 }; 14875 14876 var ages = { 14877 'characters': [ 14878 { 'age': 36 }, 14879 { 'age': 40 } 14880 ] 14881 }; 14882 14883 var heights = { 14884 'characters': [ 14885 { 'height': '5\'4"' }, 14886 { 'height': '5\'5"' } 14887 ] 14888 }; 14889 14890 var expected = { 14891 'characters': [ 14892 { 'name': 'barney', 'age': 36, 'height': '5\'4"' }, 14893 { 'name': 'fred', 'age': 40, 'height': '5\'5"' } 14894 ] 14895 }; 14896 14897 assert.deepEqual(_.merge(names, ages, heights), expected); 14898 }); 14899 14900 QUnit.test('should merge sources containing circular references', function(assert) { 14901 assert.expect(2); 14902 14903 var object = { 14904 'foo': { 'a': 1 }, 14905 'bar': { 'a': 2 } 14906 }; 14907 14908 var source = { 14909 'foo': { 'b': { 'c': { 'd': {} } } }, 14910 'bar': {} 14911 }; 14912 14913 source.foo.b.c.d = source; 14914 source.bar.b = source.foo.b; 14915 14916 var actual = _.merge(object, source); 14917 14918 assert.notStrictEqual(actual.bar.b, actual.foo.b); 14919 assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d); 14920 }); 14921 14922 QUnit.test('should work with four arguments', function(assert) { 14923 assert.expect(1); 14924 14925 var expected = { 'a': 4 }, 14926 actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected); 14927 14928 assert.deepEqual(actual, expected); 14929 }); 14930 14931 QUnit.test('should merge onto function `object` values', function(assert) { 14932 assert.expect(2); 14933 14934 function Foo() {} 14935 14936 var source = { 'a': 1 }, 14937 actual = _.merge(Foo, source); 14938 14939 assert.strictEqual(actual, Foo); 14940 assert.strictEqual(Foo.a, 1); 14941 }); 14942 14943 QUnit.test('should merge first source object properties to function', function(assert) { 14944 assert.expect(1); 14945 14946 var fn = function() {}, 14947 object = { 'prop': {} }, 14948 actual = _.merge({ 'prop': fn }, object); 14949 14950 assert.deepEqual(actual, object); 14951 }); 14952 14953 QUnit.test('should merge first and second source object properties to function', function(assert) { 14954 assert.expect(1); 14955 14956 var fn = function() {}, 14957 object = { 'prop': {} }, 14958 actual = _.merge({ 'prop': fn }, { 'prop': fn }, object); 14959 14960 assert.deepEqual(actual, object); 14961 }); 14962 14963 QUnit.test('should not merge onto function values of sources', function(assert) { 14964 assert.expect(3); 14965 14966 var source1 = { 'a': function() {} }, 14967 source2 = { 'a': { 'b': 2 } }, 14968 expected = { 'a': { 'b': 2 } }, 14969 actual = _.merge({}, source1, source2); 14970 14971 assert.deepEqual(actual, expected); 14972 assert.notOk('b' in source1.a); 14973 14974 actual = _.merge(source1, source2); 14975 assert.deepEqual(actual, expected); 14976 }); 14977 14978 QUnit.test('should merge onto non-plain `object` values', function(assert) { 14979 assert.expect(2); 14980 14981 function Foo() {} 14982 14983 var object = new Foo, 14984 actual = _.merge(object, { 'a': 1 }); 14985 14986 assert.strictEqual(actual, object); 14987 assert.strictEqual(object.a, 1); 14988 }); 14989 14990 QUnit.test('should treat sparse array sources as dense', function(assert) { 14991 assert.expect(2); 14992 14993 var array = [1]; 14994 array[2] = 3; 14995 14996 var actual = _.merge([], array), 14997 expected = array.slice(); 14998 14999 expected[1] = undefined; 15000 15001 assert.ok('1' in actual); 15002 assert.deepEqual(actual, expected); 15003 }); 15004 15005 QUnit.test('should merge `arguments` objects', function(assert) { 15006 assert.expect(7); 15007 15008 var object1 = { 'value': args }, 15009 object2 = { 'value': { '3': 4 } }, 15010 expected = { '0': 1, '1': 2, '2': 3, '3': 4 }, 15011 actual = _.merge(object1, object2); 15012 15013 assert.notOk('3' in args); 15014 assert.notOk(_.isArguments(actual.value)); 15015 assert.deepEqual(actual.value, expected); 15016 object1.value = args; 15017 15018 actual = _.merge(object2, object1); 15019 assert.notOk(_.isArguments(actual.value)); 15020 assert.deepEqual(actual.value, expected); 15021 15022 expected = { '0': 1, '1': 2, '2': 3 }; 15023 15024 actual = _.merge({}, object1); 15025 assert.notOk(_.isArguments(actual.value)); 15026 assert.deepEqual(actual.value, expected); 15027 }); 15028 15029 QUnit.test('should merge typed arrays', function(assert) { 15030 assert.expect(4); 15031 15032 var array1 = [0], 15033 array2 = [0, 0], 15034 array3 = [0, 0, 0, 0], 15035 array4 = [0, 0, 0, 0, 0, 0, 0, 0]; 15036 15037 var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2], 15038 buffer = ArrayBuffer && new ArrayBuffer(8); 15039 15040 var expected = lodashStable.map(typedArrays, function(type, index) { 15041 var array = arrays[index].slice(); 15042 array[0] = 1; 15043 return root[type] ? { 'value': array } : false; 15044 }); 15045 15046 var actual = lodashStable.map(typedArrays, function(type) { 15047 var Ctor = root[type]; 15048 return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false; 15049 }); 15050 15051 assert.ok(lodashStable.isArray(actual)); 15052 assert.deepEqual(actual, expected); 15053 15054 expected = lodashStable.map(typedArrays, function(type, index) { 15055 var array = arrays[index].slice(); 15056 array.push(1); 15057 return root[type] ? { 'value': array } : false; 15058 }); 15059 15060 actual = lodashStable.map(typedArrays, function(type, index) { 15061 var Ctor = root[type], 15062 array = lodashStable.range(arrays[index].length); 15063 15064 array.push(1); 15065 return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false; 15066 }); 15067 15068 assert.ok(lodashStable.isArray(actual)); 15069 assert.deepEqual(actual, expected); 15070 }); 15071 15072 QUnit.test('should assign `null` values', function(assert) { 15073 assert.expect(1); 15074 15075 var actual = _.merge({ 'a': 1 }, { 'a': null }); 15076 assert.strictEqual(actual.a, null); 15077 }); 15078 15079 QUnit.test('should assign non array/buffer/typed-array/plain-object source values directly', function(assert) { 15080 assert.expect(1); 15081 15082 function Foo() {} 15083 15084 var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp], 15085 expected = lodashStable.map(values, stubTrue); 15086 15087 var actual = lodashStable.map(values, function(value) { 15088 var object = _.merge({}, { 'a': value, 'b': { 'c': value } }); 15089 return object.a === value && object.b.c === value; 15090 }); 15091 15092 assert.deepEqual(actual, expected); 15093 }); 15094 15095 QUnit.test('should clone buffer source values', function(assert) { 15096 assert.expect(3); 15097 15098 if (Buffer) { 15099 var buffer = new Buffer([1]), 15100 actual = _.merge({}, { 'value': buffer }).value; 15101 15102 assert.ok(lodashStable.isBuffer(actual)); 15103 assert.strictEqual(actual[0], buffer[0]); 15104 assert.notStrictEqual(actual, buffer); 15105 } 15106 else { 15107 skipAssert(assert, 3); 15108 } 15109 }); 15110 15111 QUnit.test('should deep clone array/typed-array/plain-object source values', function(assert) { 15112 assert.expect(1); 15113 15114 var typedArray = Uint8Array 15115 ? new Uint8Array([1]) 15116 : { 'buffer': [1] }; 15117 15118 var props = ['0', 'buffer', 'a'], 15119 values = [[{ 'a': 1 }], typedArray, { 'a': [1] }], 15120 expected = lodashStable.map(values, stubTrue); 15121 15122 var actual = lodashStable.map(values, function(value, index) { 15123 var key = props[index], 15124 object = _.merge({}, { 'value': value }), 15125 subValue = value[key], 15126 newValue = object.value, 15127 newSubValue = newValue[key]; 15128 15129 return ( 15130 newValue !== value && 15131 newSubValue !== subValue && 15132 lodashStable.isEqual(newValue, value) 15133 ); 15134 }); 15135 15136 assert.deepEqual(actual, expected); 15137 }); 15138 15139 QUnit.test('should not augment source objects', function(assert) { 15140 assert.expect(6); 15141 15142 var source1 = { 'a': [{ 'a': 1 }] }, 15143 source2 = { 'a': [{ 'b': 2 }] }, 15144 actual = _.merge({}, source1, source2); 15145 15146 assert.deepEqual(source1.a, [{ 'a': 1 }]); 15147 assert.deepEqual(source2.a, [{ 'b': 2 }]); 15148 assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]); 15149 15150 var source1 = { 'a': [[1, 2, 3]] }, 15151 source2 = { 'a': [[3, 4]] }, 15152 actual = _.merge({}, source1, source2); 15153 15154 assert.deepEqual(source1.a, [[1, 2, 3]]); 15155 assert.deepEqual(source2.a, [[3, 4]]); 15156 assert.deepEqual(actual.a, [[3, 4, 3]]); 15157 }); 15158 15159 QUnit.test('should merge plain objects onto non-plain objects', function(assert) { 15160 assert.expect(4); 15161 15162 function Foo(object) { 15163 lodashStable.assign(this, object); 15164 } 15165 15166 var object = { 'a': 1 }, 15167 actual = _.merge(new Foo, object); 15168 15169 assert.ok(actual instanceof Foo); 15170 assert.deepEqual(actual, new Foo(object)); 15171 15172 actual = _.merge([new Foo], [object]); 15173 assert.ok(actual[0] instanceof Foo); 15174 assert.deepEqual(actual, [new Foo(object)]); 15175 }); 15176 15177 QUnit.test('should not overwrite existing values with `undefined` values of object sources', function(assert) { 15178 assert.expect(1); 15179 15180 var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined }); 15181 assert.deepEqual(actual, { 'a': 1, 'b': undefined }); 15182 }); 15183 15184 QUnit.test('should not overwrite existing values with `undefined` values of array sources', function(assert) { 15185 assert.expect(2); 15186 15187 var array = [1]; 15188 array[2] = 3; 15189 15190 var actual = _.merge([4, 5, 6], array), 15191 expected = [1, 5, 3]; 15192 15193 assert.deepEqual(actual, expected); 15194 15195 array = [1, , 3]; 15196 array[1] = undefined; 15197 15198 actual = _.merge([4, 5, 6], array); 15199 assert.deepEqual(actual, expected); 15200 }); 15201 15202 QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) { 15203 assert.expect(1); 15204 15205 var object = {}, 15206 pass = true; 15207 15208 defineProperty(object, 'a', { 15209 'configurable': true, 15210 'enumerable': true, 15211 'get': function() { pass = false; }, 15212 'set': function() { pass = false; } 15213 }); 15214 15215 _.merge(object, object); 15216 assert.ok(pass); 15217 }); 15218 15219 QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) { 15220 assert.expect(2); 15221 15222 var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } }, 15223 actual = _.merge(object, { 'a': ['x'] }); 15224 15225 assert.deepEqual(actual, { 'a': ['x', 'y'] }); 15226 15227 actual = _.merge({ 'a': {} }, { 'a': [] }); 15228 assert.deepEqual(actual, { 'a': [] }); 15229 }); 15230 15231 QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) { 15232 assert.expect(1); 15233 15234 var object = { 'a': 'abcde' }, 15235 actual = _.merge(object, { 'a': ['x', 'y', 'z'] }); 15236 15237 assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] }); 15238 }); 15239 15240 QUnit.test('should not error on DOM elements', function(assert) { 15241 assert.expect(1); 15242 15243 var object1 = { 'el': document && document.createElement('div') }, 15244 object2 = { 'el': document && document.createElement('div') }, 15245 pairs = [[{}, object1], [object1, object2]], 15246 expected = lodashStable.map(pairs, stubTrue); 15247 15248 var actual = lodashStable.map(pairs, function(pair) { 15249 try { 15250 return _.merge(pair[0], pair[1]).el === pair[1].el; 15251 } catch (e) {} 15252 }); 15253 15254 assert.deepEqual(actual, expected); 15255 }); 15256 }()); 15257 15258 /*--------------------------------------------------------------------------*/ 15259 15260 QUnit.module('lodash.mergeWith'); 15261 15262 (function() { 15263 QUnit.test('should handle merging when `customizer` returns `undefined`', function(assert) { 15264 assert.expect(2); 15265 15266 var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop); 15267 assert.deepEqual(actual, { 'a': { 'b': [0, 1] } }); 15268 15269 actual = _.mergeWith([], [undefined], identity); 15270 assert.deepEqual(actual, [undefined]); 15271 }); 15272 15273 QUnit.test('should clone sources when `customizer` returns `undefined`', function(assert) { 15274 assert.expect(1); 15275 15276 var source1 = { 'a': { 'b': { 'c': 1 } } }, 15277 source2 = { 'a': { 'b': { 'd': 2 } } }; 15278 15279 _.mergeWith({}, source1, source2, noop); 15280 assert.deepEqual(source1.a.b, { 'c': 1 }); 15281 }); 15282 15283 QUnit.test('should defer to `customizer` for non `undefined` results', function(assert) { 15284 assert.expect(1); 15285 15286 var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) { 15287 return lodashStable.isArray(a) ? a.concat(b) : undefined; 15288 }); 15289 15290 assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } }); 15291 }); 15292 15293 QUnit.test('should provide `stack` to `customizer`', function(assert) { 15294 assert.expect(4); 15295 15296 var actual = []; 15297 15298 _.mergeWith({}, { 'z': 1, 'a': { 'b': 2 } }, function() { 15299 actual.push(_.last(arguments)); 15300 }); 15301 15302 assert.strictEqual(actual.length, 3); 15303 _.each(actual, function(a) { 15304 assert.ok(isNpm 15305 ? a.constructor.name == 'Stack' 15306 : a instanceof mapCaches.Stack 15307 ); 15308 }); 15309 }); 15310 15311 QUnit.test('should overwrite primitives with source object clones', function(assert) { 15312 assert.expect(1); 15313 15314 var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) { 15315 return lodashStable.isArray(a) ? a.concat(b) : undefined; 15316 }); 15317 15318 assert.deepEqual(actual, { 'a': { 'b': ['c'] } }); 15319 }); 15320 15321 QUnit.test('should pop the stack of sources for each sibling property', function(assert) { 15322 assert.expect(1); 15323 15324 var array = ['b', 'c'], 15325 object = { 'a': ['a'] }, 15326 source = { 'a': array, 'b': array }; 15327 15328 var actual = _.mergeWith(object, source, function(a, b) { 15329 return lodashStable.isArray(a) ? a.concat(b) : undefined; 15330 }); 15331 15332 assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] }); 15333 }); 15334 }()); 15335 15336 /*--------------------------------------------------------------------------*/ 15337 15338 QUnit.module('lodash.method'); 15339 15340 (function() { 15341 QUnit.test('should create a function that calls a method of a given object', function(assert) { 15342 assert.expect(4); 15343 15344 var object = { 'a': stubOne }; 15345 15346 lodashStable.each(['a', ['a']], function(path) { 15347 var method = _.method(path); 15348 assert.strictEqual(method.length, 1); 15349 assert.strictEqual(method(object), 1); 15350 }); 15351 }); 15352 15353 QUnit.test('should work with deep property values', function(assert) { 15354 assert.expect(2); 15355 15356 var object = { 'a': { 'b': stubTwo } }; 15357 15358 lodashStable.each(['a.b', ['a', 'b']], function(path) { 15359 var method = _.method(path); 15360 assert.strictEqual(method(object), 2); 15361 }); 15362 }); 15363 15364 QUnit.test('should work with a non-string `path`', function(assert) { 15365 assert.expect(2); 15366 15367 var array = lodashStable.times(3, _.constant); 15368 15369 lodashStable.each([1, [1]], function(path) { 15370 var method = _.method(path); 15371 assert.strictEqual(method(array), 1); 15372 }); 15373 }); 15374 15375 QUnit.test('should coerce `path` to a string', function(assert) { 15376 assert.expect(2); 15377 15378 function fn() {} 15379 fn.toString = lodashStable.constant('fn'); 15380 15381 var expected = [1, 2, 3, 4], 15382 object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour }, 15383 paths = [null, undefined, fn, {}]; 15384 15385 lodashStable.times(2, function(index) { 15386 var actual = lodashStable.map(paths, function(path) { 15387 var method = _.method(index ? [path] : path); 15388 return method(object); 15389 }); 15390 15391 assert.deepEqual(actual, expected); 15392 }); 15393 }); 15394 15395 QUnit.test('should work with inherited property values', function(assert) { 15396 assert.expect(2); 15397 15398 function Foo() {} 15399 Foo.prototype.a = stubOne; 15400 15401 lodashStable.each(['a', ['a']], function(path) { 15402 var method = _.method(path); 15403 assert.strictEqual(method(new Foo), 1); 15404 }); 15405 }); 15406 15407 QUnit.test('should use a key over a path', function(assert) { 15408 assert.expect(2); 15409 15410 var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } }; 15411 15412 lodashStable.each(['a.b', ['a.b']], function(path) { 15413 var method = _.method(path); 15414 assert.strictEqual(method(object), 1); 15415 }); 15416 }); 15417 15418 QUnit.test('should return `undefined` when `object` is nullish', function(assert) { 15419 assert.expect(2); 15420 15421 var values = [, null, undefined], 15422 expected = lodashStable.map(values, noop); 15423 15424 lodashStable.each(['constructor', ['constructor']], function(path) { 15425 var method = _.method(path); 15426 15427 var actual = lodashStable.map(values, function(value, index) { 15428 return index ? method(value) : method(); 15429 }); 15430 15431 assert.deepEqual(actual, expected); 15432 }); 15433 }); 15434 15435 QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) { 15436 assert.expect(2); 15437 15438 var values = [, null, undefined], 15439 expected = lodashStable.map(values, noop); 15440 15441 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 15442 var method = _.method(path); 15443 15444 var actual = lodashStable.map(values, function(value, index) { 15445 return index ? method(value) : method(); 15446 }); 15447 15448 assert.deepEqual(actual, expected); 15449 }); 15450 }); 15451 15452 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) { 15453 assert.expect(4); 15454 15455 var object = {}; 15456 15457 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) { 15458 var method = _.method(path); 15459 assert.strictEqual(method(object), undefined); 15460 }); 15461 }); 15462 15463 QUnit.test('should apply partial arguments to function', function(assert) { 15464 assert.expect(2); 15465 15466 var object = { 15467 'fn': function() { 15468 return slice.call(arguments); 15469 } 15470 }; 15471 15472 lodashStable.each(['fn', ['fn']], function(path) { 15473 var method = _.method(path, 1, 2, 3); 15474 assert.deepEqual(method(object), [1, 2, 3]); 15475 }); 15476 }); 15477 15478 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) { 15479 assert.expect(2); 15480 15481 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } }; 15482 15483 lodashStable.each(['a.b', ['a', 'b']], function(path) { 15484 var method = _.method(path); 15485 assert.strictEqual(method(object), 1); 15486 }); 15487 }); 15488 }()); 15489 15490 /*--------------------------------------------------------------------------*/ 15491 15492 QUnit.module('lodash.methodOf'); 15493 15494 (function() { 15495 QUnit.test('should create a function that calls a method of a given key', function(assert) { 15496 assert.expect(4); 15497 15498 var object = { 'a': stubOne }; 15499 15500 lodashStable.each(['a', ['a']], function(path) { 15501 var methodOf = _.methodOf(object); 15502 assert.strictEqual(methodOf.length, 1); 15503 assert.strictEqual(methodOf(path), 1); 15504 }); 15505 }); 15506 15507 QUnit.test('should work with deep property values', function(assert) { 15508 assert.expect(2); 15509 15510 var object = { 'a': { 'b': stubTwo } }; 15511 15512 lodashStable.each(['a.b', ['a', 'b']], function(path) { 15513 var methodOf = _.methodOf(object); 15514 assert.strictEqual(methodOf(path), 2); 15515 }); 15516 }); 15517 15518 QUnit.test('should work with a non-string `path`', function(assert) { 15519 assert.expect(2); 15520 15521 var array = lodashStable.times(3, _.constant); 15522 15523 lodashStable.each([1, [1]], function(path) { 15524 var methodOf = _.methodOf(array); 15525 assert.strictEqual(methodOf(path), 1); 15526 }); 15527 }); 15528 15529 QUnit.test('should coerce `path` to a string', function(assert) { 15530 assert.expect(2); 15531 15532 function fn() {} 15533 fn.toString = lodashStable.constant('fn'); 15534 15535 var expected = [1, 2, 3, 4], 15536 object = { 'null': stubOne, 'undefined': stubTwo, 'fn': stubThree, '[object Object]': stubFour }, 15537 paths = [null, undefined, fn, {}]; 15538 15539 lodashStable.times(2, function(index) { 15540 var actual = lodashStable.map(paths, function(path) { 15541 var methodOf = _.methodOf(object); 15542 return methodOf(index ? [path] : path); 15543 }); 15544 15545 assert.deepEqual(actual, expected); 15546 }); 15547 }); 15548 15549 QUnit.test('should work with inherited property values', function(assert) { 15550 assert.expect(2); 15551 15552 function Foo() {} 15553 Foo.prototype.a = stubOne; 15554 15555 lodashStable.each(['a', ['a']], function(path) { 15556 var methodOf = _.methodOf(new Foo); 15557 assert.strictEqual(methodOf(path), 1); 15558 }); 15559 }); 15560 15561 QUnit.test('should use a key over a path', function(assert) { 15562 assert.expect(2); 15563 15564 var object = { 'a.b': stubOne, 'a': { 'b': stubTwo } }; 15565 15566 lodashStable.each(['a.b', ['a.b']], function(path) { 15567 var methodOf = _.methodOf(object); 15568 assert.strictEqual(methodOf(path), 1); 15569 }); 15570 }); 15571 15572 QUnit.test('should return `undefined` when `object` is nullish', function(assert) { 15573 assert.expect(2); 15574 15575 var values = [, null, undefined], 15576 expected = lodashStable.map(values, noop); 15577 15578 lodashStable.each(['constructor', ['constructor']], function(path) { 15579 var actual = lodashStable.map(values, function(value, index) { 15580 var methodOf = index ? _.methodOf() : _.methodOf(value); 15581 return methodOf(path); 15582 }); 15583 15584 assert.deepEqual(actual, expected); 15585 }); 15586 }); 15587 15588 QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) { 15589 assert.expect(2); 15590 15591 var values = [, null, undefined], 15592 expected = lodashStable.map(values, noop); 15593 15594 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 15595 var actual = lodashStable.map(values, function(value, index) { 15596 var methodOf = index ? _.methodOf() : _.methodOf(value); 15597 return methodOf(path); 15598 }); 15599 15600 assert.deepEqual(actual, expected); 15601 }); 15602 }); 15603 15604 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) { 15605 assert.expect(4); 15606 15607 var object = {}, 15608 methodOf = _.methodOf(object); 15609 15610 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) { 15611 assert.strictEqual(methodOf(path), undefined); 15612 }); 15613 }); 15614 15615 QUnit.test('should apply partial arguments to function', function(assert) { 15616 assert.expect(2); 15617 15618 var object = { 15619 'fn': function() { 15620 return slice.call(arguments); 15621 } 15622 }; 15623 15624 var methodOf = _.methodOf(object, 1, 2, 3); 15625 15626 lodashStable.each(['fn', ['fn']], function(path) { 15627 assert.deepEqual(methodOf(path), [1, 2, 3]); 15628 }); 15629 }); 15630 15631 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) { 15632 assert.expect(2); 15633 15634 var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } }, 15635 methodOf = _.methodOf(object); 15636 15637 lodashStable.each(['a.b', ['a', 'b']], function(path) { 15638 assert.strictEqual(methodOf(path), 1); 15639 }); 15640 }); 15641 }()); 15642 15643 /*--------------------------------------------------------------------------*/ 15644 15645 QUnit.module('lodash.min'); 15646 15647 (function() { 15648 QUnit.test('should return the smallest value from a collection', function(assert) { 15649 assert.expect(1); 15650 15651 assert.strictEqual(_.min([1, 2, 3]), 1); 15652 }); 15653 15654 QUnit.test('should return `undefined` for empty collections', function(assert) { 15655 assert.expect(1); 15656 15657 var values = falsey.concat([[]]), 15658 expected = lodashStable.map(values, noop); 15659 15660 var actual = lodashStable.map(values, function(value, index) { 15661 try { 15662 return index ? _.min(value) : _.min(); 15663 } catch (e) {} 15664 }); 15665 15666 assert.deepEqual(actual, expected); 15667 }); 15668 15669 QUnit.test('should work with non-numeric collection values', function(assert) { 15670 assert.expect(1); 15671 15672 assert.strictEqual(_.min(['a', 'b']), 'a'); 15673 }); 15674 }()); 15675 15676 /*--------------------------------------------------------------------------*/ 15677 15678 QUnit.module('extremum methods'); 15679 15680 lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) { 15681 var func = _[methodName], 15682 isMax = /^max/.test(methodName); 15683 15684 QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) { 15685 assert.expect(1); 15686 15687 var curr = new Date, 15688 past = new Date(0); 15689 15690 assert.strictEqual(func([curr, past]), isMax ? curr : past); 15691 }); 15692 15693 QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) { 15694 assert.expect(1); 15695 15696 var array = lodashStable.range(0, 5e5); 15697 assert.strictEqual(func(array), isMax ? 499999 : 0); 15698 }); 15699 15700 QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) { 15701 assert.expect(1); 15702 15703 if (!isNpm) { 15704 var actual = _([40])[methodName](); 15705 assert.strictEqual(actual, 40); 15706 } 15707 else { 15708 skipAssert(assert); 15709 } 15710 }); 15711 }); 15712 15713 lodashStable.each(['maxBy', 'minBy'], function(methodName) { 15714 var array = [1, 2, 3], 15715 func = _[methodName], 15716 isMax = methodName == 'maxBy'; 15717 15718 QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) { 15719 assert.expect(1); 15720 15721 var actual = func(array, function(n) { 15722 return -n; 15723 }); 15724 15725 assert.strictEqual(actual, isMax ? 1 : 3); 15726 }); 15727 15728 QUnit.test('should work with `_.property` shorthands', function(assert) { 15729 assert.expect(2); 15730 15731 var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }], 15732 actual = func(objects, 'a'); 15733 15734 assert.deepEqual(actual, objects[isMax ? 1 : 2]); 15735 15736 var arrays = [[2], [3], [1]]; 15737 actual = func(arrays, 0); 15738 15739 assert.deepEqual(actual, arrays[isMax ? 1 : 2]); 15740 }); 15741 15742 QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) { 15743 assert.expect(1); 15744 15745 var value = isMax ? -Infinity : Infinity, 15746 object = { 'a': value }; 15747 15748 var actual = func([object, { 'a': value }], function(object) { 15749 return object.a; 15750 }); 15751 15752 assert.strictEqual(actual, object); 15753 }); 15754 }); 15755 15756 /*--------------------------------------------------------------------------*/ 15757 15758 QUnit.module('lodash.mixin'); 15759 15760 (function() { 15761 function reset(wrapper) { 15762 delete wrapper.a; 15763 delete wrapper.prototype.a; 15764 delete wrapper.b; 15765 delete wrapper.prototype.b; 15766 } 15767 15768 function Wrapper(value) { 15769 if (!(this instanceof Wrapper)) { 15770 return new Wrapper(value); 15771 } 15772 if (_.has(value, '__wrapped__')) { 15773 var actions = slice.call(value.__actions__), 15774 chain = value.__chain__; 15775 15776 value = value.__wrapped__; 15777 } 15778 this.__wrapped__ = value; 15779 this.__actions__ = actions || []; 15780 this.__chain__ = chain || false; 15781 } 15782 15783 Wrapper.prototype.value = function() { 15784 return getUnwrappedValue(this); 15785 }; 15786 15787 var array = ['a'], 15788 source = { 'a': function(array) { return array[0]; }, 'b': 'B' }; 15789 15790 QUnit.test('should mixin `source` methods into lodash', function(assert) { 15791 assert.expect(4); 15792 15793 if (!isNpm) { 15794 _.mixin(source); 15795 15796 assert.strictEqual(_.a(array), 'a'); 15797 assert.strictEqual(_(array).a().value(), 'a'); 15798 assert.notOk('b' in _); 15799 assert.notOk('b' in _.prototype); 15800 15801 reset(_); 15802 } 15803 else { 15804 skipAssert(assert, 4); 15805 } 15806 }); 15807 15808 QUnit.test('should mixin chaining methods by reference', function(assert) { 15809 assert.expect(2); 15810 15811 if (!isNpm) { 15812 _.mixin(source); 15813 _.a = stubB; 15814 15815 assert.strictEqual(_.a(array), 'b'); 15816 assert.strictEqual(_(array).a().value(), 'a'); 15817 15818 reset(_); 15819 } 15820 else { 15821 skipAssert(assert, 2); 15822 } 15823 }); 15824 15825 QUnit.test('should use a default `object` of `this`', function(assert) { 15826 assert.expect(3); 15827 15828 var object = lodashStable.create(_); 15829 object.mixin(source); 15830 15831 assert.strictEqual(object.a(array), 'a'); 15832 assert.notOk('a' in _); 15833 assert.notOk('a' in _.prototype); 15834 15835 reset(_); 15836 }); 15837 15838 QUnit.test('should accept an `object`', function(assert) { 15839 assert.expect(1); 15840 15841 var object = {}; 15842 _.mixin(object, source); 15843 assert.strictEqual(object.a(array), 'a'); 15844 }); 15845 15846 QUnit.test('should accept a function `object`', function(assert) { 15847 assert.expect(2); 15848 15849 _.mixin(Wrapper, source); 15850 15851 var wrapped = Wrapper(array), 15852 actual = wrapped.a(); 15853 15854 assert.strictEqual(actual.value(), 'a'); 15855 assert.ok(actual instanceof Wrapper); 15856 15857 reset(Wrapper); 15858 }); 15859 15860 QUnit.test('should return `object`', function(assert) { 15861 assert.expect(3); 15862 15863 var object = {}; 15864 assert.strictEqual(_.mixin(object, source), object); 15865 assert.strictEqual(_.mixin(Wrapper, source), Wrapper); 15866 assert.strictEqual(_.mixin(), _); 15867 15868 reset(Wrapper); 15869 }); 15870 15871 QUnit.test('should not assign inherited `source` methods', function(assert) { 15872 assert.expect(1); 15873 15874 function Foo() {} 15875 Foo.prototype.a = noop; 15876 15877 var object = {}; 15878 assert.strictEqual(_.mixin(object, new Foo), object); 15879 }); 15880 15881 QUnit.test('should accept an `options`', function(assert) { 15882 assert.expect(8); 15883 15884 function message(func, chain) { 15885 return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain'; 15886 } 15887 15888 lodashStable.each([_, Wrapper], function(func) { 15889 lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) { 15890 if (!isNpm) { 15891 if (func === _) { 15892 _.mixin(source, options); 15893 } else { 15894 _.mixin(func, source, options); 15895 } 15896 var wrapped = func(array), 15897 actual = wrapped.a(); 15898 15899 if (options.chain) { 15900 assert.strictEqual(actual.value(), 'a', message(func, true)); 15901 assert.ok(actual instanceof func, message(func, true)); 15902 } else { 15903 assert.strictEqual(actual, 'a', message(func, false)); 15904 assert.notOk(actual instanceof func, message(func, false)); 15905 } 15906 reset(func); 15907 } 15908 else { 15909 skipAssert(assert, 2); 15910 } 15911 }); 15912 }); 15913 }); 15914 15915 QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) { 15916 assert.expect(1); 15917 15918 _.mixin({ 'a': noop }, {}); 15919 assert.notOk('a' in _); 15920 reset(_); 15921 }); 15922 15923 QUnit.test('should not error for non-object `options` values', function(assert) { 15924 assert.expect(2); 15925 15926 var pass = true; 15927 15928 try { 15929 _.mixin({}, source, 1); 15930 } catch (e) { 15931 pass = false; 15932 } 15933 assert.ok(pass); 15934 15935 pass = true; 15936 15937 try { 15938 _.mixin(source, 1); 15939 } catch (e) { 15940 pass = false; 15941 } 15942 assert.ok(pass); 15943 15944 reset(_); 15945 }); 15946 15947 QUnit.test('should not return the existing wrapped value when chaining', function(assert) { 15948 assert.expect(2); 15949 15950 lodashStable.each([_, Wrapper], function(func) { 15951 if (!isNpm) { 15952 if (func === _) { 15953 var wrapped = _(source), 15954 actual = wrapped.mixin(); 15955 15956 assert.strictEqual(actual.value(), _); 15957 } 15958 else { 15959 wrapped = _(func); 15960 actual = wrapped.mixin(source); 15961 assert.notStrictEqual(actual, wrapped); 15962 } 15963 reset(func); 15964 } 15965 else { 15966 skipAssert(assert); 15967 } 15968 }); 15969 }); 15970 15971 QUnit.test('should produce methods that work in a lazy sequence', function(assert) { 15972 assert.expect(1); 15973 15974 if (!isNpm) { 15975 _.mixin({ 'a': _.countBy, 'b': _.filter }); 15976 15977 var array = lodashStable.range(LARGE_ARRAY_SIZE), 15978 actual = _(array).a().map(square).b(isEven).take().value(); 15979 15980 assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven))); 15981 15982 reset(_); 15983 } 15984 else { 15985 skipAssert(assert); 15986 } 15987 }); 15988 }()); 15989 15990 /*--------------------------------------------------------------------------*/ 15991 15992 QUnit.module('lodash.multiply'); 15993 15994 (function() { 15995 QUnit.test('should multiply two numbers', function(assert) { 15996 assert.expect(3); 15997 15998 assert.strictEqual(_.multiply(6, 4), 24); 15999 assert.strictEqual(_.multiply(-6, 4), -24); 16000 assert.strictEqual(_.multiply(-6, -4), 24); 16001 }); 16002 16003 QUnit.test('should coerce arguments to numbers', function(assert) { 16004 assert.expect(2); 16005 16006 assert.strictEqual(_.multiply('6', '4'), 24); 16007 assert.deepEqual(_.multiply('x', 'y'), NaN); 16008 }); 16009 }()); 16010 16011 /*--------------------------------------------------------------------------*/ 16012 16013 QUnit.module('lodash.orderBy'); 16014 16015 (function() { 16016 var objects = [ 16017 { 'a': 'x', 'b': 3 }, 16018 { 'a': 'y', 'b': 4 }, 16019 { 'a': 'x', 'b': 1 }, 16020 { 'a': 'y', 'b': 2 } 16021 ]; 16022 16023 QUnit.test('should sort by a single property by a specified order', function(assert) { 16024 assert.expect(1); 16025 16026 var actual = _.orderBy(objects, 'a', 'desc'); 16027 assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]); 16028 }); 16029 16030 QUnit.test('should sort by multiple properties by specified orders', function(assert) { 16031 assert.expect(1); 16032 16033 var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']); 16034 assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]); 16035 }); 16036 16037 QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) { 16038 assert.expect(2); 16039 16040 var expected = [objects[2], objects[0], objects[3], objects[1]], 16041 actual = _.orderBy(objects, ['a', 'b']); 16042 16043 assert.deepEqual(actual, expected); 16044 16045 expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]])); 16046 16047 actual = lodashStable.map(falsey, function(order, index) { 16048 return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']); 16049 }); 16050 16051 assert.deepEqual(actual, expected); 16052 }); 16053 16054 QUnit.test('should work with `orders` specified as string objects', function(assert) { 16055 assert.expect(1); 16056 16057 var actual = _.orderBy(objects, ['a'], [Object('desc')]); 16058 assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]); 16059 }); 16060 }()); 16061 16062 /*--------------------------------------------------------------------------*/ 16063 16064 QUnit.module('lodash.overArgs'); 16065 16066 (function() { 16067 function fn() { 16068 return slice.call(arguments); 16069 } 16070 16071 QUnit.test('should transform each argument', function(assert) { 16072 assert.expect(1); 16073 16074 var over = _.overArgs(fn, doubled, square); 16075 assert.deepEqual(over(5, 10), [10, 100]); 16076 }); 16077 16078 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) { 16079 assert.expect(1); 16080 16081 var over = _.overArgs(fn, undefined, null); 16082 assert.deepEqual(over('a', 'b'), ['a', 'b']); 16083 }); 16084 16085 QUnit.test('should work with `_.property` shorthands', function(assert) { 16086 assert.expect(1); 16087 16088 var over = _.overArgs(fn, 'b', 'a'); 16089 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]); 16090 }); 16091 16092 QUnit.test('should work with `_.matches` shorthands', function(assert) { 16093 assert.expect(1); 16094 16095 var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 }); 16096 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]); 16097 }); 16098 16099 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 16100 assert.expect(1); 16101 16102 var over = _.overArgs(fn, [['b', 1], ['a', 1]]); 16103 assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]); 16104 }); 16105 16106 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) { 16107 assert.expect(2); 16108 16109 var over = _.overArgs(fn, ['a', 1]); 16110 assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]); 16111 16112 over = _.overArgs(fn, [['a', 1]]); 16113 assert.deepEqual(over({ 'a': 1 }), [true]); 16114 }); 16115 16116 QUnit.test('should flatten `transforms`', function(assert) { 16117 assert.expect(1); 16118 16119 var over = _.overArgs(fn, [doubled, square], String); 16120 assert.deepEqual(over(5, 10, 15), [10, 100, '15']); 16121 }); 16122 16123 QUnit.test('should not transform any argument greater than the number of transforms', function(assert) { 16124 assert.expect(1); 16125 16126 var over = _.overArgs(fn, doubled, square); 16127 assert.deepEqual(over(5, 10, 18), [10, 100, 18]); 16128 }); 16129 16130 QUnit.test('should not transform any arguments if no transforms are given', function(assert) { 16131 assert.expect(1); 16132 16133 var over = _.overArgs(fn); 16134 assert.deepEqual(over(5, 10, 18), [5, 10, 18]); 16135 }); 16136 16137 QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) { 16138 assert.expect(1); 16139 16140 var over = _.overArgs(fn, doubled, identity); 16141 assert.deepEqual(over(5), [10]); 16142 }); 16143 16144 QUnit.test('should provide the correct argument to each transform', function(assert) { 16145 assert.expect(1); 16146 16147 var argsList = [], 16148 transform = function() { argsList.push(slice.call(arguments)); }, 16149 over = _.overArgs(noop, transform, transform, transform); 16150 16151 over('a', 'b'); 16152 assert.deepEqual(argsList, [['a'], ['b']]); 16153 }); 16154 16155 QUnit.test('should use `this` binding of function for `transforms`', function(assert) { 16156 assert.expect(1); 16157 16158 var over = _.overArgs(function(x) { 16159 return this[x]; 16160 }, function(x) { 16161 return this === x; 16162 }); 16163 16164 var object = { 'over': over, 'true': 1 }; 16165 assert.strictEqual(object.over(object), 1); 16166 }); 16167 }()); 16168 16169 /*--------------------------------------------------------------------------*/ 16170 16171 QUnit.module('lodash.negate'); 16172 16173 (function() { 16174 QUnit.test('should create a function that negates the result of `func`', function(assert) { 16175 assert.expect(2); 16176 16177 var negate = _.negate(isEven); 16178 16179 assert.strictEqual(negate(1), true); 16180 assert.strictEqual(negate(2), false); 16181 }); 16182 16183 QUnit.test('should create a function that negates the result of `func`', function(assert) { 16184 assert.expect(2); 16185 16186 var negate = _.negate(isEven); 16187 16188 assert.strictEqual(negate(1), true); 16189 assert.strictEqual(negate(2), false); 16190 }); 16191 16192 QUnit.test('should create a function that accepts multiple arguments', function(assert) { 16193 assert.expect(1); 16194 16195 var argCount, 16196 count = 5, 16197 negate = _.negate(function() { argCount = arguments.length; }), 16198 expected = lodashStable.times(count, stubTrue); 16199 16200 var actual = lodashStable.times(count, function(index) { 16201 switch (index) { 16202 case 0: negate(); break; 16203 case 1: negate(1); break; 16204 case 2: negate(1, 2); break; 16205 case 3: negate(1, 2, 3); break; 16206 case 4: negate(1, 2, 3, 4); 16207 } 16208 return argCount == index; 16209 }); 16210 16211 assert.deepEqual(actual, expected); 16212 }); 16213 }()); 16214 16215 /*--------------------------------------------------------------------------*/ 16216 16217 QUnit.module('lodash.noConflict'); 16218 16219 (function() { 16220 QUnit.test('should return the `lodash` function', function(assert) { 16221 assert.expect(2); 16222 16223 if (!isModularize) { 16224 assert.strictEqual(_.noConflict(), oldDash); 16225 assert.notStrictEqual(root._, oldDash); 16226 root._ = oldDash; 16227 } 16228 else { 16229 skipAssert(assert, 2); 16230 } 16231 }); 16232 16233 QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) { 16234 assert.expect(2); 16235 16236 if (!isModularize) { 16237 var object = root._ = {}; 16238 assert.strictEqual(_.noConflict(), oldDash); 16239 assert.strictEqual(root._, object); 16240 root._ = oldDash; 16241 } 16242 else { 16243 skipAssert(assert, 2); 16244 } 16245 }); 16246 16247 QUnit.test('should work with a `root` of `this`', function(assert) { 16248 assert.expect(2); 16249 16250 if (!coverage && !document && !isModularize && realm.object) { 16251 var fs = require('fs'), 16252 vm = require('vm'), 16253 expected = {}, 16254 context = vm.createContext({ '_': expected, 'console': console }), 16255 source = fs.readFileSync(filePath, 'utf8'); 16256 16257 vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context); 16258 16259 assert.strictEqual(context._, expected); 16260 assert.ok(context.lodash); 16261 } 16262 else { 16263 skipAssert(assert, 2); 16264 } 16265 }); 16266 }()); 16267 16268 /*--------------------------------------------------------------------------*/ 16269 16270 QUnit.module('lodash.now'); 16271 16272 (function() { 16273 QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) { 16274 assert.expect(2); 16275 16276 var done = assert.async(); 16277 16278 var stamp = +new Date, 16279 actual = _.now(); 16280 16281 assert.ok(actual >= stamp); 16282 16283 setTimeout(function() { 16284 assert.ok(_.now() > actual); 16285 done(); 16286 }, 32); 16287 }); 16288 16289 QUnit.test('should work with mocked `Date.now`', function(assert) { 16290 assert.expect(1); 16291 16292 var now = Date.now; 16293 Date.now = stubA; 16294 16295 var actual = _.now(); 16296 Date.now = now; 16297 16298 assert.strictEqual(actual, 'a'); 16299 }); 16300 }()); 16301 16302 /*--------------------------------------------------------------------------*/ 16303 16304 QUnit.module('lodash.nth'); 16305 16306 (function() { 16307 var array = ['a', 'b', 'c', 'd']; 16308 16309 QUnit.test('should get the nth element of `array`', function(assert) { 16310 assert.expect(1); 16311 16312 var actual = lodashStable.map(array, function(value, index) { 16313 return _.nth(array, index); 16314 }); 16315 16316 assert.deepEqual(actual, array); 16317 }); 16318 16319 QUnit.test('should work with a negative `n`', function(assert) { 16320 assert.expect(1); 16321 16322 var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) { 16323 return _.nth(array, -n); 16324 }); 16325 16326 assert.deepEqual(actual, ['d', 'c', 'b', 'a']); 16327 }); 16328 16329 QUnit.test('should coerce `n` to an integer', function(assert) { 16330 assert.expect(2); 16331 16332 var values = falsey, 16333 expected = lodashStable.map(values, stubA); 16334 16335 var actual = lodashStable.map(values, function(n) { 16336 return n ? _.nth(array, n) : _.nth(array); 16337 }); 16338 16339 assert.deepEqual(actual, expected); 16340 16341 values = ['1', 1.6]; 16342 expected = lodashStable.map(values, stubB); 16343 16344 actual = lodashStable.map(values, function(n) { 16345 return _.nth(array, n); 16346 }); 16347 16348 assert.deepEqual(actual, expected); 16349 }); 16350 16351 QUnit.test('should return `undefined` for empty arrays', function(assert) { 16352 assert.expect(1); 16353 16354 var values = [null, undefined, []], 16355 expected = lodashStable.map(values, noop); 16356 16357 var actual = lodashStable.map(values, function(array) { 16358 return _.nth(array, 1); 16359 }); 16360 16361 assert.deepEqual(actual, expected); 16362 }); 16363 16364 QUnit.test('should return `undefined` for non-indexes', function(assert) { 16365 assert.expect(1); 16366 16367 var array = [1, 2], 16368 values = [Infinity, array.length], 16369 expected = lodashStable.map(values, noop); 16370 16371 array[-1] = 3; 16372 16373 var actual = lodashStable.map(values, function(n) { 16374 return _.nth(array, n); 16375 }); 16376 16377 assert.deepEqual(actual, expected); 16378 }); 16379 }()); 16380 16381 /*--------------------------------------------------------------------------*/ 16382 16383 QUnit.module('lodash.nthArg'); 16384 16385 (function() { 16386 var args = ['a', 'b', 'c', 'd']; 16387 16388 QUnit.test('should create a function that returns its nth argument', function(assert) { 16389 assert.expect(1); 16390 16391 var actual = lodashStable.map(args, function(value, index) { 16392 var func = _.nthArg(index); 16393 return func.apply(undefined, args); 16394 }); 16395 16396 assert.deepEqual(actual, args); 16397 }); 16398 16399 QUnit.test('should work with a negative `n`', function(assert) { 16400 assert.expect(1); 16401 16402 var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) { 16403 var func = _.nthArg(-n); 16404 return func.apply(undefined, args); 16405 }); 16406 16407 assert.deepEqual(actual, ['d', 'c', 'b', 'a']); 16408 }); 16409 16410 QUnit.test('should coerce `n` to an integer', function(assert) { 16411 assert.expect(2); 16412 16413 var values = falsey, 16414 expected = lodashStable.map(values, stubA); 16415 16416 var actual = lodashStable.map(values, function(n) { 16417 var func = n ? _.nthArg(n) : _.nthArg(); 16418 return func.apply(undefined, args); 16419 }); 16420 16421 assert.deepEqual(actual, expected); 16422 16423 values = ['1', 1.6]; 16424 expected = lodashStable.map(values, stubB); 16425 16426 actual = lodashStable.map(values, function(n) { 16427 var func = _.nthArg(n); 16428 return func.apply(undefined, args); 16429 }); 16430 16431 assert.deepEqual(actual, expected); 16432 }); 16433 16434 QUnit.test('should return `undefined` for empty arrays', function(assert) { 16435 assert.expect(1); 16436 16437 var func = _.nthArg(1); 16438 assert.strictEqual(func(), undefined); 16439 }); 16440 16441 QUnit.test('should return `undefined` for non-indexes', function(assert) { 16442 assert.expect(1); 16443 16444 var values = [Infinity, args.length], 16445 expected = lodashStable.map(values, noop); 16446 16447 var actual = lodashStable.map(values, function(n) { 16448 var func = _.nthArg(n); 16449 return func.apply(undefined, args); 16450 }); 16451 16452 assert.deepEqual(actual, expected); 16453 }); 16454 }()); 16455 16456 /*--------------------------------------------------------------------------*/ 16457 16458 QUnit.module('lodash.omit'); 16459 16460 (function() { 16461 var args = toArgs(['a', 'c']), 16462 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, 16463 nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } }; 16464 16465 QUnit.test('should flatten `paths`', function(assert) { 16466 assert.expect(2); 16467 16468 assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 }); 16469 assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 }); 16470 }); 16471 16472 QUnit.test('should support deep paths', function(assert) { 16473 assert.expect(1); 16474 16475 assert.deepEqual(_.omit(nested, 'b.c'), { 'a': 1, 'b': { 'd': 3} }); 16476 }); 16477 16478 QUnit.test('should support path arrays', function(assert) { 16479 assert.expect(1); 16480 16481 var object = { 'a.b': 1, 'a': { 'b': 2 } }, 16482 actual = _.omit(object, [['a.b']]); 16483 16484 assert.deepEqual(actual, { 'a': { 'b': 2 } }); 16485 }); 16486 16487 QUnit.test('should omit a key over a path', function(assert) { 16488 assert.expect(2); 16489 16490 var object = { 'a.b': 1, 'a': { 'b': 2 } }; 16491 16492 lodashStable.each(['a.b', ['a.b']], function(path) { 16493 assert.deepEqual(_.omit(object, path), { 'a': { 'b': 2 } }); 16494 }); 16495 }); 16496 16497 QUnit.test('should coerce `paths` to strings', function(assert) { 16498 assert.expect(1); 16499 16500 assert.deepEqual(_.omit({ '0': 'a' }, 0), {}); 16501 }); 16502 16503 QUnit.test('should return an empty object when `object` is nullish', function(assert) { 16504 assert.expect(2); 16505 16506 lodashStable.each([null, undefined], function(value) { 16507 objectProto.a = 1; 16508 var actual = _.omit(value, 'valueOf'); 16509 delete objectProto.a; 16510 assert.deepEqual(actual, {}); 16511 }); 16512 }); 16513 16514 QUnit.test('should work with a primitive `object`', function(assert) { 16515 assert.expect(1); 16516 16517 stringProto.a = 1; 16518 stringProto.b = 2; 16519 16520 assert.deepEqual(_.omit('', 'b'), { 'a': 1 }); 16521 16522 delete stringProto.a; 16523 delete stringProto.b; 16524 }); 16525 16526 QUnit.test('should work with `arguments` object `paths`', function(assert) { 16527 assert.expect(1); 16528 16529 assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 }); 16530 }); 16531 16532 QUnit.test('should not mutate `object`', function(assert) { 16533 assert.expect(4); 16534 16535 lodashStable.each(['a', ['a'], 'a.b', ['a.b']], function(path) { 16536 var object = { 'a': { 'b': 2 } }; 16537 _.omit(object, path); 16538 assert.deepEqual(object, { 'a': { 'b': 2 } }); 16539 }); 16540 }); 16541 }()); 16542 16543 /*--------------------------------------------------------------------------*/ 16544 16545 QUnit.module('lodash.omitBy'); 16546 16547 (function() { 16548 QUnit.test('should work with a predicate argument', function(assert) { 16549 assert.expect(1); 16550 16551 var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }; 16552 16553 var actual = _.omitBy(object, function(n) { 16554 return n != 2 && n != 4; 16555 }); 16556 16557 assert.deepEqual(actual, { 'b': 2, 'd': 4 }); 16558 }); 16559 }()); 16560 16561 /*--------------------------------------------------------------------------*/ 16562 16563 QUnit.module('omit methods'); 16564 16565 lodashStable.each(['omit', 'omitBy'], function(methodName) { 16566 var expected = { 'b': 2, 'd': 4 }, 16567 func = _[methodName], 16568 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, 16569 resolve = lodashStable.nthArg(1); 16570 16571 if (methodName == 'omitBy') { 16572 resolve = function(object, props) { 16573 props = lodashStable.castArray(props); 16574 return function(value) { 16575 return lodashStable.some(props, function(key) { 16576 key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key); 16577 return object[key] === value; 16578 }); 16579 }; 16580 }; 16581 } 16582 QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) { 16583 assert.expect(2); 16584 16585 assert.deepEqual(func(object, resolve(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 }); 16586 assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected); 16587 }); 16588 16589 QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) { 16590 assert.expect(1); 16591 16592 function Foo() {} 16593 Foo.prototype = object; 16594 16595 assert.deepEqual(func(new Foo, resolve(object, ['a', 'c'])), expected); 16596 }); 16597 16598 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 16599 assert.expect(1); 16600 16601 var object = { '-0': 'a', '0': 'b' }, 16602 props = [-0, Object(-0), 0, Object(0)], 16603 expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }]; 16604 16605 var actual = lodashStable.map(props, function(key) { 16606 return func(object, resolve(object, key)); 16607 }); 16608 16609 assert.deepEqual(actual, expected); 16610 }); 16611 16612 QUnit.test('`_.' + methodName + '` should include symbols', function(assert) { 16613 assert.expect(3); 16614 16615 function Foo() { 16616 this.a = 0; 16617 this[symbol] = 1; 16618 } 16619 16620 if (Symbol) { 16621 var symbol2 = Symbol('b'); 16622 Foo.prototype[symbol2] = 2; 16623 16624 var symbol3 = Symbol('c'); 16625 defineProperty(Foo.prototype, symbol3, { 16626 'configurable': true, 16627 'enumerable': false, 16628 'writable': true, 16629 'value': 3 16630 }); 16631 16632 var foo = new Foo, 16633 actual = func(foo, resolve(foo, 'a')); 16634 16635 assert.strictEqual(actual[symbol], 1); 16636 assert.strictEqual(actual[symbol2], 2); 16637 assert.notOk(symbol3 in actual); 16638 } 16639 else { 16640 skipAssert(assert, 3); 16641 } 16642 }); 16643 16644 QUnit.test('`_.' + methodName + '` should create an object with omitted symbols', function(assert) { 16645 assert.expect(8); 16646 16647 function Foo() { 16648 this.a = 0; 16649 this[symbol] = 1; 16650 } 16651 16652 if (Symbol) { 16653 var symbol2 = Symbol('b'); 16654 Foo.prototype[symbol2] = 2; 16655 16656 var symbol3 = Symbol('c'); 16657 defineProperty(Foo.prototype, symbol3, { 16658 'configurable': true, 16659 'enumerable': false, 16660 'writable': true, 16661 'value': 3 16662 }); 16663 16664 var foo = new Foo, 16665 actual = func(foo, resolve(foo, symbol)); 16666 16667 assert.strictEqual(actual.a, 0); 16668 assert.notOk(symbol in actual); 16669 assert.strictEqual(actual[symbol2], 2); 16670 assert.notOk(symbol3 in actual); 16671 16672 actual = func(foo, resolve(foo, symbol2)); 16673 16674 assert.strictEqual(actual.a, 0); 16675 assert.strictEqual(actual[symbol], 1); 16676 assert.notOk(symbol2 in actual); 16677 assert.notOk(symbol3 in actual); 16678 } 16679 else { 16680 skipAssert(assert, 8); 16681 } 16682 }); 16683 16684 QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) { 16685 assert.expect(1); 16686 16687 var array = [1, 2, 3]; 16688 assert.deepEqual(func(array, resolve(array, ['0', '2'])), { '1': 2 }); 16689 }); 16690 }); 16691 16692 /*--------------------------------------------------------------------------*/ 16693 16694 QUnit.module('lodash.once'); 16695 16696 (function() { 16697 QUnit.test('should invoke `func` once', function(assert) { 16698 assert.expect(2); 16699 16700 var count = 0, 16701 once = _.once(function() { return ++count; }); 16702 16703 once(); 16704 assert.strictEqual(once(), 1); 16705 assert.strictEqual(count, 1); 16706 }); 16707 16708 QUnit.test('should ignore recursive calls', function(assert) { 16709 assert.expect(2); 16710 16711 var count = 0; 16712 16713 var once = _.once(function() { 16714 once(); 16715 return ++count; 16716 }); 16717 16718 assert.strictEqual(once(), 1); 16719 assert.strictEqual(count, 1); 16720 }); 16721 16722 QUnit.test('should not throw more than once', function(assert) { 16723 assert.expect(2); 16724 16725 var once = _.once(function() { 16726 throw new Error; 16727 }); 16728 16729 assert.raises(once); 16730 16731 once(); 16732 assert.ok(true); 16733 }); 16734 }()); 16735 16736 /*--------------------------------------------------------------------------*/ 16737 16738 QUnit.module('lodash.over'); 16739 16740 (function() { 16741 QUnit.test('should create a function that invokes `iteratees`', function(assert) { 16742 assert.expect(1); 16743 16744 var over = _.over(Math.max, Math.min); 16745 assert.deepEqual(over(1, 2, 3, 4), [4, 1]); 16746 }); 16747 16748 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) { 16749 assert.expect(1); 16750 16751 var over = _.over(undefined, null); 16752 assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']); 16753 }); 16754 16755 QUnit.test('should work with `_.property` shorthands', function(assert) { 16756 assert.expect(1); 16757 16758 var over = _.over('b', 'a'); 16759 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]); 16760 }); 16761 16762 QUnit.test('should work with `_.matches` shorthands', function(assert) { 16763 assert.expect(1); 16764 16765 var over = _.over({ 'b': 1 }, { 'a': 1 }); 16766 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]); 16767 }); 16768 16769 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 16770 assert.expect(2); 16771 16772 var over = _.over([['b', 2], ['a', 2]]); 16773 16774 assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]); 16775 assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]); 16776 }); 16777 16778 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) { 16779 assert.expect(4); 16780 16781 var over = _.over(['a', 1]); 16782 16783 assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]); 16784 assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]); 16785 16786 over = _.over([['a', 1]]); 16787 16788 assert.deepEqual(over({ 'a': 1 }), [true]); 16789 assert.deepEqual(over({ 'a': 2 }), [false]); 16790 }); 16791 16792 QUnit.test('should provide arguments to predicates', function(assert) { 16793 assert.expect(1); 16794 16795 var over = _.over(function() { 16796 return slice.call(arguments); 16797 }); 16798 16799 assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]); 16800 }); 16801 16802 QUnit.test('should use `this` binding of function for `iteratees`', function(assert) { 16803 assert.expect(1); 16804 16805 var over = _.over(function() { return this.b; }, function() { return this.a; }), 16806 object = { 'over': over, 'a': 1, 'b': 2 }; 16807 16808 assert.deepEqual(object.over(), [2, 1]); 16809 }); 16810 }()); 16811 16812 /*--------------------------------------------------------------------------*/ 16813 16814 QUnit.module('lodash.overEvery'); 16815 16816 (function() { 16817 QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) { 16818 assert.expect(1); 16819 16820 var over = _.overEvery(stubTrue, stubOne, stubA); 16821 assert.strictEqual(over(), true); 16822 }); 16823 16824 QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) { 16825 assert.expect(2); 16826 16827 var count = 0, 16828 countFalse = function() { count++; return false; }, 16829 countTrue = function() { count++; return true; }, 16830 over = _.overEvery(countTrue, countFalse, countTrue); 16831 16832 assert.strictEqual(over(), false); 16833 assert.strictEqual(count, 2); 16834 }); 16835 16836 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) { 16837 assert.expect(2); 16838 16839 var over = _.overEvery(undefined, null); 16840 16841 assert.strictEqual(over(true), true); 16842 assert.strictEqual(over(false), false); 16843 }); 16844 16845 QUnit.test('should work with `_.property` shorthands', function(assert) { 16846 assert.expect(2); 16847 16848 var over = _.overEvery('b', 'a'); 16849 16850 assert.strictEqual(over({ 'a': 1, 'b': 1 }), true); 16851 assert.strictEqual(over({ 'a': 0, 'b': 1 }), false); 16852 }); 16853 16854 QUnit.test('should work with `_.matches` shorthands', function(assert) { 16855 assert.expect(2); 16856 16857 var over = _.overEvery({ 'b': 2 }, { 'a': 1 }); 16858 16859 assert.strictEqual(over({ 'a': 1, 'b': 2 }), true); 16860 assert.strictEqual(over({ 'a': 0, 'b': 2 }), false); 16861 }); 16862 16863 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 16864 assert.expect(2); 16865 16866 var over = _.overEvery([['b', 2], ['a', 1]]); 16867 16868 assert.strictEqual(over({ 'a': 1, 'b': 2 }), true); 16869 assert.strictEqual(over({ 'a': 0, 'b': 2 }), false); 16870 }); 16871 16872 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) { 16873 assert.expect(5); 16874 16875 var over = _.overEvery(['a', 1]); 16876 16877 assert.strictEqual(over({ 'a': 1, '1': 1 }), true); 16878 assert.strictEqual(over({ 'a': 1, '1': 0 }), false); 16879 assert.strictEqual(over({ 'a': 0, '1': 1 }), false); 16880 16881 over = _.overEvery([['a', 1]]); 16882 16883 assert.strictEqual(over({ 'a': 1 }), true); 16884 assert.strictEqual(over({ 'a': 2 }), false); 16885 }); 16886 16887 QUnit.test('should flatten `predicates`', function(assert) { 16888 assert.expect(1); 16889 16890 var over = _.overEvery(stubTrue, [stubFalse]); 16891 assert.strictEqual(over(), false); 16892 }); 16893 16894 QUnit.test('should provide arguments to predicates', function(assert) { 16895 assert.expect(1); 16896 16897 var args; 16898 16899 var over = _.overEvery(function() { 16900 args = slice.call(arguments); 16901 }); 16902 16903 over('a', 'b', 'c'); 16904 assert.deepEqual(args, ['a', 'b', 'c']); 16905 }); 16906 16907 QUnit.test('should use `this` binding of function for `predicates`', function(assert) { 16908 assert.expect(2); 16909 16910 var over = _.overEvery(function() { return this.b; }, function() { return this.a; }), 16911 object = { 'over': over, 'a': 1, 'b': 2 }; 16912 16913 assert.strictEqual(object.over(), true); 16914 16915 object.a = 0; 16916 assert.strictEqual(object.over(), false); 16917 }); 16918 }()); 16919 16920 /*--------------------------------------------------------------------------*/ 16921 16922 QUnit.module('lodash.overSome'); 16923 16924 (function() { 16925 QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) { 16926 assert.expect(2); 16927 16928 var over = _.overSome(stubFalse, stubOne, stubString); 16929 assert.strictEqual(over(), true); 16930 16931 over = _.overSome(stubNull, stubA, stubZero); 16932 assert.strictEqual(over(), true); 16933 }); 16934 16935 QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) { 16936 assert.expect(2); 16937 16938 var count = 0, 16939 countFalse = function() { count++; return false; }, 16940 countTrue = function() { count++; return true; }, 16941 over = _.overSome(countFalse, countTrue, countFalse); 16942 16943 assert.strictEqual(over(), true); 16944 assert.strictEqual(count, 2); 16945 }); 16946 16947 QUnit.test('should return `false` if all predicates return falsey', function(assert) { 16948 assert.expect(2); 16949 16950 var over = _.overSome(stubFalse, stubFalse, stubFalse); 16951 assert.strictEqual(over(), false); 16952 16953 over = _.overSome(stubNull, stubZero, stubString); 16954 assert.strictEqual(over(), false); 16955 }); 16956 16957 QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) { 16958 assert.expect(2); 16959 16960 var over = _.overSome(undefined, null); 16961 16962 assert.strictEqual(over(true), true); 16963 assert.strictEqual(over(false), false); 16964 }); 16965 16966 QUnit.test('should work with `_.property` shorthands', function(assert) { 16967 assert.expect(2); 16968 16969 var over = _.overSome('b', 'a'); 16970 16971 assert.strictEqual(over({ 'a': 1, 'b': 0 }), true); 16972 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false); 16973 }); 16974 16975 QUnit.test('should work with `_.matches` shorthands', function(assert) { 16976 assert.expect(2); 16977 16978 var over = _.overSome({ 'b': 2 }, { 'a': 1 }); 16979 16980 assert.strictEqual(over({ 'a': 0, 'b': 2 }), true); 16981 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false); 16982 }); 16983 16984 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 16985 assert.expect(2); 16986 16987 var over = _.overSome([['b', 2], ['a', 1]]); 16988 16989 assert.strictEqual(over({ 'a': 0, 'b': 2 }), true); 16990 assert.strictEqual(over({ 'a': 0, 'b': 0 }), false); 16991 }); 16992 16993 QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) { 16994 assert.expect(5); 16995 16996 var over = _.overSome(['a', 1]); 16997 16998 assert.strictEqual(over({ 'a': 0, '1': 0 }), false); 16999 assert.strictEqual(over({ 'a': 1, '1': 0 }), true); 17000 assert.strictEqual(over({ 'a': 0, '1': 1 }), true); 17001 17002 over = _.overSome([['a', 1]]); 17003 17004 assert.strictEqual(over({ 'a': 1 }), true); 17005 assert.strictEqual(over({ 'a': 2 }), false); 17006 }); 17007 17008 QUnit.test('should flatten `predicates`', function(assert) { 17009 assert.expect(1); 17010 17011 var over = _.overSome(stubFalse, [stubTrue]); 17012 assert.strictEqual(over(), true); 17013 }); 17014 17015 QUnit.test('should provide arguments to predicates', function(assert) { 17016 assert.expect(1); 17017 17018 var args; 17019 17020 var over = _.overSome(function() { 17021 args = slice.call(arguments); 17022 }); 17023 17024 over('a', 'b', 'c'); 17025 assert.deepEqual(args, ['a', 'b', 'c']); 17026 }); 17027 17028 QUnit.test('should use `this` binding of function for `predicates`', function(assert) { 17029 assert.expect(2); 17030 17031 var over = _.overSome(function() { return this.b; }, function() { return this.a; }), 17032 object = { 'over': over, 'a': 1, 'b': 2 }; 17033 17034 assert.strictEqual(object.over(), true); 17035 17036 object.a = object.b = 0; 17037 assert.strictEqual(object.over(), false); 17038 }); 17039 }()); 17040 17041 /*--------------------------------------------------------------------------*/ 17042 17043 QUnit.module('lodash.pad'); 17044 17045 (function() { 17046 var string = 'abc'; 17047 17048 QUnit.test('should pad a string to a given length', function(assert) { 17049 assert.expect(1); 17050 17051 var values = [, undefined], 17052 expected = lodashStable.map(values, lodashStable.constant(' abc ')); 17053 17054 var actual = lodashStable.map(values, function(value, index) { 17055 return index ? _.pad(string, 6, value) : _.pad(string, 6); 17056 }); 17057 17058 assert.deepEqual(actual, expected); 17059 }); 17060 17061 QUnit.test('should truncate pad characters to fit the pad length', function(assert) { 17062 assert.expect(2); 17063 17064 assert.strictEqual(_.pad(string, 8), ' abc '); 17065 assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_'); 17066 }); 17067 17068 QUnit.test('should coerce `string` to a string', function(assert) { 17069 assert.expect(1); 17070 17071 var values = [Object(string), { 'toString': lodashStable.constant(string) }], 17072 expected = lodashStable.map(values, stubTrue); 17073 17074 var actual = lodashStable.map(values, function(value) { 17075 return _.pad(value, 6) === ' abc '; 17076 }); 17077 17078 assert.deepEqual(actual, expected); 17079 }); 17080 }()); 17081 17082 /*--------------------------------------------------------------------------*/ 17083 17084 QUnit.module('lodash.padEnd'); 17085 17086 (function() { 17087 var string = 'abc'; 17088 17089 QUnit.test('should pad a string to a given length', function(assert) { 17090 assert.expect(1); 17091 17092 var values = [, undefined], 17093 expected = lodashStable.map(values, lodashStable.constant('abc ')); 17094 17095 var actual = lodashStable.map(values, function(value, index) { 17096 return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6); 17097 }); 17098 17099 assert.deepEqual(actual, expected); 17100 }); 17101 17102 QUnit.test('should truncate pad characters to fit the pad length', function(assert) { 17103 assert.expect(1); 17104 17105 assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_'); 17106 }); 17107 17108 QUnit.test('should coerce `string` to a string', function(assert) { 17109 assert.expect(1); 17110 17111 var values = [Object(string), { 'toString': lodashStable.constant(string) }], 17112 expected = lodashStable.map(values, stubTrue); 17113 17114 var actual = lodashStable.map(values, function(value) { 17115 return _.padEnd(value, 6) === 'abc '; 17116 }); 17117 17118 assert.deepEqual(actual, expected); 17119 }); 17120 }()); 17121 17122 /*--------------------------------------------------------------------------*/ 17123 17124 QUnit.module('lodash.padStart'); 17125 17126 (function() { 17127 var string = 'abc'; 17128 17129 QUnit.test('should pad a string to a given length', function(assert) { 17130 assert.expect(1); 17131 17132 var values = [, undefined], 17133 expected = lodashStable.map(values, lodashStable.constant(' abc')); 17134 17135 var actual = lodashStable.map(values, function(value, index) { 17136 return index ? _.padStart(string, 6, value) : _.padStart(string, 6); 17137 }); 17138 17139 assert.deepEqual(actual, expected); 17140 }); 17141 17142 QUnit.test('should truncate pad characters to fit the pad length', function(assert) { 17143 assert.expect(1); 17144 17145 assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc'); 17146 }); 17147 17148 QUnit.test('should coerce `string` to a string', function(assert) { 17149 assert.expect(1); 17150 17151 var values = [Object(string), { 'toString': lodashStable.constant(string) }], 17152 expected = lodashStable.map(values, stubTrue); 17153 17154 var actual = lodashStable.map(values, function(value) { 17155 return _.padStart(value, 6) === ' abc'; 17156 }); 17157 17158 assert.deepEqual(actual, expected); 17159 }); 17160 }()); 17161 17162 /*--------------------------------------------------------------------------*/ 17163 17164 QUnit.module('pad methods'); 17165 17166 lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) { 17167 var func = _[methodName], 17168 isPad = methodName == 'pad', 17169 isStart = methodName == 'padStart', 17170 string = 'abc'; 17171 17172 QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) { 17173 assert.expect(2); 17174 17175 assert.strictEqual(func(string, 2), string); 17176 assert.strictEqual(func(string, 3), string); 17177 }); 17178 17179 QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) { 17180 assert.expect(2); 17181 17182 lodashStable.each([0, -2], function(length) { 17183 assert.strictEqual(func(string, length), string); 17184 }); 17185 }); 17186 17187 QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) { 17188 assert.expect(2); 17189 17190 lodashStable.each(['', '4'], function(length) { 17191 var actual = length ? (isStart ? ' abc' : 'abc ') : string; 17192 assert.strictEqual(func(string, length), actual); 17193 }); 17194 }); 17195 17196 QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) { 17197 assert.expect(6); 17198 17199 lodashStable.each([undefined, '_-'], function(chars) { 17200 var expected = chars ? (isPad ? '__' : chars) : ' '; 17201 assert.strictEqual(func(null, 2, chars), expected); 17202 assert.strictEqual(func(undefined, 2, chars), expected); 17203 assert.strictEqual(func('', 2, chars), expected); 17204 }); 17205 }); 17206 17207 QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) { 17208 assert.expect(1); 17209 17210 var values = ['', Object('')], 17211 expected = lodashStable.map(values, lodashStable.constant(string)); 17212 17213 var actual = lodashStable.map(values, function(value) { 17214 return _.pad(string, 6, value); 17215 }); 17216 17217 assert.deepEqual(actual, expected); 17218 }); 17219 }); 17220 17221 /*--------------------------------------------------------------------------*/ 17222 17223 QUnit.module('lodash.parseInt'); 17224 17225 (function() { 17226 QUnit.test('should accept a `radix`', function(assert) { 17227 assert.expect(1); 17228 17229 var expected = lodashStable.range(2, 37); 17230 17231 var actual = lodashStable.map(expected, function(radix) { 17232 return _.parseInt('10', radix); 17233 }); 17234 17235 assert.deepEqual(actual, expected); 17236 }); 17237 17238 QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) { 17239 assert.expect(4); 17240 17241 assert.strictEqual(_.parseInt('10'), 10); 17242 assert.strictEqual(_.parseInt('10', 0), 10); 17243 assert.strictEqual(_.parseInt('10', 10), 10); 17244 assert.strictEqual(_.parseInt('10', undefined), 10); 17245 }); 17246 17247 QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) { 17248 assert.expect(8); 17249 17250 lodashStable.each(['0x20', '0X20'], function(string) { 17251 assert.strictEqual(_.parseInt(string), 32); 17252 assert.strictEqual(_.parseInt(string, 0), 32); 17253 assert.strictEqual(_.parseInt(string, 16), 32); 17254 assert.strictEqual(_.parseInt(string, undefined), 32); 17255 }); 17256 }); 17257 17258 QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) { 17259 assert.expect(2); 17260 17261 assert.strictEqual(_.parseInt('08'), 8); 17262 assert.strictEqual(_.parseInt('08', 10), 8); 17263 }); 17264 17265 QUnit.test('should parse strings with leading whitespace', function(assert) { 17266 assert.expect(2); 17267 17268 var expected = [8, 8, 10, 10, 32, 32, 32, 32]; 17269 17270 lodashStable.times(2, function(index) { 17271 var actual = [], 17272 func = (index ? (lodashBizarro || {}) : _).parseInt; 17273 17274 if (func) { 17275 lodashStable.times(2, function(otherIndex) { 17276 var string = otherIndex ? '10' : '08'; 17277 actual.push( 17278 func(whitespace + string, 10), 17279 func(whitespace + string) 17280 ); 17281 }); 17282 17283 lodashStable.each(['0x20', '0X20'], function(string) { 17284 actual.push( 17285 func(whitespace + string), 17286 func(whitespace + string, 16) 17287 ); 17288 }); 17289 17290 assert.deepEqual(actual, expected); 17291 } 17292 else { 17293 skipAssert(assert); 17294 } 17295 }); 17296 }); 17297 17298 QUnit.test('should coerce `radix` to a number', function(assert) { 17299 assert.expect(2); 17300 17301 var object = { 'valueOf': stubZero }; 17302 assert.strictEqual(_.parseInt('08', object), 8); 17303 assert.strictEqual(_.parseInt('0x20', object), 32); 17304 }); 17305 17306 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 17307 assert.expect(2); 17308 17309 var strings = lodashStable.map(['6', '08', '10'], Object), 17310 actual = lodashStable.map(strings, _.parseInt); 17311 17312 assert.deepEqual(actual, [6, 8, 10]); 17313 17314 actual = lodashStable.map('123', _.parseInt); 17315 assert.deepEqual(actual, [1, 2, 3]); 17316 }); 17317 }()); 17318 17319 /*--------------------------------------------------------------------------*/ 17320 17321 QUnit.module('partial methods'); 17322 17323 lodashStable.each(['partial', 'partialRight'], function(methodName) { 17324 var func = _[methodName], 17325 isPartial = methodName == 'partial', 17326 ph = func.placeholder; 17327 17328 QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) { 17329 assert.expect(1); 17330 17331 var par = func(identity, 'a'); 17332 assert.strictEqual(par(), 'a'); 17333 }); 17334 17335 QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) { 17336 assert.expect(1); 17337 17338 var fn = function(a, b) { return [a, b]; }, 17339 par = func(fn, 'a'), 17340 expected = isPartial ? ['a', 'b'] : ['b', 'a']; 17341 17342 assert.deepEqual(par('b'), expected); 17343 }); 17344 17345 QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) { 17346 assert.expect(1); 17347 17348 var fn = function() { return arguments.length; }, 17349 par = func(fn); 17350 17351 assert.strictEqual(par(), 0); 17352 }); 17353 17354 QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) { 17355 assert.expect(1); 17356 17357 var par = func(identity); 17358 assert.strictEqual(par('a'), 'a'); 17359 }); 17360 17361 QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) { 17362 assert.expect(4); 17363 17364 var fn = function() { return slice.call(arguments); }, 17365 par = func(fn, ph, 'b', ph); 17366 17367 assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']); 17368 assert.deepEqual(par('a'), ['a', 'b', undefined]); 17369 assert.deepEqual(par(), [undefined, 'b', undefined]); 17370 17371 if (isPartial) { 17372 assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']); 17373 } else { 17374 par = func(fn, ph, 'c', ph); 17375 assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']); 17376 } 17377 }); 17378 17379 QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) { 17380 assert.expect(1); 17381 17382 if (!isModularize) { 17383 var _ph = _.placeholder = {}, 17384 fn = function() { return slice.call(arguments); }, 17385 par = func(fn, _ph, 'b', ph), 17386 expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph]; 17387 17388 assert.deepEqual(par('a', 'c'), expected); 17389 delete _.placeholder; 17390 } 17391 else { 17392 skipAssert(assert); 17393 } 17394 }); 17395 17396 QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) { 17397 assert.expect(1); 17398 17399 var fn = function(a, b, c) {}, 17400 par = func(fn, 'a'); 17401 17402 assert.strictEqual(par.length, 0); 17403 }); 17404 17405 QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) { 17406 assert.expect(2); 17407 17408 function Foo(value) { 17409 return value && object; 17410 } 17411 17412 var object = {}, 17413 par = func(Foo); 17414 17415 assert.ok(new par instanceof Foo); 17416 assert.strictEqual(new par(true), object); 17417 }); 17418 17419 QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) { 17420 assert.expect(3); 17421 17422 function greet(greeting, name) { 17423 return greeting + ' ' + name; 17424 } 17425 17426 var par1 = func(greet, 'hi'), 17427 par2 = func(par1, 'barney'), 17428 par3 = func(par1, 'pebbles'); 17429 17430 assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi'); 17431 assert.strictEqual(par2(), isPartial ? 'hi barney' : 'barney hi'); 17432 assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi'); 17433 }); 17434 17435 QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) { 17436 assert.expect(2); 17437 17438 var fn = function(a, b, c) { return a + b + c; }, 17439 curried = _.curry(func(fn, 1), 2); 17440 17441 assert.strictEqual(curried(2, 3), 6); 17442 assert.strictEqual(curried(2)(3), 6); 17443 }); 17444 17445 QUnit.test('should work with placeholders and curried functions', function(assert) { 17446 assert.expect(1); 17447 17448 var fn = function() { return slice.call(arguments); }, 17449 curried = _.curry(fn), 17450 par = func(curried, ph, 'b', ph, 'd'); 17451 17452 assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']); 17453 }); 17454 }); 17455 17456 /*--------------------------------------------------------------------------*/ 17457 17458 QUnit.module('lodash.partialRight'); 17459 17460 (function() { 17461 QUnit.test('should work as a deep `_.defaults`', function(assert) { 17462 assert.expect(1); 17463 17464 var object = { 'a': { 'b': 2 } }, 17465 source = { 'a': { 'b': 3, 'c': 3 } }, 17466 expected = { 'a': { 'b': 2, 'c': 3 } }; 17467 17468 var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) { 17469 return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value; 17470 }); 17471 17472 assert.deepEqual(defaultsDeep(object, source), expected); 17473 }); 17474 }()); 17475 17476 /*--------------------------------------------------------------------------*/ 17477 17478 QUnit.module('methods using `createWrapper`'); 17479 17480 (function() { 17481 function fn() { 17482 return slice.call(arguments); 17483 } 17484 17485 var ph1 = _.bind.placeholder, 17486 ph2 = _.bindKey.placeholder, 17487 ph3 = _.partial.placeholder, 17488 ph4 = _.partialRight.placeholder; 17489 17490 QUnit.test('should work with combinations of partial functions', function(assert) { 17491 assert.expect(1); 17492 17493 var a = _.partial(fn), 17494 b = _.partialRight(a, 3), 17495 c = _.partial(b, 1); 17496 17497 assert.deepEqual(c(2), [1, 2, 3]); 17498 }); 17499 17500 QUnit.test('should work with combinations of bound and partial functions', function(assert) { 17501 assert.expect(3); 17502 17503 var fn = function() { 17504 var result = [this.a]; 17505 push.apply(result, arguments); 17506 return result; 17507 }; 17508 17509 var expected = [1, 2, 3, 4], 17510 object = { 'a': 1, 'fn': fn }; 17511 17512 var a = _.bindKey(object, 'fn'), 17513 b = _.partialRight(a, 4), 17514 c = _.partial(b, 2); 17515 17516 assert.deepEqual(c(3), expected); 17517 17518 a = _.bind(fn, object); 17519 b = _.partialRight(a, 4); 17520 c = _.partial(b, 2); 17521 17522 assert.deepEqual(c(3), expected); 17523 17524 a = _.partial(fn, 2); 17525 b = _.bind(a, object); 17526 c = _.partialRight(b, 4); 17527 17528 assert.deepEqual(c(3), expected); 17529 }); 17530 17531 QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) { 17532 assert.expect(2); 17533 17534 function Foo(a, b, c) { 17535 return b === 0 && object; 17536 } 17537 17538 var combo = _.partial(_.partialRight(Foo, 3), 1), 17539 object = {}; 17540 17541 assert.ok(new combo(2) instanceof Foo); 17542 assert.strictEqual(new combo(0), object); 17543 }); 17544 17545 QUnit.test('should work with combinations of functions with placeholders', function(assert) { 17546 assert.expect(3); 17547 17548 var expected = [1, 2, 3, 4, 5, 6], 17549 object = { 'fn': fn }; 17550 17551 var a = _.bindKey(object, 'fn', ph2, 2), 17552 b = _.partialRight(a, ph4, 6), 17553 c = _.partial(b, 1, ph3, 4); 17554 17555 assert.deepEqual(c(3, 5), expected); 17556 17557 a = _.bind(fn, object, ph1, 2); 17558 b = _.partialRight(a, ph4, 6); 17559 c = _.partial(b, 1, ph3, 4); 17560 17561 assert.deepEqual(c(3, 5), expected); 17562 17563 a = _.partial(fn, ph3, 2); 17564 b = _.bind(a, object, 1, ph1, 4); 17565 c = _.partialRight(b, ph4, 6); 17566 17567 assert.deepEqual(c(3, 5), expected); 17568 }); 17569 17570 QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) { 17571 assert.expect(3); 17572 17573 var expected = [1, 2, 3, 4], 17574 object = { 'fn': fn }; 17575 17576 var a = _.bindKey(object, 'fn', ph2, 2), 17577 b = _.partialRight(a, ph4, 4), 17578 c = _.partial(b, ph3, 3); 17579 17580 assert.deepEqual(c(1), expected); 17581 17582 a = _.bind(fn, object, ph1, 2); 17583 b = _.partialRight(a, ph4, 4); 17584 c = _.partial(b, ph3, 3); 17585 17586 assert.deepEqual(c(1), expected); 17587 17588 a = _.partial(fn, ph3, 2); 17589 b = _.bind(a, object, ph1, 3); 17590 c = _.partialRight(b, ph4, 4); 17591 17592 assert.deepEqual(c(1), expected); 17593 }); 17594 17595 QUnit.test('should work with recursively bound functions', function(assert) { 17596 assert.expect(1); 17597 17598 var fn = function() { 17599 return this.a; 17600 }; 17601 17602 var a = _.bind(fn, { 'a': 1 }), 17603 b = _.bind(a, { 'a': 2 }), 17604 c = _.bind(b, { 'a': 3 }); 17605 17606 assert.strictEqual(c(), 1); 17607 }); 17608 17609 QUnit.test('should work when hot', function(assert) { 17610 assert.expect(12); 17611 17612 lodashStable.times(2, function(index) { 17613 var fn = function() { 17614 var result = [this]; 17615 push.apply(result, arguments); 17616 return result; 17617 }; 17618 17619 var object = {}, 17620 bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object), 17621 expected = [object, 1, 2, 3]; 17622 17623 var actual = _.last(lodashStable.times(HOT_COUNT, function() { 17624 var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1); 17625 return index ? bound2(3) : bound2(1, 2, 3); 17626 })); 17627 17628 assert.deepEqual(actual, expected); 17629 17630 actual = _.last(lodashStable.times(HOT_COUNT, function() { 17631 var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object), 17632 bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1); 17633 17634 return index ? bound2(3) : bound2(1, 2, 3); 17635 })); 17636 17637 assert.deepEqual(actual, expected); 17638 }); 17639 17640 lodashStable.each(['curry', 'curryRight'], function(methodName, index) { 17641 var fn = function(a, b, c) { return [a, b, c]; }, 17642 curried = _[methodName](fn), 17643 expected = index ? [3, 2, 1] : [1, 2, 3]; 17644 17645 var actual = _.last(lodashStable.times(HOT_COUNT, function() { 17646 return curried(1)(2)(3); 17647 })); 17648 17649 assert.deepEqual(actual, expected); 17650 17651 actual = _.last(lodashStable.times(HOT_COUNT, function() { 17652 var curried = _[methodName](fn); 17653 return curried(1)(2)(3); 17654 })); 17655 17656 assert.deepEqual(actual, expected); 17657 }); 17658 17659 lodashStable.each(['partial', 'partialRight'], function(methodName, index) { 17660 var func = _[methodName], 17661 fn = function() { return slice.call(arguments); }, 17662 par1 = func(fn, 1), 17663 expected = index ? [3, 2, 1] : [1, 2, 3]; 17664 17665 var actual = _.last(lodashStable.times(HOT_COUNT, function() { 17666 var par2 = func(par1, 2); 17667 return par2(3); 17668 })); 17669 17670 assert.deepEqual(actual, expected); 17671 17672 actual = _.last(lodashStable.times(HOT_COUNT, function() { 17673 var par1 = func(fn, 1), 17674 par2 = func(par1, 2); 17675 17676 return par2(3); 17677 })); 17678 17679 assert.deepEqual(actual, expected); 17680 }); 17681 }); 17682 }()); 17683 17684 /*--------------------------------------------------------------------------*/ 17685 17686 QUnit.module('lodash.partition'); 17687 17688 (function() { 17689 var array = [1, 0, 1]; 17690 17691 QUnit.test('should split elements into two groups by `predicate`', function(assert) { 17692 assert.expect(3); 17693 17694 assert.deepEqual(_.partition([], identity), [[], []]); 17695 assert.deepEqual(_.partition(array, stubTrue), [array, []]); 17696 assert.deepEqual(_.partition(array, stubFalse), [[], array]); 17697 }); 17698 17699 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) { 17700 assert.expect(1); 17701 17702 var values = [, null, undefined], 17703 expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]])); 17704 17705 var actual = lodashStable.map(values, function(value, index) { 17706 return index ? _.partition(array, value) : _.partition(array); 17707 }); 17708 17709 assert.deepEqual(actual, expected); 17710 }); 17711 17712 QUnit.test('should work with `_.property` shorthands', function(assert) { 17713 assert.expect(1); 17714 17715 var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }], 17716 actual = _.partition(objects, 'a'); 17717 17718 assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]); 17719 }); 17720 17721 QUnit.test('should work with a number for `predicate`', function(assert) { 17722 assert.expect(2); 17723 17724 var array = [ 17725 [1, 0], 17726 [0, 1], 17727 [1, 0] 17728 ]; 17729 17730 assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]); 17731 assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]); 17732 }); 17733 17734 QUnit.test('should work with an object for `collection`', function(assert) { 17735 assert.expect(1); 17736 17737 var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor); 17738 assert.deepEqual(actual, [[1.1, 1.3], [0.2]]); 17739 }); 17740 }()); 17741 17742 /*--------------------------------------------------------------------------*/ 17743 17744 QUnit.module('lodash.pick'); 17745 17746 (function() { 17747 var args = toArgs(['a', 'c']), 17748 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, 17749 nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } }; 17750 17751 QUnit.test('should flatten `paths`', function(assert) { 17752 assert.expect(2); 17753 17754 assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 }); 17755 assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 }); 17756 }); 17757 17758 QUnit.test('should support deep paths', function(assert) { 17759 assert.expect(1); 17760 17761 assert.deepEqual(_.pick(nested, 'b.c'), { 'b': { 'c': 2 } }); 17762 }); 17763 17764 QUnit.test('should support path arrays', function(assert) { 17765 assert.expect(1); 17766 17767 var object = { 'a.b': 1, 'a': { 'b': 2 } }, 17768 actual = _.pick(object, [['a.b']]); 17769 17770 assert.deepEqual(actual, { 'a.b': 1 }); 17771 }); 17772 17773 QUnit.test('should pick a key over a path', function(assert) { 17774 assert.expect(2); 17775 17776 var object = { 'a.b': 1, 'a': { 'b': 2 } }; 17777 17778 lodashStable.each(['a.b', ['a.b']], function(path) { 17779 assert.deepEqual(_.pick(object, path), { 'a.b': 1 }); 17780 }); 17781 }); 17782 17783 QUnit.test('should coerce `paths` to strings', function(assert) { 17784 assert.expect(1); 17785 17786 assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' }); 17787 }); 17788 17789 QUnit.test('should return an empty object when `object` is nullish', function(assert) { 17790 assert.expect(2); 17791 17792 lodashStable.each([null, undefined], function(value) { 17793 assert.deepEqual(_.pick(value, 'valueOf'), {}); 17794 }); 17795 }); 17796 17797 QUnit.test('should work with a primitive `object`', function(assert) { 17798 assert.expect(1); 17799 17800 assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice }); 17801 }); 17802 17803 QUnit.test('should work with `arguments` object `paths`', function(assert) { 17804 assert.expect(1); 17805 17806 assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 }); 17807 }); 17808 }()); 17809 17810 /*--------------------------------------------------------------------------*/ 17811 17812 QUnit.module('lodash.pickBy'); 17813 17814 (function() { 17815 QUnit.test('should work with a predicate argument', function(assert) { 17816 assert.expect(1); 17817 17818 var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }; 17819 17820 var actual = _.pickBy(object, function(n) { 17821 return n == 1 || n == 3; 17822 }); 17823 17824 assert.deepEqual(actual, { 'a': 1, 'c': 3 }); 17825 }); 17826 17827 QUnit.test('should not treat keys with dots as deep paths', function(assert) { 17828 assert.expect(1); 17829 17830 var object = { 'a.b.c': 1 }, 17831 actual = _.pickBy(object, stubTrue); 17832 17833 assert.deepEqual(actual, { 'a.b.c': 1 }); 17834 }); 17835 }()); 17836 17837 /*--------------------------------------------------------------------------*/ 17838 17839 QUnit.module('pick methods'); 17840 17841 lodashStable.each(['pick', 'pickBy'], function(methodName) { 17842 var expected = { 'a': 1, 'c': 3 }, 17843 func = _[methodName], 17844 isPick = methodName == 'pick', 17845 object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, 17846 resolve = lodashStable.nthArg(1); 17847 17848 if (methodName == 'pickBy') { 17849 resolve = function(object, props) { 17850 props = lodashStable.castArray(props); 17851 return function(value) { 17852 return lodashStable.some(props, function(key) { 17853 key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key); 17854 return object[key] === value; 17855 }); 17856 }; 17857 }; 17858 } 17859 QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) { 17860 assert.expect(2); 17861 17862 assert.deepEqual(func(object, resolve(object, 'a')), { 'a': 1 }); 17863 assert.deepEqual(func(object, resolve(object, ['a', 'c'])), expected); 17864 }); 17865 17866 QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) { 17867 assert.expect(1); 17868 17869 function Foo() {} 17870 Foo.prototype = object; 17871 17872 var foo = new Foo; 17873 assert.deepEqual(func(foo, resolve(foo, ['a', 'c'])), expected); 17874 }); 17875 17876 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 17877 assert.expect(1); 17878 17879 var object = { '-0': 'a', '0': 'b' }, 17880 props = [-0, Object(-0), 0, Object(0)], 17881 expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }]; 17882 17883 var actual = lodashStable.map(props, function(key) { 17884 return func(object, resolve(object, key)); 17885 }); 17886 17887 assert.deepEqual(actual, expected); 17888 }); 17889 17890 QUnit.test('`_.' + methodName + '` should pick symbols', function(assert) { 17891 assert.expect(3); 17892 17893 function Foo() { 17894 this[symbol] = 1; 17895 } 17896 17897 if (Symbol) { 17898 var symbol2 = Symbol('b'); 17899 Foo.prototype[symbol2] = 2; 17900 17901 var symbol3 = Symbol('c'); 17902 defineProperty(Foo.prototype, symbol3, { 17903 'configurable': true, 17904 'enumerable': false, 17905 'writable': true, 17906 'value': 3 17907 }); 17908 17909 var foo = new Foo, 17910 actual = func(foo, resolve(foo, [symbol, symbol2, symbol3])); 17911 17912 assert.strictEqual(actual[symbol], 1); 17913 assert.strictEqual(actual[symbol2], 2); 17914 17915 if (isPick) { 17916 assert.strictEqual(actual[symbol3], 3); 17917 } else { 17918 assert.notOk(symbol3 in actual); 17919 } 17920 } 17921 else { 17922 skipAssert(assert, 3); 17923 } 17924 }); 17925 17926 QUnit.test('`_.' + methodName + '` should work with an array `object`', function(assert) { 17927 assert.expect(1); 17928 17929 var array = [1, 2, 3]; 17930 assert.deepEqual(func(array, resolve(array, '1')), { '1': 2 }); 17931 }); 17932 }); 17933 17934 /*--------------------------------------------------------------------------*/ 17935 17936 QUnit.module('lodash.property'); 17937 17938 (function() { 17939 QUnit.test('should create a function that plucks a property value of a given object', function(assert) { 17940 assert.expect(4); 17941 17942 var object = { 'a': 1 }; 17943 17944 lodashStable.each(['a', ['a']], function(path) { 17945 var prop = _.property(path); 17946 assert.strictEqual(prop.length, 1); 17947 assert.strictEqual(prop(object), 1); 17948 }); 17949 }); 17950 17951 QUnit.test('should pluck deep property values', function(assert) { 17952 assert.expect(2); 17953 17954 var object = { 'a': { 'b': 2 } }; 17955 17956 lodashStable.each(['a.b', ['a', 'b']], function(path) { 17957 var prop = _.property(path); 17958 assert.strictEqual(prop(object), 2); 17959 }); 17960 }); 17961 17962 QUnit.test('should pluck inherited property values', function(assert) { 17963 assert.expect(2); 17964 17965 function Foo() {} 17966 Foo.prototype.a = 1; 17967 17968 lodashStable.each(['a', ['a']], function(path) { 17969 var prop = _.property(path); 17970 assert.strictEqual(prop(new Foo), 1); 17971 }); 17972 }); 17973 17974 QUnit.test('should work with a non-string `path`', function(assert) { 17975 assert.expect(2); 17976 17977 var array = [1, 2, 3]; 17978 17979 lodashStable.each([1, [1]], function(path) { 17980 var prop = _.property(path); 17981 assert.strictEqual(prop(array), 2); 17982 }); 17983 }); 17984 17985 QUnit.test('should preserve the sign of `0`', function(assert) { 17986 assert.expect(1); 17987 17988 var object = { '-0': 'a', '0': 'b' }, 17989 props = [-0, Object(-0), 0, Object(0)]; 17990 17991 var actual = lodashStable.map(props, function(key) { 17992 var prop = _.property(key); 17993 return prop(object); 17994 }); 17995 17996 assert.deepEqual(actual, ['a', 'a', 'b', 'b']); 17997 }); 17998 17999 QUnit.test('should coerce `path` to a string', function(assert) { 18000 assert.expect(2); 18001 18002 function fn() {} 18003 fn.toString = lodashStable.constant('fn'); 18004 18005 var expected = [1, 2, 3, 4], 18006 object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 }, 18007 paths = [null, undefined, fn, {}]; 18008 18009 lodashStable.times(2, function(index) { 18010 var actual = lodashStable.map(paths, function(path) { 18011 var prop = _.property(index ? [path] : path); 18012 return prop(object); 18013 }); 18014 18015 assert.deepEqual(actual, expected); 18016 }); 18017 }); 18018 18019 QUnit.test('should pluck a key over a path', function(assert) { 18020 assert.expect(2); 18021 18022 var object = { 'a.b': 1, 'a': { 'b': 2 } }; 18023 18024 lodashStable.each(['a.b', ['a.b']], function(path) { 18025 var prop = _.property(path); 18026 assert.strictEqual(prop(object), 1); 18027 }); 18028 }); 18029 18030 QUnit.test('should return `undefined` when `object` is nullish', function(assert) { 18031 assert.expect(2); 18032 18033 var values = [, null, undefined], 18034 expected = lodashStable.map(values, noop); 18035 18036 lodashStable.each(['constructor', ['constructor']], function(path) { 18037 var prop = _.property(path); 18038 18039 var actual = lodashStable.map(values, function(value, index) { 18040 return index ? prop(value) : prop(); 18041 }); 18042 18043 assert.deepEqual(actual, expected); 18044 }); 18045 }); 18046 18047 QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) { 18048 assert.expect(2); 18049 18050 var values = [, null, undefined], 18051 expected = lodashStable.map(values, noop); 18052 18053 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 18054 var prop = _.property(path); 18055 18056 var actual = lodashStable.map(values, function(value, index) { 18057 return index ? prop(value) : prop(); 18058 }); 18059 18060 assert.deepEqual(actual, expected); 18061 }); 18062 }); 18063 18064 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) { 18065 assert.expect(4); 18066 18067 var object = {}; 18068 18069 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) { 18070 var prop = _.property(path); 18071 assert.strictEqual(prop(object), undefined); 18072 }); 18073 }); 18074 }()); 18075 18076 /*--------------------------------------------------------------------------*/ 18077 18078 QUnit.module('lodash.propertyOf'); 18079 18080 (function() { 18081 QUnit.test('should create a function that plucks a property value of a given key', function(assert) { 18082 assert.expect(3); 18083 18084 var object = { 'a': 1 }, 18085 propOf = _.propertyOf(object); 18086 18087 assert.strictEqual(propOf.length, 1); 18088 lodashStable.each(['a', ['a']], function(path) { 18089 assert.strictEqual(propOf(path), 1); 18090 }); 18091 }); 18092 18093 QUnit.test('should pluck deep property values', function(assert) { 18094 assert.expect(2); 18095 18096 var object = { 'a': { 'b': 2 } }, 18097 propOf = _.propertyOf(object); 18098 18099 lodashStable.each(['a.b', ['a', 'b']], function(path) { 18100 assert.strictEqual(propOf(path), 2); 18101 }); 18102 }); 18103 18104 QUnit.test('should pluck inherited property values', function(assert) { 18105 assert.expect(2); 18106 18107 function Foo() { 18108 this.a = 1; 18109 } 18110 Foo.prototype.b = 2; 18111 18112 var propOf = _.propertyOf(new Foo); 18113 18114 lodashStable.each(['b', ['b']], function(path) { 18115 assert.strictEqual(propOf(path), 2); 18116 }); 18117 }); 18118 18119 QUnit.test('should work with a non-string `path`', function(assert) { 18120 assert.expect(2); 18121 18122 var array = [1, 2, 3], 18123 propOf = _.propertyOf(array); 18124 18125 lodashStable.each([1, [1]], function(path) { 18126 assert.strictEqual(propOf(path), 2); 18127 }); 18128 }); 18129 18130 QUnit.test('should preserve the sign of `0`', function(assert) { 18131 assert.expect(1); 18132 18133 var object = { '-0': 'a', '0': 'b' }, 18134 props = [-0, Object(-0), 0, Object(0)]; 18135 18136 var actual = lodashStable.map(props, function(key) { 18137 var propOf = _.propertyOf(object); 18138 return propOf(key); 18139 }); 18140 18141 assert.deepEqual(actual, ['a', 'a', 'b', 'b']); 18142 }); 18143 18144 QUnit.test('should coerce `path` to a string', function(assert) { 18145 assert.expect(2); 18146 18147 function fn() {} 18148 fn.toString = lodashStable.constant('fn'); 18149 18150 var expected = [1, 2, 3, 4], 18151 object = { 'null': 1, 'undefined': 2, 'fn': 3, '[object Object]': 4 }, 18152 paths = [null, undefined, fn, {}]; 18153 18154 lodashStable.times(2, function(index) { 18155 var actual = lodashStable.map(paths, function(path) { 18156 var propOf = _.propertyOf(object); 18157 return propOf(index ? [path] : path); 18158 }); 18159 18160 assert.deepEqual(actual, expected); 18161 }); 18162 }); 18163 18164 QUnit.test('should pluck a key over a path', function(assert) { 18165 assert.expect(2); 18166 18167 var object = { 'a.b': 1, 'a': { 'b': 2 } }, 18168 propOf = _.propertyOf(object); 18169 18170 lodashStable.each(['a.b', ['a.b']], function(path) { 18171 assert.strictEqual(propOf(path), 1); 18172 }); 18173 }); 18174 18175 QUnit.test('should return `undefined` when `object` is nullish', function(assert) { 18176 assert.expect(2); 18177 18178 var values = [, null, undefined], 18179 expected = lodashStable.map(values, noop); 18180 18181 lodashStable.each(['constructor', ['constructor']], function(path) { 18182 var actual = lodashStable.map(values, function(value, index) { 18183 var propOf = index ? _.propertyOf(value) : _.propertyOf(); 18184 return propOf(path); 18185 }); 18186 18187 assert.deepEqual(actual, expected); 18188 }); 18189 }); 18190 18191 QUnit.test('should return `undefined` for deep paths when `object` is nullish', function(assert) { 18192 assert.expect(2); 18193 18194 var values = [, null, undefined], 18195 expected = lodashStable.map(values, noop); 18196 18197 lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) { 18198 var actual = lodashStable.map(values, function(value, index) { 18199 var propOf = index ? _.propertyOf(value) : _.propertyOf(); 18200 return propOf(path); 18201 }); 18202 18203 assert.deepEqual(actual, expected); 18204 }); 18205 }); 18206 18207 QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) { 18208 assert.expect(4); 18209 18210 var propOf = _.propertyOf({}); 18211 18212 lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) { 18213 assert.strictEqual(propOf(path), undefined); 18214 }); 18215 }); 18216 }()); 18217 18218 /*--------------------------------------------------------------------------*/ 18219 18220 QUnit.module('lodash.pullAll'); 18221 18222 (function() { 18223 QUnit.test('should work with the same value for `array` and `values`', function(assert) { 18224 assert.expect(1); 18225 18226 var array = [{ 'a': 1 }, { 'b': 2 }], 18227 actual = _.pullAll(array, array); 18228 18229 assert.deepEqual(actual, []); 18230 }); 18231 }()); 18232 18233 /*--------------------------------------------------------------------------*/ 18234 18235 QUnit.module('lodash.pullAllBy'); 18236 18237 (function() { 18238 QUnit.test('should accept an `iteratee`', function(assert) { 18239 assert.expect(1); 18240 18241 var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; 18242 18243 var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) { 18244 return object.x; 18245 }); 18246 18247 assert.deepEqual(actual, [{ 'x': 2 }]); 18248 }); 18249 18250 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 18251 assert.expect(1); 18252 18253 var args, 18254 array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; 18255 18256 _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() { 18257 args || (args = slice.call(arguments)); 18258 }); 18259 18260 assert.deepEqual(args, [{ 'x': 1 }]); 18261 }); 18262 }()); 18263 18264 /*--------------------------------------------------------------------------*/ 18265 18266 QUnit.module('lodash.pullAllWith'); 18267 18268 (function() { 18269 QUnit.test('should work with a `comparator`', function(assert) { 18270 assert.expect(1); 18271 18272 var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }], 18273 expected = [objects[0], objects[2]], 18274 actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual); 18275 18276 assert.deepEqual(actual, expected); 18277 }); 18278 }()); 18279 18280 /*--------------------------------------------------------------------------*/ 18281 18282 QUnit.module('pull methods'); 18283 18284 lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) { 18285 var func = _[methodName], 18286 isPull = methodName == 'pull'; 18287 18288 function pull(array, values) { 18289 return isPull 18290 ? func.apply(undefined, [array].concat(values)) 18291 : func(array, values); 18292 } 18293 18294 QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) { 18295 assert.expect(2); 18296 18297 var array = [1, 2, 3], 18298 actual = pull(array, [1, 3]); 18299 18300 assert.strictEqual(actual, array); 18301 assert.deepEqual(array, [2]); 18302 }); 18303 18304 QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) { 18305 assert.expect(2); 18306 18307 var array = [1, 2, 3, 4]; 18308 delete array[1]; 18309 delete array[3]; 18310 18311 pull(array, [1]); 18312 assert.notOk('0' in array); 18313 assert.notOk('2' in array); 18314 }); 18315 18316 QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) { 18317 assert.expect(1); 18318 18319 var array = [1, 2, 3]; 18320 delete array[1]; 18321 18322 pull(array, [undefined]); 18323 assert.deepEqual(array, [1, 3]); 18324 }); 18325 18326 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { 18327 assert.expect(1); 18328 18329 var array = [1, NaN, 3, NaN]; 18330 18331 pull(array, [NaN]); 18332 assert.deepEqual(array, [1, 3]); 18333 }); 18334 }); 18335 18336 /*--------------------------------------------------------------------------*/ 18337 18338 QUnit.module('lodash.pullAt'); 18339 18340 (function() { 18341 QUnit.test('should modify the array and return removed elements', function(assert) { 18342 assert.expect(2); 18343 18344 var array = [1, 2, 3], 18345 actual = _.pullAt(array, [0, 1]); 18346 18347 assert.deepEqual(array, [3]); 18348 assert.deepEqual(actual, [1, 2]); 18349 }); 18350 18351 QUnit.test('should work with unsorted indexes', function(assert) { 18352 assert.expect(2); 18353 18354 var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 18355 actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]); 18356 18357 assert.deepEqual(array, [1, 3, 5, 7, 9, 11]); 18358 assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]); 18359 }); 18360 18361 QUnit.test('should work with repeated indexes', function(assert) { 18362 assert.expect(2); 18363 18364 var array = [1, 2, 3, 4], 18365 actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]); 18366 18367 assert.deepEqual(array, [4]); 18368 assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]); 18369 }); 18370 18371 QUnit.test('should use `undefined` for nonexistent indexes', function(assert) { 18372 assert.expect(2); 18373 18374 var array = ['a', 'b', 'c'], 18375 actual = _.pullAt(array, [2, 4, 0]); 18376 18377 assert.deepEqual(array, ['b']); 18378 assert.deepEqual(actual, ['c', undefined, 'a']); 18379 }); 18380 18381 QUnit.test('should flatten `indexes`', function(assert) { 18382 assert.expect(4); 18383 18384 var array = ['a', 'b', 'c']; 18385 assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']); 18386 assert.deepEqual(array, ['b']); 18387 18388 array = ['a', 'b', 'c', 'd']; 18389 assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']); 18390 assert.deepEqual(array, ['b']); 18391 }); 18392 18393 QUnit.test('should return an empty array when no indexes are given', function(assert) { 18394 assert.expect(4); 18395 18396 var array = ['a', 'b', 'c'], 18397 actual = _.pullAt(array); 18398 18399 assert.deepEqual(array, ['a', 'b', 'c']); 18400 assert.deepEqual(actual, []); 18401 18402 actual = _.pullAt(array, [], []); 18403 18404 assert.deepEqual(array, ['a', 'b', 'c']); 18405 assert.deepEqual(actual, []); 18406 }); 18407 18408 QUnit.test('should work with non-index paths', function(assert) { 18409 assert.expect(2); 18410 18411 var values = lodashStable.reject(empties, function(value) { 18412 return (value === 0) || lodashStable.isArray(value); 18413 }).concat(-1, 1.1); 18414 18415 var array = lodashStable.transform(values, function(result, value) { 18416 result[value] = 1; 18417 }, []); 18418 18419 var expected = lodashStable.map(values, stubOne), 18420 actual = _.pullAt(array, values); 18421 18422 assert.deepEqual(actual, expected); 18423 18424 expected = lodashStable.map(values, noop); 18425 actual = lodashStable.at(array, values); 18426 18427 assert.deepEqual(actual, expected); 18428 }); 18429 18430 QUnit.test('should preserve the sign of `0`', function(assert) { 18431 assert.expect(1); 18432 18433 var props = [-0, Object(-0), 0, Object(0)]; 18434 18435 var actual = lodashStable.map(props, function(key) { 18436 var array = [-1]; 18437 array['-0'] = -2; 18438 return _.pullAt(array, key); 18439 }); 18440 18441 assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]); 18442 }); 18443 18444 QUnit.test('should support deep paths', function(assert) { 18445 assert.expect(3); 18446 18447 var array = []; 18448 array.a = { 'b': 2 }; 18449 18450 var actual = _.pullAt(array, 'a.b'); 18451 18452 assert.deepEqual(actual, [2]); 18453 assert.deepEqual(array.a, {}); 18454 18455 try { 18456 actual = _.pullAt(array, 'a.b.c'); 18457 } catch (e) {} 18458 18459 assert.deepEqual(actual, [undefined]); 18460 }); 18461 18462 QUnit.test('should work with a falsey `array` when keys are given', function(assert) { 18463 assert.expect(1); 18464 18465 var values = falsey.slice(), 18466 expected = lodashStable.map(values, lodashStable.constant(Array(4))); 18467 18468 var actual = lodashStable.map(values, function(array) { 18469 try { 18470 return _.pullAt(array, 0, 1, 'pop', 'push'); 18471 } catch (e) {} 18472 }); 18473 18474 assert.deepEqual(actual, expected); 18475 }); 18476 }()); 18477 18478 /*--------------------------------------------------------------------------*/ 18479 18480 QUnit.module('lodash.random'); 18481 18482 (function() { 18483 var array = Array(1000); 18484 18485 QUnit.test('should return `0` or `1` when no arguments are given', function(assert) { 18486 assert.expect(1); 18487 18488 var actual = lodashStable.uniq(lodashStable.map(array, function() { 18489 return _.random(); 18490 })).sort(); 18491 18492 assert.deepEqual(actual, [0, 1]); 18493 }); 18494 18495 QUnit.test('should support a `min` and `max`', function(assert) { 18496 assert.expect(1); 18497 18498 var min = 5, 18499 max = 10; 18500 18501 assert.ok(lodashStable.some(array, function() { 18502 var result = _.random(min, max); 18503 return result >= min && result <= max; 18504 })); 18505 }); 18506 18507 QUnit.test('should support not providing a `max`', function(assert) { 18508 assert.expect(1); 18509 18510 var min = 0, 18511 max = 5; 18512 18513 assert.ok(lodashStable.some(array, function() { 18514 var result = _.random(max); 18515 return result >= min && result <= max; 18516 })); 18517 }); 18518 18519 QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) { 18520 assert.expect(1); 18521 18522 var min = 4, 18523 max = 2, 18524 expected = [2, 3, 4]; 18525 18526 var actual = lodashStable.uniq(lodashStable.map(array, function() { 18527 return _.random(min, max); 18528 })).sort(); 18529 18530 assert.deepEqual(actual, expected); 18531 }); 18532 18533 QUnit.test('should support large integer values', function(assert) { 18534 assert.expect(2); 18535 18536 var min = Math.pow(2, 31), 18537 max = Math.pow(2, 62); 18538 18539 assert.ok(lodashStable.every(array, function() { 18540 var result = _.random(min, max); 18541 return result >= min && result <= max; 18542 })); 18543 18544 assert.ok(lodashStable.some(array, function() { 18545 return _.random(MAX_INTEGER); 18546 })); 18547 }); 18548 18549 QUnit.test('should coerce arguments to finite numbers', function(assert) { 18550 assert.expect(1); 18551 18552 var actual = [ 18553 _.random(NaN, NaN), 18554 _.random('1', '1'), 18555 _.random(Infinity, Infinity) 18556 ]; 18557 18558 assert.deepEqual(actual, [0, 1, MAX_INTEGER]); 18559 }); 18560 18561 QUnit.test('should support floats', function(assert) { 18562 assert.expect(2); 18563 18564 var min = 1.5, 18565 max = 1.6, 18566 actual = _.random(min, max); 18567 18568 assert.ok(actual % 1); 18569 assert.ok(actual >= min && actual <= max); 18570 }); 18571 18572 QUnit.test('should support providing a `floating`', function(assert) { 18573 assert.expect(3); 18574 18575 var actual = _.random(true); 18576 assert.ok(actual % 1 && actual >= 0 && actual <= 1); 18577 18578 actual = _.random(2, true); 18579 assert.ok(actual % 1 && actual >= 0 && actual <= 2); 18580 18581 actual = _.random(2, 4, true); 18582 assert.ok(actual % 1 && actual >= 2 && actual <= 4); 18583 }); 18584 18585 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 18586 assert.expect(1); 18587 18588 var array = [1, 2, 3], 18589 expected = lodashStable.map(array, stubTrue), 18590 randoms = lodashStable.map(array, _.random); 18591 18592 var actual = lodashStable.map(randoms, function(result, index) { 18593 return result >= 0 && result <= array[index] && (result % 1) == 0; 18594 }); 18595 18596 assert.deepEqual(actual, expected); 18597 }); 18598 }()); 18599 18600 /*--------------------------------------------------------------------------*/ 18601 18602 QUnit.module('range methods'); 18603 18604 lodashStable.each(['range', 'rangeRight'], function(methodName) { 18605 var func = _[methodName], 18606 isRange = methodName == 'range'; 18607 18608 function resolve(range) { 18609 return isRange ? range : range.reverse(); 18610 } 18611 18612 QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) { 18613 assert.expect(2); 18614 18615 assert.deepEqual(func(4), resolve([0, 1, 2, 3])); 18616 assert.deepEqual(func(-4), resolve([0, -1, -2, -3])); 18617 }); 18618 18619 QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) { 18620 assert.expect(2); 18621 18622 assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4])); 18623 assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2])); 18624 }); 18625 18626 QUnit.test('`_.' + methodName + '` should work with a `start`, `end`, and `step`', function(assert) { 18627 assert.expect(3); 18628 18629 assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3])); 18630 assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2])); 18631 assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15])); 18632 }); 18633 18634 QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) { 18635 assert.expect(1); 18636 18637 assert.deepEqual(func(1, 4, 0), [1, 1, 1]); 18638 }); 18639 18640 QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) { 18641 assert.expect(1); 18642 18643 assert.deepEqual(func(1, 5, 20), [1]); 18644 }); 18645 18646 QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) { 18647 assert.expect(2); 18648 18649 assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3])); 18650 assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12])); 18651 }); 18652 18653 QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) { 18654 assert.expect(1); 18655 18656 var actual = func(-0, 1); 18657 assert.strictEqual(1 / actual[0], -Infinity); 18658 }); 18659 18660 QUnit.test('`_.' + methodName + '` should treat falsey `start` as `0`', function(assert) { 18661 assert.expect(13); 18662 18663 lodashStable.each(falsey, function(value, index) { 18664 if (index) { 18665 assert.deepEqual(func(value), []); 18666 assert.deepEqual(func(value, 1), [0]); 18667 } else { 18668 assert.deepEqual(func(), []); 18669 } 18670 }); 18671 }); 18672 18673 QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) { 18674 assert.expect(1); 18675 18676 var actual = [ 18677 func('1'), 18678 func('0', 1), 18679 func(0, 1, '1'), 18680 func(NaN), 18681 func(NaN, NaN) 18682 ]; 18683 18684 assert.deepEqual(actual, [[0], [0], [0], [], []]); 18685 }); 18686 18687 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) { 18688 assert.expect(2); 18689 18690 var array = [1, 2, 3], 18691 object = { 'a': 1, 'b': 2, 'c': 3 }, 18692 expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve); 18693 18694 lodashStable.each([array, object], function(collection) { 18695 var actual = lodashStable.map(collection, func); 18696 assert.deepEqual(actual, expected); 18697 }); 18698 }); 18699 }); 18700 18701 /*--------------------------------------------------------------------------*/ 18702 18703 QUnit.module('lodash.rearg'); 18704 18705 (function() { 18706 function fn() { 18707 return slice.call(arguments); 18708 } 18709 18710 QUnit.test('should reorder arguments provided to `func`', function(assert) { 18711 assert.expect(1); 18712 18713 var rearged = _.rearg(fn, [2, 0, 1]); 18714 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']); 18715 }); 18716 18717 QUnit.test('should work with repeated indexes', function(assert) { 18718 assert.expect(1); 18719 18720 var rearged = _.rearg(fn, [1, 1, 1]); 18721 assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']); 18722 }); 18723 18724 QUnit.test('should use `undefined` for nonexistent indexes', function(assert) { 18725 assert.expect(1); 18726 18727 var rearged = _.rearg(fn, [1, 4]); 18728 assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']); 18729 }); 18730 18731 QUnit.test('should use `undefined` for non-index values', function(assert) { 18732 assert.expect(1); 18733 18734 var values = lodashStable.reject(empties, function(value) { 18735 return (value === 0) || lodashStable.isArray(value); 18736 }).concat(-1, 1.1); 18737 18738 var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c'])); 18739 18740 var actual = lodashStable.map(values, function(value) { 18741 var rearged = _.rearg(fn, [value]); 18742 return rearged('a', 'b', 'c'); 18743 }); 18744 18745 assert.deepEqual(actual, expected); 18746 }); 18747 18748 QUnit.test('should not rearrange arguments when no indexes are given', function(assert) { 18749 assert.expect(2); 18750 18751 var rearged = _.rearg(fn); 18752 assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']); 18753 18754 rearged = _.rearg(fn, [], []); 18755 assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']); 18756 }); 18757 18758 QUnit.test('should accept multiple index arguments', function(assert) { 18759 assert.expect(1); 18760 18761 var rearged = _.rearg(fn, 2, 0, 1); 18762 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']); 18763 }); 18764 18765 QUnit.test('should accept multiple arrays of indexes', function(assert) { 18766 assert.expect(1); 18767 18768 var rearged = _.rearg(fn, [2], [0, 1]); 18769 assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']); 18770 }); 18771 18772 QUnit.test('should work with fewer indexes than arguments', function(assert) { 18773 assert.expect(1); 18774 18775 var rearged = _.rearg(fn, [1, 0]); 18776 assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']); 18777 }); 18778 18779 QUnit.test('should work on functions that have been rearged', function(assert) { 18780 assert.expect(1); 18781 18782 var rearged1 = _.rearg(fn, 2, 1, 0), 18783 rearged2 = _.rearg(rearged1, 1, 0, 2); 18784 18785 assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']); 18786 }); 18787 }()); 18788 18789 /*--------------------------------------------------------------------------*/ 18790 18791 QUnit.module('lodash.reduce'); 18792 18793 (function() { 18794 var array = [1, 2, 3]; 18795 18796 QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) { 18797 assert.expect(1); 18798 18799 assert.strictEqual(_.reduce(array), 1); 18800 }); 18801 18802 QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) { 18803 assert.expect(2); 18804 18805 var args; 18806 18807 _.reduce(array, function() { 18808 args || (args = slice.call(arguments)); 18809 }, 0); 18810 18811 assert.deepEqual(args, [0, 1, 0, array]); 18812 18813 args = undefined; 18814 _.reduce(array, function() { 18815 args || (args = slice.call(arguments)); 18816 }); 18817 18818 assert.deepEqual(args, [1, 2, 1, array]); 18819 }); 18820 18821 QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) { 18822 assert.expect(2); 18823 18824 var args, 18825 object = { 'a': 1, 'b': 2 }, 18826 firstKey = _.head(_.keys(object)); 18827 18828 var expected = firstKey == 'a' 18829 ? [0, 1, 'a', object] 18830 : [0, 2, 'b', object]; 18831 18832 _.reduce(object, function() { 18833 args || (args = slice.call(arguments)); 18834 }, 0); 18835 18836 assert.deepEqual(args, expected); 18837 18838 args = undefined; 18839 expected = firstKey == 'a' 18840 ? [1, 2, 'b', object] 18841 : [2, 1, 'a', object]; 18842 18843 _.reduce(object, function() { 18844 args || (args = slice.call(arguments)); 18845 }); 18846 18847 assert.deepEqual(args, expected); 18848 }); 18849 }()); 18850 18851 /*--------------------------------------------------------------------------*/ 18852 18853 QUnit.module('lodash.reduceRight'); 18854 18855 (function() { 18856 var array = [1, 2, 3]; 18857 18858 QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) { 18859 assert.expect(1); 18860 18861 assert.strictEqual(_.reduceRight(array), 3); 18862 }); 18863 18864 QUnit.test('should provide correct `iteratee` arguments when iterating an array', function(assert) { 18865 assert.expect(2); 18866 18867 var args; 18868 18869 _.reduceRight(array, function() { 18870 args || (args = slice.call(arguments)); 18871 }, 0); 18872 18873 assert.deepEqual(args, [0, 3, 2, array]); 18874 18875 args = undefined; 18876 _.reduceRight(array, function() { 18877 args || (args = slice.call(arguments)); 18878 }); 18879 18880 assert.deepEqual(args, [3, 2, 1, array]); 18881 }); 18882 18883 QUnit.test('should provide correct `iteratee` arguments when iterating an object', function(assert) { 18884 assert.expect(2); 18885 18886 var args, 18887 object = { 'a': 1, 'b': 2 }, 18888 isFIFO = lodashStable.keys(object)[0] == 'a'; 18889 18890 var expected = isFIFO 18891 ? [0, 2, 'b', object] 18892 : [0, 1, 'a', object]; 18893 18894 _.reduceRight(object, function() { 18895 args || (args = slice.call(arguments)); 18896 }, 0); 18897 18898 assert.deepEqual(args, expected); 18899 18900 args = undefined; 18901 expected = isFIFO 18902 ? [2, 1, 'a', object] 18903 : [1, 2, 'b', object]; 18904 18905 _.reduceRight(object, function() { 18906 args || (args = slice.call(arguments)); 18907 }); 18908 18909 assert.deepEqual(args, expected); 18910 }); 18911 }()); 18912 18913 /*--------------------------------------------------------------------------*/ 18914 18915 QUnit.module('reduce methods'); 18916 18917 lodashStable.each(['reduce', 'reduceRight'], function(methodName) { 18918 var func = _[methodName], 18919 array = [1, 2, 3], 18920 isReduce = methodName == 'reduce'; 18921 18922 QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) { 18923 assert.expect(1); 18924 18925 var actual = func(['a', 'b', 'c'], function(accumulator, value) { 18926 return accumulator + value; 18927 }, ''); 18928 18929 assert.strictEqual(actual, isReduce ? 'abc' : 'cba'); 18930 }); 18931 18932 QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) { 18933 assert.expect(1); 18934 18935 var actual = [], 18936 expected = lodashStable.map(empties, noop); 18937 18938 lodashStable.each(empties, function(value) { 18939 try { 18940 actual.push(func(value, noop)); 18941 } catch (e) {} 18942 }); 18943 18944 assert.deepEqual(actual, expected); 18945 }); 18946 18947 QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) { 18948 assert.expect(1); 18949 18950 var expected = lodashStable.map(empties, lodashStable.constant('x')); 18951 18952 var actual = lodashStable.map(empties, function(value) { 18953 try { 18954 return func(value, noop, 'x'); 18955 } catch (e) {} 18956 }); 18957 18958 assert.deepEqual(actual, expected); 18959 }); 18960 18961 QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) { 18962 assert.expect(1); 18963 18964 var actual = func([], noop, undefined); 18965 assert.strictEqual(actual, undefined); 18966 }); 18967 18968 QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) { 18969 assert.expect(2); 18970 18971 var array = [], 18972 object = { '0': 1, 'length': 0 }; 18973 18974 if ('__proto__' in array) { 18975 array.__proto__ = object; 18976 assert.strictEqual(func(array, noop), undefined); 18977 } 18978 else { 18979 skipAssert(assert); 18980 } 18981 assert.strictEqual(func(object, noop), undefined); 18982 }); 18983 18984 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 18985 assert.expect(1); 18986 18987 if (!isNpm) { 18988 assert.strictEqual(_(array)[methodName](add), 6); 18989 } 18990 else { 18991 skipAssert(assert); 18992 } 18993 }); 18994 18995 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 18996 assert.expect(1); 18997 18998 if (!isNpm) { 18999 assert.ok(_(array).chain()[methodName](add) instanceof _); 19000 } 19001 else { 19002 skipAssert(assert); 19003 } 19004 }); 19005 }); 19006 19007 /*--------------------------------------------------------------------------*/ 19008 19009 QUnit.module('lodash.reject'); 19010 19011 (function() { 19012 var array = [1, 2, 3]; 19013 19014 QUnit.test('should return elements the `predicate` returns falsey for', function(assert) { 19015 assert.expect(1); 19016 19017 assert.deepEqual(_.reject(array, isEven), [1, 3]); 19018 }); 19019 }()); 19020 19021 /*--------------------------------------------------------------------------*/ 19022 19023 QUnit.module('filter methods'); 19024 19025 lodashStable.each(['filter', 'reject'], function(methodName) { 19026 var array = [1, 2, 3, 4], 19027 func = _[methodName], 19028 isFilter = methodName == 'filter', 19029 objects = [{ 'a': 0 }, { 'a': 1 }]; 19030 19031 QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) { 19032 assert.expect(1); 19033 19034 var actual = func([0], function(value, index, array) { 19035 array[index] = 1; 19036 return isFilter; 19037 }); 19038 19039 assert.deepEqual(actual, [0]); 19040 }); 19041 19042 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) { 19043 assert.expect(1); 19044 19045 assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]); 19046 }); 19047 19048 QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) { 19049 assert.expect(1); 19050 19051 assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]); 19052 }); 19053 19054 QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) { 19055 assert.expect(2); 19056 19057 if (!isNpm) { 19058 var wrapped = _(array); 19059 19060 var actual = wrapped[methodName](function(n) { 19061 return n < 3; 19062 }); 19063 19064 assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]); 19065 19066 actual = wrapped[methodName](function(n) { 19067 return n > 2; 19068 }); 19069 19070 assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]); 19071 } 19072 else { 19073 skipAssert(assert, 2); 19074 } 19075 }); 19076 19077 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) { 19078 assert.expect(2); 19079 19080 if (!isNpm) { 19081 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1), 19082 predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); }; 19083 19084 var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 19085 return ['key' + index, index]; 19086 })); 19087 19088 var actual = _(array).slice(1).map(square)[methodName](predicate).value(); 19089 assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate)); 19090 19091 actual = _(object).mapValues(square)[methodName](predicate).value(); 19092 assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate)); 19093 } 19094 else { 19095 skipAssert(assert, 2); 19096 } 19097 }); 19098 19099 QUnit.test('`_.' + methodName + '` should provide correct `predicate` arguments in a lazy sequence', function(assert) { 19100 assert.expect(5); 19101 19102 if (!isNpm) { 19103 var args, 19104 array = lodashStable.range(LARGE_ARRAY_SIZE + 1), 19105 expected = [1, 0, lodashStable.map(array.slice(1), square)]; 19106 19107 _(array).slice(1)[methodName](function(value, index, array) { 19108 args || (args = slice.call(arguments)); 19109 }).value(); 19110 19111 assert.deepEqual(args, [1, 0, array.slice(1)]); 19112 19113 args = undefined; 19114 _(array).slice(1).map(square)[methodName](function(value, index, array) { 19115 args || (args = slice.call(arguments)); 19116 }).value(); 19117 19118 assert.deepEqual(args, expected); 19119 19120 args = undefined; 19121 _(array).slice(1).map(square)[methodName](function(value, index) { 19122 args || (args = slice.call(arguments)); 19123 }).value(); 19124 19125 assert.deepEqual(args, expected); 19126 19127 args = undefined; 19128 _(array).slice(1).map(square)[methodName](function(value) { 19129 args || (args = slice.call(arguments)); 19130 }).value(); 19131 19132 assert.deepEqual(args, [1]); 19133 19134 args = undefined; 19135 _(array).slice(1).map(square)[methodName](function() { 19136 args || (args = slice.call(arguments)); 19137 }).value(); 19138 19139 assert.deepEqual(args, expected); 19140 } 19141 else { 19142 skipAssert(assert, 5); 19143 } 19144 }); 19145 }); 19146 19147 /*--------------------------------------------------------------------------*/ 19148 19149 QUnit.module('lodash.remove'); 19150 19151 (function() { 19152 QUnit.test('should modify the array and return removed elements', function(assert) { 19153 assert.expect(2); 19154 19155 var array = [1, 2, 3, 4], 19156 actual = _.remove(array, isEven); 19157 19158 assert.deepEqual(array, [1, 3]); 19159 assert.deepEqual(actual, [2, 4]); 19160 }); 19161 19162 QUnit.test('should provide correct `predicate` arguments', function(assert) { 19163 assert.expect(1); 19164 19165 var argsList = [], 19166 array = [1, 2, 3], 19167 clone = array.slice(); 19168 19169 _.remove(array, function(n, index) { 19170 var args = slice.call(arguments); 19171 args[2] = args[2].slice(); 19172 argsList.push(args); 19173 return isEven(index); 19174 }); 19175 19176 assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]); 19177 }); 19178 19179 QUnit.test('should work with `_.matches` shorthands', function(assert) { 19180 assert.expect(1); 19181 19182 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }]; 19183 _.remove(objects, { 'a': 1 }); 19184 assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]); 19185 }); 19186 19187 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 19188 assert.expect(1); 19189 19190 var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }]; 19191 _.remove(objects, ['a', 1]); 19192 assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]); 19193 }); 19194 19195 QUnit.test('should work with `_.property` shorthands', function(assert) { 19196 assert.expect(1); 19197 19198 var objects = [{ 'a': 0 }, { 'a': 1 }]; 19199 _.remove(objects, 'a'); 19200 assert.deepEqual(objects, [{ 'a': 0 }]); 19201 }); 19202 19203 QUnit.test('should preserve holes in arrays', function(assert) { 19204 assert.expect(2); 19205 19206 var array = [1, 2, 3, 4]; 19207 delete array[1]; 19208 delete array[3]; 19209 19210 _.remove(array, function(n) { 19211 return n === 1; 19212 }); 19213 19214 assert.notOk('0' in array); 19215 assert.notOk('2' in array); 19216 }); 19217 19218 QUnit.test('should treat holes as `undefined`', function(assert) { 19219 assert.expect(1); 19220 19221 var array = [1, 2, 3]; 19222 delete array[1]; 19223 19224 _.remove(array, function(n) { 19225 return n == null; 19226 }); 19227 19228 assert.deepEqual(array, [1, 3]); 19229 }); 19230 19231 QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) { 19232 assert.expect(1); 19233 19234 var array = [1, 2, 3]; 19235 19236 _.remove(array, function(n, index) { 19237 return isEven(index); 19238 }); 19239 19240 assert.deepEqual(array, [2]); 19241 }); 19242 }()); 19243 19244 /*--------------------------------------------------------------------------*/ 19245 19246 QUnit.module('lodash.repeat'); 19247 19248 (function() { 19249 var string = 'abc'; 19250 19251 QUnit.test('should repeat a string `n` times', function(assert) { 19252 assert.expect(2); 19253 19254 assert.strictEqual(_.repeat('*', 3), '***'); 19255 assert.strictEqual(_.repeat(string, 2), 'abcabc'); 19256 }); 19257 19258 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) { 19259 assert.expect(1); 19260 19261 var expected = lodashStable.map(falsey, function(value) { 19262 return value === undefined ? string : ''; 19263 }); 19264 19265 var actual = lodashStable.map(falsey, function(n, index) { 19266 return index ? _.repeat(string, n) : _.repeat(string); 19267 }); 19268 19269 assert.deepEqual(actual, expected); 19270 }); 19271 19272 QUnit.test('should return an empty string if `n` is <= `0`', function(assert) { 19273 assert.expect(2); 19274 19275 assert.strictEqual(_.repeat(string, 0), ''); 19276 assert.strictEqual(_.repeat(string, -2), ''); 19277 }); 19278 19279 QUnit.test('should coerce `n` to an integer', function(assert) { 19280 assert.expect(3); 19281 19282 assert.strictEqual(_.repeat(string, '2'), 'abcabc'); 19283 assert.strictEqual(_.repeat(string, 2.6), 'abcabc'); 19284 assert.strictEqual(_.repeat('*', { 'valueOf': stubThree }), '***'); 19285 }); 19286 19287 QUnit.test('should coerce `string` to a string', function(assert) { 19288 assert.expect(2); 19289 19290 assert.strictEqual(_.repeat(Object(string), 2), 'abcabc'); 19291 assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***'); 19292 }); 19293 19294 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 19295 assert.expect(1); 19296 19297 var actual = lodashStable.map(['a', 'b', 'c'], _.repeat); 19298 assert.deepEqual(actual, ['a', 'b', 'c']); 19299 }); 19300 }()); 19301 19302 /*--------------------------------------------------------------------------*/ 19303 19304 QUnit.module('lodash.replace'); 19305 19306 (function() { 19307 QUnit.test('should replace the matched pattern', function(assert) { 19308 assert.expect(2); 19309 19310 var string = 'abcde'; 19311 assert.strictEqual(_.replace(string, 'de', '123'), 'abc123'); 19312 assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e'); 19313 }); 19314 }()); 19315 19316 /*--------------------------------------------------------------------------*/ 19317 19318 QUnit.module('lodash.result'); 19319 19320 (function() { 19321 var object = { 'a': 1, 'b': stubB }; 19322 19323 QUnit.test('should invoke function values', function(assert) { 19324 assert.expect(1); 19325 19326 assert.strictEqual(_.result(object, 'b'), 'b'); 19327 }); 19328 19329 QUnit.test('should invoke default function values', function(assert) { 19330 assert.expect(1); 19331 19332 var actual = _.result(object, 'c', object.b); 19333 assert.strictEqual(actual, 'b'); 19334 }); 19335 19336 QUnit.test('should invoke nested function values', function(assert) { 19337 assert.expect(2); 19338 19339 var value = { 'a': lodashStable.constant({ 'b': stubB }) }; 19340 19341 lodashStable.each(['a.b', ['a', 'b']], function(path) { 19342 assert.strictEqual(_.result(value, path), 'b'); 19343 }); 19344 }); 19345 19346 QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) { 19347 assert.expect(2); 19348 19349 var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } }; 19350 19351 lodashStable.each(['a.b', ['a', 'b']], function(path) { 19352 assert.strictEqual(_.result(value, path), 1); 19353 }); 19354 }); 19355 }()); 19356 19357 /*--------------------------------------------------------------------------*/ 19358 19359 QUnit.module('lodash.get and lodash.result'); 19360 19361 lodashStable.each(['get', 'result'], function(methodName) { 19362 var func = _[methodName]; 19363 19364 QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) { 19365 assert.expect(2); 19366 19367 var object = { 'a': 1 }; 19368 19369 lodashStable.each(['a', ['a']], function(path) { 19370 assert.strictEqual(func(object, path), 1); 19371 }); 19372 }); 19373 19374 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 19375 assert.expect(1); 19376 19377 var object = { '-0': 'a', '0': 'b' }, 19378 props = [-0, Object(-0), 0, Object(0)]; 19379 19380 var actual = lodashStable.map(props, function(key) { 19381 return func(object, key); 19382 }); 19383 19384 assert.deepEqual(actual, ['a', 'a', 'b', 'b']); 19385 }); 19386 19387 QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) { 19388 assert.expect(1); 19389 19390 if (Symbol) { 19391 var object = {}; 19392 object[symbol] = 1; 19393 19394 assert.strictEqual(func(object, symbol), 1); 19395 } 19396 else { 19397 skipAssert(assert); 19398 } 19399 }); 19400 19401 QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) { 19402 assert.expect(2); 19403 19404 var object = { 'a': { 'b': 2 } }; 19405 19406 lodashStable.each(['a.b', ['a', 'b']], function(path) { 19407 assert.strictEqual(func(object, path), 2); 19408 }); 19409 }); 19410 19411 QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) { 19412 assert.expect(2); 19413 19414 var object = { 'a.b': 1, 'a': { 'b': 2 } }; 19415 19416 lodashStable.each(['a.b', ['a.b']], function(path) { 19417 assert.strictEqual(func(object, path), 1); 19418 }); 19419 }); 19420 19421 QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) { 19422 assert.expect(1); 19423 19424 var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } }; 19425 assert.strictEqual(func(object, ['a', 'b', 'c']), 4); 19426 }); 19427 19428 QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) { 19429 assert.expect(1); 19430 19431 var object = { 'a': { '': 1 } }; 19432 assert.strictEqual(func(object, 'a[]'), 1); 19433 }); 19434 19435 QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) { 19436 assert.expect(4); 19437 19438 lodashStable.each([['', ''], [[], ['']]], function(pair) { 19439 assert.strictEqual(func({}, pair[0]), undefined); 19440 assert.strictEqual(func({ '': 3 }, pair[1]), 3); 19441 }); 19442 }); 19443 19444 QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) { 19445 assert.expect(2); 19446 19447 var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } }; 19448 19449 var paths = [ 19450 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g', 19451 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g'] 19452 ]; 19453 19454 lodashStable.each(paths, function(path) { 19455 assert.strictEqual(func(object, path), 8); 19456 }); 19457 }); 19458 19459 QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) { 19460 assert.expect(4); 19461 19462 lodashStable.each(['constructor', ['constructor']], function(path) { 19463 assert.strictEqual(func(null, path), undefined); 19464 assert.strictEqual(func(undefined, path), undefined); 19465 }); 19466 }); 19467 19468 QUnit.test('`_.' + methodName + '` should return `undefined` for deep paths when `object` is nullish', function(assert) { 19469 assert.expect(2); 19470 19471 var values = [null, undefined], 19472 expected = lodashStable.map(values, noop), 19473 paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']]; 19474 19475 lodashStable.each(paths, function(path) { 19476 var actual = lodashStable.map(values, function(value) { 19477 return func(value, path); 19478 }); 19479 19480 assert.deepEqual(actual, expected); 19481 }); 19482 }); 19483 19484 QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) { 19485 assert.expect(2); 19486 19487 var object = { 'a': [, null] }; 19488 19489 lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) { 19490 assert.strictEqual(func(object, path), undefined); 19491 }); 19492 }); 19493 19494 QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) { 19495 assert.expect(2); 19496 19497 var object = { 'a': { 'b': null } }; 19498 19499 lodashStable.each(['a.b', ['a', 'b']], function(path) { 19500 assert.strictEqual(func(object, path), null); 19501 }); 19502 }); 19503 19504 QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) { 19505 assert.expect(2); 19506 19507 var paths = ['a.b', ['a', 'b']]; 19508 19509 lodashStable.each(paths, function(path) { 19510 numberProto.a = { 'b': 2 }; 19511 assert.strictEqual(func(0, path), 2); 19512 delete numberProto.a; 19513 }); 19514 }); 19515 19516 QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) { 19517 assert.expect(2); 19518 19519 var object = { 'a': {} }, 19520 values = empties.concat(true, new Date, 1, /x/, 'a'), 19521 expected = lodashStable.map(values, function(value) { return [value, value]; }); 19522 19523 lodashStable.each(['a.b', ['a', 'b']], function(path) { 19524 var actual = lodashStable.map(values, function(value) { 19525 return [func(object, path, value), func(null, path, value)]; 19526 }); 19527 19528 assert.deepEqual(actual, expected); 19529 }); 19530 }); 19531 19532 QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) { 19533 assert.expect(1); 19534 19535 assert.strictEqual(func({}, [], 'a'), 'a'); 19536 }); 19537 }); 19538 19539 /*--------------------------------------------------------------------------*/ 19540 19541 QUnit.module('lodash.rest'); 19542 19543 (function() { 19544 function fn(a, b, c) { 19545 return slice.call(arguments); 19546 } 19547 19548 QUnit.test('should apply a rest parameter to `func`', function(assert) { 19549 assert.expect(1); 19550 19551 var rest = _.rest(fn); 19552 assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]); 19553 }); 19554 19555 QUnit.test('should work with `start`', function(assert) { 19556 assert.expect(1); 19557 19558 var rest = _.rest(fn, 1); 19559 assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]); 19560 }); 19561 19562 QUnit.test('should treat `start` as `0` for `NaN` or negative values', function(assert) { 19563 assert.expect(1); 19564 19565 var values = [-1, NaN, 'a'], 19566 expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]])); 19567 19568 var actual = lodashStable.map(values, function(value) { 19569 var rest = _.rest(fn, value); 19570 return rest(1, 2, 3, 4); 19571 }); 19572 19573 assert.deepEqual(actual, expected); 19574 }); 19575 19576 QUnit.test('should coerce `start` to an integer', function(assert) { 19577 assert.expect(1); 19578 19579 var rest = _.rest(fn, 1.6); 19580 assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]); 19581 }); 19582 19583 QUnit.test('should use an empty array when `start` is not reached', function(assert) { 19584 assert.expect(1); 19585 19586 var rest = _.rest(fn); 19587 assert.deepEqual(rest(1), [1, undefined, []]); 19588 }); 19589 19590 QUnit.test('should work on functions with more than three parameters', function(assert) { 19591 assert.expect(1); 19592 19593 var rest = _.rest(function(a, b, c, d) { 19594 return slice.call(arguments); 19595 }); 19596 19597 assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]); 19598 }); 19599 }()); 19600 19601 /*--------------------------------------------------------------------------*/ 19602 19603 QUnit.module('lodash.reverse'); 19604 19605 (function() { 19606 var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null), 19607 smallArray = [0, 1, 2, null]; 19608 19609 QUnit.test('should reverse `array`', function(assert) { 19610 assert.expect(2); 19611 19612 var array = [1, 2, 3], 19613 actual = _.reverse(array); 19614 19615 assert.strictEqual(actual, array); 19616 assert.deepEqual(array, [3, 2, 1]); 19617 }); 19618 19619 QUnit.test('should return the wrapped reversed `array`', function(assert) { 19620 assert.expect(6); 19621 19622 if (!isNpm) { 19623 lodashStable.times(2, function(index) { 19624 var array = (index ? largeArray : smallArray).slice(), 19625 clone = array.slice(), 19626 wrapped = _(array).reverse(), 19627 actual = wrapped.value(); 19628 19629 assert.ok(wrapped instanceof _); 19630 assert.strictEqual(actual, array); 19631 assert.deepEqual(actual, clone.slice().reverse()); 19632 }); 19633 } 19634 else { 19635 skipAssert(assert, 6); 19636 } 19637 }); 19638 19639 QUnit.test('should work in a lazy sequence', function(assert) { 19640 assert.expect(4); 19641 19642 if (!isNpm) { 19643 lodashStable.times(2, function(index) { 19644 var array = (index ? largeArray : smallArray).slice(), 19645 expected = array.slice(), 19646 actual = _(array).slice(1).reverse().value(); 19647 19648 assert.deepEqual(actual, expected.slice(1).reverse()); 19649 assert.deepEqual(array, expected); 19650 }); 19651 } 19652 else { 19653 skipAssert(assert, 4); 19654 } 19655 }); 19656 19657 QUnit.test('should be lazy when in a lazy sequence', function(assert) { 19658 assert.expect(3); 19659 19660 if (!isNpm) { 19661 var spy = { 19662 'toString': function() { 19663 throw new Error('spy was revealed'); 19664 } 19665 }; 19666 19667 var array = largeArray.concat(spy), 19668 expected = array.slice(); 19669 19670 try { 19671 var wrapped = _(array).slice(1).map(String).reverse(), 19672 actual = wrapped.last(); 19673 } catch (e) {} 19674 19675 assert.ok(wrapped instanceof _); 19676 assert.strictEqual(actual, '1'); 19677 assert.deepEqual(array, expected); 19678 } 19679 else { 19680 skipAssert(assert, 3); 19681 } 19682 }); 19683 19684 QUnit.test('should work in a hybrid sequence', function(assert) { 19685 assert.expect(8); 19686 19687 if (!isNpm) { 19688 lodashStable.times(2, function(index) { 19689 var clone = (index ? largeArray : smallArray).slice(); 19690 19691 lodashStable.each(['map', 'filter'], function(methodName) { 19692 var array = clone.slice(), 19693 expected = clone.slice(1, -1).reverse(), 19694 actual = _(array)[methodName](identity).thru(_.compact).reverse().value(); 19695 19696 assert.deepEqual(actual, expected); 19697 19698 array = clone.slice(); 19699 actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value(); 19700 19701 assert.deepEqual(actual, [3].concat(expected.slice(0, -1))); 19702 }); 19703 }); 19704 } 19705 else { 19706 skipAssert(assert, 8); 19707 } 19708 }); 19709 19710 QUnit.test('should track the `__chain__` value of a wrapper', function(assert) { 19711 assert.expect(6); 19712 19713 if (!isNpm) { 19714 lodashStable.times(2, function(index) { 19715 var array = (index ? largeArray : smallArray).slice(), 19716 expected = array.slice().reverse(), 19717 wrapped = _(array).chain().reverse().head(); 19718 19719 assert.ok(wrapped instanceof _); 19720 assert.strictEqual(wrapped.value(), _.head(expected)); 19721 assert.deepEqual(array, expected); 19722 }); 19723 } 19724 else { 19725 skipAssert(assert, 6); 19726 } 19727 }); 19728 }()); 19729 19730 /*--------------------------------------------------------------------------*/ 19731 19732 QUnit.module('round methods'); 19733 19734 lodashStable.each(['ceil', 'floor', 'round'], function(methodName) { 19735 var func = _[methodName], 19736 isCeil = methodName == 'ceil', 19737 isFloor = methodName == 'floor'; 19738 19739 QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) { 19740 assert.expect(1); 19741 19742 var actual = func(4.006); 19743 assert.strictEqual(actual, isCeil ? 5 : 4); 19744 }); 19745 19746 QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) { 19747 assert.expect(1); 19748 19749 var actual = func(4.006, 0); 19750 assert.strictEqual(actual, isCeil ? 5 : 4); 19751 }); 19752 19753 QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) { 19754 assert.expect(2); 19755 19756 var actual = func(4.016, 2); 19757 assert.strictEqual(actual, isFloor ? 4.01 : 4.02); 19758 19759 actual = func(4.1, 2); 19760 assert.strictEqual(actual, 4.1); 19761 }); 19762 19763 QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) { 19764 assert.expect(1); 19765 19766 var actual = func(4160, -2); 19767 assert.strictEqual(actual, isFloor ? 4100 : 4200); 19768 }); 19769 19770 QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) { 19771 assert.expect(3); 19772 19773 var actual = func(4.006, NaN); 19774 assert.strictEqual(actual, isCeil ? 5 : 4); 19775 19776 var expected = isFloor ? 4.01 : 4.02; 19777 19778 actual = func(4.016, 2.6); 19779 assert.strictEqual(actual, expected); 19780 19781 actual = func(4.016, '+2'); 19782 assert.strictEqual(actual, expected); 19783 }); 19784 19785 QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) { 19786 assert.expect(3); 19787 19788 var actual = func(5e1, 2); 19789 assert.deepEqual(actual, 50); 19790 19791 actual = func('5e', 1); 19792 assert.deepEqual(actual, NaN); 19793 19794 actual = func('5e1e1', 1); 19795 assert.deepEqual(actual, NaN); 19796 }); 19797 19798 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 19799 assert.expect(1); 19800 19801 var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]], 19802 expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity]; 19803 19804 var actual = lodashStable.map(values, function(args) { 19805 return 1 / func.apply(undefined, args); 19806 }); 19807 19808 assert.deepEqual(actual, expected); 19809 }); 19810 19811 QUnit.test('`_.' + methodName + '` should not return `NaN` for large `precision` values', function(assert) { 19812 assert.expect(1); 19813 19814 var results = [ 19815 _.round(10.0000001, 1000), 19816 _.round(MAX_SAFE_INTEGER, 293) 19817 ]; 19818 19819 var expected = lodashStable.map(results, stubFalse), 19820 actual = lodashStable.map(results, lodashStable.isNaN); 19821 19822 assert.deepEqual(actual, expected); 19823 }); 19824 19825 QUnit.test('`_.' + methodName + '` should return `Infinity` given `Infinity` regardless of `precision`', function(assert) { 19826 assert.expect(6); 19827 19828 var actual = func(Infinity); 19829 assert.strictEqual(actual, Infinity); 19830 19831 actual = func(Infinity, 0); 19832 assert.strictEqual(actual, Infinity); 19833 19834 actual = func(Infinity, 2); 19835 assert.strictEqual(actual, Infinity); 19836 19837 actual = func(Infinity, -2); 19838 assert.strictEqual(actual, Infinity); 19839 19840 actual = func(Infinity, 2); 19841 assert.strictEqual(actual, isFloor ? Infinity : Infinity); 19842 19843 actual = func(Infinity, 2); 19844 assert.strictEqual(actual, isCeil ? Infinity : Infinity); 19845 }); 19846 19847 QUnit.test('`_.' + methodName + '` should return `-Infinity` given `-Infinity` regardless of `precision`', function(assert) { 19848 assert.expect(6); 19849 19850 var actual = func(-Infinity); 19851 assert.strictEqual(actual, -Infinity); 19852 19853 actual = func(-Infinity, 0); 19854 assert.strictEqual(actual, -Infinity); 19855 19856 actual = func(-Infinity, 2); 19857 assert.strictEqual(actual, -Infinity); 19858 19859 actual = func(-Infinity, -2); 19860 assert.strictEqual(actual, -Infinity); 19861 19862 actual = func(-Infinity, 2); 19863 assert.strictEqual(actual, isFloor ? -Infinity : -Infinity); 19864 19865 actual = func(-Infinity, 2); 19866 assert.strictEqual(actual, isCeil ? -Infinity : -Infinity); 19867 }); 19868 19869 QUnit.test('`_.' + methodName + '` should return `NaN` given `NaN` regardless of `precision`', function(assert) { 19870 assert.expect(6); 19871 19872 var actual = func(NaN); 19873 assert.deepEqual(actual, NaN); 19874 19875 actual = func(NaN, 0); 19876 assert.deepEqual(actual, NaN); 19877 19878 actual = func(NaN, 2); 19879 assert.deepEqual(actual, NaN); 19880 19881 actual = func(NaN, -2); 19882 assert.deepEqual(actual, NaN); 19883 19884 actual = func(NaN, 2); 19885 assert.deepEqual(actual, isFloor ? NaN : NaN); 19886 19887 actual = func(NaN, 2); 19888 assert.deepEqual(actual, isCeil ? NaN : NaN); 19889 }); 19890 }); 19891 19892 /*--------------------------------------------------------------------------*/ 19893 19894 QUnit.module('lodash.runInContext'); 19895 19896 (function() { 19897 QUnit.test('should not require a fully populated `context` object', function(assert) { 19898 assert.expect(1); 19899 19900 if (!isModularize) { 19901 var lodash = _.runInContext({ 19902 'setTimeout': function(func) { func(); } 19903 }); 19904 19905 var pass = false; 19906 lodash.delay(function() { pass = true; }, 32); 19907 assert.ok(pass); 19908 } 19909 else { 19910 skipAssert(assert); 19911 } 19912 }); 19913 19914 QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) { 19915 assert.expect(3); 19916 19917 if (!isModularize) { 19918 lodashStable.times(2, _.uniqueId); 19919 19920 var oldId = Number(_.uniqueId()), 19921 lodash = _.runInContext(); 19922 19923 assert.ok(_.uniqueId() > oldId); 19924 19925 var id = lodash.uniqueId(); 19926 assert.strictEqual(id, '1'); 19927 assert.ok(id < oldId); 19928 } 19929 else { 19930 skipAssert(assert, 3); 19931 } 19932 }); 19933 }()); 19934 19935 /*--------------------------------------------------------------------------*/ 19936 19937 QUnit.module('lodash.sample'); 19938 19939 (function() { 19940 var array = [1, 2, 3]; 19941 19942 QUnit.test('should return a random element', function(assert) { 19943 assert.expect(1); 19944 19945 var actual = _.sample(array); 19946 assert.ok(lodashStable.includes(array, actual)); 19947 }); 19948 19949 QUnit.test('should return `undefined` when sampling empty collections', function(assert) { 19950 assert.expect(1); 19951 19952 var expected = lodashStable.map(empties, noop); 19953 19954 var actual = lodashStable.transform(empties, function(result, value) { 19955 try { 19956 result.push(_.sample(value)); 19957 } catch (e) {} 19958 }); 19959 19960 assert.deepEqual(actual, expected); 19961 }); 19962 19963 QUnit.test('should sample an object', function(assert) { 19964 assert.expect(1); 19965 19966 var object = { 'a': 1, 'b': 2, 'c': 3 }, 19967 actual = _.sample(object); 19968 19969 assert.ok(lodashStable.includes(array, actual)); 19970 }); 19971 }()); 19972 19973 /*--------------------------------------------------------------------------*/ 19974 19975 QUnit.module('lodash.sampleSize'); 19976 19977 (function() { 19978 var array = [1, 2, 3]; 19979 19980 QUnit.test('should return an array of random elements', function(assert) { 19981 assert.expect(2); 19982 19983 var actual = _.sampleSize(array, 2); 19984 19985 assert.strictEqual(actual.length, 2); 19986 assert.deepEqual(lodashStable.difference(actual, array), []); 19987 }); 19988 19989 QUnit.test('should contain elements of the collection', function(assert) { 19990 assert.expect(1); 19991 19992 var actual = _.sampleSize(array, array.length).sort(); 19993 19994 assert.deepEqual(actual, array); 19995 }); 19996 19997 QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) { 19998 assert.expect(1); 19999 20000 var expected = lodashStable.map(falsey, function(value) { 20001 return value === undefined ? ['a'] : []; 20002 }); 20003 20004 var actual = lodashStable.map(falsey, function(size, index) { 20005 return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']); 20006 }); 20007 20008 assert.deepEqual(actual, expected); 20009 }); 20010 20011 QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) { 20012 assert.expect(3); 20013 20014 lodashStable.each([0, -1, -Infinity], function(n) { 20015 assert.deepEqual(_.sampleSize(array, n), []); 20016 }); 20017 }); 20018 20019 QUnit.test('should return all elements when `n` >= `length`', function(assert) { 20020 assert.expect(4); 20021 20022 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { 20023 var actual = _.sampleSize(array, n).sort(); 20024 assert.deepEqual(actual, array); 20025 }); 20026 }); 20027 20028 QUnit.test('should coerce `n` to an integer', function(assert) { 20029 assert.expect(1); 20030 20031 var actual = _.sampleSize(array, 1.6); 20032 assert.strictEqual(actual.length, 1); 20033 }); 20034 20035 QUnit.test('should return an empty array for empty collections', function(assert) { 20036 assert.expect(1); 20037 20038 var expected = lodashStable.map(empties, stubArray); 20039 20040 var actual = lodashStable.transform(empties, function(result, value) { 20041 try { 20042 result.push(_.sampleSize(value, 1)); 20043 } catch (e) {} 20044 }); 20045 20046 assert.deepEqual(actual, expected); 20047 }); 20048 20049 QUnit.test('should sample an object', function(assert) { 20050 assert.expect(2); 20051 20052 var object = { 'a': 1, 'b': 2, 'c': 3 }, 20053 actual = _.sampleSize(object, 2); 20054 20055 assert.strictEqual(actual.length, 2); 20056 assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []); 20057 }); 20058 20059 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 20060 assert.expect(1); 20061 20062 var actual = lodashStable.map([['a']], _.sampleSize); 20063 assert.deepEqual(actual, [['a']]); 20064 }); 20065 }()); 20066 20067 /*--------------------------------------------------------------------------*/ 20068 20069 QUnit.module('lodash.setWith'); 20070 20071 (function() { 20072 QUnit.test('should work with a `customizer` callback', function(assert) { 20073 assert.expect(1); 20074 20075 var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) { 20076 return lodashStable.isObject(value) ? undefined : {}; 20077 }); 20078 20079 assert.deepEqual(actual, { '0': { '1': { '2': 3 } } }); 20080 }); 20081 20082 QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) { 20083 assert.expect(1); 20084 20085 var actual = _.setWith({}, 'a[0].b.c', 4, noop); 20086 assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] }); 20087 }); 20088 }()); 20089 20090 /*--------------------------------------------------------------------------*/ 20091 20092 QUnit.module('set methods'); 20093 20094 lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) { 20095 var func = _[methodName], 20096 isUpdate = /^update/.test(methodName); 20097 20098 var oldValue = 1, 20099 value = 2, 20100 updater = isUpdate ? lodashStable.constant(value) : value; 20101 20102 QUnit.test('`_.' + methodName + '` should set property values', function(assert) { 20103 assert.expect(4); 20104 20105 lodashStable.each(['a', ['a']], function(path) { 20106 var object = { 'a': oldValue }, 20107 actual = func(object, path, updater); 20108 20109 assert.strictEqual(actual, object); 20110 assert.strictEqual(object.a, value); 20111 }); 20112 }); 20113 20114 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 20115 assert.expect(1); 20116 20117 var props = [-0, Object(-0), 0, Object(0)], 20118 expected = lodashStable.map(props, lodashStable.constant(value)); 20119 20120 var actual = lodashStable.map(props, function(key) { 20121 var object = { '-0': 'a', '0': 'b' }; 20122 func(object, key, updater); 20123 return object[lodashStable.toString(key)]; 20124 }); 20125 20126 assert.deepEqual(actual, expected); 20127 }); 20128 20129 QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) { 20130 assert.expect(2); 20131 20132 if (Symbol) { 20133 var object = {}; 20134 object[symbol] = 1; 20135 20136 assert.strictEqual(_.unset(object, symbol), true); 20137 assert.notOk(symbol in object); 20138 } 20139 else { 20140 skipAssert(assert, 2); 20141 } 20142 }); 20143 20144 QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) { 20145 assert.expect(4); 20146 20147 lodashStable.each(['a.b', ['a', 'b']], function(path) { 20148 var object = { 'a': { 'b': oldValue } }, 20149 actual = func(object, path, updater); 20150 20151 assert.strictEqual(actual, object); 20152 assert.strictEqual(object.a.b, value); 20153 }); 20154 }); 20155 20156 QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) { 20157 assert.expect(4); 20158 20159 lodashStable.each(['a.b', ['a.b']], function(path) { 20160 var object = { 'a.b': oldValue }, 20161 actual = func(object, path, updater); 20162 20163 assert.strictEqual(actual, object); 20164 assert.deepEqual(object, { 'a.b': value }); 20165 }); 20166 }); 20167 20168 QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) { 20169 assert.expect(1); 20170 20171 var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } }; 20172 20173 func(object, ['a', 'b', 'c'], updater); 20174 assert.strictEqual(object.a.b.c, value); 20175 }); 20176 20177 QUnit.test('`_.' + methodName + '` should not ignore empty brackets', function(assert) { 20178 assert.expect(1); 20179 20180 var object = {}; 20181 20182 func(object, 'a[]', updater); 20183 assert.deepEqual(object, { 'a': { '': value } }); 20184 }); 20185 20186 QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) { 20187 assert.expect(4); 20188 20189 lodashStable.each([['', ''], [[], ['']]], function(pair, index) { 20190 var object = {}; 20191 20192 func(object, pair[0], updater); 20193 assert.deepEqual(object, index ? {} : { '': value }); 20194 20195 func(object, pair[1], updater); 20196 assert.deepEqual(object, { '': value }); 20197 }); 20198 }); 20199 20200 QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) { 20201 assert.expect(2); 20202 20203 var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } }; 20204 20205 var paths = [ 20206 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g', 20207 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g'] 20208 ]; 20209 20210 lodashStable.each(paths, function(path) { 20211 func(object, path, updater); 20212 assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value); 20213 object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue; 20214 }); 20215 }); 20216 20217 QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) { 20218 assert.expect(6); 20219 20220 var object = {}; 20221 20222 lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) { 20223 var actual = func(object, path, updater); 20224 20225 assert.strictEqual(actual, object); 20226 assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] }); 20227 assert.notOk('0' in object.a); 20228 20229 delete object.a; 20230 }); 20231 }); 20232 20233 QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) { 20234 assert.expect(1); 20235 20236 var values = [null, undefined], 20237 expected = [[null, null], [undefined, undefined]]; 20238 20239 var actual = lodashStable.map(values, function(value) { 20240 try { 20241 return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)]; 20242 } catch (e) { 20243 return e.message; 20244 } 20245 }); 20246 20247 assert.deepEqual(actual, expected); 20248 }); 20249 20250 QUnit.test('`_.' + methodName + '` should overwrite primitives in the path', function(assert) { 20251 assert.expect(2); 20252 20253 lodashStable.each(['a.b', ['a', 'b']], function(path) { 20254 var object = { 'a': '' }; 20255 20256 func(object, path, updater); 20257 assert.deepEqual(object, { 'a': { 'b': 2 } }); 20258 });; 20259 }); 20260 20261 QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) { 20262 assert.expect(1); 20263 20264 var object = {}; 20265 20266 func(object, ['1a', '2b', '3c'], updater); 20267 assert.deepEqual(object, { '1a': { '2b': { '3c': value } } }); 20268 }); 20269 20270 QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) { 20271 assert.expect(4); 20272 20273 lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) { 20274 var object = {}, 20275 pass = true, 20276 updater = isUpdate ? lodashStable.constant(value) : value; 20277 20278 defineProperty(object, 'a', { 20279 'configurable': true, 20280 'enumerable': true, 20281 'get': lodashStable.constant(value), 20282 'set': function() { pass = false; } 20283 }); 20284 20285 func(object, 'a', updater); 20286 assert.ok(pass); 20287 }); 20288 }); 20289 }); 20290 20291 /*--------------------------------------------------------------------------*/ 20292 20293 QUnit.module('lodash.shuffle'); 20294 20295 (function() { 20296 var array = [1, 2, 3], 20297 object = { 'a': 1, 'b': 2, 'c': 3 }; 20298 20299 QUnit.test('should return a new array', function(assert) { 20300 assert.expect(1); 20301 20302 assert.notStrictEqual(_.shuffle(array), array); 20303 }); 20304 20305 QUnit.test('should contain the same elements after a collection is shuffled', function(assert) { 20306 assert.expect(2); 20307 20308 assert.deepEqual(_.shuffle(array).sort(), array); 20309 assert.deepEqual(_.shuffle(object).sort(), array); 20310 }); 20311 20312 QUnit.test('should shuffle small collections', function(assert) { 20313 assert.expect(1); 20314 20315 var actual = lodashStable.times(1000, function(assert) { 20316 return _.shuffle([1, 2]); 20317 }); 20318 20319 assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]); 20320 }); 20321 20322 QUnit.test('should treat number values for `collection` as empty', function(assert) { 20323 assert.expect(1); 20324 20325 assert.deepEqual(_.shuffle(1), []); 20326 }); 20327 }()); 20328 20329 /*--------------------------------------------------------------------------*/ 20330 20331 QUnit.module('lodash.size'); 20332 20333 (function() { 20334 var array = [1, 2, 3]; 20335 20336 QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) { 20337 assert.expect(1); 20338 20339 assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3); 20340 }); 20341 20342 QUnit.test('should return the length of an array', function(assert) { 20343 assert.expect(1); 20344 20345 assert.strictEqual(_.size(array), 3); 20346 }); 20347 20348 QUnit.test('should accept a falsey `object`', function(assert) { 20349 assert.expect(1); 20350 20351 var expected = lodashStable.map(falsey, stubZero); 20352 20353 var actual = lodashStable.map(falsey, function(object, index) { 20354 try { 20355 return index ? _.size(object) : _.size(); 20356 } catch (e) {} 20357 }); 20358 20359 assert.deepEqual(actual, expected); 20360 }); 20361 20362 QUnit.test('should work with `arguments` objects', function(assert) { 20363 assert.expect(1); 20364 20365 assert.strictEqual(_.size(args), 3); 20366 }); 20367 20368 QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) { 20369 assert.expect(1); 20370 20371 function Foo(elements) { 20372 push.apply(this, elements); 20373 } 20374 Foo.prototype = { 'length': 0, 'splice': arrayProto.splice }; 20375 20376 assert.strictEqual(_.size(new Foo(array)), 3); 20377 }); 20378 20379 QUnit.test('should work with maps', function(assert) { 20380 assert.expect(2); 20381 20382 if (Map) { 20383 lodashStable.each([new Map, realm.map], function(map) { 20384 map.set('a', 1); 20385 map.set('b', 2); 20386 assert.strictEqual(_.size(map), 2); 20387 map.clear(); 20388 }); 20389 } 20390 else { 20391 skipAssert(assert, 2); 20392 } 20393 }); 20394 20395 QUnit.test('should work with sets', function(assert) { 20396 assert.expect(2); 20397 20398 if (Set) { 20399 lodashStable.each([new Set, realm.set], function(set) { 20400 set.add(1); 20401 set.add(2); 20402 assert.strictEqual(_.size(set), 2); 20403 set.clear(); 20404 }); 20405 } 20406 else { 20407 skipAssert(assert, 2); 20408 } 20409 }); 20410 20411 QUnit.test('should not treat objects with negative lengths as array-like', function(assert) { 20412 assert.expect(1); 20413 20414 assert.strictEqual(_.size({ 'length': -1 }), 1); 20415 }); 20416 20417 QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) { 20418 assert.expect(1); 20419 20420 assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1); 20421 }); 20422 20423 QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) { 20424 assert.expect(1); 20425 20426 assert.strictEqual(_.size({ 'length': '0' }), 1); 20427 }); 20428 }()); 20429 20430 /*--------------------------------------------------------------------------*/ 20431 20432 QUnit.module('lodash.slice'); 20433 20434 (function() { 20435 var array = [1, 2, 3]; 20436 20437 QUnit.test('should use a default `start` of `0` and a default `end` of `length`', function(assert) { 20438 assert.expect(2); 20439 20440 var actual = _.slice(array); 20441 assert.deepEqual(actual, array); 20442 assert.notStrictEqual(actual, array); 20443 }); 20444 20445 QUnit.test('should work with a positive `start`', function(assert) { 20446 assert.expect(2); 20447 20448 assert.deepEqual(_.slice(array, 1), [2, 3]); 20449 assert.deepEqual(_.slice(array, 1, 3), [2, 3]); 20450 }); 20451 20452 QUnit.test('should work with a `start` >= `length`', function(assert) { 20453 assert.expect(4); 20454 20455 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) { 20456 assert.deepEqual(_.slice(array, start), []); 20457 }); 20458 }); 20459 20460 QUnit.test('should treat falsey `start` values as `0`', function(assert) { 20461 assert.expect(1); 20462 20463 var expected = lodashStable.map(falsey, lodashStable.constant(array)); 20464 20465 var actual = lodashStable.map(falsey, function(start) { 20466 return _.slice(array, start); 20467 }); 20468 20469 assert.deepEqual(actual, expected); 20470 }); 20471 20472 QUnit.test('should work with a negative `start`', function(assert) { 20473 assert.expect(1); 20474 20475 assert.deepEqual(_.slice(array, -1), [3]); 20476 }); 20477 20478 QUnit.test('should work with a negative `start` <= negative `length`', function(assert) { 20479 assert.expect(3); 20480 20481 lodashStable.each([-3, -4, -Infinity], function(start) { 20482 assert.deepEqual(_.slice(array, start), array); 20483 }); 20484 }); 20485 20486 QUnit.test('should work with `start` >= `end`', function(assert) { 20487 assert.expect(2); 20488 20489 lodashStable.each([2, 3], function(start) { 20490 assert.deepEqual(_.slice(array, start, 2), []); 20491 }); 20492 }); 20493 20494 QUnit.test('should work with a positive `end`', function(assert) { 20495 assert.expect(1); 20496 20497 assert.deepEqual(_.slice(array, 0, 1), [1]); 20498 }); 20499 20500 QUnit.test('should work with a `end` >= `length`', function(assert) { 20501 assert.expect(4); 20502 20503 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) { 20504 assert.deepEqual(_.slice(array, 0, end), array); 20505 }); 20506 }); 20507 20508 QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) { 20509 assert.expect(1); 20510 20511 var expected = lodashStable.map(falsey, function(value) { 20512 return value === undefined ? array : []; 20513 }); 20514 20515 var actual = lodashStable.map(falsey, function(end, index) { 20516 return index ? _.slice(array, 0, end) : _.slice(array, 0); 20517 }); 20518 20519 assert.deepEqual(actual, expected); 20520 }); 20521 20522 QUnit.test('should work with a negative `end`', function(assert) { 20523 assert.expect(1); 20524 20525 assert.deepEqual(_.slice(array, 0, -1), [1, 2]); 20526 }); 20527 20528 QUnit.test('should work with a negative `end` <= negative `length`', function(assert) { 20529 assert.expect(3); 20530 20531 lodashStable.each([-3, -4, -Infinity], function(end) { 20532 assert.deepEqual(_.slice(array, 0, end), []); 20533 }); 20534 }); 20535 20536 QUnit.test('should coerce `start` and `end` to integers', function(assert) { 20537 assert.expect(1); 20538 20539 var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]]; 20540 20541 var actual = lodashStable.map(positions, function(pos) { 20542 return _.slice.apply(_, [array].concat(pos)); 20543 }); 20544 20545 assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]); 20546 }); 20547 20548 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 20549 assert.expect(2); 20550 20551 var array = [[1], [2, 3]], 20552 actual = lodashStable.map(array, _.slice); 20553 20554 assert.deepEqual(actual, array); 20555 assert.notStrictEqual(actual, array); 20556 }); 20557 20558 QUnit.test('should work in a lazy sequence', function(assert) { 20559 assert.expect(38); 20560 20561 if (!isNpm) { 20562 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 20563 length = array.length, 20564 wrapped = _(array); 20565 20566 lodashStable.each(['map', 'filter'], function(methodName) { 20567 assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1)); 20568 assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1)); 20569 assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3)); 20570 assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1)); 20571 20572 assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length)); 20573 assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2)); 20574 assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length)); 20575 assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null)); 20576 20577 assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length)); 20578 assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length)); 20579 assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null)); 20580 20581 assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1)); 20582 assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1')); 20583 20584 assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1)); 20585 assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1)); 20586 assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1')); 20587 assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1')); 20588 assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1)); 20589 assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN)); 20590 }); 20591 } 20592 else { 20593 skipAssert(assert, 38); 20594 } 20595 }); 20596 }()); 20597 20598 /*--------------------------------------------------------------------------*/ 20599 20600 QUnit.module('lodash.some'); 20601 20602 (function() { 20603 QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) { 20604 assert.expect(2); 20605 20606 assert.strictEqual(_.some([false, 1, ''], identity), true); 20607 assert.strictEqual(_.some([null, 'a', 0], identity), true); 20608 }); 20609 20610 QUnit.test('should return `false` for empty collections', function(assert) { 20611 assert.expect(1); 20612 20613 var expected = lodashStable.map(empties, stubFalse); 20614 20615 var actual = lodashStable.map(empties, function(value) { 20616 try { 20617 return _.some(value, identity); 20618 } catch (e) {} 20619 }); 20620 20621 assert.deepEqual(actual, expected); 20622 }); 20623 20624 QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) { 20625 assert.expect(2); 20626 20627 var count = 0; 20628 20629 assert.strictEqual(_.some([null, true, null], function(value) { 20630 count++; 20631 return value; 20632 }), true); 20633 20634 assert.strictEqual(count, 2); 20635 }); 20636 20637 QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) { 20638 assert.expect(2); 20639 20640 assert.strictEqual(_.some([false, false, false], identity), false); 20641 assert.strictEqual(_.some([null, 0, ''], identity), false); 20642 }); 20643 20644 QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) { 20645 assert.expect(2); 20646 20647 var values = [, null, undefined], 20648 expected = lodashStable.map(values, stubFalse); 20649 20650 var actual = lodashStable.map(values, function(value, index) { 20651 var array = [0, 0]; 20652 return index ? _.some(array, value) : _.some(array); 20653 }); 20654 20655 assert.deepEqual(actual, expected); 20656 20657 expected = lodashStable.map(values, stubTrue); 20658 actual = lodashStable.map(values, function(value, index) { 20659 var array = [0, 1]; 20660 return index ? _.some(array, value) : _.some(array); 20661 }); 20662 20663 assert.deepEqual(actual, expected); 20664 }); 20665 20666 QUnit.test('should work with `_.property` shorthands', function(assert) { 20667 assert.expect(2); 20668 20669 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }]; 20670 assert.strictEqual(_.some(objects, 'a'), false); 20671 assert.strictEqual(_.some(objects, 'b'), true); 20672 }); 20673 20674 QUnit.test('should work with `_.matches` shorthands', function(assert) { 20675 assert.expect(2); 20676 20677 var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}]; 20678 assert.strictEqual(_.some(objects, { 'a': 0 }), true); 20679 assert.strictEqual(_.some(objects, { 'b': 2 }), false); 20680 }); 20681 20682 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 20683 assert.expect(1); 20684 20685 var actual = lodashStable.map([[1]], _.some); 20686 assert.deepEqual(actual, [true]); 20687 }); 20688 }()); 20689 20690 /*--------------------------------------------------------------------------*/ 20691 20692 QUnit.module('lodash.sortBy'); 20693 20694 (function() { 20695 var objects = [ 20696 { 'a': 'x', 'b': 3 }, 20697 { 'a': 'y', 'b': 4 }, 20698 { 'a': 'x', 'b': 1 }, 20699 { 'a': 'y', 'b': 2 } 20700 ]; 20701 20702 QUnit.test('should sort in ascending order by `iteratee`', function(assert) { 20703 assert.expect(1); 20704 20705 var actual = lodashStable.map(_.sortBy(objects, function(object) { 20706 return object.b; 20707 }), 'b'); 20708 20709 assert.deepEqual(actual, [1, 2, 3, 4]); 20710 }); 20711 20712 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 20713 assert.expect(1); 20714 20715 var array = [3, 2, 1], 20716 values = [, null, undefined], 20717 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3])); 20718 20719 var actual = lodashStable.map(values, function(value, index) { 20720 return index ? _.sortBy(array, value) : _.sortBy(array); 20721 }); 20722 20723 assert.deepEqual(actual, expected); 20724 }); 20725 20726 QUnit.test('should work with `_.property` shorthands', function(assert) { 20727 assert.expect(1); 20728 20729 var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b'); 20730 assert.deepEqual(actual, [1, 2, 3, 4, undefined]); 20731 }); 20732 20733 QUnit.test('should work with an object for `collection`', function(assert) { 20734 assert.expect(1); 20735 20736 var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin); 20737 assert.deepEqual(actual, [3, 1, 2]); 20738 }); 20739 20740 QUnit.test('should move `NaN`, nullish, and symbol values to the end', function(assert) { 20741 assert.expect(2); 20742 20743 var symbol1 = Symbol ? Symbol('a') : null, 20744 symbol2 = Symbol ? Symbol('b') : null, 20745 array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2], 20746 expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN]; 20747 20748 assert.deepEqual(_.sortBy(array), expected); 20749 20750 array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b']; 20751 expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN]; 20752 20753 assert.deepEqual(_.sortBy(array), expected); 20754 }); 20755 20756 QUnit.test('should treat number values for `collection` as empty', function(assert) { 20757 assert.expect(1); 20758 20759 assert.deepEqual(_.sortBy(1), []); 20760 }); 20761 20762 QUnit.test('should coerce arrays returned from `iteratee`', function(assert) { 20763 assert.expect(1); 20764 20765 var actual = _.sortBy(objects, function(object) { 20766 var result = [object.a, object.b]; 20767 result.toString = function() { return String(this[0]); }; 20768 return result; 20769 }); 20770 20771 assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]); 20772 }); 20773 20774 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 20775 assert.expect(1); 20776 20777 var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy); 20778 assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]); 20779 }); 20780 }()); 20781 20782 /*--------------------------------------------------------------------------*/ 20783 20784 QUnit.module('sortBy methods'); 20785 20786 lodashStable.each(['orderBy', 'sortBy'], function(methodName) { 20787 var func = _[methodName]; 20788 20789 function Pair(a, b, c) { 20790 this.a = a; 20791 this.b = b; 20792 this.c = c; 20793 } 20794 20795 var objects = [ 20796 { 'a': 'x', 'b': 3 }, 20797 { 'a': 'y', 'b': 4 }, 20798 { 'a': 'x', 'b': 1 }, 20799 { 'a': 'y', 'b': 2 } 20800 ]; 20801 20802 var stableArray = [ 20803 new Pair(1, 1, 1), new Pair(1, 2, 1), 20804 new Pair(1, 1, 1), new Pair(1, 2, 1), 20805 new Pair(1, 3, 1), new Pair(1, 4, 1), 20806 new Pair(1, 5, 1), new Pair(1, 6, 1), 20807 new Pair(2, 1, 2), new Pair(2, 2, 2), 20808 new Pair(2, 3, 2), new Pair(2, 4, 2), 20809 new Pair(2, 5, 2), new Pair(2, 6, 2), 20810 new Pair(undefined, 1, 1), new Pair(undefined, 2, 1), 20811 new Pair(undefined, 3, 1), new Pair(undefined, 4, 1), 20812 new Pair(undefined, 5, 1), new Pair(undefined, 6, 1) 20813 ]; 20814 20815 var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray); 20816 20817 QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) { 20818 assert.expect(1); 20819 20820 var actual = func(objects, ['a', 'b']); 20821 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]); 20822 }); 20823 20824 QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) { 20825 assert.expect(1); 20826 20827 var actual = func(objects, ['a', function(object) { return object.b; }]); 20828 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]); 20829 }); 20830 20831 QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) { 20832 assert.expect(2); 20833 20834 lodashStable.each([stableArray, stableObject], function(value, index) { 20835 var actual = func(value, ['a', 'c']); 20836 assert.deepEqual(actual, stableArray, index ? 'object' : 'array'); 20837 }); 20838 }); 20839 20840 QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) { 20841 assert.expect(1); 20842 20843 try { 20844 var actual = func(objects.concat(null, undefined), ['a', 'b']); 20845 } catch (e) {} 20846 20847 assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]); 20848 }); 20849 20850 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) { 20851 assert.expect(3); 20852 20853 var objects = [ 20854 { 'a': 'x', '0': 3 }, 20855 { 'a': 'y', '0': 4 }, 20856 { 'a': 'x', '0': 1 }, 20857 { 'a': 'y', '0': 2 } 20858 ]; 20859 20860 var funcs = [func, lodashStable.partialRight(func, 'bogus')]; 20861 20862 lodashStable.each(['a', 0, [0]], function(props, index) { 20863 var expected = lodashStable.map(funcs, lodashStable.constant( 20864 index 20865 ? [objects[2], objects[3], objects[0], objects[1]] 20866 : [objects[0], objects[2], objects[1], objects[3]] 20867 )); 20868 20869 var actual = lodashStable.map(funcs, function(func) { 20870 return lodashStable.reduce([props], func, objects); 20871 }); 20872 20873 assert.deepEqual(actual, expected); 20874 }); 20875 }); 20876 }); 20877 20878 /*--------------------------------------------------------------------------*/ 20879 20880 QUnit.module('sortedIndex methods'); 20881 20882 lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) { 20883 var func = _[methodName], 20884 isSortedIndex = methodName == 'sortedIndex'; 20885 20886 QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) { 20887 assert.expect(1); 20888 20889 var array = [30, 50], 20890 values = [30, 40, 50], 20891 expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2]; 20892 20893 var actual = lodashStable.map(values, function(value) { 20894 return func(array, value); 20895 }); 20896 20897 assert.deepEqual(actual, expected); 20898 }); 20899 20900 QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) { 20901 assert.expect(1); 20902 20903 var array = ['a', 'c'], 20904 values = ['a', 'b', 'c'], 20905 expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2]; 20906 20907 var actual = lodashStable.map(values, function(value) { 20908 return func(array, value); 20909 }); 20910 20911 assert.deepEqual(actual, expected); 20912 }); 20913 20914 QUnit.test('`_.' + methodName + '` should accept a nullish `array` and a `value`', function(assert) { 20915 assert.expect(1); 20916 20917 var values = [null, undefined], 20918 expected = lodashStable.map(values, lodashStable.constant([0, 0, 0])); 20919 20920 var actual = lodashStable.map(values, function(array) { 20921 return [func(array, 1), func(array, undefined), func(array, NaN)]; 20922 }); 20923 20924 assert.deepEqual(actual, expected); 20925 }); 20926 20927 QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) { 20928 assert.expect(12); 20929 20930 var symbol1 = Symbol ? Symbol('a') : null, 20931 symbol2 = Symbol ? Symbol('b') : null, 20932 symbol3 = Symbol ? Symbol('c') : null, 20933 expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN]; 20934 20935 lodashStable.each([ 20936 [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined], 20937 ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined] 20938 ], function(array) { 20939 assert.deepEqual(_.sortBy(array), expected); 20940 assert.strictEqual(func(expected, 3), 2); 20941 assert.strictEqual(func(expected, symbol3), isSortedIndex ? 3 : (Symbol ? 5 : 6)); 20942 assert.strictEqual(func(expected, null), isSortedIndex ? (Symbol ? 5 : 3) : 6); 20943 assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7); 20944 assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9); 20945 }); 20946 }); 20947 20948 QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for nulls', function(assert) { 20949 assert.expect(3); 20950 20951 var array = [null, null]; 20952 20953 assert.strictEqual(func(array, null), isSortedIndex ? 0 : 2); 20954 assert.strictEqual(func(array, 1), 0); 20955 assert.strictEqual(func(array, 'a'), 0); 20956 }); 20957 20958 QUnit.test('`_.' + methodName + '` should align with `_.sortBy` for symbols', function(assert) { 20959 assert.expect(3); 20960 20961 var symbol1 = Symbol ? Symbol('a') : null, 20962 symbol2 = Symbol ? Symbol('b') : null, 20963 symbol3 = Symbol ? Symbol('c') : null, 20964 array = [symbol1, symbol2]; 20965 20966 assert.strictEqual(func(array, symbol3), isSortedIndex ? 0 : 2); 20967 assert.strictEqual(func(array, 1), 0); 20968 assert.strictEqual(func(array, 'a'), 0); 20969 }); 20970 }); 20971 20972 /*--------------------------------------------------------------------------*/ 20973 20974 QUnit.module('sortedIndexBy methods'); 20975 20976 lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) { 20977 var func = _[methodName], 20978 isSortedIndexBy = methodName == 'sortedIndexBy'; 20979 20980 QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) { 20981 assert.expect(1); 20982 20983 var args; 20984 20985 func([30, 50], 40, function(assert) { 20986 args || (args = slice.call(arguments)); 20987 }); 20988 20989 assert.deepEqual(args, [40]); 20990 }); 20991 20992 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) { 20993 assert.expect(1); 20994 20995 var objects = [{ 'x': 30 }, { 'x': 50 }], 20996 actual = func(objects, { 'x': 40 }, 'x'); 20997 20998 assert.strictEqual(actual, 1); 20999 }); 21000 21001 QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) { 21002 assert.expect(12); 21003 21004 lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) { 21005 var array = [], 21006 values = [MAX_ARRAY_LENGTH, NaN, undefined]; 21007 21008 array.length = length; 21009 21010 lodashStable.each(values, function(value) { 21011 var steps = 0; 21012 21013 var actual = func(array, value, function(value) { 21014 steps++; 21015 return value; 21016 }); 21017 21018 var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value)) 21019 ? 0 21020 : Math.min(length, MAX_ARRAY_INDEX); 21021 21022 assert.ok(steps == 32 || steps == 33); 21023 assert.strictEqual(actual, expected); 21024 }); 21025 }); 21026 }); 21027 }); 21028 21029 /*--------------------------------------------------------------------------*/ 21030 21031 QUnit.module('sortedIndexOf methods'); 21032 21033 lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) { 21034 var func = _[methodName], 21035 isSortedIndexOf = methodName == 'sortedIndexOf'; 21036 21037 QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) { 21038 assert.expect(1); 21039 21040 var sorted = [4, 4, 5, 5, 6, 6]; 21041 assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3); 21042 }); 21043 }); 21044 21045 /*--------------------------------------------------------------------------*/ 21046 21047 QUnit.module('lodash.sortedUniq'); 21048 21049 (function() { 21050 QUnit.test('should return unique values of a sorted array', function(assert) { 21051 assert.expect(3); 21052 21053 var expected = [1, 2, 3]; 21054 21055 lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) { 21056 assert.deepEqual(_.sortedUniq(array), expected); 21057 }); 21058 }); 21059 }()); 21060 21061 /*--------------------------------------------------------------------------*/ 21062 21063 QUnit.module('lodash.split'); 21064 21065 (function() { 21066 QUnit.test('should split a string by `separator`', function(assert) { 21067 assert.expect(3); 21068 21069 var string = 'abcde'; 21070 assert.deepEqual(_.split(string, 'c'), ['ab', 'de']); 21071 assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']); 21072 assert.deepEqual(_.split(string, '', 2), ['a', 'b']); 21073 }); 21074 21075 QUnit.test('should return an array containing an empty string for empty values', function(assert) { 21076 assert.expect(1); 21077 21078 var values = [, null, undefined, ''], 21079 expected = lodashStable.map(values, lodashStable.constant([''])); 21080 21081 var actual = lodashStable.map(values, function(value, index) { 21082 return index ? _.split(value) : _.split(); 21083 }); 21084 21085 assert.deepEqual(actual, expected); 21086 }); 21087 21088 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 21089 assert.expect(1); 21090 21091 var strings = ['abc', 'def', 'ghi'], 21092 actual = lodashStable.map(strings, _.split); 21093 21094 assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]); 21095 }); 21096 21097 QUnit.test('should allow mixed string and array prototype methods', function(assert) { 21098 assert.expect(1); 21099 21100 if (!isNpm) { 21101 var wrapped = _('abc'); 21102 assert.strictEqual(wrapped.split('b').join(','), 'a,c'); 21103 } 21104 else { 21105 skipAssert(assert); 21106 } 21107 }); 21108 }()); 21109 21110 /*--------------------------------------------------------------------------*/ 21111 21112 QUnit.module('lodash.spread'); 21113 21114 (function() { 21115 function fn(a, b, c) { 21116 return slice.call(arguments); 21117 } 21118 21119 QUnit.test('should spread arguments to `func`', function(assert) { 21120 assert.expect(2); 21121 21122 var spread = _.spread(fn), 21123 expected = [1, 2]; 21124 21125 assert.deepEqual(spread([1, 2]), expected); 21126 assert.deepEqual(spread([1, 2], 3), expected); 21127 }); 21128 21129 QUnit.test('should accept a falsey `array`', function(assert) { 21130 assert.expect(1); 21131 21132 var spread = _.spread(stubTrue), 21133 expected = lodashStable.map(falsey, stubTrue); 21134 21135 var actual = lodashStable.map(falsey, function(array, index) { 21136 try { 21137 return index ? spread(array) : spread(); 21138 } catch (e) {} 21139 }); 21140 21141 assert.deepEqual(actual, expected); 21142 }); 21143 21144 QUnit.test('should work with `start`', function(assert) { 21145 assert.expect(2); 21146 21147 var spread = _.spread(fn, 1), 21148 expected = [1, 2, 3]; 21149 21150 assert.deepEqual(spread(1, [2, 3]), expected); 21151 assert.deepEqual(spread(1, [2, 3], 4), expected); 21152 }); 21153 21154 QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) { 21155 assert.expect(1); 21156 21157 var values = [-1, NaN, 'a'], 21158 expected = lodashStable.map(values, lodashStable.constant([1, 2])); 21159 21160 var actual = lodashStable.map(values, function(value) { 21161 var spread = _.spread(fn, value); 21162 return spread([1, 2]); 21163 }); 21164 21165 assert.deepEqual(actual, expected); 21166 }); 21167 21168 QUnit.test('should coerce `start` to an integer', function(assert) { 21169 assert.expect(2); 21170 21171 var spread = _.spread(fn, 1.6), 21172 expected = [1, 2, 3]; 21173 21174 assert.deepEqual(spread(1, [2, 3]), expected); 21175 assert.deepEqual(spread(1, [2, 3], 4), expected); 21176 }); 21177 }()); 21178 21179 /*--------------------------------------------------------------------------*/ 21180 21181 QUnit.module('lodash.startCase'); 21182 21183 (function() { 21184 QUnit.test('should uppercase only the first character of each word', function(assert) { 21185 assert.expect(3); 21186 21187 assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar'); 21188 assert.strictEqual(_.startCase('fooBar'), 'Foo Bar'); 21189 assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR'); 21190 }); 21191 }()); 21192 21193 /*--------------------------------------------------------------------------*/ 21194 21195 QUnit.module('lodash.startsWith'); 21196 21197 (function() { 21198 var string = 'abc'; 21199 21200 QUnit.test('should return `true` if a string starts with `target`', function(assert) { 21201 assert.expect(1); 21202 21203 assert.strictEqual(_.startsWith(string, 'a'), true); 21204 }); 21205 21206 QUnit.test('should return `false` if a string does not start with `target`', function(assert) { 21207 assert.expect(1); 21208 21209 assert.strictEqual(_.startsWith(string, 'b'), false); 21210 }); 21211 21212 QUnit.test('should work with a `position`', function(assert) { 21213 assert.expect(1); 21214 21215 assert.strictEqual(_.startsWith(string, 'b', 1), true); 21216 }); 21217 21218 QUnit.test('should work with `position` >= `length`', function(assert) { 21219 assert.expect(4); 21220 21221 lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) { 21222 assert.strictEqual(_.startsWith(string, 'a', position), false); 21223 }); 21224 }); 21225 21226 QUnit.test('should treat falsey `position` values as `0`', function(assert) { 21227 assert.expect(1); 21228 21229 var expected = lodashStable.map(falsey, stubTrue); 21230 21231 var actual = lodashStable.map(falsey, function(position) { 21232 return _.startsWith(string, 'a', position); 21233 }); 21234 21235 assert.deepEqual(actual, expected); 21236 }); 21237 21238 QUnit.test('should treat a negative `position` as `0`', function(assert) { 21239 assert.expect(6); 21240 21241 lodashStable.each([-1, -3, -Infinity], function(position) { 21242 assert.strictEqual(_.startsWith(string, 'a', position), true); 21243 assert.strictEqual(_.startsWith(string, 'b', position), false); 21244 }); 21245 }); 21246 21247 QUnit.test('should coerce `position` to an integer', function(assert) { 21248 assert.expect(1); 21249 21250 assert.strictEqual(_.startsWith(string, 'bc', 1.2), true); 21251 }); 21252 }()); 21253 21254 /*--------------------------------------------------------------------------*/ 21255 21256 QUnit.module('lodash.startsWith and lodash.endsWith'); 21257 21258 lodashStable.each(['startsWith', 'endsWith'], function(methodName) { 21259 var func = _[methodName], 21260 isStartsWith = methodName == 'startsWith'; 21261 21262 var string = 'abc', 21263 chr = isStartsWith ? 'a' : 'c'; 21264 21265 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) { 21266 assert.expect(2); 21267 21268 assert.strictEqual(func(Object(string), chr), true); 21269 assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true); 21270 }); 21271 21272 QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) { 21273 assert.expect(2); 21274 21275 assert.strictEqual(func(string, Object(chr)), true); 21276 assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true); 21277 }); 21278 21279 QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) { 21280 assert.expect(2); 21281 21282 var position = isStartsWith ? 1 : 2; 21283 21284 assert.strictEqual(func(string, 'b', Object(position)), true); 21285 assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true); 21286 }); 21287 21288 QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) { 21289 assert.expect(1); 21290 21291 var positions = [-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity]; 21292 21293 assert.ok(lodashStable.every(positions, function(position) { 21294 return func(string, '', position); 21295 })); 21296 }); 21297 }); 21298 21299 /*--------------------------------------------------------------------------*/ 21300 21301 QUnit.module('stub methods'); 21302 21303 lodashStable.each(['noop', 'stubTrue', 'stubFalse', 'stubArray', 'stubObject', 'stubString'], function(methodName) { 21304 var func = _[methodName]; 21305 21306 var pair = ({ 21307 'stubArray': [[], 'an empty array'], 21308 'stubFalse': [false, '`false`'], 21309 'stubObject': [{}, 'an empty object'], 21310 'stubString': ['', 'an empty string'], 21311 'stubTrue': [true, '`true`'], 21312 'noop': [undefined, '`undefined`'] 21313 })[methodName]; 21314 21315 var values = Array(2).concat(empties, true, 1, 'a'), 21316 expected = lodashStable.map(values, lodashStable.constant(pair[0])); 21317 21318 QUnit.test('`_.' + methodName + '` should return ' + pair[1], function(assert) { 21319 assert.expect(1); 21320 21321 var actual = lodashStable.map(values, function(value, index) { 21322 if (index < 2) { 21323 return index ? func.call({}) : func(); 21324 } 21325 return func(value); 21326 }); 21327 21328 assert.deepEqual(actual, expected); 21329 }); 21330 }); 21331 21332 /*--------------------------------------------------------------------------*/ 21333 21334 QUnit.module('lodash.subtract'); 21335 21336 (function() { 21337 QUnit.test('should subtract two numbers', function(assert) { 21338 assert.expect(3); 21339 21340 assert.strictEqual(_.subtract(6, 4), 2); 21341 assert.strictEqual(_.subtract(-6, 4), -10); 21342 assert.strictEqual(_.subtract(-6, -4), -2); 21343 }); 21344 21345 QUnit.test('should coerce arguments to numbers', function(assert) { 21346 assert.expect(2); 21347 21348 assert.strictEqual(_.subtract('6', '4'), 2); 21349 assert.deepEqual(_.subtract('x', 'y'), NaN); 21350 }); 21351 }()); 21352 21353 /*--------------------------------------------------------------------------*/ 21354 21355 QUnit.module('math operator methods'); 21356 21357 lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) { 21358 var func = _[methodName], 21359 isAddSub = methodName == 'add' || methodName == 'subtract'; 21360 21361 QUnit.test('`_.' + methodName + '` should return `' + (isAddSub ? 0 : 1) + '` when no arguments are given', function(assert) { 21362 assert.expect(1); 21363 21364 assert.strictEqual(func(), isAddSub ? 0 : 1); 21365 }); 21366 21367 QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) { 21368 assert.expect(3); 21369 21370 assert.strictEqual(func(6), 6); 21371 assert.strictEqual(func(6, undefined), 6); 21372 assert.strictEqual(func(undefined, 4), 4); 21373 }); 21374 21375 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 21376 assert.expect(2); 21377 21378 var values = [0, '0', -0, '-0'], 21379 expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]]; 21380 21381 lodashStable.times(2, function(index) { 21382 var actual = lodashStable.map(values, function(value) { 21383 var result = index ? func(undefined, value) : func(value); 21384 return [result, 1 / result]; 21385 }); 21386 21387 assert.deepEqual(actual, expected); 21388 }); 21389 }); 21390 21391 QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) { 21392 assert.expect(2); 21393 21394 assert.deepEqual(func(0, {}), NaN); 21395 assert.deepEqual(func({}, 0), NaN); 21396 }); 21397 21398 QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) { 21399 assert.expect(2); 21400 21401 if (Symbol) { 21402 assert.deepEqual(func(0, symbol), NaN); 21403 assert.deepEqual(func(symbol, 0), NaN); 21404 } 21405 else { 21406 skipAssert(assert, 2); 21407 } 21408 }); 21409 21410 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 21411 assert.expect(1); 21412 21413 if (!isNpm) { 21414 var actual = _(1)[methodName](2); 21415 assert.notOk(actual instanceof _); 21416 } 21417 else { 21418 skipAssert(assert); 21419 } 21420 }); 21421 21422 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 21423 assert.expect(1); 21424 21425 if (!isNpm) { 21426 var actual = _(1).chain()[methodName](2); 21427 assert.ok(actual instanceof _); 21428 } 21429 else { 21430 skipAssert(assert); 21431 } 21432 }); 21433 }); 21434 21435 /*--------------------------------------------------------------------------*/ 21436 21437 QUnit.module('lodash.sumBy'); 21438 21439 (function() { 21440 var array = [6, 4, 2], 21441 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; 21442 21443 QUnit.test('should work with an `iteratee`', function(assert) { 21444 assert.expect(1); 21445 21446 var actual = _.sumBy(objects, function(object) { 21447 return object.a; 21448 }); 21449 21450 assert.deepEqual(actual, 6); 21451 }); 21452 21453 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 21454 assert.expect(1); 21455 21456 var args; 21457 21458 _.sumBy(array, function() { 21459 args || (args = slice.call(arguments)); 21460 }); 21461 21462 assert.deepEqual(args, [6]); 21463 }); 21464 21465 QUnit.test('should work with `_.property` shorthands', function(assert) { 21466 assert.expect(2); 21467 21468 var arrays = [[2], [3], [1]]; 21469 assert.strictEqual(_.sumBy(arrays, 0), 6); 21470 assert.strictEqual(_.sumBy(objects, 'a'), 6); 21471 }); 21472 }()); 21473 21474 /*--------------------------------------------------------------------------*/ 21475 21476 QUnit.module('sum methods'); 21477 21478 lodashStable.each(['sum', 'sumBy'], function(methodName) { 21479 var array = [6, 4, 2], 21480 func = _[methodName]; 21481 21482 QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) { 21483 assert.expect(1); 21484 21485 assert.strictEqual(func(array), 12); 21486 }); 21487 21488 QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) { 21489 assert.expect(1); 21490 21491 var expected = lodashStable.map(empties, stubZero); 21492 21493 var actual = lodashStable.map(empties, function(value) { 21494 return func(value); 21495 }); 21496 21497 assert.deepEqual(actual, expected); 21498 }); 21499 21500 QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) { 21501 assert.expect(1); 21502 21503 assert.strictEqual(func([1, undefined]), 1); 21504 }); 21505 21506 QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) { 21507 assert.expect(1); 21508 21509 assert.deepEqual(func([1, NaN]), NaN); 21510 }); 21511 21512 QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) { 21513 assert.expect(1); 21514 21515 assert.strictEqual(func(['1', '2']), '12'); 21516 }); 21517 }); 21518 21519 /*--------------------------------------------------------------------------*/ 21520 21521 QUnit.module('lodash.tail'); 21522 21523 (function() { 21524 var array = [1, 2, 3]; 21525 21526 QUnit.test('should accept a falsey `array`', function(assert) { 21527 assert.expect(1); 21528 21529 var expected = lodashStable.map(falsey, stubArray); 21530 21531 var actual = lodashStable.map(falsey, function(array, index) { 21532 try { 21533 return index ? _.tail(array) : _.tail(); 21534 } catch (e) {} 21535 }); 21536 21537 assert.deepEqual(actual, expected); 21538 }); 21539 21540 QUnit.test('should exclude the first element', function(assert) { 21541 assert.expect(1); 21542 21543 assert.deepEqual(_.tail(array), [2, 3]); 21544 }); 21545 21546 QUnit.test('should return an empty when querying empty arrays', function(assert) { 21547 assert.expect(1); 21548 21549 assert.deepEqual(_.tail([]), []); 21550 }); 21551 21552 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 21553 assert.expect(1); 21554 21555 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 21556 actual = lodashStable.map(array, _.tail); 21557 21558 assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]); 21559 }); 21560 21561 QUnit.test('should work in a lazy sequence', function(assert) { 21562 assert.expect(4); 21563 21564 if (!isNpm) { 21565 var array = lodashStable.range(LARGE_ARRAY_SIZE), 21566 values = []; 21567 21568 var actual = _(array).tail().filter(function(value) { 21569 values.push(value); 21570 return false; 21571 }) 21572 .value(); 21573 21574 assert.deepEqual(actual, []); 21575 assert.deepEqual(values, array.slice(1)); 21576 21577 values = []; 21578 21579 actual = _(array).filter(function(value) { 21580 values.push(value); 21581 return isEven(value); 21582 }) 21583 .tail() 21584 .value(); 21585 21586 assert.deepEqual(actual, _.tail(_.filter(array, isEven))); 21587 assert.deepEqual(values, array); 21588 } 21589 else { 21590 skipAssert(assert, 4); 21591 } 21592 }); 21593 21594 QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) { 21595 assert.expect(4); 21596 21597 if (!isNpm) { 21598 var array = lodashStable.range(LARGE_ARRAY_SIZE), 21599 iteratee = function() { pass = false; }, 21600 pass = true, 21601 actual = _(array).slice(0, 1).tail().map(iteratee).value(); 21602 21603 assert.ok(pass); 21604 assert.deepEqual(actual, []); 21605 21606 pass = true; 21607 actual = _(array).filter().slice(0, 1).tail().map(iteratee).value(); 21608 21609 assert.ok(pass); 21610 assert.deepEqual(actual, []); 21611 } 21612 else { 21613 skipAssert(assert, 4); 21614 } 21615 }); 21616 }()); 21617 21618 /*--------------------------------------------------------------------------*/ 21619 21620 QUnit.module('lodash.take'); 21621 21622 (function() { 21623 var array = [1, 2, 3]; 21624 21625 QUnit.test('should take the first two elements', function(assert) { 21626 assert.expect(1); 21627 21628 assert.deepEqual(_.take(array, 2), [1, 2]); 21629 }); 21630 21631 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) { 21632 assert.expect(1); 21633 21634 var expected = lodashStable.map(falsey, function(value) { 21635 return value === undefined ? [1] : []; 21636 }); 21637 21638 var actual = lodashStable.map(falsey, function(n) { 21639 return _.take(array, n); 21640 }); 21641 21642 assert.deepEqual(actual, expected); 21643 }); 21644 21645 QUnit.test('should return an empty array when `n` < `1`', function(assert) { 21646 assert.expect(3); 21647 21648 lodashStable.each([0, -1, -Infinity], function(n) { 21649 assert.deepEqual(_.take(array, n), []); 21650 }); 21651 }); 21652 21653 QUnit.test('should return all elements when `n` >= `length`', function(assert) { 21654 assert.expect(4); 21655 21656 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { 21657 assert.deepEqual(_.take(array, n), array); 21658 }); 21659 }); 21660 21661 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 21662 assert.expect(1); 21663 21664 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 21665 actual = lodashStable.map(array, _.take); 21666 21667 assert.deepEqual(actual, [[1], [4], [7]]); 21668 }); 21669 21670 QUnit.test('should work in a lazy sequence', function(assert) { 21671 assert.expect(6); 21672 21673 if (!isNpm) { 21674 var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1), 21675 predicate = function(value) { values.push(value); return isEven(value); }, 21676 values = [], 21677 actual = _(array).take(2).take().value(); 21678 21679 assert.deepEqual(actual, _.take(_.take(array, 2))); 21680 21681 actual = _(array).filter(predicate).take(2).take().value(); 21682 assert.deepEqual(values, [1, 2]); 21683 assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2))); 21684 21685 actual = _(array).take(6).takeRight(4).take(2).takeRight().value(); 21686 assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2))); 21687 21688 values = []; 21689 21690 actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value(); 21691 assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); 21692 assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2))); 21693 } 21694 else { 21695 skipAssert(assert, 6); 21696 } 21697 }); 21698 }()); 21699 21700 /*--------------------------------------------------------------------------*/ 21701 21702 QUnit.module('lodash.takeRight'); 21703 21704 (function() { 21705 var array = [1, 2, 3]; 21706 21707 QUnit.test('should take the last two elements', function(assert) { 21708 assert.expect(1); 21709 21710 assert.deepEqual(_.takeRight(array, 2), [2, 3]); 21711 }); 21712 21713 QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) { 21714 assert.expect(1); 21715 21716 var expected = lodashStable.map(falsey, function(value) { 21717 return value === undefined ? [3] : []; 21718 }); 21719 21720 var actual = lodashStable.map(falsey, function(n) { 21721 return _.takeRight(array, n); 21722 }); 21723 21724 assert.deepEqual(actual, expected); 21725 }); 21726 21727 QUnit.test('should return an empty array when `n` < `1`', function(assert) { 21728 assert.expect(3); 21729 21730 lodashStable.each([0, -1, -Infinity], function(n) { 21731 assert.deepEqual(_.takeRight(array, n), []); 21732 }); 21733 }); 21734 21735 QUnit.test('should return all elements when `n` >= `length`', function(assert) { 21736 assert.expect(4); 21737 21738 lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) { 21739 assert.deepEqual(_.takeRight(array, n), array); 21740 }); 21741 }); 21742 21743 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 21744 assert.expect(1); 21745 21746 var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 21747 actual = lodashStable.map(array, _.takeRight); 21748 21749 assert.deepEqual(actual, [[3], [6], [9]]); 21750 }); 21751 21752 QUnit.test('should work in a lazy sequence', function(assert) { 21753 assert.expect(6); 21754 21755 if (!isNpm) { 21756 var array = lodashStable.range(LARGE_ARRAY_SIZE), 21757 predicate = function(value) { values.push(value); return isEven(value); }, 21758 values = [], 21759 actual = _(array).takeRight(2).takeRight().value(); 21760 21761 assert.deepEqual(actual, _.takeRight(_.takeRight(array))); 21762 21763 actual = _(array).filter(predicate).takeRight(2).takeRight().value(); 21764 assert.deepEqual(values, array); 21765 assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2))); 21766 21767 actual = _(array).takeRight(6).take(4).takeRight(2).take().value(); 21768 assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2))); 21769 21770 values = []; 21771 21772 actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value(); 21773 assert.deepEqual(values, array); 21774 assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2))); 21775 } 21776 else { 21777 skipAssert(assert, 6); 21778 } 21779 }); 21780 }()); 21781 21782 /*--------------------------------------------------------------------------*/ 21783 21784 QUnit.module('lodash.takeRightWhile'); 21785 21786 (function() { 21787 var array = [1, 2, 3, 4]; 21788 21789 var objects = [ 21790 { 'a': 0, 'b': 0 }, 21791 { 'a': 1, 'b': 1 }, 21792 { 'a': 2, 'b': 2 } 21793 ]; 21794 21795 QUnit.test('should take elements while `predicate` returns truthy', function(assert) { 21796 assert.expect(1); 21797 21798 var actual = _.takeRightWhile(array, function(n) { 21799 return n > 2; 21800 }); 21801 21802 assert.deepEqual(actual, [3, 4]); 21803 }); 21804 21805 QUnit.test('should provide correct `predicate` arguments', function(assert) { 21806 assert.expect(1); 21807 21808 var args; 21809 21810 _.takeRightWhile(array, function() { 21811 args = slice.call(arguments); 21812 }); 21813 21814 assert.deepEqual(args, [4, 3, array]); 21815 }); 21816 21817 QUnit.test('should work with `_.matches` shorthands', function(assert) { 21818 assert.expect(1); 21819 21820 assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2)); 21821 }); 21822 21823 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 21824 assert.expect(1); 21825 21826 assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2)); 21827 }); 21828 21829 QUnit.test('should work with `_.property` shorthands', function(assert) { 21830 assert.expect(1); 21831 21832 assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1)); 21833 }); 21834 21835 QUnit.test('should work in a lazy sequence', function(assert) { 21836 assert.expect(3); 21837 21838 if (!isNpm) { 21839 var array = lodashStable.range(LARGE_ARRAY_SIZE), 21840 predicate = function(n) { return n > 2; }, 21841 expected = _.takeRightWhile(array, predicate), 21842 wrapped = _(array).takeRightWhile(predicate); 21843 21844 assert.deepEqual(wrapped.value(), expected); 21845 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse()); 21846 assert.strictEqual(wrapped.last(), _.last(expected)); 21847 } 21848 else { 21849 skipAssert(assert, 3); 21850 } 21851 }); 21852 21853 QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) { 21854 assert.expect(5); 21855 21856 if (!isNpm) { 21857 var args, 21858 array = lodashStable.range(LARGE_ARRAY_SIZE + 1); 21859 21860 var expected = [ 21861 square(LARGE_ARRAY_SIZE), 21862 LARGE_ARRAY_SIZE - 1, 21863 lodashStable.map(array.slice(1), square) 21864 ]; 21865 21866 _(array).slice(1).takeRightWhile(function(value, index, array) { 21867 args = slice.call(arguments); 21868 }).value(); 21869 21870 assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]); 21871 21872 _(array).slice(1).map(square).takeRightWhile(function(value, index, array) { 21873 args = slice.call(arguments); 21874 }).value(); 21875 21876 assert.deepEqual(args, expected); 21877 21878 _(array).slice(1).map(square).takeRightWhile(function(value, index) { 21879 args = slice.call(arguments); 21880 }).value(); 21881 21882 assert.deepEqual(args, expected); 21883 21884 _(array).slice(1).map(square).takeRightWhile(function(index) { 21885 args = slice.call(arguments); 21886 }).value(); 21887 21888 assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]); 21889 21890 _(array).slice(1).map(square).takeRightWhile(function() { 21891 args = slice.call(arguments); 21892 }).value(); 21893 21894 assert.deepEqual(args, expected); 21895 } 21896 else { 21897 skipAssert(assert, 5); 21898 } 21899 }); 21900 }()); 21901 21902 /*--------------------------------------------------------------------------*/ 21903 21904 QUnit.module('lodash.takeWhile'); 21905 21906 (function() { 21907 var array = [1, 2, 3, 4]; 21908 21909 var objects = [ 21910 { 'a': 2, 'b': 2 }, 21911 { 'a': 1, 'b': 1 }, 21912 { 'a': 0, 'b': 0 } 21913 ]; 21914 21915 QUnit.test('should take elements while `predicate` returns truthy', function(assert) { 21916 assert.expect(1); 21917 21918 var actual = _.takeWhile(array, function(n) { 21919 return n < 3; 21920 }); 21921 21922 assert.deepEqual(actual, [1, 2]); 21923 }); 21924 21925 QUnit.test('should provide correct `predicate` arguments', function(assert) { 21926 assert.expect(1); 21927 21928 var args; 21929 21930 _.takeWhile(array, function() { 21931 args = slice.call(arguments); 21932 }); 21933 21934 assert.deepEqual(args, [1, 0, array]); 21935 }); 21936 21937 QUnit.test('should work with `_.matches` shorthands', function(assert) { 21938 assert.expect(1); 21939 21940 assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1)); 21941 }); 21942 21943 QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) { 21944 assert.expect(1); 21945 21946 assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1)); 21947 }); 21948 QUnit.test('should work with `_.property` shorthands', function(assert) { 21949 assert.expect(1); 21950 21951 assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2)); 21952 }); 21953 21954 QUnit.test('should work in a lazy sequence', function(assert) { 21955 assert.expect(3); 21956 21957 if (!isNpm) { 21958 var array = lodashStable.range(LARGE_ARRAY_SIZE), 21959 predicate = function(n) { return n < 3; }, 21960 expected = _.takeWhile(array, predicate), 21961 wrapped = _(array).takeWhile(predicate); 21962 21963 assert.deepEqual(wrapped.value(), expected); 21964 assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse()); 21965 assert.strictEqual(wrapped.last(), _.last(expected)); 21966 } 21967 else { 21968 skipAssert(assert, 3); 21969 } 21970 }); 21971 21972 QUnit.test('should work in a lazy sequence with `take`', function(assert) { 21973 assert.expect(1); 21974 21975 if (!isNpm) { 21976 var array = lodashStable.range(LARGE_ARRAY_SIZE); 21977 21978 var actual = _(array) 21979 .takeWhile(function(n) { return n < 4; }) 21980 .take(2) 21981 .takeWhile(function(n) { return n == 0; }) 21982 .value(); 21983 21984 assert.deepEqual(actual, [0]); 21985 } 21986 else { 21987 skipAssert(assert); 21988 } 21989 }); 21990 21991 QUnit.test('should provide correct `predicate` arguments in a lazy sequence', function(assert) { 21992 assert.expect(5); 21993 21994 if (!isNpm) { 21995 var args, 21996 array = lodashStable.range(LARGE_ARRAY_SIZE + 1), 21997 expected = [1, 0, lodashStable.map(array.slice(1), square)]; 21998 21999 _(array).slice(1).takeWhile(function(value, index, array) { 22000 args = slice.call(arguments); 22001 }).value(); 22002 22003 assert.deepEqual(args, [1, 0, array.slice(1)]); 22004 22005 _(array).slice(1).map(square).takeWhile(function(value, index, array) { 22006 args = slice.call(arguments); 22007 }).value(); 22008 22009 assert.deepEqual(args, expected); 22010 22011 _(array).slice(1).map(square).takeWhile(function(value, index) { 22012 args = slice.call(arguments); 22013 }).value(); 22014 22015 assert.deepEqual(args, expected); 22016 22017 _(array).slice(1).map(square).takeWhile(function(value) { 22018 args = slice.call(arguments); 22019 }).value(); 22020 22021 assert.deepEqual(args, [1]); 22022 22023 _(array).slice(1).map(square).takeWhile(function() { 22024 args = slice.call(arguments); 22025 }).value(); 22026 22027 assert.deepEqual(args, expected); 22028 } 22029 else { 22030 skipAssert(assert, 5); 22031 } 22032 }); 22033 }()); 22034 22035 /*--------------------------------------------------------------------------*/ 22036 22037 QUnit.module('lodash.tap'); 22038 22039 (function() { 22040 QUnit.test('should intercept and return the given value', function(assert) { 22041 assert.expect(2); 22042 22043 if (!isNpm) { 22044 var intercepted, 22045 array = [1, 2, 3]; 22046 22047 var actual = _.tap(array, function(value) { 22048 intercepted = value; 22049 }); 22050 22051 assert.strictEqual(actual, array); 22052 assert.strictEqual(intercepted, array); 22053 } 22054 else { 22055 skipAssert(assert, 2); 22056 } 22057 }); 22058 22059 QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) { 22060 assert.expect(2); 22061 22062 if (!isNpm) { 22063 var intercepted, 22064 array = [1, 2, 3]; 22065 22066 var wrapped = _(array).tap(function(value) { 22067 intercepted = value; 22068 value.pop(); 22069 }); 22070 22071 assert.ok(wrapped instanceof _); 22072 22073 wrapped.value(); 22074 assert.strictEqual(intercepted, array); 22075 } 22076 else { 22077 skipAssert(assert, 2); 22078 } 22079 }); 22080 }()); 22081 22082 /*--------------------------------------------------------------------------*/ 22083 22084 QUnit.module('lodash.template'); 22085 22086 (function() { 22087 QUnit.test('should escape values in "escape" delimiters', function(assert) { 22088 assert.expect(1); 22089 22090 var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'], 22091 expected = lodashStable.map(strings, lodashStable.constant('<p>&<>"'/</p>')), 22092 data = { 'value': '&<>"\'/' }; 22093 22094 var actual = lodashStable.map(strings, function(string) { 22095 return _.template(string)(data); 22096 }); 22097 22098 assert.deepEqual(actual, expected); 22099 }); 22100 22101 QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) { 22102 assert.expect(1); 22103 22104 var compiled = _.template('<%= typeof __e %>'); 22105 assert.strictEqual(compiled({}), 'undefined'); 22106 }); 22107 22108 QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) { 22109 assert.expect(1); 22110 22111 var compiled = _.template( 22112 '<ul><%\ 22113 for (var key in collection) {\ 22114 %><li><%= collection[key] %></li><%\ 22115 } %></ul>' 22116 ); 22117 22118 var data = { 'collection': { 'a': 'A', 'b': 'B' } }, 22119 actual = compiled(data); 22120 22121 assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>'); 22122 }); 22123 22124 QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) { 22125 assert.expect(1); 22126 22127 var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'), 22128 data = { 'value': true }; 22129 22130 assert.strictEqual(compiled(data), 'yap'); 22131 }); 22132 22133 QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) { 22134 assert.expect(1); 22135 22136 var compiled = _.template('<% var b = a; %><%= b.value %>'), 22137 data = { 'a': { 'value': 1 } }; 22138 22139 assert.strictEqual(compiled(data), '1'); 22140 }); 22141 22142 QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) { 22143 assert.expect(1); 22144 22145 var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'], 22146 expected = lodashStable.map(strings, lodashStable.constant('ABC')), 22147 data = { 'a': 'A' }; 22148 22149 var actual = lodashStable.map(strings, function(string) { 22150 return _.template(string)(data); 22151 }); 22152 22153 assert.deepEqual(actual, expected); 22154 }); 22155 22156 QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) { 22157 assert.expect(1); 22158 22159 var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'), 22160 data = { 'a': true }; 22161 22162 assert.strictEqual(compiled(data), 'a="A"'); 22163 }); 22164 22165 QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) { 22166 assert.expect(1); 22167 22168 var compiled = _.template('<%= value ? value : "b" %>'), 22169 data = { 'value': 'a' }; 22170 22171 assert.strictEqual(compiled(data), 'a'); 22172 }); 22173 22174 QUnit.test('should support "interpolate" delimiters containing global values', function(assert) { 22175 assert.expect(1); 22176 22177 var compiled = _.template('<%= typeof Math.abs %>'); 22178 22179 try { 22180 var actual = compiled(); 22181 } catch (e) {} 22182 22183 assert.strictEqual(actual, 'function'); 22184 }); 22185 22186 QUnit.test('should support complex "interpolate" delimiters', function(assert) { 22187 assert.expect(22); 22188 22189 lodashStable.forOwn({ 22190 '<%= a + b %>': '3', 22191 '<%= b - a %>': '1', 22192 '<%= a = b %>': '2', 22193 '<%= !a %>': 'false', 22194 '<%= ~a %>': '-2', 22195 '<%= a * b %>': '2', 22196 '<%= a / b %>': '0.5', 22197 '<%= a % b %>': '1', 22198 '<%= a >> b %>': '0', 22199 '<%= a << b %>': '4', 22200 '<%= a & b %>': '0', 22201 '<%= a ^ b %>': '3', 22202 '<%= a | b %>': '3', 22203 '<%= {}.toString.call(0) %>': numberTag, 22204 '<%= a.toFixed(2) %>': '1.00', 22205 '<%= obj["a"] %>': '1', 22206 '<%= delete a %>': 'true', 22207 '<%= "a" in obj %>': 'true', 22208 '<%= obj instanceof Object %>': 'true', 22209 '<%= new Boolean %>': 'false', 22210 '<%= typeof a %>': 'number', 22211 '<%= void a %>': '' 22212 }, 22213 function(value, key) { 22214 var compiled = _.template(key), 22215 data = { 'a': 1, 'b': 2 }; 22216 22217 assert.strictEqual(compiled(data), value, key); 22218 }); 22219 }); 22220 22221 QUnit.test('should support ES6 template delimiters', function(assert) { 22222 assert.expect(2); 22223 22224 var data = { 'value': 2 }; 22225 assert.strictEqual(_.template('1${value}3')(data), '123'); 22226 assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}'); 22227 }); 22228 22229 QUnit.test('should support the "imports" option', function(assert) { 22230 assert.expect(1); 22231 22232 var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } }); 22233 assert.strictEqual(compiled({}), '1'); 22234 }); 22235 22236 QUnit.test('should support the "variable" options', function(assert) { 22237 assert.expect(1); 22238 22239 var compiled = _.template( 22240 '<% _.each( data.a, function( value ) { %>' + 22241 '<%= value.valueOf() %>' + 22242 '<% }) %>', { 'variable': 'data' } 22243 ); 22244 22245 var data = { 'a': [1, 2, 3] }; 22246 22247 try { 22248 assert.strictEqual(compiled(data), '123'); 22249 } catch (e) { 22250 assert.ok(false, e.message); 22251 } 22252 }); 22253 22254 QUnit.test('should support custom delimiters', function(assert) { 22255 assert.expect(2); 22256 22257 lodashStable.times(2, function(index) { 22258 var settingsClone = lodashStable.clone(_.templateSettings); 22259 22260 var settings = lodashStable.assign(index ? _.templateSettings : {}, { 22261 'escape': /\{\{-([\s\S]+?)\}\}/g, 22262 'evaluate': /\{\{([\s\S]+?)\}\}/g, 22263 'interpolate': /\{\{=([\s\S]+?)\}\}/g 22264 }); 22265 22266 var expected = '<ul><li>0: a & A</li><li>1: b & B</li></ul>', 22267 compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings), 22268 data = { 'collection': ['a & A', 'b & B'] }; 22269 22270 assert.strictEqual(compiled(data), expected); 22271 lodashStable.assign(_.templateSettings, settingsClone); 22272 }); 22273 }); 22274 22275 QUnit.test('should support custom delimiters containing special characters', function(assert) { 22276 assert.expect(2); 22277 22278 lodashStable.times(2, function(index) { 22279 var settingsClone = lodashStable.clone(_.templateSettings); 22280 22281 var settings = lodashStable.assign(index ? _.templateSettings : {}, { 22282 'escape': /<\?-([\s\S]+?)\?>/g, 22283 'evaluate': /<\?([\s\S]+?)\?>/g, 22284 'interpolate': /<\?=([\s\S]+?)\?>/g 22285 }); 22286 22287 var expected = '<ul><li>0: a & A</li><li>1: b & B</li></ul>', 22288 compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings), 22289 data = { 'collection': ['a & A', 'b & B'] }; 22290 22291 assert.strictEqual(compiled(data), expected); 22292 lodashStable.assign(_.templateSettings, settingsClone); 22293 }); 22294 }); 22295 22296 QUnit.test('should use a `with` statement by default', function(assert) { 22297 assert.expect(1); 22298 22299 var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'), 22300 actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] }); 22301 22302 assert.strictEqual(actual, '1b012'); 22303 }); 22304 22305 QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) { 22306 assert.expect(1); 22307 22308 var lodash = _.templateSettings.imports._, 22309 settingsClone = lodashStable.clone(lodash.templateSettings); 22310 22311 lodash.templateSettings = lodashStable.assign(lodash.templateSettings, { 22312 'interpolate': /\{\{=([\s\S]+?)\}\}/g 22313 }); 22314 22315 var compiled = _.template('{{= a }}'); 22316 assert.strictEqual(compiled({ 'a': 1 }), '1'); 22317 22318 if (settingsClone) { 22319 lodashStable.assign(lodash.templateSettings, settingsClone); 22320 } else { 22321 delete lodash.templateSettings; 22322 } 22323 }); 22324 22325 QUnit.test('should fallback to `_.templateSettings`', function(assert) { 22326 assert.expect(1); 22327 22328 var lodash = _.templateSettings.imports._, 22329 delimiter = _.templateSettings.interpolate; 22330 22331 _.templateSettings.imports._ = { 'escape': lodashStable.escape }; 22332 _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g; 22333 22334 var compiled = _.template('{{= a }}'); 22335 assert.strictEqual(compiled({ 'a': 1 }), '1'); 22336 22337 _.templateSettings.imports._ = lodash; 22338 _.templateSettings.interpolate = delimiter; 22339 }); 22340 22341 QUnit.test('should ignore `null` delimiters', function(assert) { 22342 assert.expect(3); 22343 22344 var delimiter = { 22345 'escape': /\{\{-([\s\S]+?)\}\}/g, 22346 'evaluate': /\{\{([\s\S]+?)\}\}/g, 22347 'interpolate': /\{\{=([\s\S]+?)\}\}/g 22348 }; 22349 22350 lodashStable.forOwn({ 22351 'escape': '{{- a }}', 22352 'evaluate': '{{ print(a) }}', 22353 'interpolate': '{{= a }}' 22354 }, 22355 function(value, key) { 22356 var settings = { 'escape': null, 'evaluate': null, 'interpolate': null }; 22357 settings[key] = delimiter[key]; 22358 22359 var expected = '1 <%- a %> <% print(a) %> <%= a %>', 22360 compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings), 22361 data = { 'a': 1 }; 22362 22363 assert.strictEqual(compiled(data), expected); 22364 }); 22365 }); 22366 22367 QUnit.test('should work without delimiters', function(assert) { 22368 assert.expect(1); 22369 22370 var expected = 'abc'; 22371 assert.strictEqual(_.template(expected)({}), expected); 22372 }); 22373 22374 QUnit.test('should work with `this` references', function(assert) { 22375 assert.expect(2); 22376 22377 var compiled = _.template('a<%= this.String("b") %>c'); 22378 assert.strictEqual(compiled(), 'abc'); 22379 22380 var object = { 'b': 'B' }; 22381 object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' }); 22382 assert.strictEqual(object.compiled(), 'ABC'); 22383 }); 22384 22385 QUnit.test('should work with backslashes', function(assert) { 22386 assert.expect(1); 22387 22388 var compiled = _.template('<%= a %> \\b'), 22389 data = { 'a': 'A' }; 22390 22391 assert.strictEqual(compiled(data), 'A \\b'); 22392 }); 22393 22394 QUnit.test('should work with escaped characters in string literals', function(assert) { 22395 assert.expect(2); 22396 22397 var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>'); 22398 assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\"); 22399 22400 var data = { 'a': 'A' }; 22401 compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"'); 22402 assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"'); 22403 }); 22404 22405 QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) { 22406 assert.expect(1); 22407 22408 var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029'); 22409 assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029'); 22410 }); 22411 22412 QUnit.test('should work with statements containing quotes', function(assert) { 22413 assert.expect(1); 22414 22415 var compiled = _.template("<%\ 22416 if (a == 'A' || a == \"a\") {\ 22417 %>'a',\"A\"<%\ 22418 } %>" 22419 ); 22420 22421 var data = { 'a': 'A' }; 22422 assert.strictEqual(compiled(data), "'a',\"A\""); 22423 }); 22424 22425 QUnit.test('should work with templates containing newlines and comments', function(assert) { 22426 assert.expect(1); 22427 22428 var compiled = _.template('<%\n\ 22429 // A code comment.\n\ 22430 if (value) { value += 3; }\n\ 22431 %><p><%= value %></p>' 22432 ); 22433 22434 assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>'); 22435 }); 22436 22437 QUnit.test('should tokenize delimiters', function(assert) { 22438 assert.expect(1); 22439 22440 var compiled = _.template('<span class="icon-<%= type %>2"></span>'), 22441 data = { 'type': 1 }; 22442 22443 assert.strictEqual(compiled(data), '<span class="icon-12"></span>'); 22444 }); 22445 22446 QUnit.test('should evaluate delimiters once', function(assert) { 22447 assert.expect(1); 22448 22449 var actual = [], 22450 compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'), 22451 data = { 'func': function(value) { actual.push(value); } }; 22452 22453 compiled(data); 22454 assert.deepEqual(actual, ['a', 'b', 'c']); 22455 }); 22456 22457 QUnit.test('should match delimiters before escaping text', function(assert) { 22458 assert.expect(1); 22459 22460 var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g }); 22461 assert.strictEqual(compiled(), '<<\n a \n>>'); 22462 }); 22463 22464 QUnit.test('should resolve nullish values to an empty string', function(assert) { 22465 assert.expect(3); 22466 22467 var compiled = _.template('<%= a %><%- a %>'), 22468 data = { 'a': null }; 22469 22470 assert.strictEqual(compiled(data), ''); 22471 22472 data = { 'a': undefined }; 22473 assert.strictEqual(compiled(data), ''); 22474 22475 data = { 'a': {} }; 22476 compiled = _.template('<%= a.b %><%- a.b %>'); 22477 assert.strictEqual(compiled(data), ''); 22478 }); 22479 22480 QUnit.test('should return an empty string for empty values', function(assert) { 22481 assert.expect(1); 22482 22483 var values = [, null, undefined, ''], 22484 expected = lodashStable.map(values, stubString), 22485 data = { 'a': 1 }; 22486 22487 var actual = lodashStable.map(values, function(value, index) { 22488 var compiled = index ? _.template(value) : _.template(); 22489 return compiled(data); 22490 }); 22491 22492 assert.deepEqual(actual, expected); 22493 }); 22494 22495 QUnit.test('should parse delimiters without newlines', function(assert) { 22496 assert.expect(1); 22497 22498 var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>', 22499 compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }), 22500 data = { 'value': true }; 22501 22502 assert.strictEqual(compiled(data), expected); 22503 }); 22504 22505 QUnit.test('should support recursive calls', function(assert) { 22506 assert.expect(1); 22507 22508 var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'), 22509 data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' }; 22510 22511 assert.strictEqual(compiled(data), 'AB'); 22512 }); 22513 22514 QUnit.test('should coerce `text` to a string', function(assert) { 22515 assert.expect(1); 22516 22517 var object = { 'toString': lodashStable.constant('<%= a %>') }, 22518 data = { 'a': 1 }; 22519 22520 assert.strictEqual(_.template(object)(data), '1'); 22521 }); 22522 22523 QUnit.test('should not modify the `options` object', function(assert) { 22524 assert.expect(1); 22525 22526 var options = {}; 22527 _.template('', options); 22528 assert.deepEqual(options, {}); 22529 }); 22530 22531 QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) { 22532 assert.expect(2); 22533 22534 var data = { 'a': 1 }; 22535 22536 assert.notOk('a' in _.templateSettings); 22537 _.template('', {}, data); 22538 assert.notOk('a' in _.templateSettings); 22539 22540 delete _.templateSettings.a; 22541 }); 22542 22543 QUnit.test('should not error for non-object `data` and `options` values', function(assert) { 22544 assert.expect(2); 22545 22546 _.template('')(1); 22547 assert.ok(true, '`data` value'); 22548 22549 _.template('', 1)(1); 22550 assert.ok(true, '`options` value'); 22551 }); 22552 22553 QUnit.test('should expose the source on compiled templates', function(assert) { 22554 assert.expect(1); 22555 22556 var compiled = _.template('x'), 22557 values = [String(compiled), compiled.source], 22558 expected = lodashStable.map(values, stubTrue); 22559 22560 var actual = lodashStable.map(values, function(value) { 22561 return lodashStable.includes(value, '__p'); 22562 }); 22563 22564 assert.deepEqual(actual, expected); 22565 }); 22566 22567 QUnit.test('should expose the source on SyntaxErrors', function(assert) { 22568 assert.expect(1); 22569 22570 try { 22571 _.template('<% if x %>'); 22572 } catch (e) { 22573 var source = e.source; 22574 } 22575 assert.ok(lodashStable.includes(source, '__p')); 22576 }); 22577 22578 QUnit.test('should not include sourceURLs in the source', function(assert) { 22579 assert.expect(1); 22580 22581 var options = { 'sourceURL': '/a/b/c' }, 22582 compiled = _.template('x', options), 22583 values = [compiled.source, undefined]; 22584 22585 try { 22586 _.template('<% if x %>', options); 22587 } catch (e) { 22588 values[1] = e.source; 22589 } 22590 var expected = lodashStable.map(values, stubFalse); 22591 22592 var actual = lodashStable.map(values, function(value) { 22593 return lodashStable.includes(value, 'sourceURL'); 22594 }); 22595 22596 assert.deepEqual(actual, expected); 22597 }); 22598 22599 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 22600 assert.expect(1); 22601 22602 var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'], 22603 compiles = lodashStable.map(array, _.template), 22604 data = { 'a': 'one', 'b': '"two"', 'c': 'three' }; 22605 22606 var actual = lodashStable.map(compiles, function(compiled) { 22607 return compiled(data); 22608 }); 22609 22610 assert.deepEqual(actual, ['one', '"two"', 'three']); 22611 }); 22612 }()); 22613 22614 /*--------------------------------------------------------------------------*/ 22615 22616 QUnit.module('lodash.truncate'); 22617 22618 (function() { 22619 var string = 'hi-diddly-ho there, neighborino'; 22620 22621 QUnit.test('should use a default `length` of `30`', function(assert) { 22622 assert.expect(1); 22623 22624 assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...'); 22625 }); 22626 22627 QUnit.test('should not truncate if `string` is <= `length`', function(assert) { 22628 assert.expect(2); 22629 22630 assert.strictEqual(_.truncate(string, { 'length': string.length }), string); 22631 assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string); 22632 }); 22633 22634 QUnit.test('should truncate string the given length', function(assert) { 22635 assert.expect(1); 22636 22637 assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...'); 22638 }); 22639 22640 QUnit.test('should support a `omission` option', function(assert) { 22641 assert.expect(1); 22642 22643 assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]'); 22644 }); 22645 22646 QUnit.test('should coerce nullish `omission` values to strings', function(assert) { 22647 assert.expect(2); 22648 22649 assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull'); 22650 assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined'); 22651 }); 22652 22653 QUnit.test('should support a `length` option', function(assert) { 22654 assert.expect(1); 22655 22656 assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...'); 22657 }); 22658 22659 QUnit.test('should support a `separator` option', function(assert) { 22660 assert.expect(3); 22661 22662 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...'); 22663 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...'); 22664 assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...'); 22665 }); 22666 22667 QUnit.test('should treat negative `length` as `0`', function(assert) { 22668 assert.expect(2); 22669 22670 lodashStable.each([0, -2], function(length) { 22671 assert.strictEqual(_.truncate(string, { 'length': length }), '...'); 22672 }); 22673 }); 22674 22675 QUnit.test('should coerce `length` to an integer', function(assert) { 22676 assert.expect(4); 22677 22678 lodashStable.each(['', NaN, 4.6, '4'], function(length, index) { 22679 var actual = index > 1 ? 'h...' : '...'; 22680 assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual); 22681 }); 22682 }); 22683 22684 QUnit.test('should coerce `string` to a string', function(assert) { 22685 assert.expect(2); 22686 22687 assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...'); 22688 assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...'); 22689 }); 22690 22691 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 22692 assert.expect(1); 22693 22694 var actual = lodashStable.map([string, string, string], _.truncate), 22695 truncated = 'hi-diddly-ho there, neighbo...'; 22696 22697 assert.deepEqual(actual, [truncated, truncated, truncated]); 22698 }); 22699 }()); 22700 22701 /*--------------------------------------------------------------------------*/ 22702 22703 QUnit.module('lodash.throttle'); 22704 22705 (function() { 22706 QUnit.test('should throttle a function', function(assert) { 22707 assert.expect(2); 22708 22709 var done = assert.async(); 22710 22711 var callCount = 0, 22712 throttled = _.throttle(function() { callCount++; }, 32); 22713 22714 throttled(); 22715 throttled(); 22716 throttled(); 22717 22718 var lastCount = callCount; 22719 assert.ok(callCount); 22720 22721 setTimeout(function() { 22722 assert.ok(callCount > lastCount); 22723 done(); 22724 }, 64); 22725 }); 22726 22727 QUnit.test('subsequent calls should return the result of the first call', function(assert) { 22728 assert.expect(5); 22729 22730 var done = assert.async(); 22731 22732 var throttled = _.throttle(identity, 32), 22733 results = [throttled('a'), throttled('b')]; 22734 22735 assert.deepEqual(results, ['a', 'a']); 22736 22737 setTimeout(function() { 22738 var results = [throttled('c'), throttled('d')]; 22739 assert.notEqual(results[0], 'a'); 22740 assert.notStrictEqual(results[0], undefined); 22741 22742 assert.notEqual(results[1], 'd'); 22743 assert.notStrictEqual(results[1], undefined); 22744 done(); 22745 }, 64); 22746 }); 22747 22748 QUnit.test('should clear timeout when `func` is called', function(assert) { 22749 assert.expect(1); 22750 22751 var done = assert.async(); 22752 22753 if (!isModularize) { 22754 var callCount = 0, 22755 dateCount = 0; 22756 22757 var lodash = _.runInContext({ 22758 'Date': { 22759 'now': function() { 22760 return ++dateCount == 5 ? Infinity : +new Date; 22761 } 22762 } 22763 }); 22764 22765 var throttled = lodash.throttle(function() { callCount++; }, 32); 22766 22767 throttled(); 22768 throttled(); 22769 22770 setTimeout(function() { 22771 assert.strictEqual(callCount, 2); 22772 done(); 22773 }, 64); 22774 } 22775 else { 22776 skipAssert(assert); 22777 done(); 22778 } 22779 }); 22780 22781 QUnit.test('should not trigger a trailing call when invoked once', function(assert) { 22782 assert.expect(2); 22783 22784 var done = assert.async(); 22785 22786 var callCount = 0, 22787 throttled = _.throttle(function() { callCount++; }, 32); 22788 22789 throttled(); 22790 assert.strictEqual(callCount, 1); 22791 22792 setTimeout(function() { 22793 assert.strictEqual(callCount, 1); 22794 done(); 22795 }, 64); 22796 }); 22797 22798 lodashStable.times(2, function(index) { 22799 QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) { 22800 assert.expect(1); 22801 22802 var done = assert.async(); 22803 22804 var callCount = 0, 22805 limit = (argv || isPhantom) ? 1000 : 320, 22806 options = index ? { 'leading': false } : {}, 22807 throttled = _.throttle(function() { callCount++; }, 32, options); 22808 22809 var start = +new Date; 22810 while ((new Date - start) < limit) { 22811 throttled(); 22812 } 22813 var actual = callCount > 1; 22814 setTimeout(function() { 22815 assert.ok(actual); 22816 done(); 22817 }, 1); 22818 }); 22819 }); 22820 22821 QUnit.test('should trigger a second throttled call as soon as possible', function(assert) { 22822 assert.expect(3); 22823 22824 var done = assert.async(); 22825 22826 var callCount = 0; 22827 22828 var throttled = _.throttle(function() { 22829 callCount++; 22830 }, 128, { 'leading': false }); 22831 22832 throttled(); 22833 22834 setTimeout(function() { 22835 assert.strictEqual(callCount, 1); 22836 throttled(); 22837 }, 192); 22838 22839 setTimeout(function() { 22840 assert.strictEqual(callCount, 1); 22841 }, 254); 22842 22843 setTimeout(function() { 22844 assert.strictEqual(callCount, 2); 22845 done(); 22846 }, 384); 22847 }); 22848 22849 QUnit.test('should apply default options', function(assert) { 22850 assert.expect(2); 22851 22852 var done = assert.async(); 22853 22854 var callCount = 0, 22855 throttled = _.throttle(function() { callCount++; }, 32, {}); 22856 22857 throttled(); 22858 throttled(); 22859 assert.strictEqual(callCount, 1); 22860 22861 setTimeout(function() { 22862 assert.strictEqual(callCount, 2); 22863 done(); 22864 }, 128); 22865 }); 22866 22867 QUnit.test('should support a `leading` option', function(assert) { 22868 assert.expect(2); 22869 22870 var withLeading = _.throttle(identity, 32, { 'leading': true }); 22871 assert.strictEqual(withLeading('a'), 'a'); 22872 22873 var withoutLeading = _.throttle(identity, 32, { 'leading': false }); 22874 assert.strictEqual(withoutLeading('a'), undefined); 22875 }); 22876 22877 QUnit.test('should support a `trailing` option', function(assert) { 22878 assert.expect(6); 22879 22880 var done = assert.async(); 22881 22882 var withCount = 0, 22883 withoutCount = 0; 22884 22885 var withTrailing = _.throttle(function(value) { 22886 withCount++; 22887 return value; 22888 }, 64, { 'trailing': true }); 22889 22890 var withoutTrailing = _.throttle(function(value) { 22891 withoutCount++; 22892 return value; 22893 }, 64, { 'trailing': false }); 22894 22895 assert.strictEqual(withTrailing('a'), 'a'); 22896 assert.strictEqual(withTrailing('b'), 'a'); 22897 22898 assert.strictEqual(withoutTrailing('a'), 'a'); 22899 assert.strictEqual(withoutTrailing('b'), 'a'); 22900 22901 setTimeout(function() { 22902 assert.strictEqual(withCount, 2); 22903 assert.strictEqual(withoutCount, 1); 22904 done(); 22905 }, 256); 22906 }); 22907 22908 QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) { 22909 assert.expect(1); 22910 22911 var done = assert.async(); 22912 22913 var callCount = 0; 22914 22915 var throttled = _.throttle(function() { 22916 callCount++; 22917 }, 64, { 'trailing': false }); 22918 22919 throttled(); 22920 throttled(); 22921 22922 setTimeout(function() { 22923 throttled(); 22924 throttled(); 22925 }, 96); 22926 22927 setTimeout(function() { 22928 assert.ok(callCount > 1); 22929 done(); 22930 }, 192); 22931 }); 22932 22933 QUnit.test('should work with a system time of `0`', function(assert) { 22934 assert.expect(3); 22935 22936 var done = assert.async(); 22937 22938 if (!isModularize) { 22939 var callCount = 0, 22940 dateCount = 0; 22941 22942 var lodash = _.runInContext({ 22943 'Date': { 22944 'now': function() { 22945 return ++dateCount < 4 ? 0 : +new Date; 22946 } 22947 } 22948 }); 22949 22950 var throttled = lodash.throttle(function(value) { 22951 callCount++; 22952 return value; 22953 }, 32); 22954 22955 var results = [throttled('a'), throttled('b'), throttled('c')]; 22956 assert.deepEqual(results, ['a', 'a', 'a']); 22957 assert.strictEqual(callCount, 1); 22958 22959 setTimeout(function() { 22960 assert.strictEqual(callCount, 2); 22961 done(); 22962 }, 64); 22963 } 22964 else { 22965 skipAssert(assert, 3); 22966 done(); 22967 } 22968 }); 22969 }()); 22970 22971 /*--------------------------------------------------------------------------*/ 22972 22973 QUnit.module('lodash.debounce and lodash.throttle'); 22974 22975 lodashStable.each(['debounce', 'throttle'], function(methodName) { 22976 var func = _[methodName], 22977 isDebounce = methodName == 'debounce'; 22978 22979 QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) { 22980 assert.expect(1); 22981 22982 func(noop, 32, 1); 22983 assert.ok(true); 22984 }); 22985 22986 QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) { 22987 assert.expect(1); 22988 22989 var done = assert.async(); 22990 22991 var callCount = 0, 22992 funced = func(function() { callCount++; }); 22993 22994 funced(); 22995 22996 setTimeout(function() { 22997 funced(); 22998 assert.strictEqual(callCount, isDebounce ? 1 : 2); 22999 done(); 23000 }, 32); 23001 }); 23002 23003 QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) { 23004 assert.expect(1); 23005 23006 var done = assert.async(); 23007 23008 var actual = [], 23009 object = { 'funced': func(function() { actual.push(this); }, 32) }, 23010 expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object)); 23011 23012 object.funced(); 23013 if (!isDebounce) { 23014 object.funced(); 23015 } 23016 setTimeout(function() { 23017 assert.deepEqual(actual, expected); 23018 done(); 23019 }, 64); 23020 }); 23021 23022 QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) { 23023 assert.expect(2); 23024 23025 var done = assert.async(); 23026 23027 var actual = [], 23028 args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }), 23029 expected = args.slice(), 23030 queue = args.slice(); 23031 23032 var funced = func(function() { 23033 var current = [this]; 23034 push.apply(current, arguments); 23035 actual.push(current); 23036 23037 var next = queue.shift(); 23038 if (next) { 23039 funced.call(next[0], next[1]); 23040 } 23041 }, 32); 23042 23043 var next = queue.shift(); 23044 funced.call(next[0], next[1]); 23045 assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1)); 23046 23047 setTimeout(function() { 23048 assert.deepEqual(actual, expected.slice(0, actual.length)); 23049 done(); 23050 }, 256); 23051 }); 23052 23053 QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) { 23054 assert.expect(1); 23055 23056 var done = assert.async(); 23057 23058 if (!isModularize) { 23059 var callCount = 0, 23060 dateCount = 0; 23061 23062 var lodash = _.runInContext({ 23063 'Date': { 23064 'now': function() { 23065 return ++dateCount == 4 23066 ? +new Date(2012, 3, 23, 23, 27, 18) 23067 : +new Date; 23068 } 23069 } 23070 }); 23071 23072 var funced = lodash[methodName](function() { 23073 callCount++; 23074 }, 32); 23075 23076 funced(); 23077 23078 setTimeout(function() { 23079 funced(); 23080 assert.strictEqual(callCount, isDebounce ? 1 : 2); 23081 done(); 23082 }, 64); 23083 } 23084 else { 23085 skipAssert(assert); 23086 done(); 23087 } 23088 }); 23089 23090 QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) { 23091 assert.expect(1); 23092 23093 var done = assert.async(); 23094 23095 var callCount = 0; 23096 23097 var funced = func(function() { 23098 callCount++; 23099 }, 32, { 'leading': false }); 23100 23101 funced(); 23102 funced.cancel(); 23103 23104 setTimeout(function() { 23105 assert.strictEqual(callCount, 0); 23106 done(); 23107 }, 64); 23108 }); 23109 23110 QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) { 23111 assert.expect(3); 23112 23113 var done = assert.async(); 23114 23115 var callCount = 0; 23116 23117 var funced = func(function() { 23118 return ++callCount; 23119 }, 32, { 'leading': true }); 23120 23121 assert.strictEqual(funced(), 1); 23122 funced.cancel(); 23123 23124 assert.strictEqual(funced(), 2); 23125 funced(); 23126 23127 setTimeout(function() { 23128 assert.strictEqual(callCount, 3); 23129 done(); 23130 }, 64); 23131 }); 23132 23133 QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) { 23134 assert.expect(2); 23135 23136 var done = assert.async(); 23137 23138 var callCount = 0; 23139 23140 var funced = func(function() { 23141 return ++callCount; 23142 }, 32, { 'leading': false }); 23143 23144 funced(); 23145 assert.strictEqual(funced.flush(), 1); 23146 23147 setTimeout(function() { 23148 assert.strictEqual(callCount, 1); 23149 done(); 23150 }, 64); 23151 }); 23152 23153 QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) { 23154 assert.expect(2); 23155 23156 var done = assert.async(); 23157 23158 var callCount = 0, 23159 funced = func(function() { callCount++; }, 32); 23160 23161 funced.cancel(); 23162 assert.strictEqual(funced.flush(), undefined); 23163 23164 setTimeout(function() { 23165 assert.strictEqual(callCount, 0); 23166 done(); 23167 }, 64); 23168 }); 23169 }); 23170 23171 /*--------------------------------------------------------------------------*/ 23172 23173 QUnit.module('lodash.times'); 23174 23175 (function() { 23176 QUnit.test('should coerce non-finite `n` values to `0`', function(assert) { 23177 assert.expect(3); 23178 23179 lodashStable.each([-Infinity, NaN, Infinity], function(n) { 23180 assert.deepEqual(_.times(n), []); 23181 }); 23182 }); 23183 23184 QUnit.test('should coerce `n` to an integer', function(assert) { 23185 assert.expect(1); 23186 23187 var actual = _.times(2.6, _.identity); 23188 assert.deepEqual(actual, [0, 1]); 23189 }); 23190 23191 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 23192 assert.expect(1); 23193 23194 var args; 23195 23196 _.times(1, function(assert) { 23197 args || (args = slice.call(arguments)); 23198 }); 23199 23200 assert.deepEqual(args, [0]); 23201 }); 23202 23203 QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) { 23204 assert.expect(1); 23205 23206 var values = [, null, undefined], 23207 expected = lodashStable.map(values, lodashStable.constant([0, 1, 2])); 23208 23209 var actual = lodashStable.map(values, function(value, index) { 23210 return index ? _.times(3, value) : _.times(3); 23211 }); 23212 23213 assert.deepEqual(actual, expected); 23214 }); 23215 23216 QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) { 23217 assert.expect(1); 23218 23219 assert.deepEqual(_.times(3, doubled), [0, 2, 4]); 23220 }); 23221 23222 QUnit.test('should return an empty array for falsey and negative `n` values', function(assert) { 23223 assert.expect(1); 23224 23225 var values = falsey.concat(-1, -Infinity), 23226 expected = lodashStable.map(values, stubArray); 23227 23228 var actual = lodashStable.map(values, function(value, index) { 23229 return index ? _.times(value) : _.times(); 23230 }); 23231 23232 assert.deepEqual(actual, expected); 23233 }); 23234 23235 QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) { 23236 assert.expect(1); 23237 23238 if (!isNpm) { 23239 assert.deepEqual(_(3).times(), [0, 1, 2]); 23240 } 23241 else { 23242 skipAssert(assert); 23243 } 23244 }); 23245 23246 QUnit.test('should return a wrapped value when explicitly chaining', function(assert) { 23247 assert.expect(1); 23248 23249 if (!isNpm) { 23250 assert.ok(_(3).chain().times() instanceof _); 23251 } 23252 else { 23253 skipAssert(assert); 23254 } 23255 }); 23256 }()); 23257 23258 /*--------------------------------------------------------------------------*/ 23259 23260 QUnit.module('lodash.toArray'); 23261 23262 (function() { 23263 QUnit.test('should convert objects to arrays', function(assert) { 23264 assert.expect(1); 23265 23266 assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]); 23267 }); 23268 23269 QUnit.test('should convert iterables to arrays', function(assert) { 23270 assert.expect(1); 23271 23272 if (Symbol && Symbol.iterator) { 23273 var object = { '0': 'a', 'length': 1 }; 23274 object[Symbol.iterator] = arrayProto[Symbol.iterator]; 23275 23276 assert.deepEqual(_.toArray(object), ['a']); 23277 } 23278 else { 23279 skipAssert(assert); 23280 } 23281 }); 23282 23283 QUnit.test('should convert maps to arrays', function(assert) { 23284 assert.expect(1); 23285 23286 if (Map) { 23287 var map = new Map; 23288 map.set('a', 1); 23289 map.set('b', 2); 23290 assert.deepEqual(_.toArray(map), [['a', 1], ['b', 2]]); 23291 } 23292 else { 23293 skipAssert(assert); 23294 } 23295 }); 23296 23297 QUnit.test('should convert strings to arrays', function(assert) { 23298 assert.expect(3); 23299 23300 assert.deepEqual(_.toArray(''), []); 23301 assert.deepEqual(_.toArray('ab'), ['a', 'b']); 23302 assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']); 23303 }); 23304 23305 QUnit.test('should work in a lazy sequence', function(assert) { 23306 assert.expect(2); 23307 23308 if (!isNpm) { 23309 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1); 23310 23311 var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 23312 return ['key' + index, index]; 23313 })); 23314 23315 var actual = _(array).slice(1).map(String).toArray().value(); 23316 assert.deepEqual(actual, lodashStable.map(array.slice(1), String)); 23317 23318 actual = _(object).toArray().slice(1).map(String).value(); 23319 assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String)); 23320 } 23321 else { 23322 skipAssert(assert, 2); 23323 } 23324 }); 23325 }()); 23326 23327 /*--------------------------------------------------------------------------*/ 23328 23329 QUnit.module('lodash.toLower'); 23330 23331 (function() { 23332 QUnit.test('should convert whole string to lower case', function(assert) { 23333 assert.expect(3); 23334 23335 assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--'); 23336 assert.deepEqual(_.toLower('fooBar'), 'foobar'); 23337 assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__'); 23338 }); 23339 }()); 23340 23341 /*--------------------------------------------------------------------------*/ 23342 23343 QUnit.module('lodash.toUpper'); 23344 23345 (function() { 23346 QUnit.test('should convert whole string to upper case', function(assert) { 23347 assert.expect(3); 23348 23349 assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR'); 23350 assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR'); 23351 assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__'); 23352 }); 23353 }()); 23354 23355 /*--------------------------------------------------------------------------*/ 23356 23357 QUnit.module('lodash.slice and lodash.toArray'); 23358 23359 lodashStable.each(['slice', 'toArray'], function(methodName) { 23360 var array = [1, 2, 3], 23361 func = _[methodName]; 23362 23363 QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) { 23364 assert.expect(3); 23365 23366 var sparse = Array(3); 23367 sparse[1] = 2; 23368 23369 var actual = func(sparse); 23370 23371 assert.ok('0' in actual); 23372 assert.ok('2' in actual); 23373 assert.deepEqual(actual, sparse); 23374 }); 23375 23376 QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) { 23377 assert.expect(2); 23378 23379 var object = { '0': 'a', 'length': 1 }; 23380 assert.deepEqual(func(object), ['a']); 23381 assert.deepEqual(func(args), array); 23382 }); 23383 23384 QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) { 23385 assert.expect(2); 23386 23387 var actual = func(array); 23388 assert.deepEqual(actual, array); 23389 assert.notStrictEqual(actual, array); 23390 }); 23391 23392 QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) { 23393 assert.expect(1); 23394 23395 if (document) { 23396 try { 23397 var actual = func(document.getElementsByTagName('body')); 23398 } catch (e) {} 23399 23400 assert.deepEqual(actual, [body]); 23401 } 23402 else { 23403 skipAssert(assert); 23404 } 23405 }); 23406 }); 23407 23408 /*--------------------------------------------------------------------------*/ 23409 23410 QUnit.module('toInteger methods'); 23411 23412 lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) { 23413 var func = _[methodName], 23414 isSafe = methodName == 'toSafeInteger'; 23415 23416 QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) { 23417 assert.expect(6); 23418 23419 assert.strictEqual(func(-5.6), -5); 23420 assert.strictEqual(func('5.6'), 5); 23421 assert.strictEqual(func(), 0); 23422 assert.strictEqual(func(NaN), 0); 23423 23424 var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER; 23425 assert.strictEqual(func(Infinity), expected); 23426 assert.strictEqual(func(-Infinity), -expected); 23427 }); 23428 23429 QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) { 23430 assert.expect(1); 23431 23432 assert.strictEqual(1 / func(-0), -Infinity); 23433 }); 23434 }); 23435 23436 /*--------------------------------------------------------------------------*/ 23437 23438 QUnit.module('lodash.toLength'); 23439 23440 (function() { 23441 QUnit.test('should return a valid length', function(assert) { 23442 assert.expect(4); 23443 23444 assert.strictEqual(_.toLength(-1), 0); 23445 assert.strictEqual(_.toLength('1'), 1); 23446 assert.strictEqual(_.toLength(1.1), 1); 23447 assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH); 23448 }); 23449 23450 QUnit.test('should return `value` if a valid length', function(assert) { 23451 assert.expect(3); 23452 23453 assert.strictEqual(_.toLength(0), 0); 23454 assert.strictEqual(_.toLength(3), 3); 23455 assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH); 23456 }); 23457 23458 QUnit.test('should convert `-0` to `0`', function(assert) { 23459 assert.expect(1); 23460 23461 assert.strictEqual(1 / _.toLength(-0), Infinity); 23462 }); 23463 }()); 23464 23465 /*--------------------------------------------------------------------------*/ 23466 23467 QUnit.module('number coercion methods'); 23468 23469 lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) { 23470 var func = _[methodName]; 23471 23472 QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { 23473 assert.expect(2); 23474 23475 var values = [0, '0', -0, '-0'], 23476 expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]]; 23477 23478 lodashStable.times(2, function(index) { 23479 var others = lodashStable.map(values, index ? Object : identity); 23480 23481 var actual = lodashStable.map(others, function(value) { 23482 var result = func(value); 23483 return [result, 1 / result]; 23484 }); 23485 23486 assert.deepEqual(actual, expected); 23487 }); 23488 }); 23489 }); 23490 23491 lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) { 23492 var func = _[methodName], 23493 isToFinite = methodName == 'toFinite', 23494 isToLength = methodName == 'toLength', 23495 isToNumber = methodName == 'toNumber', 23496 isToSafeInteger = methodName == 'toSafeInteger'; 23497 23498 function negative(string) { 23499 return '-' + string; 23500 } 23501 23502 function pad(string) { 23503 return whitespace + string + whitespace; 23504 } 23505 23506 function positive(string) { 23507 return '+' + string; 23508 } 23509 23510 QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) { 23511 assert.expect(1); 23512 23513 var values = [0, 1, NaN]; 23514 23515 var expected = lodashStable.map(values, function(value) { 23516 return (!isToNumber && value !== value) ? 0 : value; 23517 }); 23518 23519 var actual = lodashStable.map(values, func); 23520 23521 assert.deepEqual(actual, expected); 23522 }); 23523 23524 QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) { 23525 assert.expect(1); 23526 23527 var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN]; 23528 23529 var expected = lodashStable.map(values, function(value) { 23530 if (!isToNumber) { 23531 if (!isToFinite && value == 1.2) { 23532 value = 1; 23533 } 23534 else if (value == Infinity) { 23535 value = MAX_INTEGER; 23536 } 23537 else if (value !== value) { 23538 value = 0; 23539 } 23540 if (isToLength || isToSafeInteger) { 23541 value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER); 23542 } 23543 } 23544 var neg = isToLength ? 0 : -value; 23545 return [value, value, neg, neg]; 23546 }); 23547 23548 var actual = lodashStable.map(values, function(value) { 23549 return [func(value), func(Object(value)), func(-value), func(Object(-value))]; 23550 }); 23551 23552 assert.deepEqual(actual, expected); 23553 }); 23554 23555 QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) { 23556 assert.expect(1); 23557 23558 var transforms = [identity, pad, positive, negative]; 23559 23560 var values = [ 23561 '10', '1.234567890', (MAX_SAFE_INTEGER + ''), 23562 '1e+308', '1e308', '1E+308', '1E308', 23563 '5e-324', '5E-324', 23564 'Infinity', 'NaN' 23565 ]; 23566 23567 var expected = lodashStable.map(values, function(value) { 23568 var n = +value; 23569 if (!isToNumber) { 23570 if (!isToFinite && n == 1.234567890) { 23571 n = 1; 23572 } 23573 else if (n == Infinity) { 23574 n = MAX_INTEGER; 23575 } 23576 else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) { 23577 n = 0; 23578 } 23579 if (isToLength || isToSafeInteger) { 23580 n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER); 23581 } 23582 } 23583 var neg = isToLength ? 0 : -n; 23584 return [n, n, n, n, n, n, neg, neg]; 23585 }); 23586 23587 var actual = lodashStable.map(values, function(value) { 23588 return lodashStable.flatMap(transforms, function(mod) { 23589 return [func(mod(value)), func(Object(mod(value)))]; 23590 }); 23591 }); 23592 23593 assert.deepEqual(actual, expected); 23594 }); 23595 23596 QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) { 23597 assert.expect(1); 23598 23599 var numbers = [42, 5349, 1715004], 23600 transforms = [identity, pad], 23601 values = ['0b101010', '0o12345', '0x1a2b3c']; 23602 23603 var expected = lodashStable.map(numbers, function(n) { 23604 return lodashStable.times(8, lodashStable.constant(n)); 23605 }); 23606 23607 var actual = lodashStable.map(values, function(value) { 23608 var upper = value.toUpperCase(); 23609 return lodashStable.flatMap(transforms, function(mod) { 23610 return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))]; 23611 }); 23612 }); 23613 23614 assert.deepEqual(actual, expected); 23615 }); 23616 23617 QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) { 23618 assert.expect(1); 23619 23620 var transforms = [identity, pad, positive, negative], 23621 values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x']; 23622 23623 var expected = lodashStable.map(values, function(n) { 23624 return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0)); 23625 }); 23626 23627 var actual = lodashStable.map(values, function(value) { 23628 return lodashStable.flatMap(transforms, function(mod) { 23629 return [func(mod(value)), func(Object(mod(value)))]; 23630 }); 23631 }); 23632 23633 assert.deepEqual(actual, expected); 23634 }); 23635 23636 QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) { 23637 assert.expect(1); 23638 23639 if (Symbol) { 23640 var object1 = Object(symbol), 23641 object2 = Object(symbol), 23642 values = [symbol, object1, object2], 23643 expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0)); 23644 23645 object2.valueOf = undefined; 23646 var actual = lodashStable.map(values, func); 23647 23648 assert.deepEqual(actual, expected); 23649 } 23650 else { 23651 skipAssert(assert); 23652 } 23653 }); 23654 23655 QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) { 23656 assert.expect(1); 23657 23658 var values = falsey.concat(whitespace); 23659 23660 var expected = lodashStable.map(values, function(value) { 23661 return (isToNumber && value !== whitespace) ? Number(value) : 0; 23662 }); 23663 23664 var actual = lodashStable.map(values, function(value, index) { 23665 return index ? func(value) : func(); 23666 }); 23667 23668 assert.deepEqual(actual, expected); 23669 }); 23670 23671 QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) { 23672 assert.expect(1); 23673 23674 var values = [ 23675 {}, 23676 [], 23677 [1], 23678 [1, 2], 23679 { 'valueOf': '1.1' }, 23680 { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') }, 23681 { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' }, 23682 { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') }, 23683 { 'valueOf': lodashStable.constant('-0x1a2b3c') }, 23684 { 'toString': lodashStable.constant('-0x1a2b3c') }, 23685 { 'valueOf': lodashStable.constant('0o12345') }, 23686 { 'toString': lodashStable.constant('0o12345') }, 23687 { 'valueOf': lodashStable.constant('0b101010') }, 23688 { 'toString': lodashStable.constant('0b101010') } 23689 ]; 23690 23691 var expected = [ 23692 NaN, 0, 1, NaN, 23693 NaN, 2.2, 1.1, 1.1, 23694 NaN, NaN, 23695 5349, 5349, 23696 42, 42 23697 ]; 23698 23699 if (isToFinite) { 23700 expected = [ 23701 0, 0, 1, 0, 23702 0, 2.2, 1.1, 1.1, 23703 0, 0, 23704 5349, 5349, 23705 42, 42 23706 ]; 23707 } 23708 else if (!isToNumber) { 23709 expected = [ 23710 0, 0, 1, 0, 23711 0, 2, 1, 1, 23712 0, 0, 23713 5349, 5349, 23714 42, 42 23715 ]; 23716 } 23717 var actual = lodashStable.map(values, func); 23718 23719 assert.deepEqual(actual, expected); 23720 }); 23721 }); 23722 23723 /*--------------------------------------------------------------------------*/ 23724 23725 QUnit.module('lodash.toPairs'); 23726 23727 (function() { 23728 QUnit.test('should be aliased', function(assert) { 23729 assert.expect(1); 23730 23731 assert.strictEqual(_.entries, _.toPairs); 23732 }); 23733 }()); 23734 23735 /*--------------------------------------------------------------------------*/ 23736 23737 QUnit.module('lodash.toPairsIn'); 23738 23739 (function() { 23740 QUnit.test('should be aliased', function(assert) { 23741 assert.expect(1); 23742 23743 assert.strictEqual(_.entriesIn, _.toPairsIn); 23744 }); 23745 }()); 23746 23747 /*--------------------------------------------------------------------------*/ 23748 23749 QUnit.module('toPairs methods'); 23750 23751 lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) { 23752 var func = _[methodName], 23753 isToPairs = methodName == 'toPairs'; 23754 23755 QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) { 23756 assert.expect(1); 23757 23758 var object = { 'a': 1, 'b': 2 }, 23759 actual = lodashStable.sortBy(func(object), 0); 23760 23761 assert.deepEqual(actual, [['a', 1], ['b', 2]]); 23762 }); 23763 23764 QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) { 23765 assert.expect(1); 23766 23767 function Foo() { 23768 this.a = 1; 23769 } 23770 Foo.prototype.b = 2; 23771 23772 var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]], 23773 actual = lodashStable.sortBy(func(new Foo), 0); 23774 23775 assert.deepEqual(actual, expected); 23776 }); 23777 23778 QUnit.test('`_.' + methodName + '` should convert objects with a `length` property', function(assert) { 23779 assert.expect(1); 23780 23781 var object = { '0': 'a', '1': 'b', 'length': 2 }, 23782 actual = lodashStable.sortBy(func(object), 0); 23783 23784 assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]); 23785 }); 23786 23787 QUnit.test('`_.' + methodName + '` should convert maps', function(assert) { 23788 assert.expect(1); 23789 23790 if (Map) { 23791 var map = new Map; 23792 map.set('a', 1); 23793 map.set('b', 2); 23794 assert.deepEqual(func(map), [['a', 1], ['b', 2]]); 23795 } 23796 else { 23797 skipAssert(assert); 23798 } 23799 }); 23800 23801 QUnit.test('`_.' + methodName + '` should convert sets', function(assert) { 23802 assert.expect(1); 23803 23804 if (Set) { 23805 var set = new Set; 23806 set.add(1); 23807 set.add(2); 23808 assert.deepEqual(func(set), [[1, 1], [2, 2]]); 23809 } 23810 else { 23811 skipAssert(assert); 23812 } 23813 }); 23814 23815 QUnit.test('`_.' + methodName + '` should convert strings', function(assert) { 23816 assert.expect(2); 23817 23818 lodashStable.each(['xo', Object('xo')], function(string) { 23819 var actual = lodashStable.sortBy(func(string), 0); 23820 assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]); 23821 }); 23822 }); 23823 }); 23824 23825 /*--------------------------------------------------------------------------*/ 23826 23827 QUnit.module('lodash.toPath'); 23828 23829 (function() { 23830 QUnit.test('should convert a string to a path', function(assert) { 23831 assert.expect(2); 23832 23833 assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']); 23834 assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']); 23835 }); 23836 23837 QUnit.test('should coerce array elements to strings', function(assert) { 23838 assert.expect(4); 23839 23840 var array = ['a', 'b', 'c']; 23841 23842 lodashStable.each([array, lodashStable.map(array, Object)], function(value) { 23843 var actual = _.toPath(value); 23844 assert.deepEqual(actual, array); 23845 assert.notStrictEqual(actual, array); 23846 }); 23847 }); 23848 23849 QUnit.test('should return new path array', function(assert) { 23850 assert.expect(1); 23851 23852 assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c')); 23853 }); 23854 23855 QUnit.test('should not coerce symbols to strings', function(assert) { 23856 assert.expect(4); 23857 23858 if (Symbol) { 23859 var object = Object(symbol); 23860 lodashStable.each([symbol, object, [symbol], [object]], function(value) { 23861 var actual = _.toPath(value); 23862 assert.ok(lodashStable.isSymbol(actual[0])); 23863 }); 23864 } 23865 else { 23866 skipAssert(assert, 4); 23867 } 23868 }); 23869 23870 QUnit.test('should handle complex paths', function(assert) { 23871 assert.expect(1); 23872 23873 var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g'); 23874 assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']); 23875 }); 23876 23877 QUnit.test('should handle consecutive empty brackets and dots', function(assert) { 23878 assert.expect(12); 23879 23880 var expected = ['', 'a']; 23881 assert.deepEqual(_.toPath('.a'), expected); 23882 assert.deepEqual(_.toPath('[].a'), expected); 23883 23884 expected = ['', '', 'a']; 23885 assert.deepEqual(_.toPath('..a'), expected); 23886 assert.deepEqual(_.toPath('[][].a'), expected); 23887 23888 expected = ['a', '', 'b']; 23889 assert.deepEqual(_.toPath('a..b'), expected); 23890 assert.deepEqual(_.toPath('a[].b'), expected); 23891 23892 expected = ['a', '', '', 'b']; 23893 assert.deepEqual(_.toPath('a...b'), expected); 23894 assert.deepEqual(_.toPath('a[][].b'), expected); 23895 23896 expected = ['a', '']; 23897 assert.deepEqual(_.toPath('a.'), expected); 23898 assert.deepEqual(_.toPath('a[]'), expected); 23899 23900 expected = ['a', '', '']; 23901 assert.deepEqual(_.toPath('a..'), expected); 23902 assert.deepEqual(_.toPath('a[][]'), expected); 23903 }); 23904 }()); 23905 23906 /*--------------------------------------------------------------------------*/ 23907 23908 QUnit.module('lodash.toPlainObject'); 23909 23910 (function() { 23911 QUnit.test('should flatten inherited string keyed properties', function(assert) { 23912 assert.expect(1); 23913 23914 function Foo() { 23915 this.b = 2; 23916 } 23917 Foo.prototype.c = 3; 23918 23919 var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo)); 23920 assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); 23921 }); 23922 23923 QUnit.test('should convert `arguments` objects to plain objects', function(assert) { 23924 assert.expect(1); 23925 23926 var actual = _.toPlainObject(args), 23927 expected = { '0': 1, '1': 2, '2': 3 }; 23928 23929 assert.deepEqual(actual, expected); 23930 }); 23931 23932 QUnit.test('should convert arrays to plain objects', function(assert) { 23933 assert.expect(1); 23934 23935 var actual = _.toPlainObject(['a', 'b', 'c']), 23936 expected = { '0': 'a', '1': 'b', '2': 'c' }; 23937 23938 assert.deepEqual(actual, expected); 23939 }); 23940 }()); 23941 23942 /*--------------------------------------------------------------------------*/ 23943 23944 QUnit.module('lodash.toString'); 23945 23946 (function() { 23947 QUnit.test('should treat nullish values as empty strings', function(assert) { 23948 assert.expect(1); 23949 23950 var values = [, null, undefined], 23951 expected = lodashStable.map(values, stubString); 23952 23953 var actual = lodashStable.map(values, function(value, index) { 23954 return index ? _.toString(value) : _.toString(); 23955 }); 23956 23957 assert.deepEqual(actual, expected); 23958 }); 23959 23960 QUnit.test('should preserve the sign of `0`', function(assert) { 23961 assert.expect(1); 23962 23963 var values = [-0, Object(-0), 0, Object(0)], 23964 expected = ['-0', '-0', '0', '0'], 23965 actual = lodashStable.map(values, _.toString); 23966 23967 assert.deepEqual(actual, expected); 23968 }); 23969 23970 QUnit.test('should preserve the sign of `0` in an array', function(assert) { 23971 assert.expect(1); 23972 23973 var values = [-0, Object(-0), 0, Object(0)]; 23974 assert.deepEqual(_.toString(values), '-0,-0,0,0'); 23975 }); 23976 23977 QUnit.test('should not error on symbols', function(assert) { 23978 assert.expect(1); 23979 23980 if (Symbol) { 23981 try { 23982 assert.strictEqual(_.toString(symbol), 'Symbol(a)'); 23983 } catch (e) { 23984 assert.ok(false, e.message); 23985 } 23986 } 23987 else { 23988 skipAssert(assert); 23989 } 23990 }); 23991 23992 QUnit.test('should not error on an array of symbols', function(assert) { 23993 assert.expect(1); 23994 23995 if (Symbol) { 23996 try { 23997 assert.strictEqual(_.toString([symbol]), 'Symbol(a)'); 23998 } catch (e) { 23999 assert.ok(false, e.message); 24000 } 24001 } 24002 else { 24003 skipAssert(assert); 24004 } 24005 }); 24006 24007 QUnit.test('should return the `toString` result of the wrapped value', function(assert) { 24008 assert.expect(1); 24009 24010 if (!isNpm) { 24011 var wrapped = _([1, 2, 3]); 24012 assert.strictEqual(wrapped.toString(), '1,2,3'); 24013 } 24014 else { 24015 skipAssert(assert); 24016 } 24017 }); 24018 }()); 24019 24020 /*--------------------------------------------------------------------------*/ 24021 24022 QUnit.module('lodash.transform'); 24023 24024 (function() { 24025 function Foo() { 24026 this.a = 1; 24027 this.b = 2; 24028 this.c = 3; 24029 } 24030 24031 QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) { 24032 assert.expect(4); 24033 24034 var accumulators = [, null, undefined], 24035 object = new Foo, 24036 expected = lodashStable.map(accumulators, stubTrue); 24037 24038 var iteratee = function(result, value, key) { 24039 result[key] = square(value); 24040 }; 24041 24042 var mapper = function(accumulator, index) { 24043 return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee); 24044 }; 24045 24046 var results = lodashStable.map(accumulators, mapper); 24047 24048 var actual = lodashStable.map(results, function(result) { 24049 return result instanceof Foo; 24050 }); 24051 24052 assert.deepEqual(actual, expected); 24053 24054 expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 })); 24055 actual = lodashStable.map(results, lodashStable.toPlainObject); 24056 24057 assert.deepEqual(actual, expected); 24058 24059 object = { 'a': 1, 'b': 2, 'c': 3 }; 24060 actual = lodashStable.map(accumulators, mapper); 24061 24062 assert.deepEqual(actual, expected); 24063 24064 object = [1, 2, 3]; 24065 expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9])); 24066 actual = lodashStable.map(accumulators, mapper); 24067 24068 assert.deepEqual(actual, expected); 24069 }); 24070 24071 QUnit.test('should create regular arrays from typed arrays', function(assert) { 24072 assert.expect(1); 24073 24074 var expected = lodashStable.map(typedArrays, stubTrue); 24075 24076 var actual = lodashStable.map(typedArrays, function(type) { 24077 var Ctor = root[type], 24078 array = Ctor ? new Ctor(new ArrayBuffer(24)) : []; 24079 24080 return lodashStable.isArray(_.transform(array, noop)); 24081 }); 24082 24083 assert.deepEqual(actual, expected); 24084 }); 24085 24086 QUnit.test('should support an `accumulator` value', function(assert) { 24087 assert.expect(6); 24088 24089 var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }], 24090 expected = lodashStable.map(values, lodashStable.constant([1, 4, 9])); 24091 24092 var actual = lodashStable.map(values, function(value) { 24093 return _.transform(value, function(result, value) { 24094 result.push(square(value)); 24095 }, []); 24096 }); 24097 24098 assert.deepEqual(actual, expected); 24099 24100 var object = { 'a': 1, 'b': 4, 'c': 9 }, 24101 expected = [object, { '0': 1, '1': 4, '2': 9 }, object]; 24102 24103 actual = lodashStable.map(values, function(value) { 24104 return _.transform(value, function(result, value, key) { 24105 result[key] = square(value); 24106 }, {}); 24107 }); 24108 24109 assert.deepEqual(actual, expected); 24110 24111 lodashStable.each([[], {}], function(accumulator) { 24112 var actual = lodashStable.map(values, function(value) { 24113 return _.transform(value, noop, accumulator); 24114 }); 24115 24116 assert.ok(lodashStable.every(actual, function(result) { 24117 return result === accumulator; 24118 })); 24119 24120 assert.strictEqual(_.transform(null, null, accumulator), accumulator); 24121 }); 24122 }); 24123 24124 QUnit.test('should treat sparse arrays as dense', function(assert) { 24125 assert.expect(1); 24126 24127 var actual = _.transform(Array(1), function(result, value, index) { 24128 result[index] = String(value); 24129 }); 24130 24131 assert.deepEqual(actual, ['undefined']); 24132 }); 24133 24134 QUnit.test('should work without an `iteratee`', function(assert) { 24135 assert.expect(1); 24136 24137 assert.ok(_.transform(new Foo) instanceof Foo); 24138 }); 24139 24140 QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) { 24141 assert.expect(2); 24142 24143 var Ctors = [Boolean, Boolean, Number, Number, Number, String, String], 24144 values = [false, true, 0, 1, NaN, '', 'a'], 24145 expected = lodashStable.map(values, stubObject); 24146 24147 var results = lodashStable.map(values, function(value) { 24148 return _.transform(value); 24149 }); 24150 24151 assert.deepEqual(results, expected); 24152 24153 expected = lodashStable.map(values, stubFalse); 24154 24155 var actual = lodashStable.map(results, function(value, index) { 24156 return value instanceof Ctors[index]; 24157 }); 24158 24159 assert.deepEqual(actual, expected); 24160 }); 24161 24162 QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) { 24163 assert.expect(1); 24164 24165 Foo.prototype.constructor = null; 24166 assert.notOk(_.transform(new Foo) instanceof Foo); 24167 Foo.prototype.constructor = Foo; 24168 }); 24169 24170 QUnit.test('should create an empty object when given a falsey `object`', function(assert) { 24171 assert.expect(1); 24172 24173 var expected = lodashStable.map(falsey, stubObject); 24174 24175 var actual = lodashStable.map(falsey, function(object, index) { 24176 return index ? _.transform(object) : _.transform(); 24177 }); 24178 24179 assert.deepEqual(actual, expected); 24180 }); 24181 24182 lodashStable.each({ 24183 'array': [1, 2, 3], 24184 'object': { 'a': 1, 'b': 2, 'c': 3 } 24185 }, 24186 function(object, key) { 24187 QUnit.test('should provide correct `iteratee` arguments when transforming an ' + key, function(assert) { 24188 assert.expect(2); 24189 24190 var args; 24191 24192 _.transform(object, function() { 24193 args || (args = slice.call(arguments)); 24194 }); 24195 24196 var first = args[0]; 24197 if (key == 'array') { 24198 assert.ok(first !== object && lodashStable.isArray(first)); 24199 assert.deepEqual(args, [first, 1, 0, object]); 24200 } else { 24201 assert.ok(first !== object && lodashStable.isPlainObject(first)); 24202 assert.deepEqual(args, [first, 1, 'a', object]); 24203 } 24204 }); 24205 }); 24206 24207 QUnit.test('should create an object from the same realm as `object`', function(assert) { 24208 assert.expect(1); 24209 24210 var objects = lodashStable.filter(realm, function(value) { 24211 return lodashStable.isObject(value) && !lodashStable.isElement(value); 24212 }); 24213 24214 var expected = lodashStable.map(objects, stubTrue); 24215 24216 var actual = lodashStable.map(objects, function(object) { 24217 var Ctor = object.constructor, 24218 result = _.transform(object); 24219 24220 if (result === object) { 24221 return false; 24222 } 24223 if (lodashStable.isTypedArray(object)) { 24224 return result instanceof Array; 24225 } 24226 return result instanceof Ctor || !(new Ctor instanceof Ctor); 24227 }); 24228 24229 assert.deepEqual(actual, expected); 24230 }); 24231 }()); 24232 24233 /*--------------------------------------------------------------------------*/ 24234 24235 QUnit.module('trim methods'); 24236 24237 lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) { 24238 var func = _[methodName], 24239 parts = []; 24240 24241 if (index != 2) { 24242 parts.push('leading'); 24243 } 24244 if (index != 1) { 24245 parts.push('trailing'); 24246 } 24247 parts = parts.join(' and '); 24248 24249 QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) { 24250 assert.expect(1); 24251 24252 var string = whitespace + 'a b c' + whitespace, 24253 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''); 24254 24255 assert.strictEqual(func(string), expected); 24256 }); 24257 24258 QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) { 24259 assert.expect(1); 24260 24261 var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) }, 24262 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''); 24263 24264 assert.strictEqual(func(object), expected); 24265 }); 24266 24267 QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) { 24268 assert.expect(1); 24269 24270 var string = '-_-a-b-c-_-', 24271 expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : ''); 24272 24273 assert.strictEqual(func(string, '_-'), expected); 24274 }); 24275 24276 QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) { 24277 assert.expect(1); 24278 24279 var object = { 'toString': lodashStable.constant('_-') }, 24280 string = '-_-a-b-c-_-', 24281 expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : ''); 24282 24283 assert.strictEqual(func(string, object), expected); 24284 }); 24285 24286 QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) { 24287 assert.expect(6); 24288 24289 lodashStable.each([null, '_-'], function(chars) { 24290 assert.strictEqual(func(null, chars), ''); 24291 assert.strictEqual(func(undefined, chars), ''); 24292 assert.strictEqual(func('', chars), ''); 24293 }); 24294 }); 24295 24296 QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) { 24297 assert.expect(2); 24298 24299 var string = whitespace + 'a b c' + whitespace, 24300 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''); 24301 24302 assert.strictEqual(func(string, undefined), expected); 24303 assert.strictEqual(func(string, ''), string); 24304 }); 24305 24306 QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) { 24307 assert.expect(1); 24308 24309 var string = Object(whitespace + 'a b c' + whitespace), 24310 trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''), 24311 actual = lodashStable.map([string, string, string], func); 24312 24313 assert.deepEqual(actual, [trimmed, trimmed, trimmed]); 24314 }); 24315 24316 QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 24317 assert.expect(1); 24318 24319 if (!isNpm) { 24320 var string = whitespace + 'a b c' + whitespace, 24321 expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''); 24322 24323 assert.strictEqual(_(string)[methodName](), expected); 24324 } 24325 else { 24326 skipAssert(assert); 24327 } 24328 }); 24329 24330 QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 24331 assert.expect(1); 24332 24333 if (!isNpm) { 24334 var string = whitespace + 'a b c' + whitespace; 24335 assert.ok(_(string).chain()[methodName]() instanceof _); 24336 } 24337 else { 24338 skipAssert(assert); 24339 } 24340 }); 24341 }); 24342 24343 /*--------------------------------------------------------------------------*/ 24344 24345 QUnit.module('uncommon symbols'); 24346 24347 (function() { 24348 var flag = '\ud83c\uddfa\ud83c\uddf8', 24349 heart = '\u2764' + emojiVar, 24350 hearts = '\ud83d\udc95', 24351 comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68', 24352 hashKeycap = '#' + emojiVar + '\u20e3', 24353 leafs = '\ud83c\udf42', 24354 mic = '\ud83c\udf99', 24355 noMic = mic + '\u20e0', 24356 raisedHand = '\u270B' + emojiVar, 24357 rocket = '\ud83d\ude80', 24358 thumbsUp = '\ud83d\udc4d'; 24359 24360 QUnit.test('should account for astral symbols', function(assert) { 24361 assert.expect(34); 24362 24363 var allHearts = _.repeat(hearts, 10), 24364 chars = hearts + comboGlyph, 24365 string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket, 24366 trimChars = comboGlyph + hearts, 24367 trimString = trimChars + string + trimChars; 24368 24369 assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs); 24370 assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket); 24371 assert.strictEqual(_.capitalize(rocket), rocket); 24372 24373 assert.strictEqual(_.pad(string, 16), ' ' + string + ' '); 24374 assert.strictEqual(_.padStart(string, 16), ' ' + string); 24375 assert.strictEqual(_.padEnd(string, 16), string + ' '); 24376 24377 assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars); 24378 assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string); 24379 assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts); 24380 24381 assert.strictEqual(_.size(string), 13); 24382 assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]); 24383 assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']); 24384 assert.deepEqual(_.split(string, undefined), [string]); 24385 assert.deepEqual(_.split(string, undefined, -1), [string]); 24386 assert.deepEqual(_.split(string, undefined, 0), []); 24387 24388 var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket]; 24389 24390 assert.deepEqual(_.split(string, ''), expected); 24391 assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6)); 24392 assert.deepEqual(_.toArray(string), expected); 24393 24394 assert.strictEqual(_.trim(trimString, chars), string); 24395 assert.strictEqual(_.trimStart(trimString, chars), string + trimChars); 24396 assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string); 24397 24398 assert.strictEqual(_.truncate(string, { 'length': 13 }), string); 24399 assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...'); 24400 24401 assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]); 24402 assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]); 24403 assert.deepEqual(_.toArray(noMic), [noMic]); 24404 24405 lodashStable.times(2, function(index) { 24406 var separator = index ? RegExp(hearts) : hearts, 24407 options = { 'length': 4, 'separator': separator }, 24408 actual = _.truncate(string, options); 24409 24410 assert.strictEqual(actual, 'A...'); 24411 assert.strictEqual(actual.length, 4); 24412 24413 actual = _.truncate(allHearts, options); 24414 assert.strictEqual(actual, hearts + '...'); 24415 assert.strictEqual(actual.length, 5); 24416 }); 24417 }); 24418 24419 QUnit.test('should account for combining diacritical marks', function(assert) { 24420 assert.expect(1); 24421 24422 var values = lodashStable.map(comboMarks, function(mark) { 24423 return 'o' + mark; 24424 }); 24425 24426 var expected = lodashStable.map(values, function(value) { 24427 return [1, [value], [value]]; 24428 }); 24429 24430 var actual = lodashStable.map(values, function(value) { 24431 return [_.size(value), _.toArray(value), _.words(value)]; 24432 }); 24433 24434 assert.deepEqual(actual, expected); 24435 }); 24436 24437 QUnit.test('should account for fitzpatrick modifiers', function(assert) { 24438 assert.expect(1); 24439 24440 var values = lodashStable.map(fitzModifiers, function(modifier) { 24441 return thumbsUp + modifier; 24442 }); 24443 24444 var expected = lodashStable.map(values, function(value) { 24445 return [1, [value], [value]]; 24446 }); 24447 24448 var actual = lodashStable.map(values, function(value) { 24449 return [_.size(value), _.toArray(value), _.words(value)]; 24450 }); 24451 24452 assert.deepEqual(actual, expected); 24453 }); 24454 24455 QUnit.test('should account for regional symbols', function(assert) { 24456 assert.expect(6); 24457 24458 var pair = flag.match(/\ud83c[\udde6-\uddff]/g), 24459 regionals = pair.join(' '); 24460 24461 assert.strictEqual(_.size(flag), 1); 24462 assert.strictEqual(_.size(regionals), 3); 24463 24464 assert.deepEqual(_.toArray(flag), [flag]); 24465 assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]); 24466 24467 assert.deepEqual(_.words(flag), [flag]); 24468 assert.deepEqual(_.words(regionals), [pair[0], pair[1]]); 24469 }); 24470 24471 QUnit.test('should account for variation selectors', function(assert) { 24472 assert.expect(3); 24473 24474 assert.strictEqual(_.size(heart), 1); 24475 assert.deepEqual(_.toArray(heart), [heart]); 24476 assert.deepEqual(_.words(heart), [heart]); 24477 }); 24478 24479 QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) { 24480 assert.expect(1); 24481 24482 var values = lodashStable.map(fitzModifiers, function(modifier) { 24483 return raisedHand + modifier; 24484 }); 24485 24486 var expected = lodashStable.map(values, function(value) { 24487 return [1, [value], [value]]; 24488 }); 24489 24490 var actual = lodashStable.map(values, function(value) { 24491 return [_.size(value), _.toArray(value), _.words(value)]; 24492 }); 24493 24494 assert.deepEqual(actual, expected); 24495 }); 24496 24497 QUnit.test('should match lone surrogates', function(assert) { 24498 assert.expect(3); 24499 24500 var pair = hearts.split(''), 24501 surrogates = pair[0] + ' ' + pair[1]; 24502 24503 assert.strictEqual(_.size(surrogates), 3); 24504 assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]); 24505 assert.deepEqual(_.words(surrogates), []); 24506 }); 24507 24508 QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) { 24509 assert.expect(1); 24510 24511 var string = fitzModifiers[0] + fitzModifiers[0]; 24512 assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]); 24513 }); 24514 }()); 24515 24516 /*--------------------------------------------------------------------------*/ 24517 24518 QUnit.module('lodash.unary'); 24519 24520 (function() { 24521 function fn() { 24522 return slice.call(arguments); 24523 } 24524 24525 QUnit.test('should cap the number of arguments provided to `func`', function(assert) { 24526 assert.expect(1); 24527 24528 var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt)); 24529 assert.deepEqual(actual, [6, 8, 10]); 24530 }); 24531 24532 QUnit.test('should not force a minimum argument count', function(assert) { 24533 assert.expect(1); 24534 24535 var capped = _.unary(fn); 24536 assert.deepEqual(capped(), []); 24537 }); 24538 24539 QUnit.test('should use `this` binding of function', function(assert) { 24540 assert.expect(1); 24541 24542 var capped = _.unary(function(a, b) { return this; }), 24543 object = { 'capped': capped }; 24544 24545 assert.strictEqual(object.capped(), object); 24546 }); 24547 }()); 24548 24549 /*--------------------------------------------------------------------------*/ 24550 24551 QUnit.module('lodash.unescape'); 24552 24553 (function() { 24554 var escaped = '&<>"'/', 24555 unescaped = '&<>"\'/'; 24556 24557 escaped += escaped; 24558 unescaped += unescaped; 24559 24560 QUnit.test('should unescape entities in order', function(assert) { 24561 assert.expect(1); 24562 24563 assert.strictEqual(_.unescape('&lt;'), '<'); 24564 }); 24565 24566 QUnit.test('should unescape the proper entities', function(assert) { 24567 assert.expect(1); 24568 24569 assert.strictEqual(_.unescape(escaped), unescaped); 24570 }); 24571 24572 QUnit.test('should handle strings with nothing to unescape', function(assert) { 24573 assert.expect(1); 24574 24575 assert.strictEqual(_.unescape('abc'), 'abc'); 24576 }); 24577 24578 QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) { 24579 assert.expect(1); 24580 24581 assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped); 24582 }); 24583 24584 lodashStable.each(['`', '/'], function(entity) { 24585 QUnit.test('should not unescape the "' + entity + '" entity', function(assert) { 24586 assert.expect(1); 24587 24588 assert.strictEqual(_.unescape(entity), entity); 24589 }); 24590 }); 24591 }()); 24592 24593 /*--------------------------------------------------------------------------*/ 24594 24595 QUnit.module('union methods'); 24596 24597 lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) { 24598 var func = _[methodName]; 24599 24600 QUnit.test('`_.' + methodName + '` should return the union of two arrays', function(assert) { 24601 assert.expect(1); 24602 24603 var actual = func([2], [1, 2]); 24604 assert.deepEqual(actual, [2, 1]); 24605 }); 24606 24607 QUnit.test('`_.' + methodName + '` should return the union of multiple arrays', function(assert) { 24608 assert.expect(1); 24609 24610 var actual = func([2], [1, 2], [2, 3]); 24611 assert.deepEqual(actual, [2, 1, 3]); 24612 }); 24613 24614 QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) { 24615 assert.expect(1); 24616 24617 var actual = func([1, 3, 2], [1, [5]], [2, [4]]); 24618 assert.deepEqual(actual, [1, 3, 2, [5], [4]]); 24619 }); 24620 24621 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) { 24622 assert.expect(3); 24623 24624 var array = [0]; 24625 assert.deepEqual(func(array, 3, { '0': 1 }, null), array); 24626 assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]); 24627 assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]); 24628 }); 24629 }); 24630 24631 /*--------------------------------------------------------------------------*/ 24632 24633 QUnit.module('lodash.unionBy'); 24634 24635 (function() { 24636 QUnit.test('should accept an `iteratee`', function(assert) { 24637 assert.expect(2); 24638 24639 var actual = _.unionBy([2.1], [1.2, 2.3], Math.floor); 24640 assert.deepEqual(actual, [2.1, 1.2]); 24641 24642 actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); 24643 assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]); 24644 }); 24645 24646 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 24647 assert.expect(1); 24648 24649 var args; 24650 24651 _.unionBy([2.1], [1.2, 2.3], function() { 24652 args || (args = slice.call(arguments)); 24653 }); 24654 24655 assert.deepEqual(args, [2.1]); 24656 }); 24657 24658 QUnit.test('should output values from the first possible array', function(assert) { 24659 assert.expect(1); 24660 24661 var actual = _.unionBy([{ 'x': 1, 'y': 1 }], [{ 'x': 1, 'y': 2 }], 'x'); 24662 assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]); 24663 }); 24664 }()); 24665 24666 /*--------------------------------------------------------------------------*/ 24667 24668 QUnit.module('lodash.unionWith'); 24669 24670 (function() { 24671 QUnit.test('should work with a `comparator`', function(assert) { 24672 assert.expect(1); 24673 24674 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }], 24675 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }], 24676 actual = _.unionWith(objects, others, lodashStable.isEqual); 24677 24678 assert.deepEqual(actual, [objects[0], objects[1], others[0]]); 24679 }); 24680 24681 QUnit.test('should output values from the first possible array', function(assert) { 24682 assert.expect(1); 24683 24684 var objects = [{ 'x': 1, 'y': 1 }], 24685 others = [{ 'x': 1, 'y': 2 }]; 24686 24687 var actual = _.unionWith(objects, others, function(a, b) { 24688 return a.x == b.x; 24689 }); 24690 24691 assert.deepEqual(actual, [{ 'x': 1, 'y': 1 }]); 24692 }); 24693 }()); 24694 24695 /*--------------------------------------------------------------------------*/ 24696 24697 QUnit.module('uniq methods'); 24698 24699 lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) { 24700 var func = _[methodName], 24701 isSorted = /^sorted/.test(methodName), 24702 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; 24703 24704 if (isSorted) { 24705 objects = _.sortBy(objects, 'a'); 24706 } 24707 else { 24708 QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) { 24709 assert.expect(1); 24710 24711 var array = [2, 1, 2]; 24712 assert.deepEqual(func(array), [2, 1]); 24713 }); 24714 } 24715 QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) { 24716 assert.expect(1); 24717 24718 var array = [1, 2, 2]; 24719 assert.deepEqual(func(array), [1, 2]); 24720 }); 24721 24722 QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) { 24723 assert.expect(1); 24724 24725 assert.deepEqual(func(objects), objects); 24726 }); 24727 24728 QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) { 24729 assert.expect(1); 24730 24731 var actual = lodashStable.map(func([-0, 0]), lodashStable.toString); 24732 assert.deepEqual(actual, ['0']); 24733 }); 24734 24735 QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) { 24736 assert.expect(1); 24737 24738 assert.deepEqual(func([NaN, NaN]), [NaN]); 24739 }); 24740 24741 QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) { 24742 assert.expect(1); 24743 24744 var largeArray = [], 24745 expected = [0, {}, 'a'], 24746 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length); 24747 24748 lodashStable.each(expected, function(value) { 24749 lodashStable.times(count, function() { 24750 largeArray.push(value); 24751 }); 24752 }); 24753 24754 assert.deepEqual(func(largeArray), expected); 24755 }); 24756 24757 QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) { 24758 assert.expect(1); 24759 24760 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 24761 return isEven(index) ? -0 : 0; 24762 }); 24763 24764 var actual = lodashStable.map(func(largeArray), lodashStable.toString); 24765 assert.deepEqual(actual, ['0']); 24766 }); 24767 24768 QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) { 24769 assert.expect(1); 24770 24771 var largeArray = [], 24772 expected = [null, undefined, false, true, NaN], 24773 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length); 24774 24775 lodashStable.each(expected, function(value) { 24776 lodashStable.times(count, function() { 24777 largeArray.push(value); 24778 }); 24779 }); 24780 24781 assert.deepEqual(func(largeArray), expected); 24782 }); 24783 24784 QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) { 24785 assert.expect(1); 24786 24787 if (Symbol) { 24788 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol); 24789 assert.deepEqual(func(largeArray), largeArray); 24790 } 24791 else { 24792 skipAssert(assert); 24793 } 24794 }); 24795 24796 QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) { 24797 assert.expect(1); 24798 24799 // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols. 24800 if (Symbol) { 24801 var expected = [ 24802 Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator, 24803 Symbol.match, Symbol.replace, Symbol.search, Symbol.species, 24804 Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables 24805 ]; 24806 24807 var largeArray = [], 24808 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length); 24809 24810 expected = lodashStable.map(expected, function(symbol) { 24811 return symbol || {}; 24812 }); 24813 24814 lodashStable.each(expected, function(value) { 24815 lodashStable.times(count, function() { 24816 largeArray.push(value); 24817 }); 24818 }); 24819 24820 assert.deepEqual(func(largeArray), expected); 24821 } 24822 else { 24823 skipAssert(assert); 24824 } 24825 }); 24826 24827 QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) { 24828 assert.expect(1); 24829 24830 var largeArray = [], 24831 expected = ['2', 2, Object('2'), Object(2)], 24832 count = Math.ceil(LARGE_ARRAY_SIZE / expected.length); 24833 24834 lodashStable.each(expected, function(value) { 24835 lodashStable.times(count, function() { 24836 largeArray.push(value); 24837 }); 24838 }); 24839 24840 assert.deepEqual(func(largeArray), expected); 24841 }); 24842 }); 24843 24844 /*--------------------------------------------------------------------------*/ 24845 24846 QUnit.module('lodash.uniq'); 24847 24848 (function() { 24849 QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) { 24850 assert.expect(1); 24851 24852 var array = [[2, 1, 2], [1, 2, 1]], 24853 actual = lodashStable.map(array, lodashStable.uniq); 24854 24855 assert.deepEqual(actual, [[2, 1], [1, 2]]); 24856 }); 24857 }()); 24858 24859 /*--------------------------------------------------------------------------*/ 24860 24861 QUnit.module('uniqBy methods'); 24862 24863 lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) { 24864 var func = _[methodName], 24865 isSorted = methodName == 'sortedUniqBy', 24866 objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; 24867 24868 if (isSorted) { 24869 objects = _.sortBy(objects, 'a'); 24870 } 24871 QUnit.test('`_.' + methodName + '` should work with an `iteratee`', function(assert) { 24872 assert.expect(1); 24873 24874 var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3); 24875 24876 var actual = func(objects, function(object) { 24877 return object.a; 24878 }); 24879 24880 assert.deepEqual(actual, expected); 24881 }); 24882 24883 QUnit.test('should work with large arrays', function(assert) { 24884 assert.expect(2); 24885 24886 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() { 24887 return [1, 2]; 24888 }); 24889 24890 var actual = func(largeArray, String); 24891 assert.strictEqual(actual[0], largeArray[0]); 24892 assert.deepEqual(actual, [[1, 2]]); 24893 }); 24894 24895 QUnit.test('`_.' + methodName + '` should provide correct `iteratee` arguments', function(assert) { 24896 assert.expect(1); 24897 24898 var args; 24899 24900 func(objects, function() { 24901 args || (args = slice.call(arguments)); 24902 }); 24903 24904 assert.deepEqual(args, [objects[0]]); 24905 }); 24906 24907 QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) { 24908 assert.expect(2); 24909 24910 var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3), 24911 actual = func(objects, 'a'); 24912 24913 assert.deepEqual(actual, expected); 24914 24915 var arrays = [[2], [3], [1], [2], [3], [1]]; 24916 if (isSorted) { 24917 arrays = lodashStable.sortBy(arrays, 0); 24918 } 24919 expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3); 24920 actual = func(arrays, 0); 24921 24922 assert.deepEqual(actual, expected); 24923 }); 24924 24925 lodashStable.each({ 24926 'an array': [0, 'a'], 24927 'an object': { '0': 'a' }, 24928 'a number': 0, 24929 'a string': '0' 24930 }, 24931 function(iteratee, key) { 24932 QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) { 24933 assert.expect(1); 24934 24935 var actual = func([['a'], ['a'], ['b']], iteratee); 24936 assert.deepEqual(actual, [['a'], ['b']]); 24937 }); 24938 }); 24939 }); 24940 24941 /*--------------------------------------------------------------------------*/ 24942 24943 QUnit.module('lodash.uniqWith'); 24944 24945 (function() { 24946 QUnit.test('should work with a `comparator`', function(assert) { 24947 assert.expect(1); 24948 24949 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }], 24950 actual = _.uniqWith(objects, lodashStable.isEqual); 24951 24952 assert.deepEqual(actual, [objects[0], objects[1]]); 24953 }); 24954 24955 QUnit.test('should preserve the sign of `0`', function(assert) { 24956 assert.expect(1); 24957 24958 var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) { 24959 return isEven(index) ? -0 : 0; 24960 }); 24961 24962 var arrays = [[-0, 0], largeArray], 24963 expected = lodashStable.map(arrays, lodashStable.constant(['-0'])); 24964 24965 var actual = lodashStable.map(arrays, function(array) { 24966 return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString); 24967 }); 24968 24969 assert.deepEqual(actual, expected); 24970 }); 24971 }()); 24972 24973 /*--------------------------------------------------------------------------*/ 24974 24975 QUnit.module('lodash.uniqueId'); 24976 24977 (function() { 24978 QUnit.test('should generate unique ids', function(assert) { 24979 assert.expect(1); 24980 24981 var actual = lodashStable.times(1000, function(assert) { 24982 return _.uniqueId(); 24983 }); 24984 24985 assert.strictEqual(lodashStable.uniq(actual).length, actual.length); 24986 }); 24987 24988 QUnit.test('should return a string value when not providing a `prefix`', function(assert) { 24989 assert.expect(1); 24990 24991 assert.strictEqual(typeof _.uniqueId(), 'string'); 24992 }); 24993 24994 QUnit.test('should coerce the prefix argument to a string', function(assert) { 24995 assert.expect(1); 24996 24997 var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)]; 24998 assert.ok(/3\d+,2\d+,1\d+/.test(actual)); 24999 }); 25000 }()); 25001 25002 /*--------------------------------------------------------------------------*/ 25003 25004 QUnit.module('lodash.unset'); 25005 25006 (function() { 25007 QUnit.test('should unset property values', function(assert) { 25008 assert.expect(4); 25009 25010 lodashStable.each(['a', ['a']], function(path) { 25011 var object = { 'a': 1, 'c': 2 }; 25012 assert.strictEqual(_.unset(object, path), true); 25013 assert.deepEqual(object, { 'c': 2 }); 25014 }); 25015 }); 25016 25017 QUnit.test('should preserve the sign of `0`', function(assert) { 25018 assert.expect(1); 25019 25020 var props = [-0, Object(-0), 0, Object(0)], 25021 expected = lodashStable.map(props, lodashStable.constant([true, false])); 25022 25023 var actual = lodashStable.map(props, function(key) { 25024 var object = { '-0': 'a', '0': 'b' }; 25025 return [_.unset(object, key), lodashStable.toString(key) in object]; 25026 }); 25027 25028 assert.deepEqual(actual, expected); 25029 }); 25030 25031 QUnit.test('should unset symbol keyed property values', function(assert) { 25032 assert.expect(2); 25033 25034 if (Symbol) { 25035 var object = {}; 25036 object[symbol] = 1; 25037 25038 assert.strictEqual(_.unset(object, symbol), true); 25039 assert.notOk(symbol in object); 25040 } 25041 else { 25042 skipAssert(assert, 2); 25043 } 25044 }); 25045 25046 QUnit.test('should unset deep property values', function(assert) { 25047 assert.expect(4); 25048 25049 lodashStable.each(['a.b', ['a', 'b']], function(path) { 25050 var object = { 'a': { 'b': null } }; 25051 assert.strictEqual(_.unset(object, path), true); 25052 assert.deepEqual(object, { 'a': {} }); 25053 }); 25054 }); 25055 25056 QUnit.test('should handle complex paths', function(assert) { 25057 assert.expect(4); 25058 25059 var paths = [ 25060 'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g', 25061 ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g'] 25062 ]; 25063 25064 lodashStable.each(paths, function(path) { 25065 var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } }; 25066 assert.strictEqual(_.unset(object, path), true); 25067 assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f); 25068 }); 25069 }); 25070 25071 QUnit.test('should return `true` for nonexistent paths', function(assert) { 25072 assert.expect(5); 25073 25074 var object = { 'a': { 'b': { 'c': null } } }; 25075 25076 lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) { 25077 assert.strictEqual(_.unset(object, path), true); 25078 }); 25079 25080 assert.deepEqual(object, { 'a': { 'b': { 'c': null } } }); 25081 }); 25082 25083 QUnit.test('should not error when `object` is nullish', function(assert) { 25084 assert.expect(1); 25085 25086 var values = [null, undefined], 25087 expected = [[true, true], [true, true]]; 25088 25089 var actual = lodashStable.map(values, function(value) { 25090 try { 25091 return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])]; 25092 } catch (e) { 25093 return e.message; 25094 } 25095 }); 25096 25097 assert.deepEqual(actual, expected); 25098 }); 25099 25100 QUnit.test('should follow `path` over non-plain objects', function(assert) { 25101 assert.expect(8); 25102 25103 var object = { 'a': '' }, 25104 paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']]; 25105 25106 lodashStable.each(paths, function(path) { 25107 numberProto.a = 1; 25108 25109 var actual = _.unset(0, path); 25110 assert.strictEqual(actual, true); 25111 assert.notOk('a' in numberProto); 25112 25113 delete numberProto.a; 25114 }); 25115 25116 lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) { 25117 stringProto.replace.b = 1; 25118 25119 var actual = _.unset(object, path); 25120 assert.strictEqual(actual, true); 25121 assert.notOk('a' in stringProto.replace); 25122 25123 delete stringProto.replace.b; 25124 }); 25125 }); 25126 25127 QUnit.test('should return `false` for non-configurable properties', function(assert) { 25128 assert.expect(1); 25129 25130 var object = {}; 25131 25132 if (!isStrict) { 25133 defineProperty(object, 'a', { 25134 'configurable': false, 25135 'enumerable': true, 25136 'writable': true, 25137 'value': 1, 25138 }); 25139 assert.strictEqual(_.unset(object, 'a'), false); 25140 } 25141 else { 25142 skipAssert(assert); 25143 } 25144 }); 25145 }()); 25146 25147 /*--------------------------------------------------------------------------*/ 25148 25149 QUnit.module('lodash.unzipWith'); 25150 25151 (function() { 25152 QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) { 25153 assert.expect(1); 25154 25155 var array = [[1, 4], [2, 5], [3, 6]]; 25156 25157 var actual = _.unzipWith(array, function(a, b, c) { 25158 return a + b + c; 25159 }); 25160 25161 assert.deepEqual(actual, [6, 15]); 25162 }); 25163 25164 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 25165 assert.expect(1); 25166 25167 var args; 25168 25169 _.unzipWith([[1, 3, 5], [2, 4, 6]], function() { 25170 args || (args = slice.call(arguments)); 25171 }); 25172 25173 assert.deepEqual(args, [1, 2]); 25174 }); 25175 25176 QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) { 25177 assert.expect(1); 25178 25179 var array = [[1, 3], [2, 4]], 25180 values = [, null, undefined], 25181 expected = lodashStable.map(values, lodashStable.constant(_.unzip(array))); 25182 25183 var actual = lodashStable.map(values, function(value, index) { 25184 return index ? _.unzipWith(array, value) : _.unzipWith(array); 25185 }); 25186 25187 assert.deepEqual(actual, expected); 25188 }); 25189 }()); 25190 25191 /*--------------------------------------------------------------------------*/ 25192 25193 QUnit.module('lodash.updateWith'); 25194 25195 (function() { 25196 QUnit.test('should work with a `customizer` callback', function(assert) { 25197 assert.expect(1); 25198 25199 var actual = _.updateWith({ '0': {} }, '[0][1][2]', stubThree, function(value) { 25200 return lodashStable.isObject(value) ? undefined : {}; 25201 }); 25202 25203 assert.deepEqual(actual, { '0': { '1': { '2': 3 } } }); 25204 }); 25205 25206 QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) { 25207 assert.expect(1); 25208 25209 var actual = _.updateWith({}, 'a[0].b.c', stubFour, noop); 25210 assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] }); 25211 }); 25212 }()); 25213 25214 /*--------------------------------------------------------------------------*/ 25215 25216 QUnit.module('update methods'); 25217 25218 lodashStable.each(['update', 'updateWith'], function(methodName) { 25219 var func = _[methodName], 25220 oldValue = 1; 25221 25222 QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) { 25223 assert.expect(4); 25224 25225 var object = { 'a': [{ 'b': { 'c': oldValue } }] }, 25226 expected = oldValue + 1; 25227 25228 lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) { 25229 func(object, path, function(n) { 25230 assert.strictEqual(n, oldValue); 25231 return ++n; 25232 }); 25233 25234 assert.strictEqual(object.a[0].b.c, expected); 25235 object.a[0].b.c = oldValue; 25236 }); 25237 }); 25238 }); 25239 25240 /*--------------------------------------------------------------------------*/ 25241 25242 QUnit.module('lodash.upperCase'); 25243 25244 (function() { 25245 QUnit.test('should uppercase as space-separated words', function(assert) { 25246 assert.expect(3); 25247 25248 assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR'); 25249 assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR'); 25250 assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR'); 25251 }); 25252 }()); 25253 25254 /*--------------------------------------------------------------------------*/ 25255 25256 QUnit.module('lodash.upperFirst'); 25257 25258 (function() { 25259 QUnit.test('should uppercase only the first character', function(assert) { 25260 assert.expect(3); 25261 25262 assert.strictEqual(_.upperFirst('fred'), 'Fred'); 25263 assert.strictEqual(_.upperFirst('Fred'), 'Fred'); 25264 assert.strictEqual(_.upperFirst('FRED'), 'FRED'); 25265 }); 25266 }()); 25267 25268 /*--------------------------------------------------------------------------*/ 25269 25270 QUnit.module('values methods'); 25271 25272 lodashStable.each(['values', 'valuesIn'], function(methodName) { 25273 var func = _[methodName], 25274 isValues = methodName == 'values'; 25275 25276 QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) { 25277 assert.expect(1); 25278 25279 var object = { 'a': 1, 'b': 2 }, 25280 actual = func(object).sort(); 25281 25282 assert.deepEqual(actual, [1, 2]); 25283 }); 25284 25285 QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) { 25286 assert.expect(1); 25287 25288 var object = { '0': 'a', '1': 'b', 'length': 2 }, 25289 actual = func(object).sort(); 25290 25291 assert.deepEqual(actual, [2, 'a', 'b']); 25292 }); 25293 25294 QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) { 25295 assert.expect(1); 25296 25297 function Foo() { 25298 this.a = 1; 25299 } 25300 Foo.prototype.b = 2; 25301 25302 var expected = isValues ? [1] : [1, 2], 25303 actual = func(new Foo).sort(); 25304 25305 assert.deepEqual(actual, expected); 25306 }); 25307 25308 QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) { 25309 assert.expect(1); 25310 25311 var values = [args, strictArgs], 25312 expected = lodashStable.map(values, lodashStable.constant([1, 2, 3])); 25313 25314 var actual = lodashStable.map(values, function(value) { 25315 return func(value).sort(); 25316 }); 25317 25318 assert.deepEqual(actual, expected); 25319 }); 25320 }); 25321 25322 /*--------------------------------------------------------------------------*/ 25323 25324 QUnit.module('lodash.without'); 25325 25326 (function() { 25327 QUnit.test('should return the difference of values', function(assert) { 25328 assert.expect(1); 25329 25330 var actual = _.without([2, 1, 2, 3], 1, 2); 25331 assert.deepEqual(actual, [3]); 25332 }); 25333 25334 QUnit.test('should use strict equality to determine the values to reject', function(assert) { 25335 assert.expect(2); 25336 25337 var object1 = { 'a': 1 }, 25338 object2 = { 'b': 2 }, 25339 array = [object1, object2]; 25340 25341 assert.deepEqual(_.without(array, { 'a': 1 }), array); 25342 assert.deepEqual(_.without(array, object1), [object2]); 25343 }); 25344 25345 QUnit.test('should remove all occurrences of each value from an array', function(assert) { 25346 assert.expect(1); 25347 25348 var array = [1, 2, 3, 1, 2, 3]; 25349 assert.deepEqual(_.without(array, 1, 2), [3, 3]); 25350 }); 25351 }()); 25352 25353 /*--------------------------------------------------------------------------*/ 25354 25355 QUnit.module('lodash.words'); 25356 25357 (function() { 25358 QUnit.test('should match words containing Latin Unicode letters', function(assert) { 25359 assert.expect(1); 25360 25361 var expected = lodashStable.map(burredLetters, function(letter) { 25362 return [letter]; 25363 }); 25364 25365 var actual = lodashStable.map(burredLetters, function(letter) { 25366 return _.words(letter); 25367 }); 25368 25369 assert.deepEqual(actual, expected); 25370 }); 25371 25372 QUnit.test('should support a `pattern`', function(assert) { 25373 assert.expect(2); 25374 25375 assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']); 25376 assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']); 25377 }); 25378 25379 QUnit.test('should work with compound words', function(assert) { 25380 assert.expect(12); 25381 25382 assert.deepEqual(_.words('12ft'), ['12', 'ft']); 25383 assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']); 25384 assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']); 25385 assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']); 25386 assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']); 25387 assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']); 25388 assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']); 25389 assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']); 25390 assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']); 25391 assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']); 25392 assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']); 25393 assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']); 25394 }); 25395 25396 QUnit.test('should work with compound words containing diacritical marks', function(assert) { 25397 assert.expect(3); 25398 25399 assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']); 25400 assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']); 25401 assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']); 25402 }); 25403 25404 QUnit.test('should not treat contractions as separate words', function(assert) { 25405 assert.expect(4); 25406 25407 var postfixes = ['d', 'll', 'm', 're', 's', 't', 've']; 25408 25409 lodashStable.each(["'", '\u2019'], function(apos) { 25410 lodashStable.times(2, function(index) { 25411 var actual = lodashStable.map(postfixes, function(postfix) { 25412 var string = 'a b' + apos + postfix + ' c'; 25413 return _.words(string[index ? 'toUpperCase' : 'toLowerCase']()); 25414 }); 25415 25416 var expected = lodashStable.map(postfixes, function(postfix) { 25417 var words = ['a', 'b' + apos + postfix, 'c']; 25418 return lodashStable.map(words, function(word) { 25419 return word[index ? 'toUpperCase' : 'toLowerCase'](); 25420 }); 25421 }); 25422 25423 assert.deepEqual(actual, expected); 25424 }); 25425 }); 25426 }); 25427 25428 QUnit.test('should not treat ordinal numbers as separate words', function(assert) { 25429 assert.expect(2); 25430 25431 var ordinals = ['1st', '2nd', '3rd', '4th']; 25432 25433 lodashStable.times(2, function(index) { 25434 var expected = lodashStable.map(ordinals, function(ordinal) { 25435 return [ordinal[index ? 'toUpperCase' : 'toLowerCase']()]; 25436 }); 25437 25438 var actual = lodashStable.map(expected, function(words) { 25439 return _.words(words[0]); 25440 }); 25441 25442 assert.deepEqual(actual, expected); 25443 }); 25444 }); 25445 25446 QUnit.test('should not treat mathematical operators as words', function(assert) { 25447 assert.expect(1); 25448 25449 var operators = ['\xac', '\xb1', '\xd7', '\xf7'], 25450 expected = lodashStable.map(operators, stubArray), 25451 actual = lodashStable.map(operators, _.words); 25452 25453 assert.deepEqual(actual, expected); 25454 }); 25455 25456 QUnit.test('should not treat punctuation as words', function(assert) { 25457 assert.expect(1); 25458 25459 var marks = [ 25460 '\u2012', '\u2013', '\u2014', '\u2015', 25461 '\u2024', '\u2025', '\u2026', 25462 '\u205d', '\u205e' 25463 ]; 25464 25465 var expected = lodashStable.map(marks, stubArray), 25466 actual = lodashStable.map(marks, _.words); 25467 25468 assert.deepEqual(actual, expected); 25469 }); 25470 25471 QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { 25472 assert.expect(1); 25473 25474 var strings = lodashStable.map(['a', 'b', 'c'], Object), 25475 actual = lodashStable.map(strings, _.words); 25476 25477 assert.deepEqual(actual, [['a'], ['b'], ['c']]); 25478 }); 25479 25480 QUnit.test('should prevent ReDoS', function(assert) { 25481 assert.expect(2); 25482 25483 var largeWordLen = 50000, 25484 largeWord = _.repeat('A', largeWordLen), 25485 maxMs = 1000, 25486 startTime = lodashStable.now(); 25487 25488 assert.deepEqual(_.words(largeWord + 'ÆiouAreVowels'), [largeWord, 'Æiou', 'Are', 'Vowels']); 25489 25490 var endTime = lodashStable.now(), 25491 timeSpent = endTime - startTime; 25492 25493 assert.ok(timeSpent < maxMs, 'operation took ' + timeSpent + 'ms'); 25494 }); 25495 }()); 25496 25497 /*--------------------------------------------------------------------------*/ 25498 25499 QUnit.module('lodash.wrap'); 25500 25501 (function() { 25502 QUnit.test('should create a wrapped function', function(assert) { 25503 assert.expect(1); 25504 25505 var p = _.wrap(lodashStable.escape, function(func, text) { 25506 return '<p>' + func(text) + '</p>'; 25507 }); 25508 25509 assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, & pebbles</p>'); 25510 }); 25511 25512 QUnit.test('should provide correct `wrapper` arguments', function(assert) { 25513 assert.expect(1); 25514 25515 var args; 25516 25517 var wrapped = _.wrap(noop, function() { 25518 args || (args = slice.call(arguments)); 25519 }); 25520 25521 wrapped(1, 2, 3); 25522 assert.deepEqual(args, [noop, 1, 2, 3]); 25523 }); 25524 25525 QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) { 25526 assert.expect(1); 25527 25528 var values = [, null, undefined], 25529 expected = lodashStable.map(values, stubA); 25530 25531 var actual = lodashStable.map(values, function(value, index) { 25532 var wrapped = index ? _.wrap('a', value) : _.wrap('a'); 25533 return wrapped('b', 'c'); 25534 }); 25535 25536 assert.deepEqual(actual, expected); 25537 }); 25538 25539 QUnit.test('should use `this` binding of function', function(assert) { 25540 assert.expect(1); 25541 25542 var p = _.wrap(lodashStable.escape, function(func) { 25543 return '<p>' + func(this.text) + '</p>'; 25544 }); 25545 25546 var object = { 'p': p, 'text': 'fred, barney, & pebbles' }; 25547 assert.strictEqual(object.p(), '<p>fred, barney, & pebbles</p>'); 25548 }); 25549 }()); 25550 25551 /*--------------------------------------------------------------------------*/ 25552 25553 QUnit.module('xor methods'); 25554 25555 lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) { 25556 var func = _[methodName]; 25557 25558 QUnit.test('`_.' + methodName + '` should return the symmetric difference of two arrays', function(assert) { 25559 assert.expect(1); 25560 25561 var actual = func([2, 1], [2, 3]); 25562 assert.deepEqual(actual, [1, 3]); 25563 }); 25564 25565 QUnit.test('`_.' + methodName + '` should return the symmetric difference of multiple arrays', function(assert) { 25566 assert.expect(2); 25567 25568 var actual = func([2, 1], [2, 3], [3, 4]); 25569 assert.deepEqual(actual, [1, 4]); 25570 25571 actual = func([1, 2], [2, 1], [1, 2]); 25572 assert.deepEqual(actual, []); 25573 }); 25574 25575 QUnit.test('`_.' + methodName + '` should return an empty array when comparing the same array', function(assert) { 25576 assert.expect(1); 25577 25578 var array = [1], 25579 actual = func(array, array, array); 25580 25581 assert.deepEqual(actual, []); 25582 }); 25583 25584 QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) { 25585 assert.expect(2); 25586 25587 var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]); 25588 assert.deepEqual(actual, [1, 4]); 25589 25590 actual = func([1, 1]); 25591 assert.deepEqual(actual, [1]); 25592 }); 25593 25594 QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) { 25595 assert.expect(1); 25596 25597 var array = [1]; 25598 assert.notStrictEqual(func(array), array); 25599 }); 25600 25601 QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) { 25602 assert.expect(1); 25603 25604 var array = [0]; 25605 assert.deepEqual(func(array, 3, null, { '0': 1 }), array); 25606 }); 25607 25608 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) { 25609 assert.expect(3); 25610 25611 var array = [1, 2]; 25612 assert.deepEqual(func(array, 3, { '0': 1 }, null), array); 25613 assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]); 25614 assert.deepEqual(func(array, null, args, null), [3]); 25615 }); 25616 25617 QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) { 25618 assert.expect(1); 25619 25620 if (!isNpm) { 25621 var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]); 25622 assert.ok(wrapped instanceof _); 25623 } 25624 else { 25625 skipAssert(assert); 25626 } 25627 }); 25628 25629 QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) { 25630 assert.expect(1); 25631 25632 if (!isNpm) { 25633 var array = lodashStable.range(LARGE_ARRAY_SIZE + 1), 25634 wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]); 25635 25636 var actual = lodashStable.map(['head', 'last'], function(methodName) { 25637 return wrapped[methodName](); 25638 }); 25639 25640 assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]); 25641 } 25642 else { 25643 skipAssert(assert); 25644 } 25645 }); 25646 }); 25647 25648 /*--------------------------------------------------------------------------*/ 25649 25650 QUnit.module('lodash.xorBy'); 25651 25652 (function() { 25653 QUnit.test('should accept an `iteratee`', function(assert) { 25654 assert.expect(2); 25655 25656 var actual = _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); 25657 assert.deepEqual(actual, [1.2, 3.4]); 25658 25659 actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); 25660 assert.deepEqual(actual, [{ 'x': 2 }]); 25661 }); 25662 25663 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 25664 assert.expect(1); 25665 25666 var args; 25667 25668 _.xorBy([2.1, 1.2], [2.3, 3.4], function() { 25669 args || (args = slice.call(arguments)); 25670 }); 25671 25672 assert.deepEqual(args, [2.3]); 25673 }); 25674 }()); 25675 25676 /*--------------------------------------------------------------------------*/ 25677 25678 QUnit.module('lodash.xorWith'); 25679 25680 (function() { 25681 QUnit.test('should work with a `comparator`', function(assert) { 25682 assert.expect(1); 25683 25684 var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }], 25685 others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }], 25686 actual = _.xorWith(objects, others, lodashStable.isEqual); 25687 25688 assert.deepEqual(actual, [objects[1], others[0]]); 25689 }); 25690 }()); 25691 25692 /*--------------------------------------------------------------------------*/ 25693 25694 QUnit.module('zipObject methods'); 25695 25696 lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) { 25697 var func = _[methodName], 25698 object = { 'barney': 36, 'fred': 40 }, 25699 isDeep = methodName == 'zipObjectDeep'; 25700 25701 QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) { 25702 assert.expect(1); 25703 25704 var actual = func(['barney', 'fred'], [36, 40]); 25705 assert.deepEqual(actual, object); 25706 }); 25707 25708 QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) { 25709 assert.expect(1); 25710 25711 assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 }); 25712 }); 25713 25714 QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) { 25715 assert.expect(1); 25716 25717 assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined }); 25718 }); 25719 25720 QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) { 25721 assert.expect(2); 25722 25723 lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) { 25724 var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 }); 25725 assert.deepEqual(func([path], [1]), expected); 25726 }); 25727 }); 25728 25729 QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) { 25730 assert.expect(1); 25731 25732 if (!isNpm) { 25733 var values = lodashStable.range(LARGE_ARRAY_SIZE), 25734 props = lodashStable.map(values, function(value) { return 'key' + value; }), 25735 actual = _(props)[methodName](values).map(square).filter(isEven).take().value(); 25736 25737 assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven))); 25738 } 25739 else { 25740 skipAssert(assert); 25741 } 25742 }); 25743 }); 25744 25745 /*--------------------------------------------------------------------------*/ 25746 25747 QUnit.module('lodash.zipWith'); 25748 25749 (function() { 25750 QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) { 25751 assert.expect(2); 25752 25753 var array1 = [1, 2, 3], 25754 array2 = [4, 5, 6], 25755 array3 = [7, 8, 9]; 25756 25757 var actual = _.zipWith(array1, array2, array3, function(a, b, c) { 25758 return a + b + c; 25759 }); 25760 25761 assert.deepEqual(actual, [12, 15, 18]); 25762 25763 var actual = _.zipWith(array1, [], function(a, b) { 25764 return a + (b || 0); 25765 }); 25766 25767 assert.deepEqual(actual, [1, 2, 3]); 25768 }); 25769 25770 QUnit.test('should provide correct `iteratee` arguments', function(assert) { 25771 assert.expect(1); 25772 25773 var args; 25774 25775 _.zipWith([1, 2], [3, 4], [5, 6], function() { 25776 args || (args = slice.call(arguments)); 25777 }); 25778 25779 assert.deepEqual(args, [1, 3, 5]); 25780 }); 25781 25782 QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) { 25783 assert.expect(1); 25784 25785 var array1 = [1, 2], 25786 array2 = [3, 4], 25787 values = [, null, undefined], 25788 expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2))); 25789 25790 var actual = lodashStable.map(values, function(value, index) { 25791 return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2); 25792 }); 25793 25794 assert.deepEqual(actual, expected); 25795 }); 25796 }()); 25797 25798 /*--------------------------------------------------------------------------*/ 25799 25800 QUnit.module('lodash.unzip and lodash.zip'); 25801 25802 lodashStable.each(['unzip', 'zip'], function(methodName, index) { 25803 var func = _[methodName]; 25804 func = lodashStable.bind(index ? func.apply : func.call, func, null); 25805 25806 var object = { 25807 'an empty array': [ 25808 [], 25809 [] 25810 ], 25811 '0-tuples': [ 25812 [[], []], 25813 [] 25814 ], 25815 '2-tuples': [ 25816 [['barney', 'fred'], [36, 40]], 25817 [['barney', 36], ['fred', 40]] 25818 ], 25819 '3-tuples': [ 25820 [['barney', 'fred'], [36, 40], [false, true]], 25821 [['barney', 36, false], ['fred', 40, true]] 25822 ] 25823 }; 25824 25825 lodashStable.forOwn(object, function(pair, key) { 25826 QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) { 25827 assert.expect(2); 25828 25829 var actual = func(pair[0]); 25830 assert.deepEqual(actual, pair[1]); 25831 assert.deepEqual(func(actual), actual.length ? pair[0] : []); 25832 }); 25833 }); 25834 25835 QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) { 25836 assert.expect(4); 25837 25838 var pair = [ 25839 [['barney', 36], ['fred', 40, false]], 25840 [['barney', 'fred'], [36, 40], [undefined, false]] 25841 ]; 25842 25843 var actual = func(pair[0]); 25844 assert.ok('0' in actual[2]); 25845 assert.deepEqual(actual, pair[1]); 25846 25847 actual = func(actual); 25848 assert.ok('2' in actual[0]); 25849 assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]); 25850 }); 25851 25852 QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) { 25853 assert.expect(1); 25854 25855 var expected = lodashStable.map(falsey, stubArray); 25856 25857 var actual = lodashStable.map(falsey, function(value) { 25858 return func([value, value, value]); 25859 }); 25860 25861 assert.deepEqual(actual, expected); 25862 }); 25863 25864 QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) { 25865 assert.expect(1); 25866 25867 var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }]; 25868 assert.deepEqual(func(array), [[1, 3], [2, 4]]); 25869 }); 25870 25871 QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) { 25872 assert.expect(1); 25873 25874 var expected = [['barney', 'fred'], [36, 40]]; 25875 assert.deepEqual(func(func(func(func(expected)))), expected); 25876 }); 25877 }); 25878 25879 /*--------------------------------------------------------------------------*/ 25880 25881 QUnit.module('lodash(...).commit'); 25882 25883 (function() { 25884 QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) { 25885 assert.expect(4); 25886 25887 if (!isNpm) { 25888 var array = [1], 25889 wrapped = _(array).push(2).push(3); 25890 25891 assert.deepEqual(array, [1]); 25892 25893 var otherWrapper = wrapped.commit(); 25894 assert.ok(otherWrapper instanceof _); 25895 assert.deepEqual(otherWrapper.value(), [1, 2, 3]); 25896 assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]); 25897 } 25898 else { 25899 skipAssert(assert, 4); 25900 } 25901 }); 25902 25903 QUnit.test('should track the `__chain__` value of a wrapper', function(assert) { 25904 assert.expect(2); 25905 25906 if (!isNpm) { 25907 var wrapped = _([1]).chain().commit().head(); 25908 assert.ok(wrapped instanceof _); 25909 assert.strictEqual(wrapped.value(), 1); 25910 } 25911 else { 25912 skipAssert(assert, 2); 25913 } 25914 }); 25915 }()); 25916 25917 /*--------------------------------------------------------------------------*/ 25918 25919 QUnit.module('lodash(...).next'); 25920 25921 lodashStable.each([false, true], function(implicit) { 25922 function chain(value) { 25923 return implicit ? _(value) : _.chain(value); 25924 } 25925 25926 var chainType = 'in an ' + (implicit ? 'implicit' : 'explict') + ' chain'; 25927 25928 QUnit.test('should follow the iterator protocol ' + chainType, function(assert) { 25929 assert.expect(3); 25930 25931 if (!isNpm) { 25932 var wrapped = chain([1, 2]); 25933 25934 assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 }); 25935 assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 }); 25936 assert.deepEqual(wrapped.next(), { 'done': true, 'value': undefined }); 25937 } 25938 else { 25939 skipAssert(assert, 3); 25940 } 25941 }); 25942 25943 QUnit.test('should act as an iterable ' + chainType, function(assert) { 25944 assert.expect(2); 25945 25946 if (!isNpm && Symbol && Symbol.iterator) { 25947 var array = [1, 2], 25948 wrapped = chain(array); 25949 25950 assert.strictEqual(wrapped[Symbol.iterator](), wrapped); 25951 assert.deepEqual(lodashStable.toArray(wrapped), array); 25952 } 25953 else { 25954 skipAssert(assert, 2); 25955 } 25956 }); 25957 25958 QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) { 25959 assert.expect(3); 25960 25961 if (!isNpm && Array.from) { 25962 var hearts = '\ud83d\udc95', 25963 values = [[1], { 'a': 1 }, hearts]; 25964 25965 lodashStable.each(values, function(value) { 25966 var wrapped = chain(value); 25967 assert.deepEqual(Array.from(wrapped), _.toArray(value)); 25968 }); 25969 } 25970 else { 25971 skipAssert(assert, 3); 25972 } 25973 }); 25974 25975 QUnit.test('should reset the iterator correctly ' + chainType, function(assert) { 25976 assert.expect(4); 25977 25978 if (!isNpm && Symbol && Symbol.iterator) { 25979 var array = [1, 2], 25980 wrapped = chain(array); 25981 25982 assert.deepEqual(lodashStable.toArray(wrapped), array); 25983 assert.deepEqual(lodashStable.toArray(wrapped), [], 'produces an empty array for exhausted iterator'); 25984 25985 var other = wrapped.filter(); 25986 assert.deepEqual(lodashStable.toArray(other), array, 'reset for new chain segments'); 25987 assert.deepEqual(lodashStable.toArray(wrapped), [], 'iterator is still exhausted'); 25988 } 25989 else { 25990 skipAssert(assert, 4); 25991 } 25992 }); 25993 25994 QUnit.test('should work in a lazy sequence ' + chainType, function(assert) { 25995 assert.expect(3); 25996 25997 if (!isNpm && Symbol && Symbol.iterator) { 25998 var array = lodashStable.range(LARGE_ARRAY_SIZE), 25999 predicate = function(value) { values.push(value); return isEven(value); }, 26000 values = [], 26001 wrapped = chain(array); 26002 26003 assert.deepEqual(lodashStable.toArray(wrapped), array); 26004 26005 wrapped = wrapped.filter(predicate); 26006 assert.deepEqual(lodashStable.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments'); 26007 assert.deepEqual(values, array, 'memoizes iterator values'); 26008 } 26009 else { 26010 skipAssert(assert, 3); 26011 } 26012 }); 26013 }); 26014 26015 /*--------------------------------------------------------------------------*/ 26016 26017 QUnit.module('lodash(...).plant'); 26018 26019 (function() { 26020 QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) { 26021 assert.expect(2); 26022 26023 if (!isNpm) { 26024 var array1 = [5, null, 3, null, 1], 26025 array2 = [10, null, 8, null, 6], 26026 wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(), 26027 wrapped2 = wrapped1.plant(array2); 26028 26029 assert.deepEqual(wrapped2.value(), [36, 64]); 26030 assert.deepEqual(wrapped1.value(), [1, 9]); 26031 } 26032 else { 26033 skipAssert(assert, 2); 26034 } 26035 }); 26036 26037 QUnit.test('should clone `chainAll` settings', function(assert) { 26038 assert.expect(1); 26039 26040 if (!isNpm) { 26041 var array1 = [2, 4], 26042 array2 = [6, 8], 26043 wrapped1 = _(array1).chain().map(square), 26044 wrapped2 = wrapped1.plant(array2); 26045 26046 assert.deepEqual(wrapped2.head().value(), 36); 26047 } 26048 else { 26049 skipAssert(assert); 26050 } 26051 }); 26052 26053 QUnit.test('should reset iterator data on cloned sequences', function(assert) { 26054 assert.expect(3); 26055 26056 if (!isNpm && Symbol && Symbol.iterator) { 26057 var array1 = [2, 4], 26058 array2 = [6, 8], 26059 wrapped1 = _(array1).map(square); 26060 26061 assert.deepEqual(lodashStable.toArray(wrapped1), [4, 16]); 26062 assert.deepEqual(lodashStable.toArray(wrapped1), []); 26063 26064 var wrapped2 = wrapped1.plant(array2); 26065 assert.deepEqual(lodashStable.toArray(wrapped2), [36, 64]); 26066 } 26067 else { 26068 skipAssert(assert, 3); 26069 } 26070 }); 26071 }()); 26072 26073 /*--------------------------------------------------------------------------*/ 26074 26075 QUnit.module('lodash(...).pop'); 26076 26077 (function() { 26078 QUnit.test('should remove elements from the end of `array`', function(assert) { 26079 assert.expect(5); 26080 26081 if (!isNpm) { 26082 var array = [1, 2], 26083 wrapped = _(array); 26084 26085 assert.strictEqual(wrapped.pop(), 2); 26086 assert.deepEqual(wrapped.value(), [1]); 26087 assert.strictEqual(wrapped.pop(), 1); 26088 26089 var actual = wrapped.value(); 26090 assert.strictEqual(actual, array); 26091 assert.deepEqual(actual, []); 26092 } 26093 else { 26094 skipAssert(assert, 5); 26095 } 26096 }); 26097 26098 QUnit.test('should accept falsey arguments', function(assert) { 26099 assert.expect(1); 26100 26101 if (!isNpm) { 26102 var expected = lodashStable.map(falsey, stubTrue); 26103 26104 var actual = lodashStable.map(falsey, function(value, index) { 26105 try { 26106 var result = index ? _(value).pop() : _().pop(); 26107 return result === undefined; 26108 } catch (e) {} 26109 }); 26110 26111 assert.deepEqual(actual, expected); 26112 } 26113 else { 26114 skipAssert(assert); 26115 } 26116 }); 26117 }()); 26118 26119 /*--------------------------------------------------------------------------*/ 26120 26121 QUnit.module('lodash(...).push'); 26122 26123 (function() { 26124 QUnit.test('should append elements to `array`', function(assert) { 26125 assert.expect(2); 26126 26127 if (!isNpm) { 26128 var array = [1], 26129 wrapped = _(array).push(2, 3), 26130 actual = wrapped.value(); 26131 26132 assert.strictEqual(actual, array); 26133 assert.deepEqual(actual, [1, 2, 3]); 26134 } 26135 else { 26136 skipAssert(assert, 2); 26137 } 26138 }); 26139 26140 QUnit.test('should accept falsey arguments', function(assert) { 26141 assert.expect(1); 26142 26143 if (!isNpm) { 26144 var expected = lodashStable.map(falsey, stubTrue); 26145 26146 var actual = lodashStable.map(falsey, function(value, index) { 26147 try { 26148 var result = index ? _(value).push(1).value() : _().push(1).value(); 26149 return lodashStable.eq(result, value); 26150 } catch (e) {} 26151 }); 26152 26153 assert.deepEqual(actual, expected); 26154 } 26155 else { 26156 skipAssert(assert); 26157 } 26158 }); 26159 }()); 26160 26161 /*--------------------------------------------------------------------------*/ 26162 26163 QUnit.module('lodash(...).shift'); 26164 26165 (function() { 26166 QUnit.test('should remove elements from the front of `array`', function(assert) { 26167 assert.expect(5); 26168 26169 if (!isNpm) { 26170 var array = [1, 2], 26171 wrapped = _(array); 26172 26173 assert.strictEqual(wrapped.shift(), 1); 26174 assert.deepEqual(wrapped.value(), [2]); 26175 assert.strictEqual(wrapped.shift(), 2); 26176 26177 var actual = wrapped.value(); 26178 assert.strictEqual(actual, array); 26179 assert.deepEqual(actual, []); 26180 } 26181 else { 26182 skipAssert(assert, 5); 26183 } 26184 }); 26185 26186 QUnit.test('should accept falsey arguments', function(assert) { 26187 assert.expect(1); 26188 26189 if (!isNpm) { 26190 var expected = lodashStable.map(falsey, stubTrue); 26191 26192 var actual = lodashStable.map(falsey, function(value, index) { 26193 try { 26194 var result = index ? _(value).shift() : _().shift(); 26195 return result === undefined; 26196 } catch (e) {} 26197 }); 26198 26199 assert.deepEqual(actual, expected); 26200 } 26201 else { 26202 skipAssert(assert); 26203 } 26204 }); 26205 }()); 26206 26207 /*--------------------------------------------------------------------------*/ 26208 26209 QUnit.module('lodash(...).sort'); 26210 26211 (function() { 26212 QUnit.test('should return the wrapped sorted `array`', function(assert) { 26213 assert.expect(2); 26214 26215 if (!isNpm) { 26216 var array = [3, 1, 2], 26217 wrapped = _(array).sort(), 26218 actual = wrapped.value(); 26219 26220 assert.strictEqual(actual, array); 26221 assert.deepEqual(actual, [1, 2, 3]); 26222 } 26223 else { 26224 skipAssert(assert, 2); 26225 } 26226 }); 26227 26228 QUnit.test('should accept falsey arguments', function(assert) { 26229 assert.expect(1); 26230 26231 if (!isNpm) { 26232 var expected = lodashStable.map(falsey, stubTrue); 26233 26234 var actual = lodashStable.map(falsey, function(value, index) { 26235 try { 26236 var result = index ? _(value).sort().value() : _().sort().value(); 26237 return lodashStable.eq(result, value); 26238 } catch (e) {} 26239 }); 26240 26241 assert.deepEqual(actual, expected); 26242 } 26243 else { 26244 skipAssert(assert); 26245 } 26246 }); 26247 }()); 26248 26249 /*--------------------------------------------------------------------------*/ 26250 26251 QUnit.module('lodash(...).splice'); 26252 26253 (function() { 26254 QUnit.test('should support removing and inserting elements', function(assert) { 26255 assert.expect(5); 26256 26257 if (!isNpm) { 26258 var array = [1, 2], 26259 wrapped = _(array); 26260 26261 assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]); 26262 assert.deepEqual(wrapped.value(), [1, 3]); 26263 assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]); 26264 26265 var actual = wrapped.value(); 26266 assert.strictEqual(actual, array); 26267 assert.deepEqual(actual, []); 26268 } 26269 else { 26270 skipAssert(assert, 5); 26271 } 26272 }); 26273 26274 QUnit.test('should accept falsey arguments', function(assert) { 26275 assert.expect(1); 26276 26277 if (!isNpm) { 26278 var expected = lodashStable.map(falsey, stubTrue); 26279 26280 var actual = lodashStable.map(falsey, function(value, index) { 26281 try { 26282 var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value(); 26283 return lodashStable.isEqual(result, []); 26284 } catch (e) {} 26285 }); 26286 26287 assert.deepEqual(actual, expected); 26288 } 26289 else { 26290 skipAssert(assert); 26291 } 26292 }); 26293 }()); 26294 26295 /*--------------------------------------------------------------------------*/ 26296 26297 QUnit.module('lodash(...).unshift'); 26298 26299 (function() { 26300 QUnit.test('should prepend elements to `array`', function(assert) { 26301 assert.expect(2); 26302 26303 if (!isNpm) { 26304 var array = [3], 26305 wrapped = _(array).unshift(1, 2), 26306 actual = wrapped.value(); 26307 26308 assert.strictEqual(actual, array); 26309 assert.deepEqual(actual, [1, 2, 3]); 26310 } 26311 else { 26312 skipAssert(assert, 2); 26313 } 26314 }); 26315 26316 QUnit.test('should accept falsey arguments', function(assert) { 26317 assert.expect(1); 26318 26319 if (!isNpm) { 26320 var expected = lodashStable.map(falsey, stubTrue); 26321 26322 var actual = lodashStable.map(falsey, function(value, index) { 26323 try { 26324 var result = index ? _(value).unshift(1).value() : _().unshift(1).value(); 26325 return lodashStable.eq(result, value); 26326 } catch (e) {} 26327 }); 26328 26329 assert.deepEqual(actual, expected); 26330 } 26331 else { 26332 skipAssert(assert); 26333 } 26334 }); 26335 }()); 26336 26337 /*--------------------------------------------------------------------------*/ 26338 26339 QUnit.module('lodash(...).value'); 26340 26341 (function() { 26342 QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) { 26343 assert.expect(4); 26344 26345 if (!isNpm) { 26346 var array = [1], 26347 wrapped = _(array).push(2).push(3); 26348 26349 assert.deepEqual(array, [1]); 26350 assert.deepEqual(wrapped.value(), [1, 2, 3]); 26351 assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]); 26352 assert.deepEqual(array, [1, 2, 3, 2, 3]); 26353 } 26354 else { 26355 skipAssert(assert, 4); 26356 } 26357 }); 26358 26359 QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) { 26360 assert.expect(1); 26361 26362 if (!isNpm) { 26363 var wrapped = _(123); 26364 assert.strictEqual(Number(wrapped), 123); 26365 } 26366 else { 26367 skipAssert(assert); 26368 } 26369 }); 26370 26371 QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) { 26372 assert.expect(1); 26373 26374 if (!isNpm && JSON) { 26375 var wrapped = _([1, 2, 3]); 26376 assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]'); 26377 } 26378 else { 26379 skipAssert(assert); 26380 } 26381 }); 26382 26383 QUnit.test('should be aliased', function(assert) { 26384 assert.expect(2); 26385 26386 if (!isNpm) { 26387 var expected = _.prototype.value; 26388 assert.strictEqual(_.prototype.toJSON, expected); 26389 assert.strictEqual(_.prototype.valueOf, expected); 26390 } 26391 else { 26392 skipAssert(assert, 2); 26393 } 26394 }); 26395 }()); 26396 26397 /*--------------------------------------------------------------------------*/ 26398 26399 QUnit.module('lodash(...) methods that return the wrapped modified array'); 26400 26401 (function() { 26402 var funcs = [ 26403 'push', 26404 'reverse', 26405 'sort', 26406 'unshift' 26407 ]; 26408 26409 lodashStable.each(funcs, function(methodName) { 26410 QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) { 26411 assert.expect(2); 26412 26413 if (!isNpm) { 26414 var array = [1, 2, 3], 26415 wrapped = _(array), 26416 actual = wrapped[methodName](); 26417 26418 assert.ok(actual instanceof _); 26419 assert.notStrictEqual(actual, wrapped); 26420 } 26421 else { 26422 skipAssert(assert, 2); 26423 } 26424 }); 26425 }); 26426 }()); 26427 26428 /*--------------------------------------------------------------------------*/ 26429 26430 QUnit.module('lodash(...) methods that return new wrapped values'); 26431 26432 (function() { 26433 var funcs = [ 26434 'castArray', 26435 'concat', 26436 'difference', 26437 'differenceBy', 26438 'differenceWith', 26439 'intersection', 26440 'intersectionBy', 26441 'intersectionWith', 26442 'pull', 26443 'pullAll', 26444 'pullAt', 26445 'sampleSize', 26446 'shuffle', 26447 'slice', 26448 'splice', 26449 'split', 26450 'toArray', 26451 'union', 26452 'unionBy', 26453 'unionWith', 26454 'uniq', 26455 'uniqBy', 26456 'uniqWith', 26457 'words', 26458 'xor', 26459 'xorBy', 26460 'xorWith' 26461 ]; 26462 26463 lodashStable.each(funcs, function(methodName) { 26464 QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) { 26465 assert.expect(2); 26466 26467 if (!isNpm) { 26468 var value = methodName == 'split' ? 'abc' : [1, 2, 3], 26469 wrapped = _(value), 26470 actual = wrapped[methodName](); 26471 26472 assert.ok(actual instanceof _); 26473 assert.notStrictEqual(actual, wrapped); 26474 } 26475 else { 26476 skipAssert(assert, 2); 26477 } 26478 }); 26479 }); 26480 }()); 26481 26482 /*--------------------------------------------------------------------------*/ 26483 26484 QUnit.module('lodash(...) methods that return unwrapped values'); 26485 26486 (function() { 26487 var funcs = [ 26488 'add', 26489 'camelCase', 26490 'capitalize', 26491 'ceil', 26492 'clone', 26493 'deburr', 26494 'defaultTo', 26495 'divide', 26496 'endsWith', 26497 'escape', 26498 'escapeRegExp', 26499 'every', 26500 'find', 26501 'floor', 26502 'has', 26503 'hasIn', 26504 'head', 26505 'includes', 26506 'isArguments', 26507 'isArray', 26508 'isArrayBuffer', 26509 'isArrayLike', 26510 'isBoolean', 26511 'isBuffer', 26512 'isDate', 26513 'isElement', 26514 'isEmpty', 26515 'isEqual', 26516 'isError', 26517 'isFinite', 26518 'isFunction', 26519 'isInteger', 26520 'isMap', 26521 'isNaN', 26522 'isNative', 26523 'isNil', 26524 'isNull', 26525 'isNumber', 26526 'isObject', 26527 'isObjectLike', 26528 'isPlainObject', 26529 'isRegExp', 26530 'isSafeInteger', 26531 'isSet', 26532 'isString', 26533 'isUndefined', 26534 'isWeakMap', 26535 'isWeakSet', 26536 'join', 26537 'kebabCase', 26538 'last', 26539 'lowerCase', 26540 'lowerFirst', 26541 'max', 26542 'maxBy', 26543 'min', 26544 'minBy', 26545 'multiply', 26546 'nth', 26547 'pad', 26548 'padEnd', 26549 'padStart', 26550 'parseInt', 26551 'pop', 26552 'random', 26553 'reduce', 26554 'reduceRight', 26555 'repeat', 26556 'replace', 26557 'round', 26558 'sample', 26559 'shift', 26560 'size', 26561 'snakeCase', 26562 'some', 26563 'startCase', 26564 'startsWith', 26565 'subtract', 26566 'sum', 26567 'toFinite', 26568 'toInteger', 26569 'toLower', 26570 'toNumber', 26571 'toSafeInteger', 26572 'toString', 26573 'toUpper', 26574 'trim', 26575 'trimEnd', 26576 'trimStart', 26577 'truncate', 26578 'unescape', 26579 'upperCase', 26580 'upperFirst' 26581 ]; 26582 26583 lodashStable.each(funcs, function(methodName) { 26584 QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) { 26585 assert.expect(1); 26586 26587 if (!isNpm) { 26588 var actual = _()[methodName](); 26589 assert.notOk(actual instanceof _); 26590 } 26591 else { 26592 skipAssert(assert); 26593 } 26594 }); 26595 26596 QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) { 26597 assert.expect(1); 26598 26599 if (!isNpm) { 26600 var actual = _().chain()[methodName](); 26601 assert.ok(actual instanceof _); 26602 } 26603 else { 26604 skipAssert(assert); 26605 } 26606 }); 26607 }); 26608 }()); 26609 26610 /*--------------------------------------------------------------------------*/ 26611 26612 QUnit.module('"Arrays" category methods'); 26613 26614 (function() { 26615 var args = toArgs([1, null, [3], null, 5]), 26616 sortedArgs = toArgs([1, [3], 5, null, null]), 26617 array = [1, 2, 3, 4, 5, 6]; 26618 26619 QUnit.test('should work with `arguments` objects', function(assert) { 26620 assert.expect(30); 26621 26622 function message(methodName) { 26623 return '`_.' + methodName + '` should work with `arguments` objects'; 26624 } 26625 26626 assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference')); 26627 assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments'); 26628 26629 assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union')); 26630 assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments'); 26631 26632 assert.deepEqual(_.compact(args), [1, [3], 5], message('compact')); 26633 assert.deepEqual(_.drop(args, 3), [null, 5], message('drop')); 26634 assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight')); 26635 assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile')); 26636 assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile')); 26637 assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex')); 26638 assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex')); 26639 assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten')); 26640 assert.deepEqual(_.head(args), 1, message('head')); 26641 assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf')); 26642 assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial')); 26643 assert.deepEqual(_.intersection(args, [1]), [1], message('intersection')); 26644 assert.deepEqual(_.last(args), 5, message('last')); 26645 assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf')); 26646 assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex')); 26647 assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf')); 26648 assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex')); 26649 assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf')); 26650 assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail')); 26651 assert.deepEqual(_.take(args, 2), [1, null], message('take')); 26652 assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight')); 26653 assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile')); 26654 assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile')); 26655 assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq')); 26656 assert.deepEqual(_.without(args, null), [1, [3], 5], message('without')); 26657 assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip')); 26658 }); 26659 26660 QUnit.test('should accept falsey primary arguments', function(assert) { 26661 assert.expect(4); 26662 26663 function message(methodName) { 26664 return '`_.' + methodName + '` should accept falsey primary arguments'; 26665 } 26666 26667 assert.deepEqual(_.difference(null, array), [], message('difference')); 26668 assert.deepEqual(_.intersection(null, array), [], message('intersection')); 26669 assert.deepEqual(_.union(null, array), array, message('union')); 26670 assert.deepEqual(_.xor(null, array), array, message('xor')); 26671 }); 26672 26673 QUnit.test('should accept falsey secondary arguments', function(assert) { 26674 assert.expect(3); 26675 26676 function message(methodName) { 26677 return '`_.' + methodName + '` should accept falsey secondary arguments'; 26678 } 26679 26680 assert.deepEqual(_.difference(array, null), array, message('difference')); 26681 assert.deepEqual(_.intersection(array, null), [], message('intersection')); 26682 assert.deepEqual(_.union(array, null), array, message('union')); 26683 }); 26684 }()); 26685 26686 /*--------------------------------------------------------------------------*/ 26687 26688 QUnit.module('"Strings" category methods'); 26689 26690 (function() { 26691 var stringMethods = [ 26692 'camelCase', 26693 'capitalize', 26694 'escape', 26695 'kebabCase', 26696 'lowerCase', 26697 'lowerFirst', 26698 'pad', 26699 'padEnd', 26700 'padStart', 26701 'repeat', 26702 'snakeCase', 26703 'toLower', 26704 'toUpper', 26705 'trim', 26706 'trimEnd', 26707 'trimStart', 26708 'truncate', 26709 'unescape', 26710 'upperCase', 26711 'upperFirst' 26712 ]; 26713 26714 lodashStable.each(stringMethods, function(methodName) { 26715 var func = _[methodName]; 26716 26717 QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) { 26718 assert.expect(1); 26719 26720 var values = [, null, undefined, ''], 26721 expected = lodashStable.map(values, stubString); 26722 26723 var actual = lodashStable.map(values, function(value, index) { 26724 return index ? func(value) : func(); 26725 }); 26726 26727 assert.deepEqual(actual, expected); 26728 }); 26729 }); 26730 }()); 26731 26732 /*--------------------------------------------------------------------------*/ 26733 26734 QUnit.module('lodash methods'); 26735 26736 (function() { 26737 var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) { 26738 return lodashStable.startsWith(methodName, '_'); 26739 }); 26740 26741 var checkFuncs = [ 26742 'after', 26743 'ary', 26744 'before', 26745 'bind', 26746 'curry', 26747 'curryRight', 26748 'debounce', 26749 'defer', 26750 'delay', 26751 'flip', 26752 'flow', 26753 'flowRight', 26754 'memoize', 26755 'negate', 26756 'once', 26757 'partial', 26758 'partialRight', 26759 'rearg', 26760 'rest', 26761 'spread', 26762 'throttle', 26763 'unary' 26764 ]; 26765 26766 var noBinding = [ 26767 'flip', 26768 'memoize', 26769 'negate', 26770 'once', 26771 'overArgs', 26772 'partial', 26773 'partialRight', 26774 'rearg', 26775 'rest', 26776 'spread' 26777 ]; 26778 26779 var rejectFalsey = [ 26780 'tap', 26781 'thru' 26782 ].concat(checkFuncs); 26783 26784 var returnArrays = [ 26785 'at', 26786 'chunk', 26787 'compact', 26788 'difference', 26789 'drop', 26790 'filter', 26791 'flatten', 26792 'functions', 26793 'initial', 26794 'intersection', 26795 'invokeMap', 26796 'keys', 26797 'map', 26798 'orderBy', 26799 'pull', 26800 'pullAll', 26801 'pullAt', 26802 'range', 26803 'rangeRight', 26804 'reject', 26805 'remove', 26806 'shuffle', 26807 'sortBy', 26808 'tail', 26809 'take', 26810 'times', 26811 'toArray', 26812 'toPairs', 26813 'toPairsIn', 26814 'union', 26815 'uniq', 26816 'values', 26817 'without', 26818 'xor', 26819 'zip' 26820 ]; 26821 26822 var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); 26823 26824 QUnit.test('should accept falsey arguments', function(assert) { 26825 assert.expect(316); 26826 26827 var arrays = lodashStable.map(falsey, stubArray); 26828 26829 lodashStable.each(acceptFalsey, function(methodName) { 26830 var expected = arrays, 26831 func = _[methodName]; 26832 26833 var actual = lodashStable.map(falsey, function(value, index) { 26834 return index ? func(value) : func(); 26835 }); 26836 26837 if (methodName == 'noConflict') { 26838 root._ = oldDash; 26839 } 26840 else if (methodName == 'pull' || methodName == 'pullAll') { 26841 expected = falsey; 26842 } 26843 if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') { 26844 assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array'); 26845 } 26846 assert.ok(true, '`_.' + methodName + '` accepts falsey arguments'); 26847 }); 26848 26849 // Skip tests for missing methods of modularized builds. 26850 lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) { 26851 if (!_[methodName]) { 26852 skipAssert(assert); 26853 } 26854 }); 26855 }); 26856 26857 QUnit.test('should return an array', function(assert) { 26858 assert.expect(70); 26859 26860 var array = [1, 2, 3]; 26861 26862 lodashStable.each(returnArrays, function(methodName) { 26863 var actual, 26864 func = _[methodName]; 26865 26866 switch (methodName) { 26867 case 'invokeMap': 26868 actual = func(array, 'toFixed'); 26869 break; 26870 case 'sample': 26871 actual = func(array, 1); 26872 break; 26873 default: 26874 actual = func(array); 26875 } 26876 assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array'); 26877 26878 var isPull = methodName == 'pull' || methodName == 'pullAll'; 26879 assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array'); 26880 }); 26881 }); 26882 26883 QUnit.test('should throw an error for falsey arguments', function(assert) { 26884 assert.expect(24); 26885 26886 lodashStable.each(rejectFalsey, function(methodName) { 26887 var expected = lodashStable.map(falsey, stubTrue), 26888 func = _[methodName]; 26889 26890 var actual = lodashStable.map(falsey, function(value, index) { 26891 var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName); 26892 26893 try { 26894 index ? func(value) : func(); 26895 } catch (e) { 26896 pass = !pass && (e instanceof TypeError) && 26897 (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT)); 26898 } 26899 return pass; 26900 }); 26901 26902 assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments'); 26903 }); 26904 }); 26905 26906 QUnit.test('should use `this` binding of function', function(assert) { 26907 assert.expect(30); 26908 26909 lodashStable.each(noBinding, function(methodName) { 26910 var fn = function() { return this.a; }, 26911 func = _[methodName], 26912 isNegate = methodName == 'negate', 26913 object = { 'a': 1 }, 26914 expected = isNegate ? false : 1; 26915 26916 var wrapper = func(_.bind(fn, object)); 26917 assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function'); 26918 26919 wrapper = _.bind(func(fn), object); 26920 assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound'); 26921 26922 object.wrapper = func(fn); 26923 assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object'); 26924 }); 26925 }); 26926 26927 QUnit.test('should not contain minified method names (test production builds)', function(assert) { 26928 assert.expect(1); 26929 26930 var shortNames = ['_', 'at', 'eq', 'gt', 'lt']; 26931 assert.ok(lodashStable.every(_.functions(_), function(methodName) { 26932 return methodName.length > 2 || lodashStable.includes(shortNames, methodName); 26933 })); 26934 }); 26935 }()); 26936 26937 /*--------------------------------------------------------------------------*/ 26938 26939 QUnit.config.asyncRetries = 10; 26940 QUnit.config.hidepassed = true; 26941 26942 if (!document) { 26943 QUnit.config.noglobals = true; 26944 QUnit.load(); 26945 QUnit.start(); 26946 } 26947}.call(this)); 26948