;(function() { /** Used as a safe reference for `undefined` in pre ES5 environments */ var undefined; /** Used as the size when optimizations are enabled for arrays */ var LARGE_ARRAY_SIZE = 75; /** Used as a reference to the global object */ var root = typeof global == 'object' && global || this; /** Used to store Lo-Dash to test for bad extensions/shims */ var lodashBizarro = root.lodashBizarro; /** Method and object shortcuts */ var phantom = root.phantom, amd = root.define && define.amd, argv = root.process && process.argv, document = !phantom && root.document, body = root.document && root.document.body, create = Object.create, freeze = Object.freeze, noop = function() {}, params = root.arguments, push = Array.prototype.push, slice = Array.prototype.slice, system = root.system, toString = Object.prototype.toString, Worker = document && root.Worker; /** The file path of the Lo-Dash file to test */ var filePath = (function() { var min = 0, result = []; if (phantom) { result = params = phantom.args; } else if (system) { min = 1; result = params = system.args; } else if (argv) { min = 2; result = params = argv; } else if (params) { result = params; } var last = result[result.length - 1]; result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js'; if (!amd) { try { return require('fs').realpathSync(result); } catch(e) { } } return result; }()); /** Detect if running in Java */ var isJava = !document && !!root.java; /** Detects if running in a PhantomJS web page */ var isPhantomPage = typeof callPhantom == 'function'; /** Detect if running in Rhino */ var isRhino = isJava && typeof global == 'function' && global().Array === root.Array; /** Use a single "load" function */ var load = (typeof require == 'function' && !amd) ? require : (isJava && root.load) || noop; /** The unit testing framework */ var QUnit = (function() { return root.QUnit || ( root.addEventListener || (root.addEventListener = noop), root.setTimeout || (root.setTimeout = noop), root.QUnit = load('../vendor/qunit/qunit/qunit.js') || root.QUnit, addEventListener === noop && delete root.addEventListener, root.QUnit ); }()); /** Load and install QUnit Extras */ var qa = load('../vendor/qunit-extras/qunit-extras.js'); if (qa) { qa.runInContext(root); } /*--------------------------------------------------------------------------*/ // log params provided to `test.js` if (params) { console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params))); } // exit early if going to run tests in a PhantomJS web page if (phantom && isModularize) { var page = require('webpage').create(); page.open(filePath, function(status) { if (status != 'success') { console.log('PhantomJS failed to load page: ' + filePath); phantom.exit(1); } }); 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); }); }); }); }; return; } /*--------------------------------------------------------------------------*/ /** The `lodash` function to test */ var _ = root._ || (root._ = ( _ = load(filePath) || root._, _ = _._ || _, (_.runInContext ? _.runInContext(root) : _) )); try { filePath = require.resolve(filePath); } catch(e) { } /** The `ui` object */ var ui = root.ui || (root.ui = { 'buildPath': filePath, 'loaderPath': '', 'urlParams': {} }); /** The basename of the Lo-Dash file to test */ var basename = _.result(/[\w.-]+$/.exec(filePath), 0, ''); /** Used to pass falsey values to methods */ var falsey = [, '', 0, false, NaN, null, undefined]; /** Used to pass empty values to methods */ var empties = [[], {}].concat(falsey.slice(1)); /** Used as the property name for wrapper metadata */ var expando = '__lodash@' + _.VERSION + '__'; /** Used to set property descriptors */ var defineProperty = (function() { try { var o = {}, func = Object.defineProperty, result = func(o, o, o) && func; } catch(e) { } return result; }()); /** Used to indicate testing a modularized build */ var isModularize = ui.isModularize || /\b(?:commonjs|(index|main)\.js|lodash-(?:amd|node)|modularize|npm)\b/.test([ui.buildPath, ui.urlParams.build, basename]); /** Detect if testing `npm` modules */ var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]); /** Used to check problem JScript properties (a.k.a. the [[DontEnum]] bug) */ var shadowedProps = [ 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf' ]; /** Used to check problem JScript properties too */ var shadowedObject = _.invert(shadowedProps); /** Used to check for problems removing whitespace */ var whitespace = ' \t\x0B\f\xA0\ufeff\n\r\u2028\u2029\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'; /** * Removes all own enumerable properties from a given object. * * @private * @param {Object} object The object to empty. */ function emptyObject(object) { _.forOwn(object, function(value, key, object) { delete object[key]; }); } /** * 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 augment. * @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; } } /** * Skips a given number of tests with a passing result. * * @private * @param {number} [count=1] The number of tests to skip. */ function skipTest(count) { count || (count = 1); while (count--) { ok(true, 'test skipped'); } } /*--------------------------------------------------------------------------*/ // setup values for Node.js (function() { if (amd) { return; } try { // add values from a different realm _.extend(_, require('vm').runInNewContext([ '({', "'_arguments': (function() { return arguments; }(1, 2, 3)),", "'_array': [1, 2, 3],", "'_boolean': new Boolean(false),", "'_date': new Date,", "'_function': function() {},", "'_nan': NaN,", "'_null': null,", "'_number': new Number(0),", "'_object': { 'a': 1, 'b': 2, 'c': 3 },", "'_regexp': /x/,", "'_string': new String('a'),", "'_undefined': undefined,", '})' ].join('\n'))); } catch(e) { return; } // load ES6 Set shim require('./asset/set'); // expose `baseEach` for better code coverage if (isModularize && !isNpm) { var path = require('path'), baseEach = require(path.join(path.dirname(filePath), 'internals', 'baseEach.js')); _._baseEach = baseEach.baseEach || baseEach; } // allow bypassing native checks var _fnToString = Function.prototype.toString; setProperty(Function.prototype, 'toString', (function() { function fnToString() { setProperty(Function.prototype, 'toString', _fnToString); var result = this === Set ? this.toString() : _fnToString.call(this); setProperty(Function.prototype, 'toString', fnToString); return result; } return fnToString; }())); // fake DOM setProperty(global, 'window', {}); setProperty(global.window, 'document', {}); setProperty(global.window.document, 'createDocumentFragment', function() { return { 'nodeType': 11 }; }); // fake `WinRTError` setProperty(global, 'WinRTError', Error); // add extensions Function.prototype._method = function() {}; // set bad shims var _isArray = Array.isArray; setProperty(Array, 'isArray', function() {}); var _now = Date.now; setProperty(Date, 'now', function() {}); var _create = Object.create; setProperty(Object, 'create', function() {}); var _defineProperty = Object.defineProperty; setProperty(Object, 'defineProperty', function() {}); var _getPrototypeOf = Object.getPrototypeOf; setProperty(Object, 'getPrototypeOf', function() {}); var _keys = Object.keys; setProperty(Object, 'keys', function() {}); var _contains = String.prototype.contains; setProperty(String.prototype, 'contains', _contains ? function() {} : Boolean); var _trim = String.prototype.trim; setProperty(String.prototype, 'trim', _trim ? function() {} : String); var _trimLeft = String.prototype.trimLeft; setProperty(String.prototype, 'trimLeft', _trimLeft ? function() {} : String); var _trimRight = String.prototype.trimRight; setProperty(String.prototype, 'trimRight', _trimRight ? function() {} : String); // clear cache so Lo-Dash can be reloaded emptyObject(require.cache); // load Lo-Dash and expose it to the bad extensions/shims lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro; // restore native methods setProperty(Array, 'isArray', _isArray); setProperty(Date, 'now', _now); setProperty(Object, 'create', _create); setProperty(Object, 'defineProperty', _defineProperty); setProperty(Object, 'getPrototypeOf', _getPrototypeOf); setProperty(Object, 'keys', _keys); setProperty(Function.prototype, 'toString', _fnToString); _.forOwn({ 'contains': _contains, 'trim': _trim, 'trimLeft': _trimLeft, 'trimRight': _trimRight }, function(func, key) { if (func) { setProperty(String.prototype, key, func); } else { delete String.prototype[key]; } }); delete global.window; delete global.WinRTError; delete Function.prototype._method; }()); // add values from an iframe (function() { if (_._object || !document) { return; } 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([ '