UNPKG

html-pages

Version:

Simple development HTTP Server for file serving and directory listing made by a Designer. Use it for hacking your HTML/JavaScript/CSS files but not for deploying your final site.

1,593 lines (1,291 loc) 797 kB
;(function() { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; /** Used to detect when a function becomes hot. */ var HOT_COUNT = 150; /** Used as the size to cover large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE = 500; /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 1.7976931348623157e+308; /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; /** `Object#toString` result references. */ var funcTag = '[object Function]', numberTag = '[object Number]', objectTag = '[object Object]'; /** Used as a reference to the global object. */ var root = (typeof global == 'object' && global) || this; /** Used to store lodash to test for bad extensions/shims. */ var lodashBizarro = root.lodashBizarro; /** Used for native method references. */ var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype, numberProto = Number.prototype, stringProto = String.prototype; /** Method and object shortcuts. */ var phantom = root.phantom, process = root.process, amd = root.define ? define.amd : undefined, args = toArgs([1, 2, 3]), argv = process ? process.argv : undefined, defineProperty = Object.defineProperty, document = phantom ? undefined : root.document, body = root.document ? root.document.body : undefined, create = Object.create, fnToString = funcProto.toString, freeze = Object.freeze, getSymbols = Object.getOwnPropertySymbols, identity = function(value) { return value; }, noop = function() {}, objToString = objectProto.toString, params = argv, push = arrayProto.push, realm = {}, slice = arrayProto.slice, strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)); var ArrayBuffer = root.ArrayBuffer, Buffer = root.Buffer, Map = root.Map, Promise = root.Promise, Proxy = root.Proxy, Set = root.Set, Symbol = root.Symbol, Uint8Array = root.Uint8Array, WeakMap = root.WeakMap, WeakSet = root.WeakSet; var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined, map = Map ? new Map : undefined, promise = Promise ? Promise.resolve(1) : undefined, set = Set ? new Set : undefined, symbol = Symbol ? Symbol('a') : undefined, weakMap = WeakMap ? new WeakMap : undefined, weakSet = WeakSet ? new WeakSet : undefined; /** Math helpers. */ var add = function(x, y) { return x + y; }, doubled = function(n) { return n * 2; }, isEven = function(n) { return n % 2 == 0; }, square = function(n) { return n * n; }; /** Stub functions. */ var stubA = function() { return 'a'; }, stubB = function() { return 'b'; }, stubC = function() { return 'c'; }; var stubTrue = function() { return true; }, stubFalse = function() { return false; }; var stubNaN = function() { return NaN; }, stubNull = function() { return null; }; var stubZero = function() { return 0; }, stubOne = function() { return 1; }, stubTwo = function() { return 2; }, stubThree = function() { return 3; }, stubFour = function() { return 4; }; var stubArray = function() { return []; }, stubObject = function() { return {}; }, stubString = function() { return ''; }; /** List of Latin Unicode letters. */ var burredLetters = [ // Latin-1 Supplement letters. '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff', // Latin Extended-A letters. '\u0100', '\u0101', '\u0102', '\u0103', '\u0104', '\u0105', '\u0106', '\u0107', '\u0108', '\u0109', '\u010a', '\u010b', '\u010c', '\u010d', '\u010e', '\u010f', '\u0110', '\u0111', '\u0112', '\u0113', '\u0114', '\u0115', '\u0116', '\u0117', '\u0118', '\u0119', '\u011a', '\u011b', '\u011c', '\u011d', '\u011e', '\u011f', '\u0120', '\u0121', '\u0122', '\u0123', '\u0124', '\u0125', '\u0126', '\u0127', '\u0128', '\u0129', '\u012a', '\u012b', '\u012c', '\u012d', '\u012e', '\u012f', '\u0130', '\u0131', '\u0132', '\u0133', '\u0134', '\u0135', '\u0136', '\u0137', '\u0138', '\u0139', '\u013a', '\u013b', '\u013c', '\u013d', '\u013e', '\u013f', '\u0140', '\u0141', '\u0142', '\u0143', '\u0144', '\u0145', '\u0146', '\u0147', '\u0148', '\u0149', '\u014a', '\u014b', '\u014c', '\u014d', '\u014e', '\u014f', '\u0150', '\u0151', '\u0152', '\u0153', '\u0154', '\u0155', '\u0156', '\u0157', '\u0158', '\u0159', '\u015a', '\u015b', '\u015c', '\u015d', '\u015e', '\u015f', '\u0160', '\u0161', '\u0162', '\u0163', '\u0164', '\u0165', '\u0166', '\u0167', '\u0168', '\u0169', '\u016a', '\u016b', '\u016c', '\u016d', '\u016e', '\u016f', '\u0170', '\u0171', '\u0172', '\u0173', '\u0174', '\u0175', '\u0176', '\u0177', '\u0178', '\u0179', '\u017a', '\u017b', '\u017c', '\u017d', '\u017e', '\u017f' ]; /** List of combining diacritical marks. */ var comboMarks = [ '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f', '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f', '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f', '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f', '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f', '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f', '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f', '\ufe20', '\ufe21', '\ufe22', '\ufe23' ]; /** List of converted Latin Unicode letters. */ var deburredLetters = [ // Converted Latin-1 Supplement letters. 'A', 'A', 'A', 'A', 'A', 'A', 'Ae', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'Th', 'ss', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y', // Converted Latin Extended-A letters. 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'N', 'n', 'N', 'n', 'N', 'n', "'n", 'N', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'Oe', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's' ]; /** Used to provide falsey values to methods. */ var falsey = [, null, undefined, false, 0, NaN, '']; /** Used to specify the emoji style glyph variant of characters. */ var emojiVar = '\ufe0f'; /** Used to provide empty values to methods. */ var empties = [[], {}].concat(falsey.slice(1)); /** Used to test error objects. */ var errors = [ new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError ]; /** List of fitzpatrick modifiers. */ var fitzModifiers = [ '\ud83c\udffb', '\ud83c\udffc', '\ud83c\udffd', '\ud83c\udffe', '\ud83c\udfff' ]; /** Used to provide primitive values to methods. */ var primitives = [null, undefined, false, true, 1, NaN, 'a']; /** Used to check whether methods support typed arrays. */ var typedArrays = [ 'Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array' ]; /** Used to check whether methods support array views. */ var arrayViews = typedArrays.concat('DataView'); /** The file path of the lodash file to test. */ var filePath = (function() { var min = 2, result = params || []; if (phantom) { min = 0; result = params = phantom.args || require('system').args; } var last = result[result.length - 1]; result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js'; if (!amd) { try { result = require('fs').realpathSync(result); } catch (e) {} try { result = require.resolve(result); } catch (e) {} } return result; }()); /** The `ui` object. */ var ui = root.ui || (root.ui = { 'buildPath': filePath, 'loaderPath': '', 'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath), 'isStrict': /\bes\b/.test(filePath) || 'default' in require(filePath), 'urlParams': {} }); /** The basename of the lodash file to test. */ var basename = /[\w.-]+$/.exec(filePath)[0]; /** Used to indicate testing a modularized build. */ var isModularize = ui.isModularize; /** Detect if testing `npm` modules. */ var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]); /** Detect if running in PhantomJS. */ var isPhantom = phantom || (typeof callPhantom == 'function'); /** Detect if lodash is in strict mode. */ var isStrict = ui.isStrict; /*--------------------------------------------------------------------------*/ // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs. root.msWDfn = undefined; // Assign `setTimeout` to itself to avoid being flagged as a leak. setProperty(root, 'setTimeout', setTimeout); // Exit early if going to run tests in a PhantomJS web page. if (phantom && isModularize) { var page = require('webpage').create(); page.onCallback = function(details) { var coverage = details.coverage; if (coverage) { var fs = require('fs'), cwd = fs.workingDirectory, sep = fs.separator; fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage)); } phantom.exit(details.failed ? 1 : 0); }; page.onConsoleMessage = function(message) { console.log(message); }; page.onInitialized = function() { page.evaluate(function() { document.addEventListener('DOMContentLoaded', function() { QUnit.done(function(details) { details.coverage = window.__coverage__; callPhantom(details); }); }); }); }; page.open(filePath, function(status) { if (status != 'success') { console.log('PhantomJS failed to load page: ' + filePath); phantom.exit(1); } }); console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params))); return; } /*--------------------------------------------------------------------------*/ /** Used to test Web Workers. */ var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) && (document && document.origin != 'null') && root.Worker; /** Used to test host objects in IE. */ try { var xml = new ActiveXObject('Microsoft.XMLDOM'); } catch (e) {} /** Poison the free variable `root` in Node.js */ try { defineProperty(global.root, 'root', { 'configurable': false, 'enumerable': false, 'get': function() { throw new ReferenceError; } }); } catch (e) {} /** Load QUnit and extras. */ var QUnit = root.QUnit || require('qunit-extras'); /** Load stable Lodash. */ var lodashStable = root.lodashStable; if (!lodashStable) { try { lodashStable = interopRequire('../node_modules/lodash/lodash.js'); } catch (e) { console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.'); return; } lodashStable = lodashStable.noConflict(); } /** The `lodash` function to test. */ var _ = root._ || (root._ = interopRequire(filePath)); /** Used to test pseudo private map caches. */ var mapCaches = (function() { var MapCache = _.memoize.Cache; var result = { 'Hash': new MapCache().__data__.hash.constructor, 'MapCache': MapCache }; _.isMatchWith({ 'a': 1 }, { 'a': 1 }, function() { var stack = lodashStable.last(arguments); result.ListCache = stack.__data__.constructor; result.Stack = stack.constructor; }); return result; }()); /** Used to detect instrumented istanbul code coverage runs. */ var coverage = root.__coverage__ || root[lodashStable.find(lodashStable.keys(root), function(key) { return /^(?:\$\$cov_\d+\$\$)$/.test(key); })]; /** Used to test async functions. */ var asyncFunc = lodashStable.attempt(function() { return Function('return async () => {}'); }); /** Used to test generator functions. */ var genFunc = lodashStable.attempt(function() { return Function('return function*(){}'); }); /** Used to restore the `_` reference. */ var oldDash = root._; /** * Used to check for problems removing whitespace. For a whitespace reference, * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js). */ var whitespace = lodashStable.filter([ // Basic whitespace characters. ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff', // Line terminators. '\n', '\r', '\u2028', '\u2029', // Unicode category "Zs" space separators. '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000' ], function(chr) { return /\s/.exec(chr); }) .join(''); /** * Creates a custom error object. * * @private * @constructor * @param {string} message The error message. */ function CustomError(message) { this.name = 'CustomError'; this.message = message; } CustomError.prototype = lodashStable.create(Error.prototype, { 'constructor': CustomError }); /** * Removes all own enumerable string keyed properties from a given object. * * @private * @param {Object} object The object to empty. */ function emptyObject(object) { lodashStable.forOwn(object, function(value, key, object) { delete object[key]; }); } /** * Extracts the unwrapped value from its wrapper. * * @private * @param {Object} wrapper The wrapper to unwrap. * @returns {*} Returns the unwrapped value. */ function getUnwrappedValue(wrapper) { var index = -1, actions = wrapper.__actions__, length = actions.length, result = wrapper.__wrapped__; while (++index < length) { var args = [result], action = actions[index]; push.apply(args, action.args); result = action.func.apply(action.thisArg, args); } return result; } /** * Loads the module of `id`. If the module has an `exports.default`, the * exported default value is returned as the resolved module. * * @private * @param {string} id The identifier of the module to resolve. * @returns {*} Returns the resolved module. */ function interopRequire(id) { var result = require(id); return 'default' in result ? result['default'] : result; } /** * Sets a non-enumerable property value on `object`. * * Note: This function is used to avoid a bug in older versions of V8 where * overwriting non-enumerable built-ins makes them enumerable. * See https://code.google.com/p/v8/issues/detail?id=1623 * * @private * @param {Object} object The object modify. * @param {string} key The name of the property to set. * @param {*} value The property value. */ function setProperty(object, key, value) { try { defineProperty(object, key, { 'configurable': true, 'enumerable': false, 'writable': true, 'value': value }); } catch (e) { object[key] = value; } return object; } /** * Skips a given number of tests with a passing result. * * @private * @param {Object} assert The QUnit assert object. * @param {number} [count=1] The number of tests to skip. */ function skipAssert(assert, count) { count || (count = 1); while (count--) { assert.ok(true, 'test skipped'); } } /** * Converts `array` to an `arguments` object. * * @private * @param {Array} array The array to convert. * @returns {Object} Returns the converted `arguments` object. */ function toArgs(array) { return (function() { return arguments; }.apply(undefined, array)); } /*--------------------------------------------------------------------------*/ // Add bizarro values. (function() { if (document || (typeof require != 'function')) { return; } var nativeString = fnToString.call(toString), reToString = /toString/g; function createToString(funcName) { return lodashStable.constant(nativeString.replace(reToString, funcName)); } // Allow bypassing native checks. setProperty(funcProto, 'toString', function wrapper() { setProperty(funcProto, 'toString', fnToString); var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this); setProperty(funcProto, 'toString', wrapper); return result; }); // Add prototype extensions. funcProto._method = noop; // Set bad shims. setProperty(Object, 'create', undefined); setProperty(Object, 'getOwnPropertySymbols', undefined); var _propertyIsEnumerable = objectProto.propertyIsEnumerable; setProperty(objectProto, 'propertyIsEnumerable', function(key) { return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); }); if (Buffer) { defineProperty(root, 'Buffer', { 'configurable': true, 'enumerable': true, 'get': function get() { var caller = get.caller, name = caller ? caller.name : ''; if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) { return Buffer; } } }); } if (Map) { setProperty(root, 'Map', (function() { var count = 0; return function() { if (count++) { return new Map; } setProperty(root, 'Map', Map); return {}; }; }())); setProperty(root.Map, 'toString', createToString('Map')); } setProperty(root, 'Promise', noop); setProperty(root, 'Set', noop); setProperty(root, 'Symbol', undefined); setProperty(root, 'WeakMap', noop); // Fake `WinRTError`. setProperty(root, 'WinRTError', Error); // Clear cache so lodash can be reloaded. emptyObject(require.cache); // Load lodash and expose it to the bad extensions/shims. lodashBizarro = interopRequire(filePath); root._ = oldDash; // Restore built-in methods. setProperty(Object, 'create', create); setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); setProperty(root, 'Buffer', Buffer); if (getSymbols) { Object.getOwnPropertySymbols = getSymbols; } else { delete Object.getOwnPropertySymbols; } if (Map) { setProperty(root, 'Map', Map); } else { delete root.Map; } if (Promise) { setProperty(root, 'Promise', Promise); } else { delete root.Promise; } if (Set) { setProperty(root, 'Set', Set); } else { delete root.Set; } if (Symbol) { setProperty(root, 'Symbol', Symbol); } else { delete root.Symbol; } if (WeakMap) { setProperty(root, 'WeakMap', WeakMap); } else { delete root.WeakMap; } delete root.WinRTError; delete funcProto._method; }()); // Add other realm values from the `vm` module. lodashStable.attempt(function() { lodashStable.assign(realm, require('vm').runInNewContext([ '(function() {', ' var noop = function() {},', ' root = this;', '', ' var object = {', " 'ArrayBuffer': root.ArrayBuffer,", " 'arguments': (function() { return arguments; }(1, 2, 3)),", " 'array': [1],", " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,", " 'boolean': Object(false),", " 'date': new Date,", " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],", " 'function': noop,", " 'map': root.Map ? new root.Map : undefined,", " 'nan': NaN,", " 'null': null,", " 'number': Object(0),", " 'object': { 'a': 1 },", " 'promise': root.Promise ? Promise.resolve(1) : undefined,", " 'regexp': /x/,", " 'set': root.Set ? new root.Set : undefined,", " 'string': Object('a'),", " 'symbol': root.Symbol ? root.Symbol() : undefined,", " 'undefined': undefined,", " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,", " 'weakSet': root.WeakSet ? new root.WeakSet : undefined", ' };', '', " ['" + arrayViews.join("', '") + "'].forEach(function(type) {", ' var Ctor = root[type]', ' object[type] = Ctor;', ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;', ' });', '', ' return object;', '}());' ].join('\n'))); }); // Add other realm values from an iframe. lodashStable.attempt(function() { _._realm = realm; var iframe = document.createElement('iframe'); iframe.frameBorder = iframe.height = iframe.width = 0; body.appendChild(iframe); var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc; idoc.write([ '<html>', '<body>', '<script>', 'var _ = parent._,', ' noop = function() {},', ' root = this;', '', 'var object = {', " 'ArrayBuffer': root.ArrayBuffer,", " 'arguments': (function() { return arguments; }(1, 2, 3)),", " 'array': [1],", " 'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,", " 'boolean': Object(false),", " 'date': new Date,", " 'element': document.body,", " 'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],", " 'function': noop,", " 'map': root.Map ? new root.Map : undefined,", " 'nan': NaN,", " 'null': null,", " 'number': Object(0),", " 'object': { 'a': 1 },", " 'promise': root.Promise ? Promise.resolve(1) : undefined,", " 'regexp': /x/,", " 'set': root.Set ? new root.Set : undefined,", " 'string': Object('a'),", " 'symbol': root.Symbol ? root.Symbol() : undefined,", " 'undefined': undefined,", " 'weakMap': root.WeakMap ? new root.WeakMap : undefined,", " 'weakSet': root.WeakSet ? new root.WeakSet : undefined", '};', '', "_.each(['" + arrayViews.join("', '") + "'], function(type) {", ' var Ctor = root[type];', ' object[type] = Ctor;', ' object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;', '});', '', '_.assign(_._realm, object);', '</script>', '</body>', '</html>' ].join('\n')); idoc.close(); delete _._realm; }); // Add a web worker. lodashStable.attempt(function() { var worker = new Worker('./asset/worker.js?t=' + (+new Date)); worker.addEventListener('message', function(e) { _._VERSION = e.data || ''; }, false); worker.postMessage(ui.buildPath); }); // Expose internal modules for better code coverage. lodashStable.attempt(function() { var path = require('path'), basePath = path.dirname(filePath); if (isModularize && !(amd || isNpm)) { lodashStable.each([ 'baseEach', 'isIndex', 'isIterateeCall', 'memoizeCapped' ], function(funcName) { _['_' + funcName] = interopRequire(path.join(basePath, '_' + funcName)); }); } }); /*--------------------------------------------------------------------------*/ if (params) { console.log('Running lodash tests.'); console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params))); } QUnit.module(basename); (function() { QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) { assert.expect(1); if (amd) { assert.strictEqual((lodashModule || {}).moduleName, 'lodash'); } else { skipAssert(assert); } }); QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) { assert.expect(1); if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) { assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed'); } else { skipAssert(assert); } }); QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) { assert.expect(1); if (amd) { assert.strictEqual((underscoreModule || {}).moduleName, 'underscore'); } else { skipAssert(assert); } }); QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) { assert.expect(1); var done = assert.async(); if (Worker) { var limit = 30000 / QUnit.config.asyncRetries, start = +new Date; var attempt = function() { var actual = _._VERSION; if ((new Date - start) < limit && typeof actual != 'string') { setTimeout(attempt, 16); return; } assert.strictEqual(actual, _.VERSION); done(); }; attempt(); } else { skipAssert(assert); done(); } }); QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) { assert.expect(1); if (lodashBizarro) { assert.notOk('_method' in lodashBizarro); } else { skipAssert(assert); } }); QUnit.test('should avoid non-native built-ins', function(assert) { assert.expect(6); function message(lodashMethod, nativeMethod) { return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`'; } function Foo() { this.a = 1; } Foo.prototype.b = 2; var object = { 'a': 1 }, otherObject = { 'b': 2 }, largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object)); if (lodashBizarro) { try { var actual = lodashBizarro.create(Foo.prototype); } catch (e) { actual = null; } var label = message('_.create', 'Object.create'); assert.ok(actual instanceof Foo, label); try { actual = [ lodashBizarro.difference([object, otherObject], largeArray), lodashBizarro.intersection(largeArray, [object]), lodashBizarro.uniq(largeArray) ]; } catch (e) { actual = null; } label = message('_.difference`, `_.intersection`, and `_.uniq', 'Map'); assert.deepEqual(actual, [[otherObject], [object], [object]], label); try { if (Symbol) { object[symbol] = {}; } actual = [ lodashBizarro.clone(object), lodashBizarro.cloneDeep(object) ]; } catch (e) { actual = null; } label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols'); assert.deepEqual(actual, [object, object], label); try { // Avoid buggy symbol detection in Babel's `_typeof` helper. var symObject = setProperty(Object(symbol), 'constructor', Object); actual = [ Symbol ? lodashBizarro.clone(symObject) : {}, Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false, Symbol ? lodashBizarro.toString(symObject) : '' ]; } catch (e) { actual = null; } label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol'); assert.deepEqual(actual, [{}, false, ''], label); try { var map = new lodashBizarro.memoize.Cache; actual = map.set('a', 1).get('a'); } catch (e) { actual = null; } label = message('_.memoize.Cache', 'Map'); assert.deepEqual(actual, 1, label); try { map = new (Map || Object); if (Symbol && Symbol.iterator) { map[Symbol.iterator] = null; } actual = lodashBizarro.toArray(map); } catch (e) { actual = null; } label = message('_.toArray', 'Map'); assert.deepEqual(actual, [], label); } else { skipAssert(assert, 6); } }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('isIndex'); (function() { var func = _._isIndex; QUnit.test('should return `true` for indexes', function(assert) { assert.expect(1); if (func) { var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]], expected = lodashStable.map(values, stubTrue); var actual = lodashStable.map(values, function(args) { return func.apply(undefined, args); }); assert.deepEqual(actual, expected); } else { skipAssert(assert); } }); QUnit.test('should return `false` for non-indexes', function(assert) { assert.expect(1); if (func) { var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]], expected = lodashStable.map(values, stubFalse); var actual = lodashStable.map(values, function(args) { return func.apply(undefined, args); }); assert.deepEqual(actual, expected); } else { skipAssert(assert); } }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('isIterateeCall'); (function() { var array = [1], func = _._isIterateeCall, object = { 'a': 1 }; QUnit.test('should return `true` for iteratee calls', function(assert) { assert.expect(3); function Foo() {} Foo.prototype.a = 1; if (func) { assert.strictEqual(func(1, 0, array), true); assert.strictEqual(func(1, 'a', object), true); assert.strictEqual(func(1, 'a', new Foo), true); } else { skipAssert(assert, 3); } }); QUnit.test('should return `false` for non-iteratee calls', function(assert) { assert.expect(4); if (func) { assert.strictEqual(func(2, 0, array), false); assert.strictEqual(func(1, 1.1, array), false); assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false); assert.strictEqual(func(1, 'b', object), false); } else { skipAssert(assert, 4); } }); QUnit.test('should work with `NaN` values', function(assert) { assert.expect(2); if (func) { assert.strictEqual(func(NaN, 0, [NaN]), true); assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true); } else { skipAssert(assert, 2); } }); QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) { assert.expect(1); if (func) { try { var actual = func(1, { 'toString': null }, [1]); } catch (e) { var message = e.message; } assert.strictEqual(actual, false, message || ''); } else { skipAssert(assert); } }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('map caches'); (function() { var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || noop]; var pairs = lodashStable.map(keys, function(key, index) { var lastIndex = keys.length - 1; return [key, keys[lastIndex - index]]; }); function createCaches(pairs) { var largeStack = new mapCaches.Stack(pairs), length = pairs ? pairs.length : 0; lodashStable.times(LARGE_ARRAY_SIZE - length, function() { largeStack.set({}, {}); }); return { 'hashes': new mapCaches.Hash(pairs), 'list caches': new mapCaches.ListCache(pairs), 'map caches': new mapCaches.MapCache(pairs), 'stack caches': new mapCaches.Stack(pairs), 'large stacks': largeStack }; } lodashStable.forOwn(createCaches(pairs), function(cache, kind) { var isLarge = /^large/.test(kind); QUnit.test('should implement a `Map` interface for ' + kind, function(assert) { assert.expect(83); lodashStable.each(keys, function(key, index) { var value = pairs[index][1]; assert.deepEqual(cache.get(key), value); assert.strictEqual(cache.has(key), true); assert.strictEqual(cache.delete(key), true); assert.strictEqual(cache.has(key), false); assert.strictEqual(cache.get(key), undefined); assert.strictEqual(cache.delete(key), false); assert.strictEqual(cache.set(key, value), cache); assert.strictEqual(cache.has(key), true); }); assert.strictEqual(cache.size, isLarge ? LARGE_ARRAY_SIZE : keys.length); assert.strictEqual(cache.clear(), undefined); assert.ok(lodashStable.every(keys, function(key) { return !cache.has(key); })); }); }); lodashStable.forOwn(createCaches(), function(cache, kind) { QUnit.test('should support changing values of ' + kind, function(assert) { assert.expect(10); lodashStable.each(keys, function(key) { cache.set(key, 1).set(key, 2); assert.strictEqual(cache.get(key), 2); }); }); }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash constructor'); (function() { var values = empties.concat(true, 1, 'a'), expected = lodashStable.map(values, stubTrue); QUnit.test('should create a new instance when called without the `new` operator', function(assert) { assert.expect(1); if (!isNpm) { var actual = lodashStable.map(values, function(value) { return _(value) instanceof _; }); assert.deepEqual(actual, expected); } else { skipAssert(assert); } }); QUnit.test('should return the given `lodash` instances', function(assert) { assert.expect(1); if (!isNpm) { var actual = lodashStable.map(values, function(value) { var wrapped = _(value); return _(wrapped) === wrapped; }); assert.deepEqual(actual, expected); } else { skipAssert(assert); } }); QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) { assert.expect(1); if (!isNpm && lodashBizarro) { var actual = lodashStable.map(values, function(value) { var wrapped = _(lodashBizarro(value)), unwrapped = wrapped.value(); return wrapped instanceof _ && ((unwrapped === value) || (unwrapped !== unwrapped && value !== value)); }); assert.deepEqual(actual, expected); } else { skipAssert(assert); } }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.add'); (function() { QUnit.test('should add two numbers', function(assert) { assert.expect(3); assert.strictEqual(_.add(6, 4), 10); assert.strictEqual(_.add(-6, 4), -2); assert.strictEqual(_.add(-6, -4), -10); }); QUnit.test('should not coerce arguments to numbers', function(assert) { assert.expect(2); assert.strictEqual(_.add('6', '4'), '64'); assert.strictEqual(_.add('x', 'y'), 'xy'); }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.after'); (function() { function after(n, times) { var count = 0; lodashStable.times(times, _.after(n, function() { count++; })); return count; } QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) { assert.expect(4); assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times'); assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times'); assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately'); assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once'); }); QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) { assert.expect(1); assert.strictEqual(after(NaN, 1), 1); }); QUnit.test('should use `this` binding of function', function(assert) { assert.expect(2); var after = _.after(1, function(assert) { return ++this.count; }), object = { 'after': after, 'count': 0 }; object.after(); assert.strictEqual(object.after(), 2); assert.strictEqual(object.count, 2); }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.ary'); (function() { function fn(a, b, c) { return slice.call(arguments); } QUnit.test('should cap the number of arguments provided to `func`', function(assert) { assert.expect(2); var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1)); assert.deepEqual(actual, [6, 8, 10]); var capped = _.ary(fn, 2); assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']); }); QUnit.test('should use `func.length` if `n` is not given', function(assert) { assert.expect(1); var capped = _.ary(fn); assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']); }); QUnit.test('should treat a negative `n` as `0`', function(assert) { assert.expect(1); var capped = _.ary(fn, -1); try { var actual = capped('a'); } catch (e) {} assert.deepEqual(actual, []); }); QUnit.test('should coerce `n` to an integer', function(assert) { assert.expect(1); var values = ['1', 1.6, 'xyz'], expected = [['a'], ['a'], []]; var actual = lodashStable.map(values, function(n) { var capped = _.ary(fn, n); return capped('a', 'b'); }); assert.deepEqual(actual, expected); }); QUnit.test('should not force a minimum argument count', function(assert) { assert.expect(1); var args = ['a', 'b', 'c'], capped = _.ary(fn, 3); var expected = lodashStable.map(args, function(arg, index) { return args.slice(0, index); }); var actual = lodashStable.map(expected, function(array) { return capped.apply(undefined, array); }); assert.deepEqual(actual, expected); }); QUnit.test('should use `this` binding of function', function(assert) { assert.expect(1); var capped = _.ary(function(a, b) { return this; }, 1), object = { 'capped': capped }; assert.strictEqual(object.capped(), object); }); QUnit.test('should use the existing `ary` if smaller', function(assert) { assert.expect(1); var capped = _.ary(_.ary(fn, 1), 2); assert.deepEqual(capped('a', 'b', 'c'), ['a']); }); QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) { assert.expect(1); var funcs = lodashStable.map([fn], _.ary), actual = funcs[0]('a', 'b', 'c'); assert.deepEqual(actual, ['a', 'b', 'c']); }); QUnit.test('should work when combined with other methods that use metadata', function(assert) { assert.expect(2); var array = ['a', 'b', 'c'], includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2); assert.strictEqual(includes('b')(array, 2), true); if (!isNpm) { includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value(); assert.strictEqual(includes('b')(array, 2), true); } else { skipAssert(assert); } }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.assignIn'); (function() { QUnit.test('should be aliased', function(assert) { assert.expect(1); assert.strictEqual(_.extend, _.assignIn); }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.assign and lodash.assignIn'); lodashStable.each(['assign', 'assignIn'], function(methodName) { var func = _[methodName]; QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) { assert.expect(1); assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 }); }); QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) { assert.expect(2); var expected = { 'a': 1, 'b': 2, 'c': 3 }; assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected); assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected); }); QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) { assert.expect(1); var expected = { 'a': 3, 'b': 2, 'c': 1 }; assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); }); QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) { assert.expect(1); var expected = { 'a': null, 'b': undefined, 'c': null }; assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected); }); QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) { assert.expect(1); var object = {}; var descriptor = { 'configurable': true, 'enumerable': true, 'set': function() { throw new Error; } }; var source = { 'a': 1, 'b': undefined, 'c': NaN, 'd': undefined, 'constructor': Object, 'toString': lodashStable.constant('source') }; defineProperty(object, 'a', lodashStable.assign({}, descriptor, { 'get': stubOne })); defineProperty(object, 'b', lodashStable.assign({}, descriptor, { 'get': noop })); defineProperty(object, 'c', lodashStable.assign({}, descriptor, { 'get': stubNaN })); defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, { 'get': lodashStable.constant(Object) })); try { var actual = func(object, source); } catch (e) {} assert.deepEqual(actual, source); }); QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) { assert.expect(1); var array = [1]; array[2] = 3; assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 }); }); QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) { assert.expect(1); function Foo() {} Foo.prototype.a = 1; assert.deepEqual(func({}, Foo.prototype), { 'a': 1 }); }); QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) { assert.expect(1); assert.deepEqual(func({}, 'a'), { '0': 'a' }); }); }); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.assignInWith'); (function() { QUnit.test('should be aliased', function(assert) { assert.expect(1); assert.strictEqual(_.extendWith, _.assignInWith); }); }()); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.assignWith and lodash.assignInWith'); lodashStable.each(['assignWith', 'assignInWith'], function(methodName) { var func = _[methodName]; QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) { assert.expect(1); var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) { return a === undefined ? b : a; }); assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 }); }); QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) { assert.expect(1); var expected = { 'a': 1 }; assert.deepEqual(func({}, expected, noop), expected); }); }); /*--------------------------------------------------------------------------*/ QUnit.module('lodash.at'); (function() { var array = ['a', 'b', 'c'], object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; QUnit.test('should return the elements corresponding to the specified keys', function(assert) { assert.expect(1); var actual = _.at(array, [0, 2]); assert.deepEqual(actual, ['a', 'c']); }); QUnit.test('should return `undefined` for nonexistent keys', function(assert) { assert.expect(1); var actual = _.at(array, [2, 4, 0]); assert.deepEqual(actual, ['c', undefined, 'a']); }); QUnit.test('should work with non-index keys on array values', function(assert) { assert.expect(1); var values = lodashStable.reject(empties, function(value) { return (value === 0) || lodashStable.isArray(value); }).concat(-1, 1.1); var array = lodashStable.transform(values, function(result, value) { result[value] = 1; }, []); var expected = lodashStable.map(values, stubOne), actual = _.at(array, values); assert.deepEqual(actual, expected); }); QUnit.test('should return an empty array when no keys are given', function(assert) { assert.expect(2); assert.deepEqual(_.at(array), []); assert.deepEqual(_.at(array, [], []), []); }); QUnit.test('should accept multiple key arguments', function(assert) { assert.expect(1); var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2); assert.deepEqual(actual, ['d', 'a', 'c']); }); QUnit.test('should work with a falsey `object` when keys are given', function(assert) { assert.expect(1); var expected = lodashStable.map(falsey, lodashStable.constant(Array(4))); var actual = lodashStable.map(falsey, function(object) { try { return _.at(object, 0, 1, 'pop', 'push'); } catch (e) {} }); assert.deepEqual(actual, expected); }); QUnit.test('should work with an `arguments` object for `object`', function(assert) { assert.expect(1); var actual = _.at(args, [2, 0]); assert.deepEqual(actual, [3, 1]); }); QUnit.test('should work with `arguments` object as secondary arguments', function(assert) { assert.expect(1); var actual = _.at([1, 2, 3, 4, 5], args); assert.deepEqual(actual, [2, 3, 4]); }); QUnit.test('should work with an object for `object`', function(assert) { assert.expect(1); var actual = _.at(object, ['a[0].b.c', 'a[1]']); assert.deepEqual(actual, [3, 4]); }); QUnit.test('should pluck inherited property values', function(assert) { assert.expect(1); function Foo() { this.a = 1; } Foo.prototype.b = 2; var actual = _.at(new Foo, 'b'); assert.deepEqual(actual, [2]); }); QUnit.test('should work in a lazy sequence', function(assert) { assert.expect(6);