diff --git a/.eslintrc b/.eslintrc index ed06396c..4a00786e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,8 +5,14 @@ "impliedStrict": true } }, + "plugins": ["jest"], + "extends": [ + "plugin:jest/recommended", + "plugin:jest/style" + ], "env": { "es2020": true, + "jest/globals": true, "node": true }, "rules": { diff --git a/.gitignore b/.gitignore index 18ef0a70..9e59d950 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ jspm_packages node_modules npm-debug.log .DS_Store +.coverage/ diff --git a/.travis.yml b/.travis.yml index 6174fd7f..08c15dde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,5 @@ cache: install: - npm install script: - - npm test + - npm run lint + - npm run test-with-coverage diff --git a/appveyor.yml b/appveyor.yml index 1d590444..f7f8a92f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,5 +10,6 @@ install: test_script: - node --version - npm --version - - npm test + - npm run lint + - npm run test-with-coverage build: off diff --git a/bin/stencil-bundle b/bin/stencil-bundle.js similarity index 78% rename from bin/stencil-bundle rename to bin/stencil-bundle.js index babf4d95..e0b30876 100755 --- a/bin/stencil-bundle +++ b/bin/stencil-bundle.js @@ -20,21 +20,24 @@ Program .parse(process.argv); if (!versionCheck()) { - return; + process.exit(2); } themeConfig = ThemeConfig.getInstance(themePath); if (Program.dest === true) { - return console.error('Error: You have to specify a value for -d or --dest'.red); + console.error('Error: You have to specify a value for -d or --dest'.red); + process.exit(2); } if (Program.name === true) { - return console.error('Error: You have to specify a value for -n or --name'.red); + console.error('Error: You have to specify a value for -n or --name'.red); + process.exit(2); } if (!themeConfig.configExists()) { - return console.error('Error: You must have a '.red + 'config.json'.cyan + ' file in your top level theme directory.'); + console.error('Error: You must have a '.red + 'config.json'.cyan + ' file in your top level theme directory.'); + process.exit(2); } configuration = themeConfig.getRawConfig(); diff --git a/bin/stencil-init b/bin/stencil-init.js similarity index 96% rename from bin/stencil-init rename to bin/stencil-init.js index 078126cf..f64dee3b 100755 --- a/bin/stencil-init +++ b/bin/stencil-init.js @@ -16,7 +16,7 @@ Program .parse(process.argv); if (!versionCheck()) { - return; + process.exit(2); } const dotStencilFilePath = './.stencil'; diff --git a/bin/stencil-pull b/bin/stencil-pull.js similarity index 98% rename from bin/stencil-pull rename to bin/stencil-pull.js index 10853e28..163294c4 100755 --- a/bin/stencil-pull +++ b/bin/stencil-pull.js @@ -17,7 +17,7 @@ Program .parse(process.argv); if (!versionCheck()) { - return; + process.exit(2); } stencilPull(Object.assign({}, options, { diff --git a/bin/stencil-push b/bin/stencil-push.js similarity index 94% rename from bin/stencil-push rename to bin/stencil-push.js index edea7f83..06b499e0 100755 --- a/bin/stencil-push +++ b/bin/stencil-push.js @@ -20,7 +20,7 @@ Program .parse(process.argv); if (!versionCheck()) { - return; + process.exit(2); } stencilPush(Object.assign({}, options, { @@ -32,7 +32,7 @@ stencilPush(Object.assign({}, options, { }), (err, result) => { if (err) { console.log("\n\n" + 'not ok'.red + ` -- ${err} see details below:`); - themeApiClient.printErrorMessages(err.messages) + themeApiClient.printErrorMessages(err.messages); console.log('If this error persists, please visit https://github.com/bigcommerce/stencil-cli/issues and submit an issue.'); } else { console.log('ok'.green + ` -- ${result}`); diff --git a/bin/stencil-release b/bin/stencil-release.js similarity index 93% rename from bin/stencil-release rename to bin/stencil-release.js index e3fb4b57..35c7caaf 100755 --- a/bin/stencil-release +++ b/bin/stencil-release.js @@ -11,7 +11,7 @@ Program .parse(process.argv); if (!versionCheck()) { - return; + process.exit(2); } release(); diff --git a/bin/stencil-start b/bin/stencil-start.js similarity index 82% rename from bin/stencil-start rename to bin/stencil-start.js index 1b6f7ba2..00b93acf 100755 --- a/bin/stencil-start +++ b/bin/stencil-start.js @@ -15,7 +15,7 @@ const Pkg = require('../package.json'); const Program = require('commander'); const Server = require('../server'); const ThemeConfig = require('../lib/theme-config'); -const buildConfig = require('../lib/build-config'); +const BuildConfigManager = require('../lib/BuildConfigManager'); const jsonLint = require('../lib/json-lint'); const versionCheck = require('../lib/version-check'); @@ -36,23 +36,26 @@ Program // https://browsersync.io/docs/options#option-tunnel const tunnel = typeof Program.tunnel === 'string' ? Program.tunnel - : Boolean(Program.tunnel) // convert undefined/true -> false/true + : Boolean(Program.tunnel); // convert undefined/true -> false/true if (!versionCheck()) { - return; + process.exit(2); } if (!fileExist(dotStencilFilePath)) { - return console.error('Error: Please run'.red + ' $ stencil init'.cyan + ' first.'.red); + console.error('Error: Please run'.red + ' $ stencil init'.cyan + ' first.'.red); + process.exit(2); } if (!fileExist(Path.join(themePath, 'config.json'))) { - return console.error('Error: You must have a '.red + 'config.json'.cyan + ' file in your top level theme directory.'); + console.error('Error: You must have a '.red + 'config.json'.cyan + ' file in your top level theme directory.'); + process.exit(2); } // If the value is true it means that no variation was passed in. if (Program.variation === true) { - return console.error('Error: You have to specify a value for -v or --variation'.red); + console.error('Error: You have to specify a value for -v or --variation'.red); + process.exit(2); } // Instantiate themeConfig @@ -61,25 +64,27 @@ if (Program.variation) { try { themeConfig.setVariationByName(Program.variation); } catch (err) { - return console.error('Error: The variation '.red + Program.variation + ' does not exists in your config.json file'.red); + console.error('Error: The variation '.red + Program.variation + ' does not exists in your config.json file'.red); + process.exit(2); } } -let configuration = themeConfig.getConfig(); -let dotStencilFile = Fs.readFileSync(dotStencilFilePath, {encoding: 'utf-8'}); +let dotStencilFile = Fs.readFileSync(dotStencilFilePath, { encoding: 'utf-8' }); try { dotStencilFile = jsonLint.parse(dotStencilFile, dotStencilFilePath); } catch (e) { - return console.error(e.stack); + console.error(e.stack); + process.exit(2); } let browserSyncPort = dotStencilFile.port; let stencilServerPort = ++dotStencilFile.port; if (!(dotStencilFile.normalStoreUrl) || !(dotStencilFile.customLayouts)) { - return console.error( + console.error( 'Error: Your stencil config is outdated. Please run'.red + - ' $ stencil init'.cyan + ' again.'.red + ' $ stencil init'.cyan + ' again.'.red, ); + process.exit(2); } let staplerUrl; @@ -101,18 +106,16 @@ Wreck.get( rejectUnauthorized: false, }, function (err, res, payload) { - let bundleTask; - if (err || !payload) { console.error( - 'The BigCommerce Store you are pointing to either does not exist or is not available at this time.'.red + 'The BigCommerce Store you are pointing to either does not exist or is not available at this time.'.red, ); } else if (payload.error) { return console.error(payload.error.red); } else if (payload.status !== 'ok') { console.error( 'Error: You are using an outdated version of stencil-cli, please run '.red + - '$ npm install -g @bigcommerce/stencil-cli'.cyan + '$ npm install -g @bigcommerce/stencil-cli'.cyan, ); } else { dotStencilFile.storeUrl = payload.sslUrl; @@ -121,7 +124,7 @@ Wreck.get( return startServer(); } - } + }, ); /** @@ -135,11 +138,12 @@ async function startServer() { themePath: themePath, }); + const buildConfigManger = new BuildConfigManager(); let watchFiles = [ '/assets', '/templates', '/lang', - '/.config' + '/.config', ]; let watchIgnored = [ '/assets/scss', @@ -156,25 +160,13 @@ async function startServer() { } }); - Bs.watch('config.json', (event) => { - if (event === 'change') { - try { - configuration = themeConfig.getConfig(); - } catch (e) { - return console.error(e); - } - - Bs.reload(); - } - }); - Bs.watch('.config/storefront.json', (event, file) => { if (event === 'change') { console.log("storefront json changed"); Bs.emitter.emit("storefront_config_file:changed", { event: event, path: file, - namespace: "" + namespace: "", }); Bs.reload(); } @@ -191,15 +183,15 @@ async function startServer() { } catch (e) { console.error(e); } - }) + }); }); - if (buildConfig.watchOptions && buildConfig.watchOptions.files) { - watchFiles = buildConfig.watchOptions.files; + if (buildConfigManger.watchOptions && buildConfigManger.watchOptions.files) { + watchFiles = buildConfigManger.watchOptions.files; } - if (buildConfig.watchOptions && buildConfig.watchOptions.ignored) { - watchIgnored = buildConfig.watchOptions.ignored; + if (buildConfigManger.watchOptions && buildConfigManger.watchOptions.ignored) { + watchIgnored = buildConfigManger.watchOptions.ignored; } Bs.init({ @@ -227,8 +219,8 @@ async function startServer() { } }); - if (buildConfig.development) { - buildConfig.initWorker().development(Bs); + if (buildConfigManger.development) { + buildConfigManger.initWorker().development(Bs); } } @@ -248,7 +240,7 @@ function assembleTemplates(templatePath, callback) { callback(err); } callback(null, results); - }) + }); }); } diff --git a/bin/stencil b/bin/stencil.js similarity index 100% rename from bin/stencil rename to bin/stencil.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..98a7480f --- /dev/null +++ b/jest.config.js @@ -0,0 +1,31 @@ +// For a detailed explanation regarding each configuration property, visit: +// https://jestjs.io/docs/en/configuration.html + +module.exports = { + collectCoverage: false, + collectCoverageFrom: [ + './bin/**/*.js', + './server/**/*.js', + './lib/**/*.js', + './tasks/**/*.js', + ], + coverageDirectory: './.coverage', + coverageThreshold: { + global: { + branches: 33, + functions: 47, + lines: 47, + statements: 47, + }, + }, + moduleFileExtensions: [ + "js", + "json", + "node", + ], + testEnvironment: "node", + testMatch: [ + "**/__tests__/**/*.[jt]s", + "**/?(*.)+(spec|test).[tj]s", + ], +}; diff --git a/lib/BuildConfigManager.js b/lib/BuildConfigManager.js new file mode 100644 index 00000000..7199eed4 --- /dev/null +++ b/lib/BuildConfigManager.js @@ -0,0 +1,106 @@ +'use strict'; + +const _ = require('lodash'); +const fork = require('child_process').fork; +const Path = require('path'); +const fsModule = require('fs'); + +class BuildConfigManager { + constructor({ + workDir = process.cwd(), + fs = fsModule, + } = {}) { + this.CONFIG_FILE_NAME = 'stencil.conf.js'; + + this._workDir = workDir; + this._buildConfigPath = Path.join(workDir, this.CONFIG_FILE_NAME); + this._fs = fs; + this._onReadyCallbacks = []; + this._worker = null; + this._workerIsReady = false; + + const config = this._getConfig(this._buildConfigPath); + + this.development = config.development || this._devWorker; + this.production = config.production || this._prodWorker; + this.watchOptions = config.watchOptions; + } + + initWorker() { + if (this._fs.existsSync(this._buildConfigPath)) { + this._worker = fork(this._buildConfigPath, [], { cwd: this._workDir }); + + this._worker.on('message', message => { + if (message === 'ready') { + this._workerIsReady = true; + this._onReadyCallbacks.forEach(callback => callback()); + } + }); + } + + return this; + } + + stopWorker(signal = 'SIGTERM') { + this._worker.kill(signal); + } + + _getConfig(configPath) { + if (this._fs.existsSync(configPath)) { + return require(configPath); + } + + return {}; + } + + _onWorkerReady(onReady) { + if (this._workerIsReady) { + process.nextTick(onReady); + } + + this._onReadyCallbacks.push(onReady); + } + + _devWorker(browserSync) { + if (!this._worker) { + return; + } + // send a message to the worker to start watching + // and wait for message to reload the browser + this._worker.send('development'); + this._worker.on('message', message => { + if (message === 'reload') { + browserSync.reload(); + } + }); + } + + _prodWorker(done) { + const callback = _.once(done); + + if (!this._worker) { + return process.nextTick(() => callback('worker initialization failed')); + } + + const timeout = setTimeout(() => { + this.stopWorker(); + callback('worker timed out'); + }, 20000); + + this._onWorkerReady(() => { + clearTimeout(timeout); + // send a message to the worker to start bundling js + this._worker.send('production'); + this._worker.on('message', message => { + if (message === 'done') { + this._worker.kill(); + callback(); + } + }); + }); + + this._worker.on('close', () => callback('worker terminated')); + } +} + +module.exports = BuildConfigManager; diff --git a/lib/BuildConfigManager.spec.js b/lib/BuildConfigManager.spec.js new file mode 100644 index 00000000..107a7ee6 --- /dev/null +++ b/lib/BuildConfigManager.spec.js @@ -0,0 +1,99 @@ +'use strict'; + +const { promisify } = require('util'); + +const BuildConfigManager = require('./BuildConfigManager'); + +const cwd = process.cwd(); + +describe('BuildConfigManager integration tests', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe('constructor', () => { + it('should return an instance with correct watchOptions taken from the config file', () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/valid-config`, + }); + + expect(buildConfig.watchOptions).toBeInstanceOf(Object); + expect(buildConfig.watchOptions.files).toBeInstanceOf(Array); + expect(buildConfig.watchOptions.ignored).toBeInstanceOf(Array); + }); + }); + + describe('production method', () => { + it('should resolve successfully for "valid-config"', async () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/valid-config`, + }); + buildConfig.initWorker(); + + expect(buildConfig.production).toBeInstanceOf(Function); + + await promisify(buildConfig.production.bind(buildConfig))(); + + buildConfig.stopWorker(); + }); + + it('should resolve successfully for "legacy-config"', async () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/legacy-config`, + }); + buildConfig.initWorker(); + + expect(buildConfig.production).toBeInstanceOf(Function); + + await promisify(buildConfig.production.bind(buildConfig))(); + + buildConfig.stopWorker(); + }); + + it('should reject with "worker terminated" message for "noworker-config"', async () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/noworker-config`, + }); + + const initedBuildConfig = buildConfig.initWorker(); + + expect(buildConfig.production).toBeInstanceOf(Function); + + await expect( + promisify(initedBuildConfig.production.bind(initedBuildConfig))(), + ).rejects.toContain('worker terminated'); + + buildConfig.stopWorker(); + }); + }); + + describe('development method', () => { + it('should reload the browser when a message "reload" is received from stencil.conf.js (valid-config)', async () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/valid-config`, + }); + + expect(buildConfig.development).toBeInstanceOf(Function); + + await new Promise(done => + buildConfig.initWorker().development({ reload: done }), + ); + + buildConfig.stopWorker(); + }); + + it('should reload the browser when "reload" method is called from stencil.conf.js (legacy-config)', async () => { + const buildConfig = new BuildConfigManager({ + workDir: `${cwd}/test/_mocks/build-config/legacy-config`, + }); + + expect(buildConfig.development).toBeInstanceOf(Function); + + await new Promise(done => + buildConfig.initWorker().development({ reload: done }), + ); + + buildConfig.stopWorker(); + }); + }); +}); diff --git a/lib/build-config.js b/lib/build-config.js deleted file mode 100644 index 9296d486..00000000 --- a/lib/build-config.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -const _ = require('lodash'); -const fork = require('child_process').fork; -const Path = require('path'); -const Fs = require('fs'); -const buildConfigPath = Path.join(process.cwd(), 'stencil.conf.js'); -const config = getConfig(); -const onReadyCallbacks = []; -let worker = null; -let workerIsReady = false; - -const api = { - development: config.development || devWorker, - initWorker: initWorker, - production: config.production || prodWorker, - watchOptions: config.watchOptions, -}; - -module.exports = api; - -function getConfig() { - let config = {}; - - if (Fs.existsSync(buildConfigPath)) { - config = require(buildConfigPath); - } - - return config; -} - -function initWorker() { - if (Fs.existsSync(buildConfigPath)) { - worker = fork(buildConfigPath, [], { cwd: process.cwd() }); - - worker.on('message', message => { - if (message === 'ready') { - workerIsReady = true; - onReadyCallbacks.forEach(callback => callback()); - } - }); - } - - return api; -} - -function onWorkerReady(onReady) { - if (workerIsReady) { - process.nextTick(onReady); - } - - onReadyCallbacks.push(onReady); -} - -function devWorker(browserSync) { - if (!worker) { - return; - } - // send a message to the worker to start watching - // and wait for message to reload the browser - worker.send('development'); - worker.on('message', message => { - if (message === 'reload') { - browserSync.reload(); - } - }); -} - -function prodWorker(done) { - const callback = _.once(done); - - if (!worker) { - return process.nextTick(() => callback('worker initialization failed')); - } - - const timeout = setTimeout(() => { - worker.kill(); - callback('worker timed out'); - }, 20000); - - onWorkerReady(() => { - clearTimeout(timeout); - // send a message to the worker to start bundling js - worker.send('production'); - worker.on('message', message => { - if (message === 'done') { - worker.kill(); - callback(); - } - }); - }); - - worker.on('close', () => callback('worker terminated')); -} diff --git a/lib/build-config.spec.js b/lib/build-config.spec.js deleted file mode 100644 index 099084d1..00000000 --- a/lib/build-config.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); -const { promisify } = require('util'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; -const it = lab.it; -const cwd = process.cwd(); - -describe('stencilBuildConfig', () => { - let sandbox; - - function loadModule(mockName) { - const path = `${cwd}/test/_mocks/build-config/${mockName}`; - delete require.cache[require.resolve('./build-config')]; - sandbox.stub(process, 'cwd').returns(path); - - return require('./build-config'); - } - - lab.beforeEach(() => { - sandbox = sinon.createSandbox(); - }); - - lab.afterEach(() => { - sandbox.restore(); - }); - - it('should return watchOptions', () => { - const buildConfig = loadModule('valid-config'); - - expect(buildConfig.watchOptions).to.be.an.object(); - expect(buildConfig.watchOptions.files).to.be.an.array(); - expect(buildConfig.watchOptions.ignored).to.be.an.array(); - }); - - describe('production method', () => { - it('should resolve successfully for "valid-config"', async () => { - const buildConfig = loadModule('valid-config'); - const initedBuildConfig = buildConfig.initWorker(); - - expect(buildConfig.production).to.be.a.function(); - - await promisify(initedBuildConfig.production.bind(initedBuildConfig))(); - }); - - it('should resolve successfully for "legacy-config"', async () => { - const buildConfig = loadModule('legacy-config'); - const initedBuildConfig = buildConfig.initWorker(); - - expect(buildConfig.production).to.be.a.function(); - - await promisify(initedBuildConfig.production.bind(initedBuildConfig))(); - }); - - it('should reject with "worker terminated" message for "noworker-config"', async () => { - const buildConfig = loadModule('noworker-config'); - const initedBuildConfig = buildConfig.initWorker(); - - expect(buildConfig.production).to.be.a.function(); - - let message; - try { - await promisify(initedBuildConfig.production.bind(initedBuildConfig))(); - } catch (err) { - message = err; - } - - expect(message).to.equal('worker terminated'); - }); - }); - - describe('development method', () => { - it('should reload the browser when a message "reload" is received from stencil.conf.js (valid-config)', async () => { - const buildConfig = loadModule('valid-config'); - - expect(buildConfig.development).to.be.a.function(); - - await new Promise(done => - buildConfig.initWorker().development({ reload: done }), - ); - }); - - it('should reload the browser when "reload" method is called from stencil.conf.js (legacy-config)', async () => { - const buildConfig = loadModule('legacy-config'); - - expect(buildConfig.development).to.be.a.function(); - - await new Promise(done => - buildConfig.initWorker().development({ reload: done }), - ); - }); - }); -}); diff --git a/lib/bundle-validator.spec.js b/lib/bundle-validator.spec.js index 09bb2bda..a10aa909 100644 --- a/lib/bundle-validator.spec.js +++ b/lib/bundle-validator.spec.js @@ -1,50 +1,46 @@ -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const sinon = require('sinon'); const Path = require('path'); const { promisify } = require('util'); -const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); + const ThemeConfig = require('./theme-config'); const BundleValidator = require('./bundle-validator'); -const expect = Code.expect; -const it = lab.it; + +const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); describe('BundleValidator', function () { let themeConfig; - lab.beforeEach(function() { + beforeEach(() => { themeConfig = ThemeConfig.getInstance(themePath); themeConfig.getConfig(); }); + afterEach(() => { + jest.restoreAllMocks(); + }); + it('should not run image validations for private themes', async () => { const validator = new BundleValidator(themePath, themeConfig, true); - const sizeOfSpy = sinon.spy(validator, 'sizeOf'); + const sizeOfSpy = jest.spyOn(validator, 'sizeOf'); await promisify(validator.validateTheme.bind(validator))(); - expect(sizeOfSpy.called).to.equal(false); - - sizeOfSpy.restore(); + expect(sizeOfSpy).not.toHaveBeenCalled(); }); it('should run image validations for marketplace themes', async () => { const validator = new BundleValidator(themePath, themeConfig, false); - const sizeOfSpy = sinon.spy(validator, 'sizeOf'); + const sizeOfSpy = jest.spyOn(validator, 'sizeOf'); await promisify(validator.validateTheme.bind(validator))(); - expect(sizeOfSpy.called).to.equal(true); - - sizeOfSpy.restore(); + expect(sizeOfSpy).toHaveBeenCalled(); }); it ('should validate returned objects exist in templates', async () => { - const validResults = [ - {"page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{{footer.scripts}}}\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", + const assembledTemplates = [ + { + "page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{{footer.scripts}}}\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", "components/index":"

This is the index

\n", }, { @@ -53,14 +49,15 @@ describe('BundleValidator', function () { ]; const validator = new BundleValidator(themePath, themeConfig, false); - const result = await promisify(validator.validateObjects.bind(validator))(validResults); + const result = await promisify(validator.validateObjects.bind(validator))(assembledTemplates); - expect(result).to.equal(true); + expect(result).toEqual(true); }); it ('should validate returned objects when they have whitespace in the object name', async () => { - const validResults = [ - {"page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{{footer.scripts}}}\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", + const assembledTemplates = [ + { + "page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{{footer.scripts}}}\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", "components/index":"

This is the index

\n", }, { @@ -69,38 +66,35 @@ describe('BundleValidator', function () { ]; const validator = new BundleValidator(themePath, themeConfig, false); - const result = await promisify(validator.validateObjects.bind(validator))(validResults); + const result = await promisify(validator.validateObjects.bind(validator))(assembledTemplates); - expect(result).to.equal(true); + expect(result).toEqual(true); }); it ('should not validate returned objects exist in templates', async () => { - const validResults = [ - {"page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", - "components/index":"

This is the index

\n", + const assembledTemplates = [ + { + "page":"---\nfront_matter_options:\n setting_x:\n value: {{theme_settings.front_matter_value}}\n---\n\n\n\n{{#if theme_settings.display_that}}\n
{{> components/index}}
\n{{/if}}\n\n\n", + "components/index": "

This is the index

\n", }, { - "page2":"\n\n\n

{{theme_settings.customizable_title}}

\n{{{head.scripts}}}\n\n\n", + "page2": "\n\n\n

{{theme_settings.customizable_title}}

\n{{{head.scripts}}}\n\n\n", }, ]; const validator = new BundleValidator(themePath, themeConfig, false); - let error; - let result; - try { - result = await promisify(validator.validateObjects.bind(validator))(validResults); - } catch (err) { - error = err; - } - - expect(result).to.be.undefined(); - expect(error.message).to.equal('Missing required objects/properties: footer.scripts'); + await expect( + promisify(validator.validateObjects.bind(validator))(assembledTemplates), + ).rejects.toThrow('Missing required objects/properties: footer.scripts'); }); it ('should validate theme schema successfully', async () => { const validator = new BundleValidator(themePath, themeConfig, false); - await promisify(validator.validateTheme.bind(validator))(); + const res = await promisify(validator.validateTheme.bind(validator))(); + + expect(res).toHaveLength(4); // 4 validation tasks + expect(res).not.toContain(false); }); it ('should validate theme schema and throw errors', async () => { @@ -110,14 +104,8 @@ describe('BundleValidator', function () { const validator = new BundleValidator(themePath, themeConfig, false); - let error; - try { - await promisify(validator.validateTheme.bind(validator))(); - } catch (err) { - error = err; - } - - expect(error instanceof Error).to.be.true(); - expect(error.message).to.contain('schema[0].settings[0] should have required property \'content\''); + await expect( + promisify(validator.validateTheme.bind(validator))(), + ).rejects.toThrow('schema[0].settings[0] should have required property \'content\''); }); }); diff --git a/lib/cycles.spec.js b/lib/cycles.spec.js index d4fb9d76..1bc84ec6 100644 --- a/lib/cycles.spec.js +++ b/lib/cycles.spec.js @@ -1,13 +1,5 @@ -const Code = require('code'); -const Lab = require('@hapi/lab'); - const Cycles = require('./cycles'); -const expect = Code.expect; -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const it = lab.it; - describe('Cycles', () => { const invaldResults = [ { @@ -39,26 +31,26 @@ describe('Cycles', () => { ]; it('should throw error when cycle is detected', () => { - const throws = function () { + const action = () => { new Cycles(invaldResults).detect(); }; - expect(throws).throw(Error, /Circular/); + expect(action).toThrow(Error, /Circular/); }); it('should throw an error when non array passed in', () => { - const throws = function () { + const action = () => { new Cycles('test'); }; - expect(throws).throw(Error); + expect(action).toThrow(Error); }); - it('should not throw an error when checking for cycles', () => { - const throws = function () { + it('should not throw an error when cycles weren\'t detected', () => { + const action = () => { new Cycles(validResults).detect(); }; - expect(throws).to.not.throw(); + expect(action).not.toThrow(); }); }); diff --git a/lib/json-lint.spec.js b/lib/json-lint.spec.js index 8908e456..17dafc0f 100644 --- a/lib/json-lint.spec.js +++ b/lib/json-lint.spec.js @@ -1,10 +1,4 @@ -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; const jsonLint = require('./json-lint'); -const expect = Code.expect; -const it = lab.it; describe('json-lint', function () { const badJsonFilename = '/path/to/badfile.json'; @@ -17,7 +11,7 @@ describe('json-lint', function () { jsonLint.parse(badJson, badJsonFilename); }; - expect(throws).throw(Error, file); + expect(throws).toThrow(Error, file); }); it('should not need a file name', () => { @@ -25,6 +19,6 @@ describe('json-lint', function () { jsonLint.parse(badJson); }; - expect(throws).throw(Error, !file); + expect(throws).toThrow(Error, !file); }); }); diff --git a/lib/regions.spec.js b/lib/regions.spec.js index 7f09171b..ce1cefea 100644 --- a/lib/regions.spec.js +++ b/lib/regions.spec.js @@ -1,29 +1,20 @@ 'use strict'; -const Code = require('code'); const Fs = require('fs'); const { promisify } = require('util'); -const Sinon = require('sinon'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; -const it = lab.it; const Regions = require('./regions'); const StencilBundle = require('./stencil-bundle'); const themePath = `${process.cwd()}/test/_mocks/themes/regions`; describe('Stencil Bundle', () => { - let sandbox; let bundle; - lab.beforeEach(() => { - sandbox = Sinon.createSandbox(); + beforeEach(() => { const themeConfigStub = { - configExists: sandbox.stub().returns(true), - getRawConfig: sandbox.stub().returns({}), - getSchema: sandbox.stub().callsArgWith(0, null), + configExists: jest.fn().mockReturnValue(true), + getRawConfig: jest.fn().mockReturnValue({}), + getSchema: jest.fn().mockImplementation(cb => cb(null)), }; const rawConfig = { @@ -31,15 +22,14 @@ describe('Stencil Bundle', () => { "version": "1.1.0", }; - sandbox.stub(Fs, 'writeFile').callsArgWith(2, null); + jest.spyOn(console, 'log').mockImplementation(jest.fn()); // Prevent littering the console with info messages + jest.spyOn(Fs, 'writeFile').mockImplementation((path, data, cb) => cb(null)); - bundle = new StencilBundle(themePath, themeConfigStub, rawConfig, { - marketplace: false, - }); + bundle = new StencilBundle(themePath, themeConfigStub, rawConfig, { marketplace: false }); }); - lab.afterEach(() => { - sandbox.restore(); + afterEach(() => { + jest.restoreAllMocks(); }); it('should return all regions with the right order.', async () => { @@ -49,7 +39,7 @@ describe('Stencil Bundle', () => { const templates = await assembleTemplatesTask(); const manifest = await generateManifest({ templates }); - expect(manifest.regions['pages/page']).to.equal([ + expect(manifest.regions['pages/page']).toEqual([ { name: 'top_region' }, { name: 'dynamic_a' }, { name: 'dynamic_b' }, @@ -61,7 +51,6 @@ describe('Stencil Bundle', () => { }); }); - describe('Regions', () => { describe('parseRegions', () => { const map = { @@ -82,9 +71,9 @@ describe('Regions', () => { '{{{region name=\'foo\'}}}{{{region name="bar"}}}{{{region name="foo"}}}': [{ name: 'foo' }, { name: 'bar' }], }; - for (let template in map) { + for (let template of Object.keys(map)) { it(`should parse region for template ${template}`, () => { - expect(Regions.parseRegions(template)).to.equal(map[template]); + expect(Regions.parseRegions(template)).toEqual(map[template]); }); } }); diff --git a/lib/stencil-bundle.js b/lib/stencil-bundle.js index 1846cdb3..3763d452 100644 --- a/lib/stencil-bundle.js +++ b/lib/stencil-bundle.js @@ -33,7 +33,7 @@ const Async = require('async'); const Crypto = require('crypto'); const Fs = require('fs'); const Path = require('path'); -const buildConfig = require('../lib/build-config'); +const BuildConfigManager = require('./BuildConfigManager'); const BundleValidator = require('./bundle-validator'); const Cycles = require('./cycles'); const CssAssembler = require('./css-assembler'); @@ -41,7 +41,13 @@ const LangAssembler = require('./lang-assembler'); const TemplateAssembler = require('./template-assembler'); const Regions = require('./regions'); -function Bundle(themePath, themeConfig, rawConfig, options) { +function Bundle( + themePath, + themeConfig, + rawConfig, + options, + buildConfigManger = new BuildConfigManager(), +) { const tasks = {}; this.options = options || {}; @@ -61,10 +67,10 @@ function Bundle(themePath, themeConfig, rawConfig, options) { tasks.schema = this.assembleSchema.bind(this); tasks.schemaTranslations = this.assembleSchemaTranslations.bind(this); - if (typeof buildConfig.production === 'function') { + if (typeof buildConfigManger.production === 'function') { tasks.theme = callback => { console.log('Theme task Started...'); - buildConfig.initWorker().production(err => { + buildConfigManger.initWorker().production(err => { if (err) { return callback(err); } @@ -262,15 +268,13 @@ function validateTheme(callback) { } function bundleTaskRunner(callback) { - let defaultName = this.configuration.name + '-' + this.configuration.version + '.zip'; + let defaultName = this.configuration.name + ? this.configuration.name + '-' + this.configuration.version + '.zip' + : 'Theme.zip'; const outputName = typeof this.options.name === 'string' ? this.options.name + '.zip' : defaultName; const outputFolder = typeof this.options.dest === 'string' ? this.options.dest : this.themePath; const bundleZipPath = Path.join(outputFolder, outputName); - if (!this.configuration.name) { - defaultName = 'Theme.zip'; - } - Async.parallel(this.tasks, (err, taskResults) => { if (err) { return callback(err); diff --git a/lib/stencil-bundle.spec.js b/lib/stencil-bundle.spec.js index 265cf906..47d0b85c 100644 --- a/lib/stencil-bundle.spec.js +++ b/lib/stencil-bundle.spec.js @@ -1,161 +1,147 @@ 'use strict'; -const Code = require('code'); const Fs = require('fs'); -const Sinon = require('sinon'); const Path = require('path'); const { promisify } = require('util'); const async = require('async'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); -const expect = Code.expect; -const it = lab.it; + const StencilBundle = require('./stencil-bundle'); const LangAssembler = require('./lang-assembler'); + +const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); const themeSchema = Fs.readFileSync((Path.join(themePath, 'schema.json'))).toString(); describe('Stencil Bundle', () => { - let sandbox; let Bundle; - lab.beforeEach(() => { - sandbox = Sinon.createSandbox(); + beforeEach(() => { const themeConfigStub = getThemeConfigStub(); const rawConfig = { "name": "Cornerstone", "version": "1.1.0", }; - sandbox.stub(console, 'log'); - sandbox.stub(console, 'error'); - sandbox.stub(Fs, 'writeFile').callsArgWith(2, null); + jest.spyOn(console, 'log').mockImplementation(jest.fn()); + jest.spyOn(console, 'error').mockImplementation(jest.fn()); + jest.spyOn(Fs, 'writeFile').mockImplementation((path, data, cb) => cb(null)); Bundle = new StencilBundle(themePath, themeConfigStub, rawConfig, { marketplace: false, }); }); - lab.afterEach(() => { - sandbox.restore(); + afterEach(() => { + jest.restoreAllMocks(); }); it('should initialize bundling', () => { - sandbox.stub(async, 'series').callsArgWith(1, new Error('error')); + jest.spyOn(async, 'series').mockImplementation((tasks, cb) => cb(new Error('error'))); const throws = () => { Bundle.initBundle(); }; - expect(throws).to.throw(Error); - expect(async.series.calledOnce).to.equal(true); + expect(throws).toThrow(Error); + expect(async.series).toHaveBeenCalledTimes(1); }); it('should assemble CSS files', async () => { - sandbox.stub(async, 'map').callsArgWith(2, null, ['this is dog']); + jest.spyOn(async, 'map').mockImplementation((coll, iteratee, cb) => cb(null, ['this is dog'])); const task = Bundle.getCssAssembleTask('scss'); const result = await promisify(task.bind(Bundle))(); - expect(result).to.equal({'theme.scss': 'this is dog'}); + expect(result).toEqual({'theme.scss': 'this is dog'}); }); it('should error on assemble CSS files', async () => { - sandbox.stub(async, 'map').callsArgWith(2, 'our_error'); - - let error; - try { - const task = Bundle.getCssAssembleTask('scss'); - await promisify(task.bind(Bundle))(); - } catch (err) { - error = err; - } - expect(error).to.equal('our_error'); + jest.spyOn(async, 'map').mockImplementation((coll, iteratee, cb) => cb(new Error('our_error1'))); + + const task = Bundle.getCssAssembleTask('scss'); + + await expect( + promisify(task.bind(Bundle))(), + ).rejects.toThrow('our_error1'); }); it('should assembleTemplates', async () => { const result = await promisify(Bundle.assembleTemplatesTask.bind(Bundle))(); - expect(result['pages/page']).to.include(['pages/page', 'components/a']); - expect(result['pages/page2']).to.include(['pages/page2', 'components/b']); + expect(result['pages/page']).toEqual( + expect.objectContaining({ + 'components/a': expect.any(String), + 'pages/page': expect.any(String), + }), + ); + expect(result['pages/page2']).toEqual( + expect.objectContaining({ + 'components/b': expect.any(String), + 'pages/page2': expect.any(String), + }), + ); }); it('should error when running assembleTemplates', async () => { - sandbox.stub(async, 'map').callsArgWith(2, 'our_error'); - - let error; - try { - await promisify(Bundle.assembleTemplatesTask.bind(Bundle))(); - } catch (err) { - error = err; - } + jest.spyOn(async, 'map').mockImplementation((coll, iteratee, cb) => cb(new Error('our_error2'))); - expect(error).to.equal('our_error'); + await expect( + promisify(Bundle.assembleTemplatesTask.bind(Bundle))(), + ).rejects.toThrow('our_error2'); }); it('should assemble the Schema', async () => { const result = await promisify(Bundle.assembleSchema.bind(Bundle))(); - expect(result).to.equal(themeSchema); + expect(result).toEqual(themeSchema); }); it('should assemble the Lang Files', async () => { - sandbox.stub(LangAssembler, 'assemble').callsArgWith(0, null); + jest.spyOn(LangAssembler, 'assemble').mockImplementation(cb => cb(null)); await promisify(Bundle.assembleLangTask.bind(Bundle))(); - expect(LangAssembler.assemble.calledOnce).to.equal(true); + expect(LangAssembler.assemble).toHaveBeenCalledTimes(1); }); it('should error on assembling the Lang Files', async () => { - sandbox.stub(LangAssembler, 'assemble').callsArgWith(0, 'our_error'); + jest.spyOn(LangAssembler, 'assemble').mockImplementation(cb => cb(new Error('our_error3'))); - let error; - try { - await promisify(Bundle.assembleLangTask.bind(Bundle))(); - } catch (err) { - error = err; - } + await expect( + promisify(Bundle.assembleLangTask.bind(Bundle))(), + ).rejects.toThrow('our_error3'); - expect(LangAssembler.assemble.calledOnce).to.equal(true); - expect(error).to.equal('our_error'); + expect(LangAssembler.assemble).toHaveBeenCalledTimes(1); }); it('should generate a manifest of files.', async () => { const templates = await promisify(Bundle.assembleTemplatesTask.bind(Bundle))(); const manifest = await promisify(Bundle.generateManifest.bind(Bundle))({ templates }); - expect(manifest.templates).to.contain(['components/a', 'components/b']); + expect(manifest.templates).toEqual(expect.arrayContaining(['components/a', 'components/b'])); }); it('should error while reading files to generate a manifest of files.', async () => { Bundle.templatesPath = 'invalid/path'; - let error; - try { - await promisify(Bundle.generateManifest.bind(Bundle))({}); - } catch (err) { - error = err; - } + await expect( + promisify(Bundle.generateManifest.bind(Bundle))({}), + ).rejects.toThrow('no such file or directory'); - expect(Fs.writeFile.calledOnce).to.equal(false); - expect(error instanceof Error).to.be.true(); - expect(error.message).to.contain('no such file or directory'); + expect(Fs.writeFile).toHaveBeenCalledTimes(0); }); function getThemeConfigStub() { const rawConfig = { meta: { - "author_name": "Emilio Esteves", - "author_email": "Emilio@work.net", - "author_support_url": "http://emilio.net", + author_name: "Emilio Esteves", + author_email: "Emilio@work.net", + author_support_url: "http://emilio.net", }, }; return { - configExists: sandbox.stub().returns(true), - getRawConfig: sandbox.stub().returns(rawConfig), - getSchema: sandbox.stub().callsArgWith(0, null, themeSchema), + configExists: jest.fn().mockReturnValue(true), + getRawConfig: jest.fn().mockReturnValue(rawConfig), + getSchema: jest.fn(cb => cb(null, themeSchema)), }; } }); diff --git a/lib/stencil-download.utils.spec.js b/lib/stencil-download.utils.spec.js index 7a46cafa..b9db830f 100644 --- a/lib/stencil-download.utils.spec.js +++ b/lib/stencil-download.utils.spec.js @@ -1,36 +1,31 @@ 'use strict'; + require('colors'); const fs = require('fs'); -const Code = require('code'); const Path = require('path'); const { promisify } = require('util'); const yauzl = require('yauzl'); const request = require("request"); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; -const it = lab.it; -const sinon = require('sinon'); const tmp = require('tmp'); + const { downloadThemeFiles } = require('./stencil-download.utils'); describe('ThemeDownloader', function () { - let sandbox; let archiveMockUrl = Path.join(process.cwd(), 'test', '_mocks', 'themes', 'valid', 'mock-theme.zip'); let themeCallback; let options = {}; let fsWriteSub; + let fsCreateWriteStreamStub; let zipOpenSpy; - lab.beforeEach(() => { - sandbox = sinon.createSandbox(); - options = {downloadUrl: archiveMockUrl}; - + beforeEach(() => { + options = { downloadUrl: archiveMockUrl }; themeCallback = () => {}; - sandbox.stub(request, 'Request').callsFake(requestStub); - fsWriteSub = sandbox.stub(fs, 'writeFile').callsFake(writeFileStub); + jest.spyOn(console, 'log').mockImplementation(jest.fn()); + + jest.spyOn(request, 'Request').mockImplementation(requestStub); + fsWriteSub = jest.spyOn(fs, 'writeFile').mockImplementation(writeFileStub); function writeFileStub(name, config, options, callback) { callback(false); @@ -48,102 +43,96 @@ describe('ThemeDownloader', function () { }; } - sandbox.stub(fs, 'createWriteStream').callsFake(tempPath => { + fsCreateWriteStreamStub = jest.spyOn(fs, 'createWriteStream').mockImplementation(tempPath => { fs.writeFileSync(tempPath, fs.readFileSync(options.downloadUrl)); }); }); - lab.afterEach(() => { - sandbox.restore(); + afterEach(() => { + jest.restoreAllMocks(); }); describe("Verify till Zip opens", () => { - lab.beforeEach(() => { - zipOpenSpy = sandbox.spy(yauzl, 'open'); + beforeEach(() => { + zipOpenSpy = jest.spyOn(yauzl, 'open'); zipOpenSpy(archiveMockUrl, {lazyEntries: true}, themeCallback); }); - lab.afterEach(() => { - sandbox.restore(); + afterEach(() => { + jest.restoreAllMocks(); }); it('should verify that the tmp.file() is called', async () => { - const tmpSpy = sandbox.spy(tmp); + const tmpFileSpy = jest.spyOn(tmp, 'file'); const promise = promisify(downloadThemeFiles)(options); - zipOpenSpy.lastCall.callback(); + zipOpenSpy.mock.calls[0][2](); await promise; - expect(tmpSpy.file.called).to.be.true(); + expect(tmpFileSpy).toHaveBeenCalledTimes(1); }); it('should return a callback error', async () => { - const throwsSpy = sandbox.spy(request); - downloadThemeFiles(null, themeCallback); - - try { - throwsSpy(); - } catch (e) { - } - - sandbox.assert.threw(throwsSpy); + await expect( + promisify(downloadThemeFiles)(null), + ).rejects.toThrow('Cannot read property \'downloadUrl\' of null'); }); it('should verify request is called with downloadUrl', async () => { const promise = promisify(downloadThemeFiles)(options); - zipOpenSpy.lastCall.callback(); + zipOpenSpy.mock.calls[0][2](); await promise; - sandbox.assert.calledOnce(request.Request); + expect(request.Request).toHaveBeenCalledTimes(1); }); it('should verify createWriteStream is also called within the request', async () => { const promise = promisify(downloadThemeFiles)(options); - zipOpenSpy.lastCall.callback(); + zipOpenSpy.mock.calls[0][2](); await promise; - sandbox.assert.calledOnce(fs.createWriteStream); + expect(fsCreateWriteStreamStub).toHaveBeenCalledTimes(1); }); it('should verify that the yauzl zip module is called', async () => { const promise = promisify(downloadThemeFiles)(options); - zipOpenSpy.lastCall.callback(); + zipOpenSpy.mock.calls[0][2](); await promise; - expect(yauzl.open.called).to.be.true(); + expect(yauzl.open).toHaveBeenCalledTimes(2); }); it('should call the zip open callback with zipFile', async () => { const zip = await promisify(zipOpenSpy)(archiveMockUrl, {lazyEntries: true}); - expect(zip.fileSize).to.be.greaterThan(100); + expect(zip.fileSize).toBeGreaterThan(100); }); }); describe("Verify After zip opens", () => { - lab.afterEach(() => { - options = {downloadUrl: archiveMockUrl}; - sandbox.restore(); + afterEach(() => { + options = { downloadUrl: archiveMockUrl }; + jest.restoreAllMocks(); }); it('should write the two files inside the zip archive', async () => { await promisify(downloadThemeFiles)(options); - expect(fsWriteSub.calledTwice).to.be.true(); + expect(fsWriteSub).toHaveBeenCalledTimes(2); }); it('should exclude config.json from files to write', async () => { options.exclude = ['config.json']; await promisify(downloadThemeFiles)(options); - expect(fsWriteSub.calledOnce).to.be.true(); + expect(fsWriteSub).toHaveBeenCalledTimes(1); }); it('should write config.json only', async () => { options.file = 'config.json'; await promisify(downloadThemeFiles)(options); - expect(fsWriteSub.calledOnce).to.be.true(); + expect(fsWriteSub).toHaveBeenCalledTimes(1); }); }); }); diff --git a/lib/stencil-init.spec.js b/lib/stencil-init.spec.js index a9b391b4..6c2d42c6 100644 --- a/lib/stencil-init.spec.js +++ b/lib/stencil-init.spec.js @@ -1,9 +1,6 @@ 'use strict'; const _ = require('lodash'); -const Code = require('code'); -const Sinon = require('sinon'); -const Lab = require('@hapi/lab'); const fs = require('fs'); const inquirer = require('inquirer'); @@ -13,9 +10,6 @@ const StencilInit = require('./stencil-init'); const { DEFAULT_CUSTOM_LAYOUTS_CONFIG } = require('../constants'); const { assertNoMutations } = require('../test/assertions/assertNoMutations'); -const { afterEach, beforeEach, describe, it } = exports.lab = Lab.script(); -const { expect } = Code; - const getStencilConfig = () => ({ customLayouts: { brand: { @@ -43,18 +37,18 @@ const getCliOptions = () => ({ token: "accessToken_from_CLI_options", }); -afterEach(() => Sinon.restore()); +afterEach(() => jest.restoreAllMocks()); -describe('StencilInit integration tests:', () => { - describe('run', async () => { +describe('StencilInit integration tests', () => { + describe('run', () => { it('should perform all the actions, save the result and inform the user about the successful finish', async () => { const dotStencilFilePath = './test/_mocks/bin/dotStencilFile.json'; const answers = getAnswers(); const expectedResult = JSON.stringify({ customLayouts: DEFAULT_CUSTOM_LAYOUTS_CONFIG, ...answers }, null, 2); - const fsWriteFileSyncStub = Sinon.stub(fs, "writeFileSync"); - const inquirerPromptStub = Sinon.stub(inquirer, 'prompt').returns(answers); - const consoleErrorStub = Sinon.stub(console, 'error'); - const consoleLogStub = Sinon.stub(console, 'log'); + const fsWriteFileSyncStub = jest.spyOn(fs, "writeFileSync").mockImplementation(jest.fn()); + const inquirerPromptStub = jest.spyOn(inquirer, 'prompt').mockReturnValue(answers); + const consoleErrorStub = jest.spyOn(console, 'error').mockImplementation(jest.fn()); + const consoleLogStub = jest.spyOn(console, 'log').mockImplementation(jest.fn()); // Test with real entities, just some methods stubbed const instance = new StencilInit({ @@ -66,18 +60,18 @@ describe('StencilInit integration tests:', () => { }); await instance.run(dotStencilFilePath, getCliOptions()); - expect(fsWriteFileSyncStub.calledOnce).to.be.true(); - expect(inquirerPromptStub.calledOnce).to.be.true(); - expect(consoleErrorStub.calledOnce).to.be.false(); - expect(consoleLogStub.calledOnce).to.be.true(); + expect(fsWriteFileSyncStub).toHaveBeenCalledTimes(1); + expect(inquirerPromptStub).toHaveBeenCalledTimes(1); + expect(consoleErrorStub).toHaveBeenCalledTimes(0); + expect(consoleLogStub).toHaveBeenCalledTimes(1); - expect(fsWriteFileSyncStub.lastCall.args).to.equal([dotStencilFilePath, expectedResult]); - expect(consoleLogStub.calledWith('You are now ready to go! To start developing, run $ ' + 'stencil start'.cyan)).to.be.true(); + expect(fsWriteFileSyncStub).toHaveBeenCalledWith(dotStencilFilePath, expectedResult); + expect(consoleLogStub).toHaveBeenCalledWith('You are now ready to go! To start developing, run $ ' + 'stencil start'.cyan); }); }); }); -describe('StencilInit unit tests:', () => { +describe('StencilInit unit tests', () => { const serverConfigPort = 3000; const dotStencilFilePath = '/some/test/path/dotStencilFile.json'; let consoleStub; @@ -89,26 +83,24 @@ describe('StencilInit unit tests:', () => { beforeEach(() => { consoleStub = { - log: Sinon.stub(), - error: Sinon.stub(), + log: jest.fn(), + error: jest.fn(), }; inquirerStub = { - prompt: Sinon.stub().returns(getAnswers()), + prompt: jest.fn().mockReturnValue(getAnswers()), }; jsonLintStub = { - parse: Sinon.stub().returns(getStencilConfig()), + parse: jest.fn().mockReturnValue(getStencilConfig()), }; fsStub = { - existsSync: Sinon.stub(), - readFileSync: Sinon.stub(), - writeFileSync: Sinon.stub(), + existsSync: jest.fn(), + readFileSync: jest.fn(), + writeFileSync: jest.fn(), }; serverConfigStub = { - get: Sinon.stub().callsFake(prop => { - return ({ - '/server/port': serverConfigPort, - })[prop]; - }), + get: jest.fn(prop => ({ + '/server/port': serverConfigPort, + })[prop]), }; getStencilInitInstance = () => new StencilInit({ @@ -124,73 +116,74 @@ describe('StencilInit unit tests:', () => { it('should create an instance of StencilInit without options parameters passed', async () => { const instance = new StencilInit(); - expect(instance).to.be.instanceOf(StencilInit); + expect(instance).toBeInstanceOf(StencilInit); }); it('should create an instance of StencilInit with options parameters passed', async () => { const instance = getStencilInitInstance(); - expect(instance).to.be.instanceOf(StencilInit); + expect(instance).toBeInstanceOf(StencilInit); }); }); - describe('readStencilConfig ', async () => { + describe('readStencilConfig ', () => { it('should return an empty config if the file doesn\'t exist', async () => { const instance = getStencilInitInstance(); - fsStub.existsSync.returns(false); + fsStub.existsSync.mockReturnValue(false); const res = instance.readStencilConfig(dotStencilFilePath); - expect(fsStub.existsSync.calledOnce).to.be.true(); - expect(res).to.equal({}); + expect(fsStub.existsSync).toHaveBeenCalledTimes(1); + expect(res).toEqual({}); }); it('should read the file and return parsed results if the file exists and it is valid', async () => { const parsedConfig = getStencilConfig(); const serializedConfig = JSON.stringify(parsedConfig, null, 2); const instance = getStencilInitInstance(); - fsStub.existsSync.returns(true); - fsStub.readFileSync.returns(serializedConfig); - jsonLintStub.parse.returns(parsedConfig); + fsStub.existsSync.mockReturnValue(true); + fsStub.readFileSync.mockReturnValue(serializedConfig); + jsonLintStub.parse.mockReturnValue(parsedConfig); const res = instance.readStencilConfig(dotStencilFilePath); - expect(fsStub.existsSync.calledOnce).to.be.true(); - expect(fsStub.readFileSync.calledOnce).to.be.true(); - expect(jsonLintStub.parse.calledOnce).to.be.true(); - expect(consoleStub.error.calledOnce).to.be.false(); + expect(fsStub.existsSync).toHaveBeenCalledTimes(1); + expect(fsStub.readFileSync).toHaveBeenCalledTimes(1); + expect(jsonLintStub.parse).toHaveBeenCalledTimes(1); + expect(consoleStub.error).toHaveBeenCalledTimes(0); - expect(fsStub.existsSync.calledWith(dotStencilFilePath)).to.be.true(); - expect(fsStub.readFileSync.calledWith(dotStencilFilePath, { encoding: 'utf-8' })).to.be.true(); - expect(jsonLintStub.parse.calledWith(serializedConfig, dotStencilFilePath)).to.be.true(); + expect(fsStub.existsSync).toHaveBeenCalledWith(dotStencilFilePath); + expect(fsStub.readFileSync).toHaveBeenCalledWith(dotStencilFilePath, { encoding: 'utf-8' }); + expect(jsonLintStub.parse).toHaveBeenCalledWith(serializedConfig, dotStencilFilePath); - expect(res).to.equal(parsedConfig); + expect(res).toEqual(parsedConfig); }); it('should read the file, inform the user that the file is broken and return an empty config', async () => { const serializedConfig = '{ I am broken! }'; const thrownError = new Error('invalid file'); const instance = getStencilInitInstance(); - fsStub.existsSync.returns(true); - fsStub.readFileSync.returns(serializedConfig); - jsonLintStub.parse.throws(thrownError); + fsStub.existsSync.mockReturnValue(true); + fsStub.readFileSync.mockReturnValue(serializedConfig); + jsonLintStub.parse.mockImplementation(() => { throw thrownError; }); const res = instance.readStencilConfig(dotStencilFilePath); - expect(fsStub.existsSync.calledOnce).to.be.true(); - expect(fsStub.readFileSync.calledOnce).to.be.true(); - expect(jsonLintStub.parse.calledOnce).to.be.true(); - expect(consoleStub.error.calledOnce).to.be.true(); + expect(fsStub.existsSync).toHaveBeenCalledTimes(1); + expect(fsStub.readFileSync).toHaveBeenCalledTimes(1); + expect(jsonLintStub.parse).toHaveBeenCalledTimes(1); + expect(consoleStub.error).toHaveBeenCalledTimes(1); - expect(fsStub.existsSync.calledWith(dotStencilFilePath)).to.be.true(); - expect(fsStub.readFileSync.calledWith(dotStencilFilePath, { encoding: 'utf-8' })).to.be.true(); - expect(jsonLintStub.parse.calledWith(serializedConfig, dotStencilFilePath)).to.be.true(); + expect(fsStub.existsSync).toHaveBeenCalledWith(dotStencilFilePath); + expect(fsStub.readFileSync).toHaveBeenCalledWith(dotStencilFilePath, { encoding: 'utf-8' }); + expect(jsonLintStub.parse).toHaveBeenCalledWith(serializedConfig, dotStencilFilePath); - expect(res).to.equal({}); + expect(res).toEqual({}); }); }); - describe('getDefaultAnswers', async () => { + describe('getDefaultAnswers', () => { + // eslint-disable-next-line jest/expect-expect it('should not mutate the passed objects', async () => { const stencilConfig = getStencilConfig(); const cliOptions = getCliOptions(); @@ -209,9 +202,9 @@ describe('StencilInit unit tests:', () => { const res = instance.getDefaultAnswers(stencilConfig, cliOptions); - expect(res.normalStoreUrl).to.equal(cliOptions.url); - expect(res.accessToken).to.equal(cliOptions.token); - expect(res.port).to.equal(cliOptions.port); + expect(res.normalStoreUrl).toEqual(cliOptions.url); + expect(res.accessToken).toEqual(cliOptions.token); + expect(res.port).toEqual(cliOptions.port); }); it('should pick values from stencilConfig if cliOptions are empty', async () => { @@ -221,9 +214,9 @@ describe('StencilInit unit tests:', () => { const res = instance.getDefaultAnswers(stencilConfig, cliOptions); - expect(res.normalStoreUrl).to.equal(stencilConfig.normalStoreUrl); - expect(res.accessToken).to.equal(stencilConfig.accessToken); - expect(res.port).to.equal(stencilConfig.port); + expect(res.normalStoreUrl).toEqual(stencilConfig.normalStoreUrl); + expect(res.accessToken).toEqual(stencilConfig.accessToken); + expect(res.port).toEqual(stencilConfig.port); }); it('should pick values from serverConfig if stencilConfig and cliOptions are empty', async () => { @@ -233,23 +226,23 @@ describe('StencilInit unit tests:', () => { const res = instance.getDefaultAnswers(stencilConfig, cliOptions); - expect(res.port).to.equal(serverConfigPort); + expect(res.port).toEqual(serverConfigPort); - expect(res.normalStoreUrl).to.equal(cliOptions.url); - expect(res.accessToken).to.equal(stencilConfig.accessToken); + expect(res.normalStoreUrl).toEqual(cliOptions.url); + expect(res.accessToken).toEqual(stencilConfig.accessToken); }); }); - describe('askQuestions', async () => { + describe('askQuestions', () => { it('should call inquirer.prompt with correct arguments', async () => { const defaultAnswers = getAnswers(); const instance = getStencilInitInstance(); await instance.askQuestions(defaultAnswers); - expect(inquirerStub.prompt.calledOnce).to.be.true(); + expect(inquirerStub.prompt).toHaveBeenCalledTimes(1); // We compare the serialized results because the objects contain functions which hinders direct comparison - expect(JSON.stringify(inquirerStub.prompt.lastCall.args)).to.equal(JSON.stringify([[ + expect(JSON.stringify(inquirerStub.prompt.mock.calls)).toEqual(JSON.stringify([[[ { type: 'input', name: 'normalStoreUrl', @@ -283,11 +276,12 @@ describe('StencilInit unit tests:', () => { } }, }, - ]])); + ]]])); }); }); - describe('applyAnswers', async () => { + describe('applyAnswers', () => { + // eslint-disable-next-line jest/expect-expect it('should not mutate the passed objects', async () => { const stencilConfig = getStencilConfig(); const answers = getAnswers(); @@ -306,12 +300,12 @@ describe('StencilInit unit tests:', () => { const res = instance.applyAnswers(stencilConfig, answers); - expect(res.normalStoreUrl).to.equal(answers.normalStoreUrl); - expect(res.accessToken).to.equal(answers.accessToken); - expect(res.port).to.equal(answers.port); + expect(res.normalStoreUrl).toEqual(answers.normalStoreUrl); + expect(res.accessToken).toEqual(answers.accessToken); + expect(res.port).toEqual(answers.port); - expect(res.githubToken).to.equal(stencilConfig.githubToken); - expect(res.customLayouts).to.equal(stencilConfig.customLayouts); + expect(res.githubToken).toEqual(stencilConfig.githubToken); + expect(res.customLayouts).toEqual(stencilConfig.customLayouts); }); it('should add a customLayouts property with default empty values if it\'s absent in stencilConfig', async () => { @@ -321,14 +315,14 @@ describe('StencilInit unit tests:', () => { const res = instance.applyAnswers(stencilConfig, answers); - expect(res.customLayouts).to.equal(DEFAULT_CUSTOM_LAYOUTS_CONFIG); + expect(res.customLayouts).toEqual(DEFAULT_CUSTOM_LAYOUTS_CONFIG); // Make sure that other props aren't overwritten: - expect(res.accessToken).to.equal(answers.accessToken); - expect(res.githubToken).to.equal(stencilConfig.githubToken); + expect(res.accessToken).toEqual(answers.accessToken); + expect(res.githubToken).toEqual(stencilConfig.githubToken); }); }); - describe('saveStencilConfig ', async () => { + describe('saveStencilConfig ', () => { it('should call fs.writeFileSync with the serialized config', async () => { const stencilConfig = getStencilConfig(); const serializedConfig = JSON.stringify(stencilConfig, null, 2); @@ -336,8 +330,8 @@ describe('StencilInit unit tests:', () => { instance.saveStencilConfig(stencilConfig, dotStencilFilePath); - expect(fsStub.writeFileSync.calledOnce).to.be.true(); - expect(fsStub.writeFileSync.calledWith(dotStencilFilePath, serializedConfig)).to.be.true(); + expect(fsStub.writeFileSync).toHaveBeenCalledTimes(1); + expect(fsStub.writeFileSync).toHaveBeenCalledWith(dotStencilFilePath, serializedConfig); }); }); }); diff --git a/lib/stencil-push.spec.js b/lib/stencil-push.spec.js index 4324b4de..7d6d237d 100644 --- a/lib/stencil-push.spec.js +++ b/lib/stencil-push.spec.js @@ -1,45 +1,26 @@ 'use strict'; -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); const Wreck = require('wreck'); const { promisify } = require('util'); const StencilPush = require('./stencil-push'); const utils = require('./stencil-push.utils.js'); +const { MockDB } = require('../test/_mocks/MockDB'); -const expect = Code.expect; -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const it = lab.it; -const mockDb = { - _data: {}, - get data() { - return this._data; - }, - set data(data) { - this._data = data; - }, -}; +const mockDb = new MockDB(); describe('stencil push', () => { - let sandbox; - - lab.beforeEach(() => { - mockDb.data = {}; - sandbox = sinon.createSandbox(); - - sandbox.stub(Wreck, 'get').callsFake(requestStub); - sandbox.stub(Wreck, 'post').callsFake(requestStub); - sandbox.stub(Wreck, 'put').callsFake(requestStub); - sandbox.stub(utils, 'generateBundle').callsFake(utilStub({ + beforeEach(() => { + jest.spyOn(Wreck, 'get').mockImplementation(requestStub); + jest.spyOn(Wreck, 'post').mockImplementation(requestStub); + jest.spyOn(Wreck, 'put').mockImplementation(requestStub); + jest.spyOn(utils, 'generateBundle').mockImplementation(utilStub({ bundleZipPath: 'bundleZipPath', })); - sandbox.stub(utils, 'promptUserWhetherToApplyTheme').callsFake(utilStub({ + jest.spyOn(utils, 'promptUserWhetherToApplyTheme').mockImplementation(utilStub({ applyTheme: true, })); - sandbox.stub(utils, 'promptUserForVariation').callsFake(utilStub({ + jest.spyOn(utils, 'promptUserForVariation').mockImplementation(utilStub({ variationId: 'bold', })); @@ -50,16 +31,13 @@ describe('stencil push', () => { } function utilStub(data) { - return (options, callback) => { - process.nextTick(() => { - callback(null, Object.assign({}, options, data)); - }); - }; + return async options => ({...options, ...data}); } }); - lab.afterEach(() => { - sandbox.restore(); + afterEach(() => { + jest.restoreAllMocks(); + mockDb.data = {}; }); it('should throw an error if dotStencilFilePath is not provided', () => { @@ -67,29 +45,20 @@ describe('stencil push', () => { StencilPush(); }; - expect(throws).to.throw('dotStencilFilePath is required!'); + expect(throws).toThrow('dotStencilFilePath is required!'); }); it('should return an error if dotStencilFilePath does not map to a file', async () => { - let error; - try { - await promisify(StencilPush)({ dotStencilFilePath: 'DNE' }); - } catch (err) { - error = err; - } - - expect(error).to.be.an.error(/ENOENT/); + await expect( + promisify(StencilPush)({ dotStencilFilePath: 'DNE' }), + ).rejects.toThrow(/ENOENT/); }); it('should return an error if it fails to retrieve the store hash', async () => { const dotStencilFilePath = `${__dirname}/../test/_mocks/bin/dotStencilFile.json`; - let error; - try { - await promisify(StencilPush)({ dotStencilFilePath }); - } catch (err) { - error = err; - } - expect(error).to.be.an.error('Failed to retrieve store hash'); + await expect( + promisify(StencilPush)({ dotStencilFilePath }), + ).rejects.toThrow('Failed to retrieve store hash'); }); }); diff --git a/lib/stencil-push.utils.spec.js b/lib/stencil-push.utils.spec.js index ac886bbf..655d92c8 100644 --- a/lib/stencil-push.utils.spec.js +++ b/lib/stencil-push.utils.spec.js @@ -1,41 +1,26 @@ 'use strict'; -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); const Wreck = require('wreck'); const { promisify } = require('util'); const mockConfig = require('../test/_mocks/bin/dotStencilFile.json'); +const { MockDB } = require('../test/_mocks/MockDB'); const { getStoreHash } = require('./stencil-push.utils'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const it = lab.it; -const expect = Code.expect; -const mockDb = { - _data: {}, - get data() { - return this._data; - }, - set data(data) { - this._data = data; - }, -}; +const mockDb = new MockDB(); describe('stencil push utils', () => { - lab.beforeEach(() => { - this.wreckReqStub = sinon.stub(Wreck, 'request').callsFake((method, url, options, callback) => { - callback(null, mockDb.data); - }); - this.wreckReadStub = sinon.stub(Wreck, 'read').callsFake((response, options, callback) => { - callback(null, response); - }); + beforeEach(() => { + jest.spyOn(Wreck, 'request').mockImplementation( + (method, url, options, cb) => cb(null, mockDb.data), + ); + jest.spyOn(Wreck, 'read').mockImplementation( + (response, options, cb) => cb(null, response), + ); }); - lab.afterEach(() => { - this.wreckReqStub.restore(); - this.wreckReadStub.restore(); + afterEach(() => { + jest.restoreAllMocks(); }); describe('.getStoreHash()', () => { @@ -47,8 +32,8 @@ describe('stencil push utils', () => { it('should get the store hash', async () => { const result = await promisify(getStoreHash)({ config: mockConfig }); - expect(result.storeHash).to.be.equal(mockDb.data.store_hash); - expect(result.config.normalStoreUrl).to.be.equal(mockConfig.normalStoreUrl); + expect(result.storeHash).toEqual(mockDb.data.store_hash); + expect(result.config.normalStoreUrl).toEqual(mockConfig.normalStoreUrl); }); }); }); diff --git a/lib/theme-api-client.js b/lib/theme-api-client.js index f7810db4..a1ba3b9d 100644 --- a/lib/theme-api-client.js +++ b/lib/theme-api-client.js @@ -1,5 +1,6 @@ 'use strict'; +require('colors'); const fs = require('fs'); const path = require('path'); const request = require("request"); @@ -99,22 +100,23 @@ function getJob(options, callback) { }); } -function printErrorMessages(errors_array) { - if (!Array.isArray(errors_array)) { +/** + * @param {object[]} errors + * @returns {void} + */ +function printErrorMessages(errors) { + if (!Array.isArray(errors)) { console.log("unknown error".red); - return false; + return; } - for (var i = 0; i < errors_array.length; i++) { - try { - console.log(errors_array[i].message.red + '\n'); - } catch (err) { - continue; + for (let error of errors) { + if (error && error.message) { + console.log(error.message.red + '\n'); } } console.log('Please visit the troubleshooting page https://developer.bigcommerce.com/stencil-docs/deploying-a-theme/troubleshooting-theme-uploads'); - return true; } function getThemes(options, callback) { diff --git a/lib/theme-api-client.spec.js b/lib/theme-api-client.spec.js index ab79e7f1..cdd0c1b8 100644 --- a/lib/theme-api-client.spec.js +++ b/lib/theme-api-client.spec.js @@ -1,55 +1,69 @@ 'use strict'; -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; +require('colors'); const themeApiClient = require('./theme-api-client'); -const it = lab.it; -const sinon = require('sinon'); describe('theme-api-client', () => { - describe('printErrorMessages()', () => { + describe('printErrorMessages', () => { let consoleLogStub; - lab.before(() => { - consoleLogStub = sinon.stub(console, 'log'); + beforeAll(() => { + consoleLogStub = jest.spyOn(console, 'log').mockImplementation(jest.fn()); }); - lab.after(() => { - console.log.restore(); - }); + afterEach(() => { + jest.clearAllMocks(); + }); - it('should log unknown error and return if input is not an array', () => { - expect(themeApiClient.printErrorMessages("string")).to.be.equal(false); - expect(consoleLogStub.calledOnce).to.be.equal(true); + afterAll(() => { + jest.restoreAllMocks(); + }); - consoleLogStub.resetHistory(); + it('should log unknown error and return if input is not an array, but string', () => { + themeApiClient.printErrorMessages('string'); - expect(themeApiClient.printErrorMessages({ "key": "value" })).to.be.equal(false); - expect(consoleLogStub.calledOnce).to.be.equal(true); + expect(consoleLogStub).toHaveBeenCalledTimes(1); + expect(consoleLogStub).toHaveBeenCalledWith('unknown error'.red); + }); - consoleLogStub.resetHistory(); + it('should log unknown error and return if input is not an array, but object', () => { + themeApiClient.printErrorMessages({ 'key': 'value' }); - expect(themeApiClient.printErrorMessages(null)).to.be.equal(false); - expect(consoleLogStub.calledOnce).to.be.equal(true); - }); + expect(consoleLogStub).toHaveBeenCalledTimes(1); + expect(consoleLogStub).toHaveBeenCalledWith('unknown error'.red); + }); + + it('should log unknown error and return if input is not an array, but null', () => { + themeApiClient.printErrorMessages(null); + + expect(consoleLogStub).toHaveBeenCalledTimes(1); + expect(consoleLogStub).toHaveBeenCalledWith('unknown error'.red); + }); it('should log error message for each error in the array', () => { - consoleLogStub.resetHistory(); - const arrayInput = [{"message": "first_error"}, {"message": "2nd_error"}]; + const arrayInput = [{'message': 'first_error'}, {'message': '2nd_error'}]; - expect(themeApiClient.printErrorMessages(arrayInput)).to.be.equal(true); - expect(consoleLogStub.calledThrice).to.be.equal(true); + themeApiClient.printErrorMessages(arrayInput); + + expect(consoleLogStub).toHaveBeenCalledTimes(3); + expect(consoleLogStub.mock.calls).toEqual([ + ['first_error'.red + '\n'], + ['2nd_error'.red + '\n'], + ['Please visit the troubleshooting page https://developer.bigcommerce.com/stencil-docs/deploying-a-theme/troubleshooting-theme-uploads'], + ]); }); it('should skip non object elements in the input array', () => { - consoleLogStub.resetHistory(); - const arrayInput = [{"message": "first_error"}, "string", {"message": "2nd_error"}]; + const arrayInput = [{'message': 'first_error'}, 'string', {'message': '2nd_error'}]; + + themeApiClient.printErrorMessages(arrayInput); - expect(themeApiClient.printErrorMessages(arrayInput)).to.be.equal(true); - expect(consoleLogStub.calledThrice).to.be.equal(true); + expect(consoleLogStub).toHaveBeenCalledTimes(3); + expect(consoleLogStub.mock.calls).toEqual([ + ['first_error'.red + '\n'], + ['2nd_error'.red + '\n'], + ['Please visit the troubleshooting page https://developer.bigcommerce.com/stencil-docs/deploying-a-theme/troubleshooting-theme-uploads'], + ]); }); }); }); diff --git a/lib/theme-config.spec.js b/lib/theme-config.spec.js index a956d886..a34f3000 100644 --- a/lib/theme-config.spec.js +++ b/lib/theme-config.spec.js @@ -1,9 +1,6 @@ 'use strict'; -const Code = require('code'); const _ = require('lodash'); -const Lab = require('@hapi/lab'); -const Sinon = require('sinon'); const Path = require('path'); const Os = require('os'); const Fs = require('fs'); @@ -14,21 +11,20 @@ const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); const missingVariationsThemePath = Path.join(process.cwd(), 'test/_mocks/themes/missing-variation'); const bareBonesThemePath = Path.join(process.cwd(), 'test/_mocks/themes/bare-bones'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; -const it = lab.it; - describe('ThemeConfig', () => { let themeConfig; - lab.beforeEach(async () => { + beforeEach(async () => { themeConfig = ThemeConfig.getInstance(themePath).setVariationByName('First'); }); + afterEach(async () => { + jest.restoreAllMocks(); + }); + describe('getInstance()', () => { it ('should always return the same instance', async () => { - expect(themeConfig).to.equal(ThemeConfig.getInstance()); + expect(themeConfig).toEqual(ThemeConfig.getInstance()); }); it ('should allow overwriting of configPath, schemaPath, and variationName by calling getInstance with params', async () => { @@ -37,9 +33,9 @@ describe('ThemeConfig', () => { const secondSchemaPath = isWindows ? '\\fake\\schema.json' : '/fake/schema.json'; const secondThemeConfig = ThemeConfig.getInstance('/fake'); - expect(secondThemeConfig.configPath).to.equal(secondConfigPath); - expect(secondThemeConfig.schemaPath).to.equal(secondSchemaPath); - expect(secondThemeConfig).to.equal(themeConfig); + expect(secondThemeConfig.configPath).toEqual(secondConfigPath); + expect(secondThemeConfig.schemaPath).toEqual(secondSchemaPath); + expect(secondThemeConfig).toEqual(themeConfig); }); }); @@ -65,15 +61,15 @@ describe('ThemeConfig', () => { thumb: { width: 10, height: 10 }, }; - expect(config.settings).to.equal(settingsToCompare); - expect(config.images).to.equal(imagesToCompare); - expect(ThemeConfig.getInstance().globalSettings).to.equal(originalSettingsToCompare); + expect(config.settings).toEqual(settingsToCompare); + expect(config.images).toEqual(imagesToCompare); + expect(ThemeConfig.getInstance().globalSettings).toEqual(originalSettingsToCompare); }); it('should throw an Error if there are no variations in config.json file', async () => { const themeConfig = ThemeConfig.getInstance(missingVariationsThemePath); - expect(themeConfig.getConfig).to.throw(Error); + expect(themeConfig.getConfig).toThrow(Error); }); it('should grab the first variation if none is passed in', async () => { @@ -81,14 +77,14 @@ describe('ThemeConfig', () => { themeConfig.setVariationByName(null); // console.log(themeConfig.getConfig()); - expect(themeConfig.getConfig().variationName).to.equal('First'); + expect(themeConfig.getConfig().variationName).toEqual('First'); }); it('should grab a specific variation if passed in', async () => { const themeConfig = ThemeConfig.getInstance(); themeConfig.setVariationByName('Second'); - expect(themeConfig.getConfig().variationName).to.equal('Second'); + expect(themeConfig.getConfig().variationName).toEqual('Second'); }); it('should throw an Error if the passed in variation name does not match any in the config.json', async () => { @@ -98,18 +94,18 @@ describe('ThemeConfig', () => { themeConfig.setVariationByName('Does Not Exist'); } - expect(setVariation).to.throw(Error); + expect(setVariation).toThrow(Error); }); it('should set proper default values if they do not exist', async () => { const themeConfig = ThemeConfig.getInstance(bareBonesThemePath), config = themeConfig.getConfig(); - expect(config.settings).to.equal({}); - expect(config.images).to.equal({}); - expect(config.css_compiler).to.equal('scss'); - expect(config.autoprefixer_cascade).to.equal(true); - expect(config.autoprefixer_browsers).to.equal(['> 1%', 'last 2 versions', 'Firefox ESR']); + expect(config.settings).toEqual({}); + expect(config.images).toEqual({}); + expect(config.css_compiler).toEqual('scss'); + expect(config.autoprefixer_cascade).toEqual(true); + expect(config.autoprefixer_browsers).toEqual(['> 1%', 'last 2 versions', 'Firefox ESR']); }); }); @@ -119,7 +115,7 @@ describe('ThemeConfig', () => { originalSettings, themeConfig; - lab.beforeEach(async () => { + beforeEach(async () => { themeConfig = ThemeConfig.getInstance(); config = themeConfig.getConfig(); originalSettings = _.cloneDeep(config.settings); @@ -133,50 +129,46 @@ describe('ThemeConfig', () => { }); it('should update the currentConfig with the new changes', async () => { - expect(originalSettings).not.to.equal(newSettings); + expect(originalSettings).not.toEqual(newSettings); themeConfig.updateConfig(newSettings); - expect(themeConfig.getConfig().settings).not.to.equal(originalSettings); - expect(themeConfig.getConfig().settings).to.equal(newSettings); + expect(themeConfig.getConfig().settings).not.toEqual(originalSettings); + expect(themeConfig.getConfig().settings).toEqual(newSettings); }); - it('should not write to config file if saveToFile is falsey', async () => { - Sinon.stub(Fs, 'writeFileSync'); + it('should not write to config file if saveToFile is falsy', async () => { + jest.spyOn(Fs, 'writeFileSync').mockImplementation(jest.fn()); themeConfig.updateConfig(newSettings); - expect(Fs.writeFileSync.called).to.be.false(); - Fs.writeFileSync.restore(); + + expect(Fs.writeFileSync.called).toBeFalsy(); }); it('should write to config file if saveToFile is truthy', async () => { - Sinon.stub(Fs, 'writeFileSync'); + jest.spyOn(Fs, 'writeFileSync').mockImplementation(jest.fn()); themeConfig.updateConfig(newSettings, true); - expect(Fs.writeFileSync.called).to.be.true(); - Fs.writeFileSync.restore(); + + expect(Fs.writeFileSync).toHaveBeenCalled(); }); it('should just modify the variations section of the file', async () => { const configPath = Path.join(themePath, 'config.json'); const initialConfig = JSON.parse(Fs.readFileSync(configPath, {encoding: 'utf-8'})); - const testSavePromise = new Promise(resolve => - Sinon.stub(Fs, 'writeFileSync').callsFake((...args) => resolve(args)), - ); + const writeFileSyncStub = jest.spyOn(Fs, 'writeFileSync').mockImplementation(jest.fn()); + themeConfig.updateConfig(newSettings, true); - let [, newConfig] = await testSavePromise; - newConfig = JSON.parse(newConfig); + const newConfig = JSON.parse(writeFileSyncStub.mock.calls[0][1]); - expect(newConfig).not.to.equal(initialConfig); + expect(newConfig).not.toEqual(initialConfig); delete newConfig.variations; delete initialConfig.variations; - expect(newConfig).to.equal(initialConfig); - - Fs.writeFileSync.restore(); + expect(newConfig).toEqual(initialConfig); }); }); @@ -187,14 +179,14 @@ describe('ThemeConfig', () => { const schema = await promisify(themeConfig.getSchema.bind(themeConfig))(); - expect(schema).to.be.an.array(); + expect(schema).toBeInstanceOf(Array); - expect(schema[0]).to.equal(originalSchema[0]); - expect(schema).to.have.length(2); + expect(schema[0]).toEqual(originalSchema[0]); + expect(schema).toHaveLength(2); - expect(schema[1].settings[0].force_reload).to.true(); - expect(schema[1].settings[1].force_reload).to.true(); - expect(schema[1].settings[2].force_reload).to.true(); + expect(schema[1].settings[0].force_reload).toBeTruthy(); + expect(schema[1].settings[1].force_reload).toBeTruthy(); + expect(schema[1].settings[2].force_reload).toBeTruthy(); }); it('should return an empty schema', async () => { @@ -202,8 +194,8 @@ describe('ThemeConfig', () => { const schema = await promisify(themeConfig.getSchema.bind(themeConfig))(); - expect(schema).to.be.an.array(); - expect(schema).to.have.length(0); + expect(schema).toBeInstanceOf(Array); + expect(schema).toHaveLength(0); }); }); }); diff --git a/lib/validator/schema-translations.spec.js b/lib/validator/schema-translations.spec.js index 7b4d00f4..57eae1ef 100644 --- a/lib/validator/schema-translations.spec.js +++ b/lib/validator/schema-translations.spec.js @@ -1,10 +1,4 @@ const Paths = require('path'); -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const it = lab.it; -const expect = Code.expect; const ValidatorSchemaTranslations = require('./schema-translations'); const schema = require(Paths.join(process.cwd(), 'test/_mocks/themes/valid/schema.json')); @@ -21,7 +15,7 @@ describe('ValidatorSchemaTranslations', () => { instance.setTranslations(schemaTranslations); - expect(instance.getTranslations()).equals(schemaTranslations); + expect(instance.getTranslations()).toEqual(schemaTranslations); }); it('should return translations keys', () => { @@ -29,13 +23,13 @@ describe('ValidatorSchemaTranslations', () => { instance.setSchema(schema); - expect(instance.getSchemaKeys()).equals(['i18n.Test']); + expect(instance.getSchemaKeys()).toEqual(['i18n.Test']); }); it('should return validation schema', () => { const instance = validatorSchemaTranslations(); - expect(instance.getValidationSchema()).equals(validationsTranslations); + expect(instance.getValidationSchema()).toEqual(validationsTranslations); }); it('should return i18n keys array without duplicates', () => { @@ -44,7 +38,7 @@ describe('ValidatorSchemaTranslations', () => { instance.setSchemaKeys('i18n.Global'); instance.setSchemaKeys('i18n.Global'); - expect(instance.getSchemaKeys()).equals(['i18n.Global']); + expect(instance.getSchemaKeys()).toEqual(['i18n.Global']); }); it('should return empty i18n keys array if specify empty string', () => { @@ -52,6 +46,6 @@ describe('ValidatorSchemaTranslations', () => { instance.setSchemaKeys(''); - expect(instance.getSchemaKeys()).equals([]); + expect(instance.getSchemaKeys()).toEqual([]); }); }); diff --git a/package-lock.json b/package-lock.json index 37779ca3..efd58b4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,19 @@ } }, "@babel/core": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", - "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", + "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.5", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/generator": "^7.11.4", + "@babel/helper-module-transforms": "^7.11.0", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.10.5", + "@babel/parser": "^7.11.4", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.5", - "@babel/types": "^7.10.5", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -91,21 +91,6 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -136,22 +121,16 @@ } }, "@babel/generator": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", - "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", "dev": true, "requires": { - "@babel/types": "^7.10.5", + "@babel/types": "^7.11.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, "dependencies": { - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -181,12 +160,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", - "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", "dev": true, "requires": { - "@babel/types": "^7.10.5" + "@babel/types": "^7.11.0" } }, "@babel/helper-module-imports": { @@ -199,17 +178,17 @@ } }, "@babel/helper-module-transforms": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", - "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", "@babel/helper-replace-supers": "^7.10.4", "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", "@babel/template": "^7.10.4", - "@babel/types": "^7.10.5", + "@babel/types": "^7.11.0", "lodash": "^4.17.19" } }, @@ -251,12 +230,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.11.0" } }, "@babel/helper-validator-identifier": { @@ -320,9 +299,9 @@ } }, "@babel/parser": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", - "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -510,17 +489,17 @@ } }, "@babel/traverse": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", - "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.5", + "@babel/generator": "^7.11.0", "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.5", - "@babel/types": "^7.10.5", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" @@ -605,22 +584,14 @@ } }, "@babel/types": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", - "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - } } }, "@bcoe/v8-coverage": { @@ -1349,41 +1320,6 @@ "@hapi/hoek": "8.x.x" } }, - "@hapi/bossy": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@hapi/bossy/-/bossy-4.1.3.tgz", - "integrity": "sha512-a3+tEnP2OeN1rm3Bqpo8rO11RAIAOIre4pmjzABkAQp23Y0qv/bD2txkdTl9Gajxo6YNYsgy9dlyQcCUczx8JQ==", - "dev": true, - "requires": { - "@hapi/boom": "7.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/joi": "16.x.x" - }, - "dependencies": { - "@hapi/boom": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", - "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", - "dev": true, - "requires": { - "@hapi/hoek": "8.x.x" - } - }, - "@hapi/joi": { - "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz", - "integrity": "sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==", - "dev": true, - "requires": { - "@hapi/address": "^2.1.2", - "@hapi/formula": "^1.2.0", - "@hapi/hoek": "^8.2.4", - "@hapi/pinpoint": "^1.0.2", - "@hapi/topo": "^3.1.3" - } - } - } - }, "@hapi/bounce": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-1.3.2.tgz", @@ -1408,25 +1344,6 @@ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" }, - "@hapi/eslint-config-hapi": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/@hapi/eslint-config-hapi/-/eslint-config-hapi-12.3.0.tgz", - "integrity": "sha512-P3ZdC97vYUAVgV6fBuAEXh2Ol04R+Zp5LMNmJ9SAF69u8wT7v6vCgdX/SqZiXEzEKQ9YFpuh+m28wNj5aJ1tDg==", - "dev": true - }, - "@hapi/eslint-plugin-hapi": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@hapi/eslint-plugin-hapi/-/eslint-plugin-hapi-4.3.5.tgz", - "integrity": "sha512-2o6eJrE6qH0orR0kDB3B+lyQ1Swq7SrZ+ZubvE5UGmXBrHOYmWV/RhuvCU0mmSwRn0vyU3sK41doEqya7G3lIA==", - "dev": true, - "requires": { - "@hapi/rule-capitalize-modules": "1.x.x", - "@hapi/rule-for-loop": "1.x.x", - "@hapi/rule-no-arrowception": "1.x.x", - "@hapi/rule-no-var": "1.x.x", - "@hapi/rule-scope-start": "2.x.x" - } - }, "@hapi/formula": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz", @@ -1890,155 +1807,11 @@ } } }, - "@hapi/lab": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@hapi/lab/-/lab-21.0.0.tgz", - "integrity": "sha512-csYjq2DE+JzKPW+BaqEfDzbHJC5LIC+M1eYUljm0+zD7xoaKUXFPEWqlP4JSbJ4e16wRNY8Uid3UshxC+rUByw==", - "dev": true, - "requires": { - "@hapi/bossy": "4.x.x", - "@hapi/eslint-config-hapi": "12.x.x", - "@hapi/eslint-plugin-hapi": "4.x.x", - "@hapi/hoek": "8.x.x", - "diff": "4.x.x", - "eslint": "6.x.x", - "espree": "6.x.x", - "find-rc": "4.x.x", - "globby": "10.x.x", - "handlebars": "4.x.x", - "mkdirp": "0.5.x", - "seedrandom": "3.x.x", - "source-map": "0.7.x", - "source-map-support": "0.5.x", - "supports-color": "7.x.x", - "typescript": "3.6.x", - "will-call": "1.x.x" - }, - "dependencies": { - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, "@hapi/pinpoint": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz", "integrity": "sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==" }, - "@hapi/rule-capitalize-modules": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@hapi/rule-capitalize-modules/-/rule-capitalize-modules-1.2.1.tgz", - "integrity": "sha512-XduBSQQehgY/PJX/Ud2H5UdVyNVEC3QiU00vOHWvpn+kbH1co2dmzpu2JEGGxKmdGHjm8jdDkrlqVxGFXHAuhQ==", - "dev": true - }, - "@hapi/rule-for-loop": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@hapi/rule-for-loop/-/rule-for-loop-1.2.1.tgz", - "integrity": "sha512-9Y2yjNpmhntryViPTb6JlTCqma9fF+H0lCtjvlWA0La/ckxPSzXfwh9kgroyjQ3mJiwKDUYboqC4/BK6L5DFUg==", - "dev": true - }, - "@hapi/rule-no-arrowception": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@hapi/rule-no-arrowception/-/rule-no-arrowception-1.1.2.tgz", - "integrity": "sha512-NV6IpfcUpI6w/6oR2oBFaBUoOGC3j3xzfXq7ZciBnmOyReqwuSiyvwLb9SeSomei/n1LHaVdnIXJnMD9IAma2Q==", - "dev": true - }, - "@hapi/rule-no-var": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@hapi/rule-no-var/-/rule-no-var-1.1.4.tgz", - "integrity": "sha512-u0gtMRd9uxlmmew3H5pBZJe1D64dTz5yhPWU3UcurOwZGTbGYU2PAUpjxE0TOaeCRDW+tL5Y/9f7637P2vqQSA==", - "dev": true - }, - "@hapi/rule-scope-start": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@hapi/rule-scope-start/-/rule-scope-start-2.2.0.tgz", - "integrity": "sha512-n0adld0osaYNXlus/64dCN0GlkMvmwuJfkpM0OtrA2U7x2Iu1XoHV6Lmne3C+9gM8X/xLUviYLoTCOC7IW8RYg==", - "dev": true - }, "@hapi/topo": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", @@ -2103,39 +1876,6 @@ "path-exists": "^4.0.0" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2157,15 +1897,16 @@ "dev": true }, "@jest/console": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.1.0.tgz", - "integrity": "sha512-+0lpTHMd/8pJp+Nd4lyip+/Iyf2dZJvcCqrlkeZQoQid+JlThA4M9vxHtheyrQ99jJTMQam+es4BcvZ5W5cC3A==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz", + "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.1.0", - "jest-util": "^26.1.0", + "jest-message-util": "^26.3.0", + "jest-util": "^26.3.0", "slash": "^3.0.0" }, "dependencies": { @@ -2210,12 +1951,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -2228,33 +1963,34 @@ } }, "@jest/core": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.1.0.tgz", - "integrity": "sha512-zyizYmDJOOVke4OO/De//aiv8b07OwZzL2cfsvWF3q9YssfpcKfcnZAwDY8f+A76xXSMMYe8i/f/LPocLlByfw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.2.tgz", + "integrity": "sha512-sDva7YkeNprxJfepOctzS8cAk9TOekldh+5FhVuXS40+94SHbiicRO1VV2tSoRtgIo+POs/Cdyf8p76vPTd6dg==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/reporters": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.3.0", + "@jest/reporters": "^26.4.1", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.1.0", - "jest-config": "^26.1.0", - "jest-haste-map": "^26.1.0", - "jest-message-util": "^26.1.0", + "jest-changed-files": "^26.3.0", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-resolve-dependencies": "^26.1.0", - "jest-runner": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", - "jest-watcher": "^26.1.0", + "jest-resolve": "^26.4.0", + "jest-resolve-dependencies": "^26.4.2", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", + "jest-watcher": "^26.3.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -2321,26 +2057,6 @@ "to-regex-range": "^5.0.1" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2363,15 +2079,6 @@ "picomatch": "^2.0.5" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2381,12 +2088,6 @@ "glob": "^7.1.3" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -2417,51 +2118,53 @@ } }, "@jest/environment": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.1.0.tgz", - "integrity": "sha512-86+DNcGongbX7ai/KE/S3/NcUVZfrwvFzOOWX/W+OOTvTds7j07LtC+MgGydH5c8Ri3uIrvdmVgd1xFD5zt/xA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, "@jest/fake-timers": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.1.0.tgz", - "integrity": "sha512-Y5F3kBVWxhau3TJ825iuWy++BAuQzK/xEa+wD9vDH3RytW9f2DbMVodfUQC54rZDX3POqdxCgcKdgcOL0rYUpA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0" + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "@jest/globals": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.1.0.tgz", - "integrity": "sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.2.tgz", + "integrity": "sha512-Ot5ouAlehhHLRhc+sDz2/9bmNv9p5ZWZ9LE1pXGGTCXBasmi5jnYjlgYcYt03FBwLmZXCZ7GrL29c33/XRQiow==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/types": "^26.1.0", - "expect": "^26.1.0" + "@jest/environment": "^26.3.0", + "@jest/types": "^26.3.0", + "expect": "^26.4.2" } }, "@jest/reporters": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.1.0.tgz", - "integrity": "sha512-SVAysur9FOIojJbF4wLP0TybmqwDkdnFxHSPzHMMIYyBtldCW9gG+Q5xWjpMFyErDiwlRuPyMSJSU64A67Pazg==", + "version": "26.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.1.tgz", + "integrity": "sha512-aROTkCLU8++yiRGVxLsuDmZsQEKO6LprlrxtAuzvtpbIFl3eIjgIf3EUxDKgomkS25R9ZzwGEdB5weCcBZlrpQ==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -2472,16 +2175,16 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.1.0", - "jest-resolve": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", - "node-notifier": "^7.0.0", + "jest-haste-map": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", + "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" + "v8-to-istanbul": "^5.0.1" }, "dependencies": { "ansi-styles": { @@ -2519,47 +2222,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -2572,73 +2240,57 @@ } }, "@jest/source-map": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", - "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz", + "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==", "dev": true, "requires": { "callsites": "^3.0.0", "graceful-fs": "^4.2.4", "source-map": "^0.6.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "@jest/test-result": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.1.0.tgz", - "integrity": "sha512-Xz44mhXph93EYMA8aYDz+75mFbarTV/d/x0yMdI3tfSRs/vh4CqSxgzVmCps1fPkHDCtn0tU8IH9iCKgGeGpfw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.1.0.tgz", - "integrity": "sha512-Z/hcK+rTq56E6sBwMoQhSRDVjqrGtj1y14e2bIgcowARaIE1SgOanwx6gvY4Q9gTKMoZQXbXvptji+q5GYxa6Q==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.2.tgz", + "integrity": "sha512-83DRD8N3M0tOhz9h0bn6Kl6dSp+US6DazuVF8J9m21WAp5x7CqSMaNycMP0aemC/SH/pDQQddbsfHRTBXVUgog==", "dev": true, "requires": { - "@jest/test-result": "^26.1.0", + "@jest/test-result": "^26.3.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.1.0", - "jest-runner": "^26.1.0", - "jest-runtime": "^26.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } + "jest-haste-map": "^26.3.0", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2" } }, "@jest/transform": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.1.0.tgz", - "integrity": "sha512-ICPm6sUXmZJieq45ix28k0s+d/z2E8CHDsq+WwtWI6kW8m7I8kPqarSEcUN86entHQ570ZBRci5OWaKL0wlAWw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz", + "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.1.0", + "jest-haste-map": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-util": "^26.1.0", + "jest-util": "^26.3.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -2699,12 +2351,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2727,12 +2373,6 @@ "picomatch": "^2.0.5" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -2754,13 +2394,14 @@ } }, "@jest/types": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.1.0.tgz", - "integrity": "sha512-GXigDDsp6ZlNMhXQDeuy/iYCDsRIHJabWtDzvnn36+aqFfG14JmFV0e/iXxY4SP9vbXSiPNOWdehU5MeqrYHBQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -2817,32 +2458,6 @@ } } }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, "@octokit/auth-token": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", @@ -2965,9 +2580,9 @@ } }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -2982,33 +2597,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "@sinonjs/formatio": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-4.0.1.tgz", - "integrity": "sha512-asIdlLFrla/WZybhm0C8eEzaDNNrzymiTqHMeJl6zPW2881l3uuVRpm0QlRQEjqYWv6CcKMGYME3LbrLJsORBw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^4.2.0" - } - }, - "@sinonjs/samsam": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-4.2.2.tgz", - "integrity": "sha512-z9o4LZUzSD9Hl22zV38aXNykgFeVj8acqfFabCY6FY83n/6s/XwNJyYYldz6/9lBJanpno9h+oL6HTISkviweA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.6.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, "@types/babel__core": { "version": "7.1.9", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", @@ -3055,16 +2643,6 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "@types/graceful-fs": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", @@ -3090,20 +2668,18 @@ } }, "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==" }, "@types/minimist": { "version": "1.2.0", @@ -3155,6 +2731,64 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -3171,9 +2805,9 @@ "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" }, "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", + "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", "dev": true }, "abbrev": { @@ -3918,12 +3552,6 @@ } } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", @@ -4093,16 +3721,16 @@ } }, "babel-jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz", - "integrity": "sha512-Nkqgtfe7j6PxLO6TnCQQlkMm8wdTdnIF8xrdpooHCuD5hXRzVEPbPneTJKknH5Dsv3L8ip9unHDAp48YQ54Dkg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", + "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==", "dev": true, "requires": { - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.1.0", + "babel-preset-jest": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -4143,24 +3771,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -4186,9 +3802,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz", - "integrity": "sha512-qhqLVkkSlqmC83bdMhM8WW4Z9tB+JkjqAqlbbohS9sJLT5Ha2vfzuKqg5yenXrAjOPG2YC0WiXdH3a9PvB+YYw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -4217,13 +3833,13 @@ } }, "babel-preset-jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz", - "integrity": "sha512-na9qCqFksknlEj5iSdw1ehMVR06LCCTkZLGKeEtxDDdhg8xpUF09m29Kvh1pRbZ07h7AQ5ttLYUwpXL4tO6w7w==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz", + "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.1.0", - "babel-preset-current-node-syntax": "^0.1.2" + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.3" } }, "bach": { @@ -4921,14 +4537,6 @@ "dev": true, "requires": { "rsvp": "^4.8.4" - }, - "dependencies": { - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - } } }, "caseless": { @@ -5177,15 +4785,6 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "code": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/code/-/code-4.1.0.tgz", - "integrity": "sha1-IJrRHQWvigwceq9pTZ+k0sfZW4U=", - "dev": true, - "requires": { - "hoek": "4.x.x" - } - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -6933,35 +6532,12 @@ "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=" }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", + "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", "dev": true }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } - } - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -7149,6 +6725,12 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.526.tgz", "integrity": "sha512-HiroW5ZbGwgT8kCnoEO8qnGjoTPzJxduvV/Vv/wH63eo2N6Zj3xT5fmmaSPAPUM05iN9/5fIEkIg3owTtV6QZg==" }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -7582,6 +7164,14 @@ } } }, + "eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "requires": { + "@typescript-eslint/experimental-utils": "^2.5.0" + } + }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", @@ -7734,15 +7324,13 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true } } }, @@ -7769,16 +7357,16 @@ } }, "expect": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.1.0.tgz", - "integrity": "sha512-QbH4LZXDsno9AACrN9eM0zfnby9G+OsdNgZUohjg/P0mLy1O+/bzTAJGT6VSIjVCe8yKM6SzEl/ckEOFBT7Vnw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0" }, "dependencies": { @@ -7906,103 +7494,26 @@ }, "extsprintf": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -8013,15 +7524,6 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, - "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -8121,12 +7623,6 @@ } } }, - "find-rc": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/find-rc/-/find-rc-4.0.1.tgz", - "integrity": "sha512-YEox27Ie95/zoqkxm6BYSPguJsvYz9d9G1YuaNKhxjSgZbjMC9q5blmvbL4+Ail8yacQIE0OObhDb+ZwvfJafw==", - "dev": true - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -9924,59 +9420,6 @@ "type-fest": "^0.8.1" } }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, "globule": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", @@ -11167,12 +10610,6 @@ "remarkable": "^1.6.2" } }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -11478,66 +10915,6 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { @@ -11783,9 +11160,9 @@ } }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", "dev": true, "optional": true }, @@ -12091,14 +11468,14 @@ } }, "jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.1.0.tgz", - "integrity": "sha512-LIti8jppw5BcQvmNJe4w2g1N/3V68HUfAv9zDVm7v+VAtQulGhH0LnmmiVkbNE4M4I43Bj2fXPiBGKt26k9tHw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.2.tgz", + "integrity": "sha512-LLCjPrUh98Ik8CzW8LLVnSCfLaiY+wbK53U7VxnFSX7Q+kWC4noVeDvGWIFw0Amfq1lq2VfGm7YHWSLBV62MJw==", "dev": true, "requires": { - "@jest/core": "^26.1.0", + "@jest/core": "^26.4.2", "import-local": "^3.0.2", - "jest-cli": "^26.1.0" + "jest-cli": "^26.4.2" }, "dependencies": { "ansi-regex": { @@ -12175,12 +11552,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -12194,59 +11565,26 @@ "dev": true }, "jest-cli": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.1.0.tgz", - "integrity": "sha512-Imumvjgi3rU7stq6SJ1JUEMaV5aAgJYXIs0jPqdUnF47N/Tk83EXfmtvNKQ+SnFVI6t6mDOvfM3aA9Sg6kQPSw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.2.tgz", + "integrity": "sha512-zb+lGd/SfrPvoRSC/0LWdaWCnscXc1mGYW//NP4/tmBvRPT3VntZ2jtKUONsRi59zc5JqmsSajA9ewJKFYp8Cw==", "dev": true, "requires": { - "@jest/core": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/core": "^26.4.2", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-config": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "prompts": "^2.0.1", "yargs": "^15.3.1" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -12343,12 +11681,12 @@ } }, "jest-changed-files": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.1.0.tgz", - "integrity": "sha512-HS5MIJp3B8t0NRKGMCZkcDUZo36mVRvrDETl81aqljT1S9tqiHRSpyoOvWg9ZilzZG9TDisDNaN1IXm54fLRZw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz", + "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "execa": "^4.0.0", "throat": "^5.0.0" }, @@ -12382,9 +11720,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -12448,29 +11786,29 @@ } }, "jest-config": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.1.0.tgz", - "integrity": "sha512-ONTGeoMbAwGCdq4WuKkMcdMoyfs5CLzHEkzFOlVvcDXufZSaIWh/OXMLa2fwKXiOaFcqEw8qFr4VOKJQfn4CVw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.2.tgz", + "integrity": "sha512-QBf7YGLuToiM8PmTnJEdRxyYy3mHWLh24LJZKVdXZ2PNdizSe1B/E8bVm+HYcjbEzGuVXDv/di+EzdO/6Gq80A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.1.0", - "@jest/types": "^26.1.0", - "babel-jest": "^26.1.0", + "@jest/test-sequencer": "^26.4.2", + "@jest/types": "^26.3.0", + "babel-jest": "^26.3.0", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.1.0", - "jest-environment-node": "^26.1.0", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.1.0", + "jest-environment-jsdom": "^26.3.0", + "jest-environment-node": "^26.3.0", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.4.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "micromatch": "^4.0.2", - "pretty-format": "^26.1.0" + "pretty-format": "^26.4.2" }, "dependencies": { "ansi-styles": { @@ -12526,26 +11864,6 @@ "to-regex-range": "^5.0.1" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -12568,15 +11886,6 @@ "picomatch": "^2.0.5" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -12598,15 +11907,15 @@ } }, "jest-diff": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.1.0.tgz", - "integrity": "sha512-GZpIcom339y0OXznsEKjtkfKxNdg7bVbEofK8Q6MnevTIiR1jNhDWKhRX6X0SDXJlwn3dy59nZ1z55fLkAqPWg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz", + "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "diff-sequences": "^26.3.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "ansi-styles": { @@ -12671,16 +11980,16 @@ } }, "jest-each": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.1.0.tgz", - "integrity": "sha512-lYiSo4Igr81q6QRsVQq9LIkJW0hZcKxkIkHzNeTMPENYYDw/W/Raq28iJ0sLlNFYz2qxxeLnc5K2gQoFYlu2bA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.2.tgz", + "integrity": "sha512-p15rt8r8cUcRY0Mvo1fpkOGYm7iI8S6ySxgIdfh3oOIv+gHwrHTy5VWCGOecWUhDsit4Nz8avJWdT07WLpbwDA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.1.0", - "pretty-format": "^26.1.0" + "jest-get-type": "^26.3.0", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "ansi-styles": { @@ -12736,57 +12045,60 @@ } }, "jest-environment-jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz", - "integrity": "sha512-dWfiJ+spunVAwzXbdVqPH1LbuJW/kDL+FyqgA5YzquisHqTi0g9hquKif9xKm7c1bKBj6wbmJuDkeMCnxZEpUw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz", + "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0", "jsdom": "^16.2.2" } }, "jest-environment-node": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.1.0.tgz", - "integrity": "sha512-DNm5x1aQH0iRAe9UYAkZenuzuJ69VKzDCAYISFHQ5i9e+2Tbeu2ONGY7YStubCLH8a1wdKBgqScYw85+ySxqxg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz", + "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0" + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-haste-map": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.1.0.tgz", - "integrity": "sha512-WeBS54xCIz9twzkEdm6+vJBXgRBQfdbbXD0dk8lJh7gLihopABlJmIQFdWSDDtuDe4PRiObsjZSUjbJ1uhWEpA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz", + "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.3.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "anymatch": { @@ -12824,12 +12136,6 @@ "dev": true, "optional": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -12860,40 +12166,32 @@ "requires": { "is-number": "^7.0.0" } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "jest-jasmine2": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz", - "integrity": "sha512-1IPtoDKOAG+MeBrKvvuxxGPJb35MTTRSDglNdWWCndCB3TIVzbLThRBkwH9P081vXLgiJHZY8Bz3yzFS803xqQ==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.2.tgz", + "integrity": "sha512-z7H4EpCldHN1J8fNgsja58QftxBSL+JcwZmaXIvV9WKIM+x49F4GLHu/+BQh2kzRKHAgaN/E82od+8rTOBPyPA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.1.0", - "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/environment": "^26.3.0", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.1.0", + "expect": "^26.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.1.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "pretty-format": "^26.1.0", + "jest-each": "^26.4.2", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2", "throat": "^5.0.0" }, "dependencies": { @@ -12950,25 +12248,25 @@ } }, "jest-leak-detector": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz", - "integrity": "sha512-dsMnKF+4BVOZwvQDlgn3MG+Ns4JuLv8jNvXH56bgqrrboyCbI1rQg6EI5rs+8IYagVcfVP2yZFKfWNZy0rK0Hw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.2.tgz", + "integrity": "sha512-akzGcxwxtE+9ZJZRW+M2o+nTNnmQZxrHJxX/HjgDaU5+PLmY1qnQPnMjgADPGCRPhB+Yawe1iij0REe+k/aHoA==", "dev": true, "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" } }, "jest-matcher-utils": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz", - "integrity": "sha512-PW9JtItbYvES/xLn5mYxjMd+Rk+/kIt88EfH3N7w9KeOrHWaHrdYPnVHndGbsFGRJ2d5gKtwggCvkqbFDoouQA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz", + "integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.1.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "ansi-styles": { @@ -13024,13 +12322,13 @@ } }, "jest-message-util": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.1.0.tgz", - "integrity": "sha512-dY0+UlldiAJwNDJ08SF0HdF32g9PkbF2NRK/+2iMPU40O6q+iSn1lgog/u0UH8ksWoPv0+gNq8cjhYO2MFtT0g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz", + "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "@types/stack-utils": "^1.0.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -13092,12 +12390,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -13120,12 +12412,6 @@ "picomatch": "^2.0.5" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -13147,12 +12433,13 @@ } }, "jest-mock": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.1.0.tgz", - "integrity": "sha512-1Rm8EIJ3ZFA8yCIie92UbxZWj9SuVmUGcyhLHyAhY6WI3NIct38nVcfOPWhJteqSn8V8e3xOMha9Ojfazfpovw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz", + "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==", "dev": true, "requires": { - "@jest/types": "^26.1.0" + "@jest/types": "^26.3.0", + "@types/node": "*" } }, "jest-pnp-resolver": { @@ -13168,16 +12455,16 @@ "dev": true }, "jest-resolve": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.1.0.tgz", - "integrity": "sha512-KsY1JV9FeVgEmwIISbZZN83RNGJ1CC+XUCikf/ZWJBX/tO4a4NvA21YixokhdR9UnmPKKAC4LafVixJBrwlmfg==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz", + "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.3.0", "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" @@ -13227,61 +12514,22 @@ "locate-path": "^5.0.0", "path-exists": "^4.0.0" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -13331,12 +12579,6 @@ "path-parse": "^1.0.6" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -13349,39 +12591,40 @@ } }, "jest-resolve-dependencies": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz", - "integrity": "sha512-fQVEPHHQ1JjHRDxzlLU/buuQ9om+hqW6Vo928aa4b4yvq4ZHBtRSDsLdKQLuCqn5CkTVpYZ7ARh2fbA8WkRE6g==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.2.tgz", + "integrity": "sha512-ADHaOwqEcVc71uTfySzSowA/RdxUpCxhxa2FNLiin9vWLB1uLPad3we+JSSROq5+SrL9iYPdZZF8bdKM7XABTQ==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.1.0" + "jest-snapshot": "^26.4.2" } }, "jest-runner": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.1.0.tgz", - "integrity": "sha512-elvP7y0fVDREnfqit0zAxiXkDRSw6dgCkzPCf1XvIMnSDZ8yogmSKJf192dpOgnUVykmQXwYYJnCx641uLTgcw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.2.tgz", + "integrity": "sha512-FgjDHeVknDjw1gRAYaoUoShe1K3XUuFMkIaXbdhEys+1O4bEJS8Avmn4lBwoMfL8O5oFTdWYKcf3tEJyyYyk8g==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/environment": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.1.0", + "jest-config": "^26.4.2", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.1.0", - "jest-jasmine2": "^26.1.0", - "jest-leak-detector": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-resolve": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", + "jest-haste-map": "^26.3.0", + "jest-leak-detector": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-runtime": "^26.4.2", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, @@ -13421,28 +12664,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -13455,34 +12682,34 @@ } }, "jest-runtime": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.1.0.tgz", - "integrity": "sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA==", - "dev": true, - "requires": { - "@jest/console": "^26.1.0", - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/globals": "^26.1.0", - "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.2.tgz", + "integrity": "sha512-4Pe7Uk5a80FnbHwSOk7ojNCJvz3Ks2CNQWT5Z7MJo4tX0jb3V/LThKvD9tKPNVNyeMH98J/nzGlcwc00R2dSHQ==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/globals": "^26.4.2", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.1.0", - "jest-haste-map": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-mock": "^26.1.0", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-resolve": "^26.4.0", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" @@ -13562,26 +12789,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -13594,48 +12801,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13648,12 +12813,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -13744,42 +12903,35 @@ } }, "jest-serializer": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.1.0.tgz", - "integrity": "sha512-eqZOQG/0+MHmr25b2Z86g7+Kzd5dG9dhCiUoyUNJPgiqi38DqbDEOlHcNijyfZoj74soGBohKBZuJFS18YTJ5w==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz", + "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.1.0.tgz", - "integrity": "sha512-YhSbU7eMTVQO/iRbNs8j0mKRxGp4plo7sJ3GzOQ0IYjvsBiwg0T1o0zGQAYepza7lYHuPTrG5J2yDd0CE2YxSw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.2.tgz", + "integrity": "sha512-N6Uub8FccKlf5SBFnL2Ri/xofbaA68Cc3MGjP/NuwgnsvWh+9hLIR/DhrxbSiKXMY9vUW5dI6EW1eHaDHqe9sg==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.1.0", + "expect": "^26.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.1.0", - "jest-get-type": "^26.0.0", - "jest-haste-map": "^26.1.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-resolve": "^26.1.0", + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.1.0", + "pretty-format": "^26.4.2", "semver": "^7.3.2" }, "dependencies": { @@ -13818,24 +12970,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -13848,12 +12988,13 @@ } }, "jest-util": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.1.0.tgz", - "integrity": "sha512-rNMOwFQevljfNGvbzNQAxdmXQ+NawW/J72dmddsK0E8vgxXCMtwQ/EH0BiWEIxh0hhMcTsxwAxINt7Lh46Uzbg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", @@ -13913,12 +13054,6 @@ "to-regex-range": "^5.0.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -13962,17 +13097,17 @@ } }, "jest-validate": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.1.0.tgz", - "integrity": "sha512-WPApOOnXsiwhZtmkDsxnpye+XLb/tUISP+H6cHjfUIXvlG+eKwP+isnivsxlHCPaO9Q5wvbhloIBkdF3qUn+Nw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.2.tgz", + "integrity": "sha512-blft+xDX7XXghfhY0mrsBCYhX365n8K5wNDC4XAcNKqqjEzsRUSXP44m6PL0QJEW2crxQFLLztVnJ4j7oPlQrQ==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.1.0" + "pretty-format": "^26.4.2" }, "dependencies": { "ansi-styles": { @@ -14034,16 +13169,17 @@ } }, "jest-watcher": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.1.0.tgz", - "integrity": "sha512-ffEOhJl2EvAIki613oPsSG11usqnGUzIiK7MMX6hE4422aXOcVEG3ySCTDFLn1+LZNXGPE8tuJxhp8OBJ1pgzQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz", + "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==", "dev": true, "requires": { - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.1.0", + "jest-util": "^26.3.0", "string-length": "^4.0.1" }, "dependencies": { @@ -14100,11 +13236,12 @@ } }, "jest-worker": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz", - "integrity": "sha512-Z9P5pZ6UC+kakMbNJn+tA2RdVdNX5WH1x+5UCBZ9MxIK24pjYtFt96fK+UwBTrjLYm232g1xz0L3eTh51OW+yQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, @@ -14158,9 +13295,9 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", - "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", "dev": true, "requires": { "abab": "^2.0.3", @@ -14210,12 +13347,24 @@ } } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz", + "integrity": "sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -14236,6 +13385,23 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, "jsonfile": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", @@ -14276,12 +13442,6 @@ "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", "dev": true }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -14667,12 +13827,6 @@ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -14784,15 +13938,6 @@ "chalk": "^1.0.0" } }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -15215,12 +14360,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, "messageformat": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-0.2.2.tgz", @@ -15545,20 +14684,6 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, - "nise": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-3.0.1.tgz", - "integrity": "sha512-fYcH9y0drBGSoi88kvhpbZEsenX58Yr+wOJ4/Mi1K4cy+iGP/a73gNoyNhu5E9QxPdgTlVChfIaAlnyOy/gHUA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/formatio": "^4.0.1", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^5.0.1", - "path-to-regexp": "^1.7.0" - } - }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", @@ -15637,9 +14762,9 @@ "dev": true }, "node-notifier": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.2.tgz", - "integrity": "sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", "dev": true, "optional": true, "requires": { @@ -15647,7 +14772,7 @@ "is-wsl": "^2.2.0", "semver": "^7.3.2", "shellwords": "^0.1.1", - "uuid": "^8.2.0", + "uuid": "^8.3.0", "which": "^2.0.2" }, "dependencies": { @@ -15661,13 +14786,6 @@ "is-docker": "^2.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true, - "optional": true - }, "uuid": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", @@ -16383,23 +15501,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -16461,6 +15562,33 @@ "node-modules-regexp": "^1.0.0" } }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -16595,12 +15723,12 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, "pretty-format": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.1.0.tgz", - "integrity": "sha512-GmeO1PEYdM+non4BKCj+XsPJjFOJIPnsLewqhDVoqY1xo0yNmDas7tC2XwpMrRAHR3MaE2hPo37deX5OisJ2Wg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", + "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -17480,12 +16608,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -17526,6 +16648,12 @@ } } }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -17534,12 +16662,6 @@ "is-promise": "^2.1.0" } }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, "rx": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", @@ -18266,50 +17388,18 @@ } } }, - "sinon": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-8.1.1.tgz", - "integrity": "sha512-E+tWr3acRdoe1nXbHMu86SSqA1WGM7Yw3jZRLvlCMnXwTHP8lgFFVn5BnKnF26uc5SfZ3D7pA9sN7S3Y2jG4Ew==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/formatio": "^4.0.1", - "@sinonjs/samsam": "^4.2.2", - "diff": "^4.0.2", - "lolex": "^5.1.2", - "nise": "^3.0.1", - "supports-color": "^7.1.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -18601,6 +17691,16 @@ "urix": "^0.1.0" } }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", @@ -19138,20 +18238,6 @@ "minimatch": "^3.0.4" }, "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -19248,6 +18334,12 @@ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-gfm-code-block": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz", @@ -19397,6 +18489,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -19462,12 +18562,6 @@ "kind-of": "^3.1.0" } }, - "typescript": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.5.tgz", - "integrity": "sha512-BEjlc0Z06ORZKbtcxGrIvvwYs5hAnuo6TKdNFL55frVDlB+na3z5bsLhFaIxmT+dPWgBIjMo6aNnTOgHHmHgiQ==", - "dev": true - }, "ua-parser-js": { "version": "0.7.21", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", @@ -19661,9 +18755,9 @@ "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==" }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz", + "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -19847,22 +18941,14 @@ "dev": true }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-ZmVCr6nfBeaMxEHALLEGy0LszYjpJqf6PVNQUQ1qd9Et+q7Jpygd4rGGDXgHjD8e99yLFseD69msHDM4YwPZ4A==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "webidl-conversions": "^6.1.0" } }, "which": { @@ -19892,12 +18978,6 @@ "string-width": "^1.0.2 || 2" } }, - "will-call": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/will-call/-/will-call-1.0.1.tgz", - "integrity": "sha512-1hEeV8SfBYhNRc/bNXeQfyUBX8Dl9SCYME3qXh99iZP9wJcnhnlBsoBw8Y0lXVZ3YuPsoxImTzBiol1ouNR/hg==", - "dev": true - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 8610ea07..730f5803 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,19 @@ }, "scripts": { "lint": "eslint .", - "test": "npm run lint && npm run run-tests", - "run-tests": "lab bin/ server/ lib/ tasks/ -t 80 -l -e 'development' -P spec --verbose", - "test-cov-html": "lab bin/ server/ lib/ -r html -o coverage.html -P spec" + "lint-and-fix": "eslint . --fix", + "test": "jest", + "test-with-coverage": "jest --coverage --verbose" }, "bin": { - "stencil": "./bin/stencil", - "stencil-init": "./bin/stencil-init", - "stencil-push": "./bin/stencil-push", - "stencil-start": "./bin/stencil-start", - "stencil-release": "./bin/stencil-release" + "stencil": "./bin/stencil.js", + "stencil-bundle": "./bin/stencil-bundle.js", + "stencil-download": "./bin/stencil-download.js", + "stencil-init": "./bin/stencil-init.js", + "stencil-push": "./bin/stencil-push.js", + "stencil-pull": "./bin/stencil-pull.js", + "stencil-start": "./bin/stencil-start.js", + "stencil-release": "./bin/stencil-release.js" }, "config": { "stencil_version": "1.0" @@ -51,6 +54,7 @@ "commander": "^2.7.1", "confidence": "^4.0.2", "eslint": "^6.8.0", + "eslint-plugin-jest": "^23.20.0", "front-matter": "^1.0.0", "glob": "^7.1.6", "graceful-fs": "^4.2.4", @@ -74,8 +78,6 @@ "devDependencies": { "@commitlint/cli": "^10.0.0", "@commitlint/config-conventional": "^10.0.0", - "@hapi/lab": "^21.0.0", - "code": "^4.1.0", "conventional-changelog-cli": "^2.1.0", "gulp": "^4.0.2", "gulp-bump": "^3.2.0", @@ -85,10 +87,9 @@ "gulp-prompt": "^1.2.0", "gulp-util": "^3.0.8", "husky": "^4.2.5", - "jest": "^26.1.0", + "jest": "^26.4.2", "npm-which": "^3.0.1", - "object-to-spawn-args": "^2.0.0", - "sinon": "^8.1.1" + "object-to-spawn-args": "^2.0.0" }, "husky": { "hooks": { diff --git a/server/lib/utils.spec.js b/server/lib/utils.spec.js index ff672cdf..1268a677 100644 --- a/server/lib/utils.spec.js +++ b/server/lib/utils.spec.js @@ -1,29 +1,21 @@ -const Code = require('code'); -const Lab = require('@hapi/lab'); - const Utils = require('./utils'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const expect = Code.expect; -const it = lab.it; - describe('Utils', () => { describe('uuid2int', () => { it('should return an int value presentation', () => { - expect(Utils.uuid2int('00000000-0000-0000-0000-000000000001')).to.equal(1); - expect(Utils.uuid2int('00000000-0000-0000-0000-000000000102')).to.equal(102); + expect(Utils.uuid2int('00000000-0000-0000-0000-000000000001')).toEqual(1); + expect(Utils.uuid2int('00000000-0000-0000-0000-000000000102')).toEqual(102); }); it('should throw an error if an invalid uuid is used', () => { - expect(() => Utils.uuid2int('00002')).to.throw(Error); + expect(() => Utils.uuid2int('00002')).toThrow(Error); }); }); describe('int2uuid', () => { it('should return an uuid value presentation', () => { - expect(Utils.int2uuid(1)).to.equal('00000000-0000-0000-0000-000000000001'); - expect(Utils.int2uuid(505)).to.equal('00000000-0000-0000-0000-000000000505'); + expect(Utils.int2uuid(1)).toEqual('00000000-0000-0000-0000-000000000001'); + expect(Utils.int2uuid(505)).toEqual('00000000-0000-0000-0000-000000000505'); }); }); }); diff --git a/server/plugins/renderer/renderer.module.spec.js b/server/plugins/renderer/renderer.module.spec.js index f130cfe5..a5c84ff5 100644 --- a/server/plugins/renderer/renderer.module.spec.js +++ b/server/plugins/renderer/renderer.module.spec.js @@ -1,23 +1,19 @@ 'use strict'; -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); const Wreck = require('wreck'); const Path = require('path'); const Server = require('../../../server'); -const lab = exports.lab = Lab.script(); -const expect = Code.expect; -const it = lab.it; - -lab.describe('Renderer Plugin', () => { +describe('Renderer Plugin', () => { let server; let wreckRequestStub; - let wreckReadStub; - lab.before(async () => { + beforeAll(async () => { + // Prevent littering the console + jest.spyOn(console, 'log').mockImplementation(jest.fn()); + jest.spyOn(console, 'error').mockImplementation(jest.fn()); + const options = { dotStencilFile: { storeUrl: "https://store-abc123.mybigcommerce.com", @@ -39,19 +35,16 @@ lab.describe('Renderer Plugin', () => { } return h.continue; }); - }); - lab.beforeEach(() => { - wreckRequestStub = sinon.stub(Wreck, 'request'); - wreckReadStub = sinon.stub(Wreck, 'read'); + wreckRequestStub = jest.spyOn(Wreck, 'request').mockImplementation(jest.fn()); + jest.spyOn(Wreck, 'read').mockImplementation(jest.fn()); }); - lab.afterEach(async () => { - wreckRequestStub.restore(); - wreckReadStub.restore(); + afterEach(() => { + jest.resetAllMocks(); }); - lab.after(async () => { + afterAll(async () => { await server.stop(); }); @@ -60,12 +53,11 @@ lab.describe('Renderer Plugin', () => { method: "GET", url: "/test", }; - - wreckRequestStub.callsArgWith(3, new Error('failure')); + wreckRequestStub.mockImplementation((method, url, options, cb) => cb(new Error('failure'))); const response = await server.inject(options); - expect(response.statusCode).to.equal(500); + expect(response.statusCode).toEqual(500); }); it('should handle responses of a 500 in the BCApp request', async () => { @@ -73,11 +65,11 @@ lab.describe('Renderer Plugin', () => { method: "GET", url: "/", }; - wreckRequestStub.callsArgWith(3, null, { statusCode: 500 }); + wreckRequestStub.mockImplementation((method, url, options, cb) => cb(null, { statusCode: 500 })); const response = await server.inject(options); - expect(response.statusCode).to.equal(500); + expect(response.statusCode).toEqual(500); }); it('should handle redirects in the BCApp request', async () => { @@ -85,17 +77,18 @@ lab.describe('Renderer Plugin', () => { method: "GET", url: "/", }; - wreckRequestStub.callsArgWith(3, null, { + const redirectResponse = { statusCode: 301, headers: { location: 'http://www.example.com/', }, - }); + }; + wreckRequestStub.mockImplementation((method, url, options, cb) => cb(null, redirectResponse)); const response = await server.inject(options); - expect(response.statusCode).to.equal(301); - expect(response.headers.location).to.equal('http://www.example.com/'); + expect(response.statusCode).toEqual(301); + expect(response.headers.location).toEqual('http://www.example.com/'); }); it('should handle unauthorized in the Stapler Request', async () => { @@ -103,15 +96,16 @@ lab.describe('Renderer Plugin', () => { method: "GET", url: "/", }; - wreckRequestStub.callsArgWith(3, null, { + const unauthorizedResponse = { statusCode: 401, headers: { location: 'http://www.example.com/', }, - }); + }; + wreckRequestStub.mockImplementation((method, url, options, cb) => cb(null, unauthorizedResponse)); const response = await server.inject(options); - expect(response.statusCode).to.equal(401); + expect(response.statusCode).toEqual(401); }); }); diff --git a/server/plugins/renderer/responses/pencil-response.spec.js b/server/plugins/renderer/responses/pencil-response.spec.js index 48d04b76..35806283 100644 --- a/server/plugins/renderer/responses/pencil-response.spec.js +++ b/server/plugins/renderer/responses/pencil-response.spec.js @@ -1,15 +1,6 @@ -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); - const PencilResponse = require('./pencil-response'); -const lab = exports.lab = Lab.script(); -const expect = Code.expect; -const it = lab.it; - - -lab.describe('PencilResponse', () => { +describe('PencilResponse', () => { const assembler = { getTemplates: path => new Promise(resolve => resolve({ path })), getTranslations: () => new Promise(resolve => resolve([])), @@ -20,8 +11,7 @@ lab.describe('PencilResponse', () => { let response; let h; - - lab.beforeEach(() => { + beforeEach(() => { data = { context: { settings: {}, @@ -33,7 +23,7 @@ lab.describe('PencilResponse', () => { remote: true, remote_data: '', }; - + request = { url: {}, path: '/', @@ -47,32 +37,33 @@ lab.describe('PencilResponse', () => { }; h = { - response: sinon.stub().returns(response), + response: jest.fn().mockReturnValue(response), }; - }); it('should return error, when the wrong template_engine is sent', () => { data.context.template_engine = "handlebars"; + const pencilResponse = new PencilResponse(data, assembler); + expect( () => pencilResponse.respond(request, h), - ).to.throw(Error, 'Provided Handlebars version is not supported! Please use:handlebars-v3, handlebars-v4'); + ).toThrow('Provided Handlebars version is not supported! Please use:handlebars-v3, handlebars-v4'); }); it('should render successfully with supported template_engine', async () => { const pencilResponse = new PencilResponse(data, assembler); await pencilResponse.respond(request, h); - console.log(h.response.called); - expect(h.response.called).to.be.true(); + + expect(h.response).toHaveBeenCalledTimes(1); }); it('should default to handlebars_v3 when the template_engine doesn\'t exist', async () => { delete data.context.template_engine; - console.log(data.context); + const pencilResponse = new PencilResponse(data, assembler); await pencilResponse.respond(request, h); - console.log(h.response.called); - expect(h.response.called).to.be.true(); + + expect(h.response).toHaveBeenCalledTimes(1); }); }); diff --git a/server/plugins/renderer/responses/raw-response.spec.js b/server/plugins/renderer/responses/raw-response.spec.js index 335540c2..2264cbbc 100644 --- a/server/plugins/renderer/responses/raw-response.spec.js +++ b/server/plugins/renderer/responses/raw-response.spec.js @@ -1,15 +1,9 @@ 'use strict'; -const Code = require('code'); -const Lab = require('@hapi/lab'); -const sinon = require('sinon'); const RawResponse = require('./raw-response'); const Utils = require('../../../lib/utils'); -const lab = exports.lab = Lab.script(); -const expect = Code.expect; -const it = lab.it; -lab.describe('RawResponse', () => { +describe('RawResponse', () => { const data = new Buffer('hello'); const headers = { @@ -21,7 +15,7 @@ lab.describe('RawResponse', () => { let response; let h; - lab.beforeEach(() => { + beforeEach(() => { request = { url: {}, path: '/', @@ -30,30 +24,35 @@ lab.describe('RawResponse', () => { response = { code: () => response, - header: sinon.spy(), + header: jest.fn(), }; h = { - response: sinon.stub().returns(response), + response: jest.fn().mockReturnValue(response), }; }); - lab.describe('respond()', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe('respond()', () => { it('should respond', () => { const rawResponse = new RawResponse(data, headers, statusCode); rawResponse.respond(request, h); - expect(h.response.called).to.be.true(); + expect(h.response).toHaveBeenCalled(); }); it('should append checkout css if is the checkout page', () => { request.path = '/checkout.php?blah=blah'; const rawResponse = new RawResponse(data, headers, statusCode); + const expectedCss = ` { @@ -61,8 +60,8 @@ lab.describe('RawResponse', () => { rawResponse.respond(request, h); - expect(response.header.neverCalledWith('transfer-encoding')).to.be.true(); - expect(response.header.calledWith('content-type')).to.be.true(); + expect(response.header).not.toHaveBeenCalledWith('transfer-encoding'); + expect(response.header.mock.calls[0]).toContain('content-type'); }); }); }); diff --git a/server/plugins/router/router.module.spec.js b/server/plugins/router/router.module.spec.js index 27c8d884..741d349f 100644 --- a/server/plugins/router/router.module.spec.js +++ b/server/plugins/router/router.module.spec.js @@ -1,14 +1,7 @@ -const Code = require('code'); const Hapi = require('@hapi/hapi'); -const Lab = require('@hapi/lab'); const router = require('./router.module'); -const expect = Code.expect; -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const it = lab.it; - describe('Router', () => { const SERVER_OPTIONS = { port: 3000, @@ -36,7 +29,7 @@ describe('Router', () => { version: '0.0.1', }; - lab.before(async () => { + beforeAll(async () => { await server.register([ require('@hapi/inert'), require('@hapi/h2o2'), @@ -48,7 +41,7 @@ describe('Router', () => { await server.start(); }); - lab.after(async () => { + afterAll(async () => { await server.stop(); }); @@ -60,8 +53,8 @@ describe('Router', () => { const response = await server.inject(options); - expect(response.statusCode).to.equal(200); - expect(response.payload).to.equal('RendererHandlerFired'); + expect(response.statusCode).toEqual(200); + expect(response.payload).toEqual('RendererHandlerFired'); }); it('should call the CSS handler', async () => { @@ -72,8 +65,8 @@ describe('Router', () => { const response = await server.inject(options); - expect(response.statusCode).to.equal(200); - expect(response.payload).to.equal('CssHandlerFired'); + expect(response.statusCode).toEqual(200); + expect(response.payload).toEqual('CssHandlerFired'); }); it('should call the assets handler', async () => { @@ -84,8 +77,8 @@ describe('Router', () => { const response = await server.inject(options); - expect(response.statusCode).to.equal(200); - expect(response.payload).to.equal('assetHandlerFired'); + expect(response.statusCode).toEqual(200); + expect(response.payload).toEqual('assetHandlerFired'); }); it('should inject host and origin headers for GraphQL requests', async () => { @@ -97,7 +90,7 @@ describe('Router', () => { const response = await server.inject(options); - expect(response.request.payload.headers).to.include({ + expect(response.request.payload.headers).toMatchObject({ authorization: 'auth123', origin: 'https://store-abc124.mybigcommerce.com', host: 'store-abc124.mybigcommerce.com', diff --git a/tasks/changelog/changelog-generator.js b/tasks/changelog/changelog-generator.js index 70755778..22de919c 100644 --- a/tasks/changelog/changelog-generator.js +++ b/tasks/changelog/changelog-generator.js @@ -26,11 +26,12 @@ function ChangelogGenerator(fs, cwd, commandExecutor) { */ function getOptions(customOptions) { customOptions = customOptions ? customOptions : {}; - const options = Object.assign({ + const options = { config: customOptions.preset ? undefined : path.join(__dirname, 'default-config.js'), infile: path.join(cwd, 'CHANGELOG.md'), sameFile: true, - }, customOptions); + ...customOptions, + }; try { fs.statSync(options.infile); diff --git a/tasks/changelog/changelog-generator.spec.js b/tasks/changelog/changelog-generator.spec.js index 409557f1..1e6ee8a1 100644 --- a/tasks/changelog/changelog-generator.spec.js +++ b/tasks/changelog/changelog-generator.spec.js @@ -1,30 +1,29 @@ -const ChangelogGenerator = require('./changelog-generator'); -const CommandExecutor = require('./command-executor'); -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const sinon = require('sinon'); -const expect = Code.expect; -const it = lab.it; const path = require('path'); const { promisify } = require('util'); +const ChangelogGenerator = require('./changelog-generator'); +const CommandExecutor = require('./command-executor'); + describe('ChangelogGenerator', () => { let changelogGenerator; let commandExecutor; - let fs; + let fsMock; let executeCommandSpy; - lab.beforeEach( () => { - fs = { + beforeEach( () => { + fsMock = { statSync: function() { return true; }, }; commandExecutor = new CommandExecutor(require('child_process')); - executeCommandSpy = sinon.spy(commandExecutor, "executeCommand"); + executeCommandSpy = jest.spyOn(commandExecutor, "executeCommand") + .mockImplementation((executable, argv, options, done) => done()); + + changelogGenerator = new ChangelogGenerator(fsMock, '/src', commandExecutor); + }); - changelogGenerator = new ChangelogGenerator(fs, '/src', commandExecutor); + afterEach(() => { + jest.restoreAllMocks(); }); it('executes `conventional-changelog` command', async() => { @@ -35,7 +34,8 @@ describe('ChangelogGenerator', () => { // just need to make sure that executeCommandSpy was called properly } catch (err) {} - expect(executeCommandSpy.secondCall.calledWith( + expect(executeCommandSpy).toHaveBeenNthCalledWith( + 2, 'conventional-changelog', [], { @@ -43,7 +43,8 @@ describe('ChangelogGenerator', () => { infile: path.join('/src', 'CHANGELOG.md'), sameFile: true, }, - )).to.equal(true); + expect.any(Function), + ); }); it('executes `conventional-changelog` command with a preset if it is provided', async() => { @@ -54,7 +55,8 @@ describe('ChangelogGenerator', () => { // just need to make sure that executeCommandSpy was called properly } catch (err) {} - expect(executeCommandSpy.secondCall.calledWith( + expect(executeCommandSpy).toHaveBeenNthCalledWith( + 2, 'conventional-changelog', [], { @@ -63,7 +65,8 @@ describe('ChangelogGenerator', () => { preset: 'angular', sameFile: true, }, - )).to.equal(true); + expect.any(Function), + ); }); it('executes `conventional-changelog` command from scratch if CHANGELOG does not exist', async() => { @@ -76,7 +79,8 @@ describe('ChangelogGenerator', () => { // just need to make sure that executeCommandSpy was called properly } catch (err) {} - expect(executeCommandSpy.secondCall.calledWith( + expect(executeCommandSpy).toHaveBeenNthCalledWith( + 2, 'conventional-changelog', [], { @@ -85,6 +89,7 @@ describe('ChangelogGenerator', () => { releaseCount: 0, sameFile: true, }, - )).to.equal(true); + expect.any(Function), + ); }); }); diff --git a/tasks/changelog/command-executor.spec.js b/tasks/changelog/command-executor.spec.js index 017a9159..7399d6b8 100644 --- a/tasks/changelog/command-executor.spec.js +++ b/tasks/changelog/command-executor.spec.js @@ -1,12 +1,6 @@ -const CommandExecutor = require('./command-executor'); const { promisify } = require('util'); -const Code = require('code'); -const Lab = require('@hapi/lab'); -const lab = exports.lab = Lab.script(); -const describe = lab.describe; -const sinon = require('sinon'); -const expect = Code.expect; -const it = lab.it; + +const CommandExecutor = require('./command-executor'); describe('CommandExecutor', () => { let commandExecutor; @@ -14,11 +8,10 @@ describe('CommandExecutor', () => { let spawnSpy; let processMock; let spawn; - let doneCallBack; it('spawns a new process to run the given command', async () => { childProcess = require('child_process'); - spawnSpy = sinon.spy(childProcess, "spawn"); + spawnSpy = jest.spyOn(childProcess, "spawn").mockImplementation(jest.fn()); commandExecutor = new CommandExecutor(childProcess); const executeCommand = promisify(commandExecutor.executeCommand.bind(commandExecutor)); @@ -29,13 +22,14 @@ describe('CommandExecutor', () => { // just need to make sure that spawnSpy was called properly } catch (err) {} - expect(spawnSpy.calledWith( + expect(spawnSpy).toHaveBeenCalledWith( require('npm-which')(__dirname).sync('jest'), ['--config', 'config.js', 'xyz.js'], { stdio: 'inherit' }, - )).to.equal(true); + ); }); + // eslint-disable-next-line jest/expect-expect it('resolves successfully if the process exits with a successful exit code', async () => { processMock = { on: function(event, callback) { return callback(0); }, @@ -55,13 +49,8 @@ describe('CommandExecutor', () => { commandExecutor = new CommandExecutor({ spawn }); const executeCommand = promisify(commandExecutor.executeCommand.bind(commandExecutor)); - let error; - try { - await executeCommand('jest', ['xyz.js'], {config: 'config.js'}, doneCallBack); - } catch (err) { - error = err; - } - - expect(error).to.be.an.error(); + await expect( + executeCommand('jest', ['xyz.js'], {config: 'config.js'}), + ).rejects.toThrow(); }); }); diff --git a/test/_mocks/MockDB.js b/test/_mocks/MockDB.js new file mode 100644 index 00000000..4d126ee9 --- /dev/null +++ b/test/_mocks/MockDB.js @@ -0,0 +1,17 @@ +class MockDB { + constructor () { + this._data = {}; + } + + get data () { + return this._data; + } + + set data (data) { + this._data = data; + } +} + +module.exports = { + MockDB, +}; diff --git a/test/assertions/assertNoMutations.js b/test/assertions/assertNoMutations.js index c2c42a94..6ace9d2a 100644 --- a/test/assertions/assertNoMutations.js +++ b/test/assertions/assertNoMutations.js @@ -1,8 +1,3 @@ -const Code = require('code'); - -const { expect} = Code; - - /** Asserts that all the passed entities weren't mutated after executing the passed procedure * * @param {object[]} entities @@ -15,7 +10,7 @@ async function assertNoMutations (entities, procedure) { await procedure(); entities.forEach((entity, i) => { - expect(entitiesBefore[i]).to.equal(JSON.stringify(entity)); + expect(entitiesBefore[i]).toEqual(JSON.stringify(entity)); }); }