### Configure Modular Script Loading with RequireJS/curl Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/backbone.html Sets up configuration for modular loaders like RequireJS or curl. It defines base URLs, path aliases for libraries like Backbone and jQuery, and packages for test modules. The configuration adapts based on whether the environment is modularized, ensuring correct loading of Underscore/Lodash and other test dependencies before starting QUnit. ```JavaScript (function() { if (window.curl) { curl.config({ 'apiName': 'require' }); } if (!window.require) { return; } var reBasename = /[\w.-]+$/, basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''), modulePath = ui.buildPath.replace(/\.js$/, ''), locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''), moduleMain = modulePath.match(reBasename)[0], uid = +new Date; function getConfig() { var result = { 'baseUrl': './', 'urlArgs': 't=' + uid++, 'waitSeconds': 0, 'paths': { 'backbone': '../vendor/backbone/backbone', 'jquery': '../node_modules/jquery/dist/jquery' }, 'packages': [{ 'name': 'test', 'location': '../vendor/backbone/test', 'config': { // Work around no global being exported. 'exports': 'QUnit', 'loader': 'curl/loader/legacy' } }] }; if (ui.isModularize) { result.packages.push({ 'name': 'underscore', 'location': locationPath, 'main': moduleMain }); } else { result.paths.underscore = modulePath; } return result; } QUnit.config.autostart = false; require(getConfig(), ['underscore'], function(lodash) { _ = mixinPrereqs(lodash); require(getConfig(), ['backbone'], function() { require(getConfig(), [ 'test/setup/dom-setup', 'test/setup/environment', 'test/noconflict', 'test/events', 'test/model', 'test/collection', 'test/router', 'test/view', 'test/sync' ], QUnit.start); }); }); }()); ``` -------------------------------- ### JavaScript: Load and Start QUnit Tests Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html The `loadTests` function is a utility that leverages the module loader configuration generated by `getConfig`. Its primary role is to load the 'test' module (which is configured to export QUnit) and then immediately initiate the QUnit test runner by calling `QUnit.start()`, beginning the execution of defined tests. ```JavaScript function loadTests() { require(getConfig(), ['test'], function() { QUnit.start(); }); } ``` -------------------------------- ### JavaScript Performance Suite Initialization and Script Loading Source: https://github.com/alisonzxq/zxqhelper/blob/main/perf/index.html This JavaScript snippet handles the dynamic loading of external scripts, reassigns the lodash variable to prevent conflicts, and initializes the performance suite. It includes logic to adjust the height of a Firebug UI element based on window dimensions and ensures the performance run starts after the UI is ready. ```javascript document.write(' ``` -------------------------------- ### JavaScript: Define Module Loader Configuration Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html This function, `getConfig`, dynamically creates a configuration object for module loaders like RequireJS or curl. It sets base URLs, cache-busting arguments, and timeout values. Crucially, it defines 'paths' and 'packages' for various modules ('test', 'lodash', 'shimmed', 'underscore'), adapting their locations based on whether the environment is modularized (`ui.isModularize`). ```JavaScript function getConfig() { var result = { 'baseUrl': './', 'urlArgs': 't=' + uid++, 'waitSeconds': 0, 'paths': {}, 'packages': [{ 'name': 'test', 'location': basePath + 'test', 'main': 'test', 'config': { // Work around no global being exported. 'exports': 'QUnit', 'loader': 'curl/loader/legacy' } }] }; if (ui.isModularize) { result.packages.push({ 'name': 'lodash', 'location': locationPath, 'main': moduleMain }, { 'name': 'shimmed', 'location': shimmedLocationPath, 'main': moduleMain }, { 'name': 'underscore', 'location': underscoreLocationPath, 'main': moduleMain }); } else { result.paths.lodash = modulePath; result.paths.shimmed = shimmedLocationPath + '/' + moduleMain; result.paths.underscore = underscoreLocationPath + '/' + moduleMain; } return result; } ``` -------------------------------- ### CSS Styling for Performance Toolbar and Firebug UI Source: https://github.com/alisonzxq/zxqhelper/blob/main/perf/index.html Defines the foundational CSS for the HTML body, a Firebug-like UI element, and a performance toolbar. It sets margins, padding, height, background, font styles, and layout properties for various UI components to ensure proper display and overflow handling. ```css html, body { margin: 0; padding: 0; height: 100%; } #FirebugUI { top: 2.5em; } #perf-toolbar { background-color: #EEE; color: #5E740B; font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; font-size: small; padding: 0.5em 1em 0.5em 1em; overflow: hidden; } #perf-toolbar label { display: inline-block; margin-right: 0.5em; } #perf-toolbar span { display: inline-block; float: right; line-height: 2.1em; margin-left: 1em; margin-top: 0; } ``` -------------------------------- ### Configure Curl Module Loader API Name Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html Configures the `curl` module loader's API name to 'require' if the `window.curl` object is available. This is part of the setup for how modules are loaded within the test environment. ```JavaScript if (window.curl) { curl.config({ 'apiName': 'require' }); } ``` -------------------------------- ### JavaScript: Orchestrate Module Loading and Test Execution Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html The `loadModulesAndTests` function manages the loading of core modules ('lodash', 'shimmed', 'underscore') using the configured module loader. It assigns these loaded modules to global variables and handles their `noConflict` methods if available. Depending on the `ui.isModularize` flag, it conditionally loads additional internal Lodash modules before finally invoking `loadTests()` to begin the QUnit test suite. ```JavaScript function loadModulesAndTests() { require(getConfig(), ['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) { lodashModule = lodash; lodashModule.moduleName = 'lodash'; if (shimmed) { shimmedModule = shimmed.result(shimmed, 'noConflict') || shimmed; shimmedModule.moduleName = 'shimmed'; } if (underscore) { underscoreModule = underscore.result(underscore, 'noConflict') || underscore; underscoreModule.moduleName = 'underscore'; } window._ = lodash; if (ui.isModularize) { require(getConfig(), [ 'lodash/_baseEach', 'lodash/_isIndex', 'lodash/_isIterateeCall' ], function(baseEach, isIndex, isIterateeCall) { lodash._baseEach = baseEach; lodash._isIndex = isIndex; lodash._isIterateeCall = isIterateeCall; loadTests(); }); } else { loadTests(); } }); } ``` -------------------------------- ### Mixin Lodash Utilities into Underscore/Backbone Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/backbone.html Defines a self-executing function `mixinPrereqs` that extends the Underscore/Lodash object (used by Backbone) with various utility methods and aliases. It handles conflicts by using `_.noConflict()` and ensures compatibility by mapping aliases and picking specific functions from Lodash to be mixed in. ```JavaScript var mixinPrereqs = (function() { var aliasToReal = { 'indexBy': 'keyBy', 'invoke': 'invokeMap' }; var keyMap = { 'rest': 'tail' }; var lodash = _.noConflict(); return function(_) { lodash(_) .defaultsDeep({ 'templateSettings': lodash.templateSettings }) .mixin(lodash.pick(lodash, lodash.difference([ 'countBy', 'debounce', 'difference', 'find', 'findIndex', 'findLastIndex', 'groupBy', 'includes', 'invert', 'invokeMap', 'keyBy', 'omit', 'partition', 'reduceRight', 'reject', 'sample', 'without' ], lodash.functions(_)))) .value(); lodash.forOwn(keyMap, function(realName, otherName) { _[otherName] = lodash[realName]; _.prototype[otherName] = lodash.prototype[realName]; }); lodash.forOwn(aliasToReal, function(realName, alias) { _[alias] = _[realName]; _.prototype[alias] = _.prototype[realName]; }); return _; }; }()); ``` -------------------------------- ### Configure Global Error Handling for Test Suite Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/backbone.html Sets up a global error handler to prevent test results from being reported to Sauce Labs when script errors occur, specifically when running on port 9001. It also clears QUnit's 'done' callbacks and stores the error message for debugging. Additionally, it configures QUnit for async retries and to hide passed tests. ```JavaScript if (location.port == '9001') { window.onerror = function(message) { if (window.QUnit) { QUnit.config.done.length = 0; } global_test_results = { 'message': message }; }; } QUnit.config.asyncRetries = 10; QUnit.config.hidepassed = true; ``` -------------------------------- ### Configure Error Reporting for lodash-fp QUnit Tests Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/fp.html This JavaScript snippet sets up a global error handler (window.onerror) to prevent test results from being reported to Sauce Labs when script errors occur, specifically if the application is running on port 9001. It clears QUnit's done callbacks and stores the error message. ```javascript if (location.port == '9001') { window.onerror = function(message) { if (window.QUnit) { QUnit.config.done.length = 0; } global_test_results = { 'message': message }; }; } ``` -------------------------------- ### Shim Native Browser APIs and Globals for Testing Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html The `addBizarroMethods` function modifies various native JavaScript objects and browser APIs (like `Object.create`, `Map`, `Promise`, `Symbol`, `global`, `exports`) to introduce non-standard or faked behaviors. This is crucial for testing how the Lodash library behaves under unusual or shimmed environments, ensuring its robustness and compatibility. ```JavaScript function addBizarroMethods() { var funcProto = Function.prototype, objectProto = Object.prototype; var hasOwnProperty = objectProto.hasOwnProperty, fnToString = funcProto.toString, nativeString = fnToString.call(objectProto.toString), noop = function() {}, propertyIsEnumerable = objectProto.propertyIsEnumerable, reToString = /toString/g; function constant(value) { return function() { return value; }; } function createToString(funcName) { return constant(nativeString.replace(reToString, funcName)); } // Allow bypassing native checks. setProperty(funcProto, 'toString', (function() { function wrapper() { setProperty(funcProto, 'toString', fnToString); var result = hasOwnProperty.call(this, 'toString') ? this.toString() : fnToString.call(this); setProperty(funcProto, 'toString', wrapper); return result; } return wrapper; }())); // Add prototype extensions. funcProto._method = noop; // Set bad shims. setProperty(Object, '_create', Object.create); setProperty(Object, 'create', undefined); setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols); setProperty(Object, 'getOwnPropertySymbols', undefined); setProperty(objectProto, '_propertyIsEnumerable', propertyIsEnumerable); setProperty(objectProto, 'propertyIsEnumerable', function(key) { return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); }); setProperty(window, '_Map', window.Map); if (_Map) { setProperty(window, 'Map', (function(Map) { var count = 0; return function() { if (count++) { return new Map; } var result = {}; setProperty(window, 'Map', Map); return result; }; }(_Map))); setProperty(Map, 'toString', createToString('Map')); } setProperty(window, '_Promise', window.Promise); setProperty(window, 'Promise', noop); setProperty(window, '_Set', window.Set); setProperty(window, 'Set', noop); setProperty(window, '_Symbol', window.Symbol); setProperty(window, 'Symbol', undefined); setProperty(window, '_WeakMap', window.WeakMap); setProperty(window, 'WeakMap', noop); // Fake `WinRTError`. setProperty(window, 'WinRTError', Error); // Fake free variable `global`. setProperty(window, 'exports', window); setProperty(window, 'global', window); setProperty(window, 'module', {}); } ``` -------------------------------- ### Restore Native Browser APIs and Globals After Testing Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html The `removeBizarroMethods` function reverts the changes made by `addBizarroMethods`. It restores native browser APIs and global objects to their original state or deletes the faked properties, ensuring a clean environment after the tests that require shims are completed. ```JavaScript function removeBizarroMethods() { var funcProto = Function.prototype, objectProto = Object.prototype; setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable); if (Object._create) { Object.create = Object._create; } else { delete Object.create; } if (Object._getOwnPropertySymbols) { Object.getOwnPropertySymbols = Object._getOwnPropertySymbols; } else { delete Object.getOwnPropertySymbols; } if (_Map) { Map = _Map; } else { setProperty(window, 'Map', undefined); } if (_Promise) { Promise = _Promise; } else { setProperty(window, 'Promise', undefined); } if (_Set) { Set = _Set; } else { setProperty(window, 'Set', undefined); } if (_Symbol) { Symbol = _Symbol; } if (_WeakMap) { WeakMap = _WeakMap; } else { setProperty(window, 'WeakMap', undefined); } setProperty(window, '_Map', undefined); setProperty(window, '_Promise', undefined); setProperty(window, '_Set', undefined); setProperty(window, '_Symbol', undefined); setProperty(window, '_WeakMap', undefined); setProperty(window, 'WinRTError', undefined); setProperty(window, 'exports', document.getElementById('exports')); setProperty(window, 'global', undefined); setProperty(window, 'module', document.getElementById('module')); delete funcProto._method; delete Object._create; delete Object._getOwnPropertySymbols; delete objectProto._propertyIsEnumerable; } ``` -------------------------------- ### Configure Global Error Handler for Test Suite Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html Sets up a global error handler for the test suite when running on port 9001. This handler prevents test results from being reported to Sauce Labs in case of script errors and captures the error message in a global variable `global_test_results`. ```JavaScript if (location.port == '9001') { window.onerror = function(message) { if (window.QUnit) { QUnit.config.done.length = 0; } global_test_results = { 'message': message }; }; } ``` -------------------------------- ### JavaScript: Update QUnit User Agent Display Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html This `window.onload` event handler is responsible for enhancing the readability of the QUnit test runner's user agent display. It uses a `setInterval` to repeatedly check for the presence of the 'qunit-userAgent' HTML element. Once found, it updates its `innerHTML` with a more descriptive `platform` string and clears the interval, ensuring the display is updated as soon as the element is available. ```JavaScript window.onload = function() { var timeoutId = setInterval(function() { var ua = document.getElementById('qunit-userAgent'); if (ua) { ua.innerHTML = platform; clearInterval(timeoutId); } }, 16); }; ``` -------------------------------- ### Utility Function to Set Object Properties Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/index.html A helper function `setProperty` that attempts to define a property on an object using `Object.defineProperty` with specific attributes (configurable, non-enumerable, writable). If `defineProperty` fails (e.g., in older environments or strict mode issues), it falls back to direct property assignment. ```JavaScript function setProperty(object, key, value) { try { Object.defineProperty(object, key, { 'configurable': true, 'enumerable': false, 'writable': true, 'value': value }); } catch (e) { object[key] = value; } return object; } ``` -------------------------------- ### Configure QUnit and Load Test Modules Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/underscore.html This snippet configures QUnit's autostart to false and sets specific functions and utilities as 'excused' to prevent test failures. It then leverages a `require` function to load a primary module (inferred to be Lodash) and subsequently loads multiple test modules (collections, arrays, functions, objects, cross-document, utility, chaining), finally calling `QUnit.start` to begin the tests. ```JavaScript leMain }); } else { result.paths[moduleId] = modulePath; } return result; } QUnit.config.autostart = false; QUnit.config.excused.Functions.iteratee = true; QUnit.config.excused.Utility.noConflict = true; QUnit.config.excused.Utility['noConflict (node vm)'] = true; require(getConfig(), [moduleId], function(lodash) { _ = mixinPrereqs(lodash); require(getConfig(), [ 'test/collections', 'test/arrays', 'test/functions', 'test/objects', 'test/cross-document', 'test/utility', 'test/chaining' ], QUnit.start); }); }()); ``` -------------------------------- ### Configure Module Loader Paths and Packages Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/underscore.html This JavaScript function, 'getConfig', generates a configuration object suitable for module loaders such as RequireJS or curl. It sets essential parameters like 'baseUrl', 'urlArgs' for cache busting, 'waitSeconds', and defines 'paths' and 'packages'. Notably, it includes a package for QUnit tests and the main library module, adapting to whether the library is modularized. Note: The provided source text for this function appears truncated. ```javascript function getConfig() { var result = { 'baseUrl': './', 'urlArgs': 't=' + uid++, 'waitSeconds': 0, 'paths': {}, 'packages': [{ 'name': 'test', 'location': '../vendor/underscore/test', 'config': { // Work around no global being exported. 'exports': 'QUnit', 'loader': 'curl/loader/legacy' } }] }; if (ui.isModularize) { result.packages.push({ 'name': moduleId, 'location': locationPath, 'main': modu }); } return result; } ``` -------------------------------- ### Build Lodash using lodash-cli Source: https://github.com/alisonzxq/zxqhelper/blob/main/README.md This snippet shows the shell commands used to build Lodash from source using the `lodash-cli` tool. It demonstrates how to generate the full build and a core build, outputting them to specified distribution paths. ```shell $ npm run build $ lodash -o ./dist/lodash.js $ lodash core -o ./dist/lodash.core.js ``` -------------------------------- ### Wrap Node.js 'require' for Browser Compatibility Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/underscore.html This JavaScript snippet redefines the global 'require' function to ensure compatibility with tests designed for Node.js environments when run in a browser. It specifically handles the '..' path, redirecting it to return the global '_' object, which is likely the main library being tested. ```javascript (function() { if (window.curl) { curl.config({ 'apiName': 'require' }); } if (!window.require) { return; } // Wrap to work around tests assuming Node `require` use. require = (function(func) { return function() { return arguments[0] === '..' ? window._ : func.apply(null, arguments); }; }(require)); ``` -------------------------------- ### Dynamically Load Test Scripts Based on Loader Type Source: https://github.com/alisonzxq/zxqhelper/blob/main/test/underscore.html This JavaScript code dynamically loads test scripts into the HTML document. It checks the 'loader' URL parameter: if set to 'none', it loads a single build script followed by a series of Underscore.js test files. Otherwise, it loads a modular loader (e.g., curl) for asynchronous script loading. ```javascript document.write(ui.urlParams.loader == 'none' ? '