From ad03d2972deba18a7a214324fbd73cb14bbe0d79 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Tue, 28 Jul 2020 14:11:00 -0700 Subject: [PATCH] build UMD bundle and polyfill language features (#4366) - use rollup's `umd` bundle instead of `iife` - consume Rollup config's `output` prop in `karma-rollup-plugin` - simplify `rollup.config.js` `output` prop - fix invalid `script` tag `src` attrib in `lib/browser/template.html` (& reformat) - use core-js polyfills - remove old ESlint rule to disallow `Object.assign` (it's now allowed... but so is object rest/spread, which works in many cases) - fix travis script - karma-related: - update Symbol test for IE11, as the polyfill is just a polyfill. - add a proper RequireJS integration test - remove the old `bundle/amd.spec.js` test - try to make `karma.conf.js` less intimidating - allow custom externals/globals in karma rollup plugin - `unexpected`, `unexpected-eventemitter`, and `unexpected-sinon` are now external (not bundled) and loaded via their globals - modified `test/browser-specific/setup.js` to use `require()` since we can do that now - bundle now has an inline source map since I couldn't figure out any other way to load it - removed duplication of work in the karma plugin; no call to `bundle.generate()` is needed. furthermore the `code` prop did not include the inline source maps. so we just write the file and read the result. could probably avoid reading the file by manually stitching the `code` and `map` props together, but I'm unsure how - loads `mocha.js.map` for debugging --- .eslintrc.yml | 5 - .travis.yml | 2 +- browser-entry.js | 6 +- karma.conf.js | 414 ++++++++++++------ lib/browser/template.html | 12 +- package-lock.json | 282 ++++++------ package-scripts.js | 16 +- package.json | 3 + rollup.config.js | 35 +- scripts/karma-rollup-plugin.js | 49 ++- .../fixtures/requirejs/lib.fixture.js | 3 + .../fixtures/requirejs/main.fixture.js | 9 + test/browser-specific/requirejs-setup.js | 17 + test/browser-specific/setup.js | 6 +- test/bundle/amd.spec.js | 16 - test/unit/utils.spec.js | 6 +- 16 files changed, 546 insertions(+), 335 deletions(-) create mode 100644 test/browser-specific/fixtures/requirejs/lib.fixture.js create mode 100644 test/browser-specific/fixtures/requirejs/main.fixture.js create mode 100644 test/browser-specific/requirejs-setup.js delete mode 100644 test/bundle/amd.spec.js diff --git a/.eslintrc.yml b/.eslintrc.yml index ee6c65f773..2e30c5e3e2 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -15,11 +15,6 @@ rules: strict: - error - safe - # disallow Object.assign - no-restricted-properties: - - error - - object: 'Object' - property: 'assign' overrides: - files: - 'docs/js/**/*.js' diff --git a/.travis.yml b/.travis.yml index ca2131eb66..adcf866c6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,7 @@ jobs: node_js: '10' name: 'Node.js v10' - - script: npm start test.bundle test.browser + - script: npm start test.browser name: 'Browser' node_js: 12 install: npm ci # we need the native modules here diff --git a/browser-entry.js b/browser-entry.js index d5e3717c79..cdcb56b6fb 100644 --- a/browser-entry.js +++ b/browser-entry.js @@ -210,10 +210,10 @@ Mocha.process = process; * Expose mocha. */ -global.Mocha = Mocha; -global.mocha = mocha; +mocha.Mocha = Mocha; +mocha.mocha = mocha; // this allows test/acceptance/required-tokens.js to pass; thus, // you can now do `const describe = require('mocha').describe` in a // browser context (assuming browserification). should fix #880 -module.exports = global; +module.exports = Object.assign(mocha, global); diff --git a/karma.conf.js b/karma.conf.js index ac65e5a578..785172061b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,14 +1,35 @@ -'use strict'; +/** + * Mocha's Karma config. + * + * IMPORTANT: + * - Karma must _always_ be run with `NODE_PATH=.` where `.` is the project + * root; this allows `karma-mocha` to use our built version of Mocha + * - You must build Mocha's browser bundle before running Karma. This is + * typically done automatically in `package-scripts.js`. + * + * There are actually several different configurations here depending on the + * values of various environment variables (e.g., `MOCHA_TEST`, `CI`, etc.), + * which is why it's so hairy. + * + * This code avoids mutating the configuration object (the `cfg` variable) + * directly; instead, we create new objects/arrays. This makes it a little more + * obvious what's happening, even though it's verbose. + * + * The main export is a function which Karma calls with a config object; the + * final line of this function should be `config.set(cfg)` which registers the + * configuration we've built. + */ +'use strict'; const fs = require('fs'); const path = require('path'); const os = require('os'); const rollupPlugin = require('./scripts/karma-rollup-plugin'); -const baseBundleDirpath = path.join(__dirname, '.karma'); - +const BASE_BUNDLE_DIR_PATH = path.join(__dirname, '.karma'); +const env = process.env; const hostname = os.hostname(); -const browserPlatformPairs = { +const SAUCE_BROWSER_PLATFORM_MAP = { 'chrome@latest': 'Windows 10', 'MicrosoftEdge@latest': 'Windows 10', 'internet explorer@latest': 'Windows 10', @@ -16,57 +37,58 @@ const browserPlatformPairs = { 'safari@latest': 'macOS 10.13' }; -module.exports = config => { - let bundleDirpath; - const cfg = { - frameworks: ['rollup', 'mocha'], - files: [ - // we use the BDD interface for all of the tests that - // aren't interface-specific. - 'test/unit/*.spec.js' - ], - plugins: [ - 'karma-mocha', - 'karma-mocha-reporter', - 'karma-sauce-launcher', - 'karma-chrome-launcher', - rollupPlugin - ], - rollup: { - configFile: 'rollup.config.js', - include: ['test/**'], - bundlePath: bundleDirpath - }, - reporters: ['mocha'], - colors: true, - browsers: ['ChromeHeadless'], - logLevel: config.LOG_INFO, - client: { - mocha: { - reporter: 'html' - } - }, - mochaReporter: { - showDiff: true - }, - customLaunchers: { - ChromeDebug: { - base: 'Chrome', - flags: ['--remote-debugging-port=9333'] - } +const baseConfig = { + frameworks: ['rollup', 'mocha'], + files: [ + // we use the BDD interface for all of the tests that + // aren't interface-specific. + 'test/unit/*.spec.js' + ], + plugins: [ + 'karma-mocha', + 'karma-mocha-reporter', + 'karma-sauce-launcher', + 'karma-chrome-launcher', + rollupPlugin + ], + rollup: { + configFile: 'rollup.config.js', + include: ['test/**'] + }, + reporters: ['mocha'], + colors: true, + browsers: ['ChromeHeadless'], + client: { + mocha: { + // this helps debug + reporter: 'html' } - }; + }, + mochaReporter: { + showDiff: true + }, + customLaunchers: { + ChromeDebug: { + base: 'Chrome', + flags: ['--remote-debugging-port=9333'] + } + } +}; + +module.exports = config => { + let bundleDirPath = path.join(BASE_BUNDLE_DIR_PATH, hostname); + let cfg = {...baseConfig}; // TO RUN AGAINST SAUCELABS LOCALLY, execute: // `CI=1 SAUCE_USERNAME= SAUCE_ACCESS_KEY= npm start test.browser` - const env = process.env; let sauceConfig; + // configuration for CI mode if (env.CI) { console.error('CI mode enabled'); if (env.TRAVIS) { console.error('Travis-CI detected'); - bundleDirpath = path.join(baseBundleDirpath, process.env.TRAVIS_BUILD_ID); + bundleDirPath = path.join(BASE_BUNDLE_DIR_PATH, env.TRAVIS_BUILD_ID); if (env.SAUCE_USERNAME && env.SAUCE_ACCESS_KEY) { // correlate build/tunnel with Travis sauceConfig = { @@ -82,7 +104,6 @@ module.exports = config => { throw new Error('no browser tests should run on AppVeyor!'); } else { console.error(`Local environment (${hostname}) detected`); - bundleDirpath = path.join(baseBundleDirpath, hostname); // don't need to run sauce from appveyor b/c travis does it. if (env.SAUCE_USERNAME || env.SAUCE_ACCESS_KEY) { const id = `${hostname} (${Date.now()})`; @@ -96,94 +117,241 @@ module.exports = config => { console.error('No SauceLabs credentials present'); } } - fs.mkdirSync(bundleDirpath, {recursive: true}); - } else { - console.error('CI mode disabled'); } - if (sauceConfig) { - cfg.sauceLabs = sauceConfig; - addSauceTests(cfg); + cfg = createBundleDir(cfg, bundleDirPath); + cfg = addSauceTests(cfg, sauceConfig); + cfg = chooseTestSuite(cfg, env.MOCHA_TEST); + + // include sourcemap + cfg = { + ...cfg, + files: [...cfg.files, {pattern: './mocha.js.map', included: false}] + }; + + config.set(cfg); +}; + +/** + * Creates dir `bundleDirPath` if it does not exist; returns new Karma config + * containing `bundleDirPath` for rollup plugin. + * + * If this fails, the rollup plugin will use a temp dir. + * @param {object} cfg - Karma config. + * @param {string} [bundleDirPath] - Path where the output bundle should live + * @returns {object} - New Karma config + */ +const createBundleDir = (cfg, bundleDirPath) => { + if (bundleDirPath) { + try { + fs.mkdirSync(bundleDirPath, {recursive: true}); + cfg = { + ...cfg, + rollup: { + ...cfg.rollup, + bundleDirPath + } + }; + } catch (ignored) { + console.error( + `Failed to create ${bundleDirPath}; using temp directory instead` + ); + } } + return {...cfg}; +}; - /* the MOCHA_TEST env var will be set for "special" cases of tests. - * these may require different interfaces or other setup which make - * them unable to be batched w/ the rest. - */ - const MOCHA_TEST = env.MOCHA_TEST; - switch (MOCHA_TEST) { - case 'bdd': - case 'tdd': - case 'qunit': - if (cfg.sauceLabs) { - cfg.sauceLabs.testName = `Interface "${MOCHA_TEST}" Integration Tests`; - } - cfg.files = [`test/interfaces/${MOCHA_TEST}.spec.js`]; - cfg.client.mocha.ui = MOCHA_TEST; - break; +/** + * Adds Saucelabs-specific config to a Karma config object. + * + * If `sauceLabs` parameter is falsy, just return a clone of the `cfg` parameter. + * + * @see https://github.com/karma-runner/karma-sauce-launcher + * @see https://github.com/bermi/sauce-connect-launcher#advanced-usage + * @param {object} cfg - Karma config + * @param {object} [sauceLabs] - SauceLabs config + * @returns {object} Karma config + */ +const addSauceTests = (cfg, sauceLabs) => { + if (sauceLabs) { + const sauceBrowsers = Object.keys(SAUCE_BROWSER_PLATFORM_MAP); - case 'esm': - // just run against ChromeHeadless, since other browsers may not - // support - cfg.browsers = ['ChromeHeadless']; - cfg.files = [ - { - pattern: 'test/browser-specific/fixtures/esm.fixture.mjs', - type: 'module' - }, - {pattern: 'test/browser-specific/esm.spec.mjs', type: 'module'} - ]; - break; - default: - if (cfg.sauceLabs) { - cfg.sauceLabs.testName = 'Unit Tests'; - } + // creates Karma `customLauncher` configs from `SAUCE_BROWSER_PLATFORM_MAP` + const customLaunchers = sauceBrowsers.reduce((acc, sauceBrowser) => { + const platform = SAUCE_BROWSER_PLATFORM_MAP[sauceBrowser]; + const [browserName, version] = sauceBrowser.split('@'); + return { + ...acc, + [sauceBrowser]: { + base: 'SauceLabs', + browserName, + version, + platform + } + }; + }, {}); + + return { + ...cfg, + reporters: [...cfg.reporters, 'saucelabs'], + browsers: [...cfg.browsers, ...sauceBrowsers], + customLaunchers: { + ...cfg.customLaunchers, + ...customLaunchers + }, + sauceLabs: { + ...sauceLabs, + public: 'public', + connectOptions: { + connectRetries: 2, + connectRetryTimeout: 30000, + detached: sauceLabs.startConnect, + tunnelIdentifier: sauceLabs.tunnelIdentifier + } + }, + concurrency: Infinity, + retryLimit: 1, + captureTimeout: 120000, + browserNoActivityTimeout: 20000 + }; } + return {...cfg}; +}; - cfg.files.unshift( +/** + * Returns a new Karma config containing standard dependencies for our tests. + * + * Most suites use this. + * @param {object} cfg - Karma config + * @returns {object} New Karma config + */ +const addStandardDependencies = cfg => ({ + ...cfg, + files: [ require.resolve('sinon/pkg/sinon.js'), require.resolve('unexpected/unexpected'), - {pattern: require.resolve('unexpected/unexpected.js.map'), included: false}, + { + pattern: require.resolve('unexpected/unexpected.js.map'), + included: false + }, require.resolve('unexpected-sinon'), require.resolve('unexpected-eventemitter/dist/unexpected-eventemitter.js'), - require.resolve('./test/browser-specific/setup') - ); - - config.set(cfg); -}; - -function addSauceTests(cfg) { - cfg.reporters.push('saucelabs'); - const browsers = Object.keys(browserPlatformPairs); - cfg.browsers = cfg.browsers.concat(browsers); - cfg.customLaunchers = browsers.reduce((acc, browser) => { - const platform = browserPlatformPairs[browser]; - const [browserName, version] = browser.split('@'); - acc[browser] = { - base: 'SauceLabs', - browserName: browserName, - version: version, - platform: platform - }; - return acc; - }, cfg.customLaunchers); - - // See https://github.com/karma-runner/karma-sauce-launcher - // See https://github.com/bermi/sauce-connect-launcher#advanced-usage - Object.assign(cfg.sauceLabs, { - public: 'public', - connectOptions: { - connectRetries: 2, - connectRetryTimeout: 30000, - detached: cfg.sauceLabs.startConnect, - tunnelIdentifier: cfg.sauceLabs.tunnelIdentifier + require.resolve('./test/browser-specific/setup'), + ...cfg.files + ], + rollup: { + ...cfg.rollup, + external: [ + 'sinon', + 'unexpected', + 'unexpected-eventemitter', + 'unexpected-sinon' + ], + globals: { + sinon: 'sinon', + unexpected: 'weknowhow.expect', + 'unexpected-sinon': 'weknowhow.unexpectedSinon', + 'unexpected-eventemitter': 'unexpectedEventEmitter' } - }); + } +}); - cfg.concurrency = Infinity; - cfg.retryLimit = 1; +/** + * Adds a name for the tests, reflected in SauceLabs' UI. Returns new Karma + * config. + * + * Does not add a test name if the `sauceLabs` prop of `cfg` is falsy (which + * would imply that we're not running tests on SauceLabs). + * + * @param {string} testName - SauceLabs test name + * @param {object} cfg - Karma config. + * @returns {object} New Karma config + */ +const addSauceLabsTestName = (testName, cfg) => + cfg.sauceLabs + ? { + ...cfg, + sauceLabs: { + ...cfg.sauceLabs, + testName + } + } + : {...cfg}; - // for slow browser booting, ostensibly - cfg.captureTimeout = 120000; - cfg.browserNoActivityTimeout = 20000; -} +/** + * Returns a new Karma config to run with specific configuration (which cannot + * be run with other configurations) as specified by `value`. Known values: + * + * - `bdd` - `bdd`-specific tests + * - `tdd` - `tdd`-specific tests + * - `qunit` - `qunit`-specific tests + * - `esm` - ESM-specific tests + * - `requirejs` - RequireJS-specific tests + * + * Since we can't change Mocha's interface on-the-fly, tests for specific interfaces + * must be run in isolation. + * @param {object} cfg - Karma config + * @param {string} [value] - Configuration identifier, if any + * @returns {object} New Karma config + */ +const chooseTestSuite = (cfg, value) => { + switch (value) { + case 'bdd': + case 'tdd': + case 'qunit': + return addStandardDependencies({ + ...cfg, + ...addSauceLabsTestName(`Interface "${value}" Integration Tests`, cfg), + files: [`test/interfaces/${value}.spec.js`], + client: { + ...cfg.client, + mocha: { + ...cfg.client.mocha, + ui: value + } + } + }); + case 'esm': + return addStandardDependencies({ + ...addSauceLabsTestName('ESM Integration Tests', cfg), + // just run against ChromeHeadless, since other browsers may not + // support ESM. + // XXX: remove following line when dropping IE11 + browsers: ['ChromeHeadless'], + files: [ + { + pattern: 'test/browser-specific/fixtures/esm.fixture.mjs', + type: 'module' + }, + { + pattern: 'test/browser-specific/esm.spec.mjs', + type: 'module' + } + ] + }); + case 'requirejs': + // no standard deps because I'm too lazy to figure out how to make + // them work with RequireJS. not important anyway + return { + ...addSauceLabsTestName('RequireJS Tests', cfg), + plugins: [...cfg.plugins, 'karma-requirejs'], + frameworks: ['requirejs', ...cfg.frameworks], + files: [ + { + pattern: 'test/browser-specific/fixtures/requirejs/*.fixture.js', + included: false + }, + 'test/browser-specific/requirejs-setup.js' + ], + // this skips bundling the above tests & fixtures + rollup: { + ...cfg.rollup, + include: [] + } + }; + default: + return addStandardDependencies({ + ...addSauceLabsTestName('Unit Tests', cfg) + }); + } +}; diff --git a/lib/browser/template.html b/lib/browser/template.html index af4d3e4f42..4ebd4af488 100644 --- a/lib/browser/template.html +++ b/lib/browser/template.html @@ -1,16 +1,18 @@ - + Mocha - - + +
- - + + diff --git a/package-lock.json b/package-lock.json index 85e832440d..c2d9f39ad8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5558,28 +5558,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, + "resolved": "", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": false, + "resolved": "", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": false, + "resolved": "", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, @@ -5590,14 +5590,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, + "resolved": "", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -5608,42 +5608,42 @@ }, "chownr": { "version": "1.1.4", - "resolved": false, + "resolved": "", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, + "resolved": "", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, + "resolved": "", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "3.2.6", - "resolved": false, + "resolved": "", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "optional": true, @@ -5653,28 +5653,28 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": false, + "resolved": "", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, + "resolved": "", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.7", - "resolved": false, + "resolved": "", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "optional": true, @@ -5684,14 +5684,14 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, + "resolved": "", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, @@ -5708,7 +5708,7 @@ }, "glob": { "version": "7.1.6", - "resolved": false, + "resolved": "", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "optional": true, @@ -5723,14 +5723,14 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": false, + "resolved": "", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, @@ -5740,7 +5740,7 @@ }, "ignore-walk": { "version": "3.0.3", - "resolved": false, + "resolved": "", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "optional": true, @@ -5750,7 +5750,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, + "resolved": "", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, @@ -5761,21 +5761,21 @@ }, "inherits": { "version": "2.0.4", - "resolved": false, + "resolved": "", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": false, + "resolved": "", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, @@ -5785,14 +5785,14 @@ }, "isarray": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, + "resolved": "", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, @@ -5802,14 +5802,14 @@ }, "minimist": { "version": "1.2.5", - "resolved": false, + "resolved": "", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true }, "minipass": { "version": "2.9.0", - "resolved": false, + "resolved": "", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "optional": true, @@ -5820,7 +5820,7 @@ }, "minizlib": { "version": "1.3.3", - "resolved": false, + "resolved": "", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "optional": true, @@ -5830,7 +5830,7 @@ }, "mkdirp": { "version": "0.5.3", - "resolved": false, + "resolved": "", "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", "dev": true, "optional": true, @@ -5840,14 +5840,14 @@ }, "ms": { "version": "2.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true }, "needle": { "version": "2.3.3", - "resolved": false, + "resolved": "", "integrity": "sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw==", "dev": true, "optional": true, @@ -5859,7 +5859,7 @@ }, "node-pre-gyp": { "version": "0.14.0", - "resolved": false, + "resolved": "", "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", "dev": true, "optional": true, @@ -5878,7 +5878,7 @@ }, "nopt": { "version": "4.0.3", - "resolved": false, + "resolved": "", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "optional": true, @@ -5889,7 +5889,7 @@ }, "npm-bundled": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", "dev": true, "optional": true, @@ -5899,14 +5899,14 @@ }, "npm-normalize-package-bin": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.8", - "resolved": false, + "resolved": "", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "dev": true, "optional": true, @@ -5918,7 +5918,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, @@ -5931,21 +5931,21 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": false, + "resolved": "", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, + "resolved": "", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, @@ -5955,21 +5955,21 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, + "resolved": "", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, @@ -5980,21 +5980,21 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": false, + "resolved": "", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, @@ -6007,7 +6007,7 @@ }, "readable-stream": { "version": "2.3.7", - "resolved": false, + "resolved": "", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "optional": true, @@ -6023,7 +6023,7 @@ }, "rimraf": { "version": "2.7.1", - "resolved": false, + "resolved": "", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "optional": true, @@ -6033,49 +6033,49 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, + "resolved": "", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.1", - "resolved": false, + "resolved": "", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, @@ -6087,7 +6087,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -6097,7 +6097,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, @@ -6107,14 +6107,14 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.13", - "resolved": false, + "resolved": "", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "optional": true, @@ -6130,14 +6130,14 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": false, + "resolved": "", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, @@ -6147,14 +6147,14 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "optional": true @@ -7628,6 +7628,12 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "dev": true + }, "core-js-compat": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", @@ -13131,6 +13137,12 @@ } } }, + "karma-requirejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-requirejs/-/karma-requirejs-1.1.0.tgz", + "integrity": "sha1-/driy4fX68FvsCIok1ZNf+5Xh5g=", + "dev": true + }, "karma-sauce-launcher": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-2.0.2.tgz", @@ -18601,6 +18613,12 @@ "integrity": "sha1-/CwfhjbPuFWvmrlVrArQh4vK2wo=", "dev": true }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -22098,28 +22116,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, + "resolved": "", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": false, + "resolved": "", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": false, + "resolved": "", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, @@ -22130,14 +22148,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, + "resolved": "", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -22148,42 +22166,42 @@ }, "chownr": { "version": "1.1.4", - "resolved": false, + "resolved": "", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, + "resolved": "", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, + "resolved": "", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "3.2.6", - "resolved": false, + "resolved": "", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "optional": true, @@ -22193,28 +22211,28 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": false, + "resolved": "", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, + "resolved": "", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.7", - "resolved": false, + "resolved": "", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "optional": true, @@ -22224,14 +22242,14 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, + "resolved": "", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, @@ -22248,7 +22266,7 @@ }, "glob": { "version": "7.1.6", - "resolved": false, + "resolved": "", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "optional": true, @@ -22263,14 +22281,14 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": false, + "resolved": "", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, @@ -22280,7 +22298,7 @@ }, "ignore-walk": { "version": "3.0.3", - "resolved": false, + "resolved": "", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "optional": true, @@ -22290,7 +22308,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, + "resolved": "", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, @@ -22301,21 +22319,21 @@ }, "inherits": { "version": "2.0.4", - "resolved": false, + "resolved": "", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": false, + "resolved": "", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, @@ -22325,14 +22343,14 @@ }, "isarray": { "version": "1.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, + "resolved": "", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, @@ -22342,14 +22360,14 @@ }, "minimist": { "version": "1.2.5", - "resolved": false, + "resolved": "", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true }, "minipass": { "version": "2.9.0", - "resolved": false, + "resolved": "", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "optional": true, @@ -22360,7 +22378,7 @@ }, "minizlib": { "version": "1.3.3", - "resolved": false, + "resolved": "", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "optional": true, @@ -22370,7 +22388,7 @@ }, "mkdirp": { "version": "0.5.3", - "resolved": false, + "resolved": "", "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", "dev": true, "optional": true, @@ -22380,14 +22398,14 @@ }, "ms": { "version": "2.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "optional": true }, "needle": { "version": "2.3.3", - "resolved": false, + "resolved": "", "integrity": "sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw==", "dev": true, "optional": true, @@ -22399,7 +22417,7 @@ }, "node-pre-gyp": { "version": "0.14.0", - "resolved": false, + "resolved": "", "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", "dev": true, "optional": true, @@ -22418,7 +22436,7 @@ }, "nopt": { "version": "4.0.3", - "resolved": false, + "resolved": "", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "optional": true, @@ -22429,7 +22447,7 @@ }, "npm-bundled": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", "dev": true, "optional": true, @@ -22439,14 +22457,14 @@ }, "npm-normalize-package-bin": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.8", - "resolved": false, + "resolved": "", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "dev": true, "optional": true, @@ -22458,7 +22476,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, @@ -22471,21 +22489,21 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": false, + "resolved": "", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, + "resolved": "", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, @@ -22495,21 +22513,21 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, + "resolved": "", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, @@ -22520,21 +22538,21 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": false, + "resolved": "", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, @@ -22547,7 +22565,7 @@ }, "readable-stream": { "version": "2.3.7", - "resolved": false, + "resolved": "", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "optional": true, @@ -22563,7 +22581,7 @@ }, "rimraf": { "version": "2.7.1", - "resolved": false, + "resolved": "", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "optional": true, @@ -22573,49 +22591,49 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, + "resolved": "", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, + "resolved": "", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.1", - "resolved": false, + "resolved": "", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, @@ -22627,7 +22645,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -22637,7 +22655,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, @@ -22647,14 +22665,14 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, + "resolved": "", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.13", - "resolved": false, + "resolved": "", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "optional": true, @@ -22670,14 +22688,14 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": false, + "resolved": "", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, @@ -22687,14 +22705,14 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, + "resolved": "", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "optional": true diff --git a/package-scripts.js b/package-scripts.js index e4a98e4b14..dd9f1f7af8 100644 --- a/package-scripts.js +++ b/package-scripts.js @@ -75,7 +75,7 @@ module.exports = { }, test: { default: { - script: 'nps lint test.node test.browser test.bundle', + script: 'nps lint test.node test.browser', description: 'Run all linters and all tests' }, node: { @@ -221,7 +221,7 @@ module.exports = { browser: { default: { script: - 'nps clean build test.browser.unit test.browser.bdd test.browser.tdd test.browser.qunit test.browser.esm', + 'nps clean build test.browser.unit test.browser.bdd test.browser.tdd test.browser.qunit test.browser.esm test.browser.requirejs', description: 'Run browser tests' }, unit: { @@ -247,16 +247,10 @@ module.exports = { script: 'cross-env MOCHA_TEST=esm nps test.browser.unit', description: 'Run browser ES modules support test', hiddenFromHelp: true - } - }, - bundle: { - default: { - script: 'nps clean build test.bundle.amd', - description: 'Run bundle-related tests' }, - amd: { - script: test('amd', 'test/bundle/amd.spec'), - description: 'Run AMD bundle tests', + requirejs: { + script: 'cross-env MOCHA_TEST=requirejs nps test.browser.unit', + description: 'Run RequireJS compat test', hiddenFromHelp: true } } diff --git a/package.json b/package.json index a178cd873d..a835bf9afd 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "babel-eslint": "^10.1.0", "chai": "^4.2.0", "coffee-script": "^1.12.7", + "core-js": "^3.6.5", "coveralls": "^3.0.11", "cross-env": "^6.0.3", "cross-spawn": "^7.0.1", @@ -113,6 +114,7 @@ "karma-chrome-launcher": "^3.1.0", "karma-mocha": "^1.3.0", "karma-mocha-reporter": "^2.2.5", + "karma-requirejs": "^1.1.0", "karma-sauce-launcher": "^2.0.2", "lint-staged": "^9.5.0", "markdown-it": "^10.0.0", @@ -129,6 +131,7 @@ "remark": "^11.0.2", "remark-github": "^8.0.0", "remark-inline-links": "^3.1.3", + "requirejs": "^2.3.6", "rewiremock": "^3.14.1", "rimraf": "^3.0.2", "rollup": "^2.18.2", diff --git a/rollup.config.js b/rollup.config.js index c03a2de9d9..9005b6138a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -13,14 +13,12 @@ import pickFromPackageJson from './scripts/pick-from-package-json'; const config = { input: './browser-entry.js', - output: [ - { - file: './mocha.js', - format: 'iife', - sourcemap: true - } - ], - + output: { + file: './mocha.js', + format: 'umd', + sourcemap: true, + name: 'mocha' + }, plugins: [ json(), pickFromPackageJson({ @@ -32,9 +30,26 @@ const config = { nodeResolve({ browser: true }), - babel({presets: ['@babel/preset-env'], babelHelpers: 'bundled'}) + babel({ + exclude: /core-js/, + presets: [ + [ + '@babel/preset-env', + { + modules: false, + spec: true, + useBuiltIns: 'usage', + forceAllTransforms: true, + corejs: { + version: 3, + proposals: false + } + } + ] + ], + babelHelpers: 'bundled' + }) ], - onwarn: (warning, warn) => { if (warning.code === 'CIRCULAR_DEPENDENCY') return; diff --git a/scripts/karma-rollup-plugin.js b/scripts/karma-rollup-plugin.js index 440dd943fc..cf7b4796b0 100644 --- a/scripts/karma-rollup-plugin.js +++ b/scripts/karma-rollup-plugin.js @@ -12,7 +12,7 @@ * rollup with a modified config that allows for multiple entry points for a * single output bundle. * - * This is am implementation that specifically solves Mocha's use case. It + * This is an implementation that specifically solves Mocha's use case. It * does not support watch mode. It is possible that is coulkd eventually be * made reusable with more work and actual testing. * @@ -57,9 +57,11 @@ function framework(fileConfigs, pluginConfig, basePath, preprocessors) { ) ); - let bundleLocation = pluginConfig.bundlePath - ? pluginConfig.bundlePath - : path.resolve(os.tmpdir(), `${uuid.v4()}.rollup.js`); + const bundleFilename = `${uuid.v4()}.rollup.js`; + let bundleLocation = path.resolve( + pluginConfig.bundleDirPath ? pluginConfig.bundleDirPath : os.tmpdir(), + bundleFilename + ); if (process.platform === 'win32') { bundleLocation = bundleLocation.replace(/\\/g, '/'); } @@ -107,7 +109,7 @@ framework.$inject = [ function bundlePreprocessor(config) { const { basePath, - rollup: {configFile} + rollup: {configFile, globals = {}, external = []} } = config; const configPromise = loadConfigFile(path.resolve(basePath, configFile)); @@ -115,33 +117,34 @@ function bundlePreprocessor(config) { return async function(content, file, done) { const {options, warnings} = await configPromise; const config = options[0]; - const plugins = config.plugins || []; + // plugins is always an array + const pluginConfig = [ + ...(config.plugins || []), + multiEntry({exports: false}) + ]; + // XXX: output is always an array, but we only have one output config. + // if we have multiple, this code needs changing. + const outputConfig = { + ...((config.output || [])[0] || {}), + file: file.path, + globals, + sourcemap: 'inline' + }; warnings.flush(); const bundle = await rollup.rollup({ input: fileMap.get(file.path), - plugins: [...plugins, multiEntry({exports: false})], - external: ['sinon'], + plugins: pluginConfig, + external, onwarn: config.onwarn }); - const sharedOutputConfig = { - sourcemap: true, - format: 'iife', - globals: { - sinon: 'sinon' - } - }; - - const {output} = await bundle.generate(sharedOutputConfig); - - await bundle.write({ - file: file.path, - ...sharedOutputConfig - }); + await bundle.write(outputConfig); + console.error(`wrote bundle to ${file.path}`); + const code = fs.readFileSync(outputConfig.file, 'utf8'); - done(null, output[0].code); + done(null, code); }; } diff --git a/test/browser-specific/fixtures/requirejs/lib.fixture.js b/test/browser-specific/fixtures/requirejs/lib.fixture.js new file mode 100644 index 0000000000..7c0ff46219 --- /dev/null +++ b/test/browser-specific/fixtures/requirejs/lib.fixture.js @@ -0,0 +1,3 @@ +define('lib', function() { + return 'foo'; +}); diff --git a/test/browser-specific/fixtures/requirejs/main.fixture.js b/test/browser-specific/fixtures/requirejs/main.fixture.js new file mode 100644 index 0000000000..1e1e1fa25c --- /dev/null +++ b/test/browser-specific/fixtures/requirejs/main.fixture.js @@ -0,0 +1,9 @@ +define(['lib'], function(lib) { + describe('lib', function() { + it('should equal "foo"', function() { + if (lib !== 'foo') { + throw new Error('should be "foo"'); + } + }); + }); +}); diff --git a/test/browser-specific/requirejs-setup.js b/test/browser-specific/requirejs-setup.js new file mode 100644 index 0000000000..360703778b --- /dev/null +++ b/test/browser-specific/requirejs-setup.js @@ -0,0 +1,17 @@ +/* eslint-disable strict */ +(function() { + 'use strict'; + var tests = []; + + for (var file in window.__karma__.files) { + if (/fixture\.js$/.test(file)) { + tests.push(file); + } + } + + require.config({ + baseUrl: '/base', + deps: tests, + callback: window.__karma__.start + }); +})(); diff --git a/test/browser-specific/setup.js b/test/browser-specific/setup.js index 31f5c82396..6809f3b294 100644 --- a/test/browser-specific/setup.js +++ b/test/browser-specific/setup.js @@ -2,7 +2,7 @@ process.stdout = require('browser-stdout')(); -global.expect = global.weknowhow.expect +global.expect = require('unexpected') .clone() - .use(global.weknowhow.unexpectedSinon) - .use(global.unexpectedEventEmitter); + .use(require('unexpected-sinon')) + .use(require('unexpected-eventemitter')); diff --git a/test/bundle/amd.spec.js b/test/bundle/amd.spec.js deleted file mode 100644 index bc6e93aa4e..0000000000 --- a/test/bundle/amd.spec.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -var path = require('path'); -var fs = require('fs'); - -it('should build a non-broken bundle for AMD', function(done) { - var bundle = path.join(process.cwd(), 'mocha.js'); - fs.readFile(bundle, 'utf8', function(err, content) { - if (err) { - return done(err); - } - - expect(content, 'not to match', /define.amd/); - done(); - }); -}); diff --git a/test/unit/utils.spec.js b/test/unit/utils.spec.js index 6dcff87d18..9fa6cc74e4 100644 --- a/test/unit/utils.spec.js +++ b/test/unit/utils.spec.js @@ -496,11 +496,11 @@ describe('lib/utils', function() { if (typeof global.Symbol === 'function') { it('should handle Symbol', function() { var symbol = Symbol('value'); - expect(stringify(symbol), 'to be', 'Symbol(value)'); + expect(stringify(symbol), 'to match', /^Symbol\(value\)/); expect( stringify({symbol: symbol}), - 'to be', - '{\n "symbol": Symbol(value)\n}' + 'to match', + /"symbol": Symbol\(value\)/ ); }); }