From a5de3691e76a2a999ac3392830d1e26d279d60ab Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 20 May 2018 17:37:21 +0100 Subject: [PATCH] Use Babel directly Simplify test and helper file precompilation. Remove alternate Babel options resolution, at the cost of false cache positives. Fixes #1732 Fixes #1667 Fixes #1789 --- api.js | 49 +- docs/recipes/babel.md | 20 +- lib/babel-config.js | 197 ------ lib/babel-pipeline.js | 196 ++++++ lib/caching-precompiler.js | 102 --- lib/cli.js | 4 +- lib/worker/precompiler-hook.js | 6 +- package-lock.json | 624 +++++++++---------- package.json | 14 +- profile.js | 163 +++-- test/api.js | 153 ++++- test/babel-config.js | 217 ------- test/caching-precompiler.js | 104 ---- test/fixture/babelrc-js/test.js | 12 +- test/fixture/babelrc/disable-stage-4.babelrc | 3 + test/fixture/babelrc/test.js | 12 +- 16 files changed, 781 insertions(+), 1095 deletions(-) delete mode 100644 lib/babel-config.js create mode 100644 lib/babel-pipeline.js delete mode 100644 lib/caching-precompiler.js delete mode 100644 test/babel-config.js delete mode 100644 test/caching-precompiler.js create mode 100644 test/fixture/babelrc/disable-stage-4.babelrc diff --git a/api.js b/api.js index 5342377eb..e1d67eb75 100644 --- a/api.js +++ b/api.js @@ -10,9 +10,9 @@ const debounce = require('lodash.debounce'); const Bluebird = require('bluebird'); const getPort = require('get-port'); const arrify = require('arrify'); +const makeDir = require('make-dir'); const ms = require('ms'); -const babelConfigHelper = require('./lib/babel-config'); -const CachingPrecompiler = require('./lib/caching-precompiler'); +const babelPipeline = require('./lib/babel-pipeline'); const Emittery = require('./lib/emittery'); const RunStatus = require('./lib/run-status'); const AvaFiles = require('./lib/ava-files'); @@ -37,6 +37,8 @@ class Api extends Emittery { this.options = Object.assign({match: []}, options); this.options.require = resolveModules(this.options.require); + + this._precompiler = null; } run(files, runtimeOptions) { @@ -117,11 +119,10 @@ class Api extends Emittery { } }); - // Set up a fresh precompiler for each test run. return emittedRun .then(() => this._setupPrecompiler()) .then(precompilation => { - if (!precompilation) { + if (!precompilation.precompileFile) { return null; } @@ -132,11 +133,13 @@ class Api extends Emittery { return new AvaFiles({cwd: this.options.resolveTestsFrom}).findTestHelpers().then(helpers => { return { cacheDir: precompilation.cacheDir, - map: files.concat(helpers).reduce((acc, file) => { + map: [...files, ...helpers].reduce((acc, file) => { try { const realpath = fs.realpathSync(file); - const hash = precompilation.precompiler.precompileFile(realpath); - acc[realpath] = hash; + const cachePath = precompilation.precompileFile(realpath); + if (cachePath) { + acc[realpath] = cachePath; + } } catch (err) { throw Object.assign(err, {file}); } @@ -204,31 +207,23 @@ class Api extends Emittery { } _setupPrecompiler() { + if (this._precompiler) { + return this._precompiler; + } + const cacheDir = this.options.cacheEnabled === false ? uniqueTempDir() : path.join(this.options.projectDir, 'node_modules', '.cache', 'ava'); - return this._buildBabelConfig(cacheDir).then(result => { - return result ? { - cacheDir, - precompiler: new CachingPrecompiler({ - path: cacheDir, - getBabelOptions: result.getOptions, - babelCacheKeys: result.cacheKeys - }) - } : null; - }); - } - - _buildBabelConfig(cacheDir) { - if (this._babelConfigPromise) { - return this._babelConfigPromise; - } + // Ensure cacheDir exists + makeDir.sync(cacheDir); - const compileEnhancements = this.options.compileEnhancements !== false; - const promise = babelConfigHelper.build(this.options.projectDir, cacheDir, this.options.babelConfig, compileEnhancements); - this._babelConfigPromise = promise; - return promise; + const {projectDir, babelConfig, compileEnhancements} = this.options; + this._precompiler = { + cacheDir, + precompileFile: babelPipeline.build(projectDir, cacheDir, babelConfig, compileEnhancements !== false) + }; + return this._precompiler; } _computeForkExecArgv() { diff --git a/docs/recipes/babel.md b/docs/recipes/babel.md index 67f4f044d..2c6eb77fb 100644 --- a/docs/recipes/babel.md +++ b/docs/recipes/babel.md @@ -2,14 +2,12 @@ Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/babel.md) -AVA uses [Babel 7](https://babeljs.io) so you can use the latest JavaScript syntax in your tests. We do this by compiling test and helper files using our [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) preset. We also use a [second preset](https://github.com/avajs/babel-preset-transform-test-files) to enable [enhanced assertion messages](../../readme#enhanced-assertion-messages) and detect improper use of `t.throws()` assertions. +AVA uses [Babel 7](https://babeljs.io) so you can use the latest JavaScript syntax in your tests. We do this by compiling test and helper files using our [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) preset. We also use a [second preset, `@ava/transform-test-files`](https://github.com/avajs/babel-preset-transform-test-files) to enable [enhanced assertion messages](../../readme#enhanced-assertion-messages) and detect improper use of `t.throws()` assertions. -By default our Babel pipeline is applied to test and helper files ending in `.js`. If your project uses Babel then we'll automatically compile these files using your project's Babel configuration. +By default our Babel pipeline is applied to test and helper files ending in `.js`. If your project uses Babel then we'll automatically compile these files using your project's Babel configuration. The `@ava/transform-helper-files` preset is applied first, and the `@ava/stage-4` last. If you are using Babel for your source files then you must also [configure source compilation](#compile-sources). -AVA only looks for Babel configuration files in your project directory. That is, `.babelrc` or `.babelrc.js` files next to your `package.json` file, or the `package.json` file itself. - ## Customize how AVA compiles your test files You can override the default Babel configuration AVA uses for test file compilation in `package.json`. For example, the configuration below adds support for JSX syntax and stage 3 features: @@ -29,6 +27,16 @@ You can override the default Babel configuration AVA uses for test file compilat All `.babelrc` options are allowed inside the `testOptions` object. +## Reset AVA's cache + +AVA caches the compiled test and helper files. It automatically recompiles these files when you change them, however it can't detect updates of your Babel plugins and presets, or changes to your Babel configuration files. + +Instead run the following to reset AVA's cache when you change the configuration or update plugins or presets: + +```console +$ npx ava --reset-cache +``` + ## Make AVA skip your project's Babel options You may not want AVA to use your project's Babel options, for example if your project is relying on Babel 6. You can set the `babelrc` option to `false`: @@ -65,6 +73,8 @@ You can disable AVA's stage-4 preset: Note that this *does not* stop AVA from compiling your test files using Babel. +You **must** disable the preset by configuring it in the `testOptions`. AVA will still apply the preset if you configure it in other files (for instance a `.babelrc` file). This is [due to a Babel issue](https://github.com/babel/babel/issues/7920). + ## Preserve ES module syntax By default AVA's stage-4 preset will convert ES module syntax to CommonJS. This can be disabled: @@ -83,6 +93,8 @@ By default AVA's stage-4 preset will convert ES module syntax to CommonJS. This } ``` +You **must** configure the preset in the `testOptions` in order to preserve the ES module syntax. AVA will still apply the preset if you configure it in other files (for instance a `.babelrc` file). This is [due to a Babel issue](https://github.com/babel/babel/issues/7920). + You'll have to use the [`esm`](https://github.com/standard-things/esm) module so that AVA can still load your test files. [See our recipe for details](./es-modules.md). ## Disable AVA's Babel pipeline diff --git a/lib/babel-config.js b/lib/babel-config.js deleted file mode 100644 index c087d5b41..000000000 --- a/lib/babel-config.js +++ /dev/null @@ -1,197 +0,0 @@ -'use strict'; -const fs = require('fs'); -const path = require('path'); -const configManager = require('hullabaloo-config-manager'); -const md5Hex = require('md5-hex'); -const makeDir = require('make-dir'); -const chalk = require('./chalk').get(); - -const stage4Path = require.resolve('../stage-4'); -const syntaxAsyncGeneratorsPath = require.resolve('@babel/plugin-syntax-async-generators'); -const syntaxObjectRestSpreadPath = require.resolve('@babel/plugin-syntax-object-rest-spread'); -const transformTestFilesPath = require.resolve('@ava/babel-preset-transform-test-files'); - -function validate(conf) { - if (conf === false) { - return null; - } - - if (conf === undefined) { - return {testOptions: {}}; - } - - if (!conf || typeof conf !== 'object' || !conf.testOptions || typeof conf.testOptions !== 'object' || Array.isArray(conf.testOptions) || Object.keys(conf).length > 1) { - throw new Error(`Unexpected Babel configuration for AVA. See ${chalk.underline('https://github.com/avajs/ava/blob/master/docs/recipes/babel.md')} for allowed values.`); - } - - return conf; -} - -function verifyExistingOptions(verifierFile, baseConfig, cache, envName) { - return new Promise((resolve, reject) => { - try { - resolve(fs.readFileSync(verifierFile)); - } catch (err) { - if (err && err.code === 'ENOENT') { - resolve(null); - } else { - reject(err); - } - } - }) - .then(buffer => { - if (!buffer) { - return null; - } - - const verifier = configManager.restoreVerifier(buffer); - const fixedSourceHashes = new Map(); - fixedSourceHashes.set(baseConfig.source, baseConfig.hash); - if (baseConfig.extends) { - fixedSourceHashes.set(baseConfig.extends.source, baseConfig.extends.hash); - } - return verifier.verifyEnv(envName, {sources: fixedSourceHashes}, cache) - .then(result => { - if (!result.cacheKeys) { - return null; - } - - if (result.dependenciesChanged) { - fs.writeFileSync(verifierFile, result.verifier.toBuffer()); - } - - return result.cacheKeys; - }); - }); -} - -function resolveOptions(baseConfig, cache, envName, optionsFile, verifierFile) { // eslint-disable-line max-params - return configManager.fromConfig(baseConfig, {cache, expectedEnvNames: [envName]}) - .then(result => { - fs.writeFileSync(optionsFile, result.generateModule()); - - return result.createVerifier() - .then(verifier => { - fs.writeFileSync(verifierFile, verifier.toBuffer()); - return verifier.cacheKeysForEnv(envName); - }); - }); -} - -function build(projectDir, cacheDir, userOptions, compileEnhancements) { - if (!userOptions && !compileEnhancements) { - return Promise.resolve(null); - } - - // Note that Babel ignores empty string values, even for NODE_ENV. Here - // default to 'test' unless NODE_ENV is defined, in which case fall back to - // Babel's default of 'development' if it's empty. - const envName = process.env.BABEL_ENV || ('NODE_ENV' in process.env ? process.env.NODE_ENV : 'test') || 'development'; - - // Compute a seed based on the Node.js version and the project directory. - // Dependency hashes may vary based on the Node.js version, e.g. with the - // @ava/stage-4 Babel preset. Sources and dependencies paths are absolute in - // the generated module and verifier state. Those paths wouldn't necessarily - // be valid if the project directory changes. - // Also include `envName`, so options can be cached even if users change - // BABEL_ENV or NODE_ENV between runs. - const seed = md5Hex([process.versions.node, projectDir, envName]); - - // Ensure cacheDir exists - makeDir.sync(cacheDir); - - // The file names predict where valid options may be cached, and thus should - // include the seed. - const optionsFile = path.join(cacheDir, `${seed}.babel-options.js`); - const verifierFile = path.join(cacheDir, `${seed}.verifier.bin`); - - const baseOptions = { - babelrc: false, - plugins: [ - // TODO: Remove once Babel can parse this syntax unaided. - syntaxAsyncGeneratorsPath, - syntaxObjectRestSpreadPath - ], - presets: [] - }; - - if (userOptions) { - // Always apply the stage-4 preset. - baseOptions.presets.push(stage4Path); - - // By default extend the project's Babel configuration, but allow this to be - // disabled through userOptions. - if (userOptions.testOptions.babelrc !== false) { - baseOptions.babelrc = true; - } - if (userOptions.testOptions.extends) { - baseOptions.extends = userOptions.testOptions.extends; - } - } - - const baseConfig = configManager.createConfig({ - dir: projectDir, - fileType: 'JSON', - hash: md5Hex(JSON.stringify(baseOptions)), - options: baseOptions, - source: '(AVA) baseConfig' - }); - - let intermediateConfig = baseConfig; - if (userOptions && Object.keys(userOptions.testOptions).length > 0) { - // At this level, babelrc *must* be false. - const options = Object.assign({}, userOptions.testOptions, {babelrc: false}); - // Any extends option has been applied in baseConfig. - delete options.extends; - intermediateConfig = configManager.createConfig({ - dir: projectDir, - fileType: 'JSON', - hash: md5Hex(JSON.stringify(options)), - options, - source: path.join(projectDir, 'package.json') + '#ava.babel' - }); - intermediateConfig.extend(baseConfig); - } - - let finalConfig = intermediateConfig; - if (compileEnhancements) { - finalConfig = configManager.createConfig({ - dir: projectDir, - fileType: 'JSON', - hash: '', // This is deterministic, so no actual value necessary. - options: { - babelrc: false, - presets: [ - [transformTestFilesPath, {powerAssert: true}] - ] - }, - source: '(AVA) compileEnhancements' - }); - finalConfig.extend(intermediateConfig); - } - - const cache = configManager.prepareCache(); - return verifyExistingOptions(verifierFile, finalConfig, cache, envName) - .then(cacheKeys => { - if (cacheKeys) { - return cacheKeys; - } - - return resolveOptions(finalConfig, cache, envName, optionsFile, verifierFile); - }) - .then(cacheKeys => { - const getOptions = require(optionsFile).getOptions; - return { - getOptions() { - return getOptions(envName, cache); - }, - // Include the seed in the cache keys used to store compilation results. - cacheKeys: Object.assign({seed}, cacheKeys) - }; - }); -} - -module.exports = { - validate, - build -}; diff --git a/lib/babel-pipeline.js b/lib/babel-pipeline.js new file mode 100644 index 000000000..b9cd16374 --- /dev/null +++ b/lib/babel-pipeline.js @@ -0,0 +1,196 @@ +'use strict'; +const fs = require('fs'); +const path = require('path'); +const writeFileAtomic = require('@ava/write-file-atomic'); +const babel = require('@babel/core'); +const convertSourceMap = require('convert-source-map'); +const md5Hex = require('md5-hex'); +const packageHash = require('package-hash'); +const stripBomBuf = require('strip-bom-buf'); +const chalk = require('./chalk').get(); + +function getSourceMap(filePath, code) { + let sourceMap = convertSourceMap.fromSource(code); + + if (!sourceMap) { + const dirPath = path.dirname(filePath); + sourceMap = convertSourceMap.fromMapFileSource(code, dirPath); + } + + return sourceMap ? sourceMap.toObject() : undefined; +} + +function validate(conf) { + if (conf === false) { + return null; + } + + const defaultOptions = {babelrc: true}; + + if (conf === undefined) { + return {testOptions: defaultOptions}; + } + + if (!conf || typeof conf !== 'object' || !conf.testOptions || typeof conf.testOptions !== 'object' || Array.isArray(conf.testOptions) || Object.keys(conf).length > 1) { + throw new Error(`Unexpected Babel configuration for AVA. See ${chalk.underline('https://github.com/avajs/ava/blob/master/docs/recipes/babel.md')} for allowed values.`); + } + + return { + testOptions: Object.assign({}, defaultOptions, conf.testOptions) + }; +} + +// Compare actual values rather than file paths, which should be +// more reliable. +function makeValueChecker(ref) { + const expected = require(ref); + return ({value}) => value === expected; +} + +// Resolved paths are used to create the config item, rather than the plugin +// function itself, so Babel can print better error messages. +// See . +function createConfigItem(ref, type, options = {}) { + return babel.createConfigItem([require.resolve(ref), options], {type}); +} + +// Assume the stage-4 preset is wanted if there are `userOptions`, but there is +// no declaration of a stage-` preset that comes with `false` for its options. +// +// Ideally we'd detect the stage-4 preset anywhere in the configuration +// hierarchy, but Babel's loadPartialConfig() does not return disabled presets. +// See . +function wantsStage4(userOptions, projectDir) { + if (!userOptions) { + return false; + } + + if (!userOptions.testOptions.presets) { + return true; + } + + const stage4 = require('../stage-4'); + return userOptions.testOptions.presets.every(arr => { + if (!Array.isArray(arr)) { + return true; // There aren't any preset options. + } + + const [ref, options] = arr; + // Require the preset given the aliasing `ava/stage-4` does towards + // `@ava/babel-preset-stage-4`. + const resolved = require(babel.resolvePreset(ref, projectDir)); + return resolved !== stage4 || options !== false; + }); +} + +function build(projectDir, cacheDir, userOptions, compileEnhancements) { + if (!userOptions && !compileEnhancements) { + return null; + } + + // Note that Babel ignores empty string values, even for NODE_ENV. Here + // default to 'test' unless NODE_ENV is defined, in which case fall back to + // Babel's default of 'development' if it's empty. + const envName = process.env.BABEL_ENV || ('NODE_ENV' in process.env ? process.env.NODE_ENV : 'test') || 'development'; + + // Prepare inputs for caching seeds. Compute a seed based on the Node.js + // version and the project directory. Dependency hashes may vary based on the + // Node.js version, e.g. with the @ava/stage-4 Babel preset. Certain plugins + // and presets are provided as absolute paths, which wouldn't necessarily + // be valid if the project directory changes. Also include `envName`, so + // options can be cached even if users change BABEL_ENV or NODE_ENV between + // runs. + const seedInputs = [ + process.versions.node, + packageHash.sync(require.resolve('../package.json')), + projectDir, + envName, + JSON.stringify(userOptions) + ]; + + // TODO: Take resolved plugin and preset files and compute package hashes for + // inclusion in the cache key. + const cacheKey = md5Hex(seedInputs); + + const ensureStage4 = wantsStage4(userOptions, projectDir); + const containsAsyncGenerators = makeValueChecker('@babel/plugin-syntax-async-generators'); + const containsObjectRestSpread = makeValueChecker('@babel/plugin-syntax-object-rest-spread'); + const containsStage4 = makeValueChecker('../stage-4'); + const containsTransformTestFiles = makeValueChecker('@ava/babel-preset-transform-test-files'); + + const loadOptions = (filename, inputSourceMap) => { + const partialTestConfig = babel.loadPartialConfig(Object.assign({ + babelrc: false, + babelrcRoots: [projectDir], + configFile: false, + cwd: projectDir + }, userOptions && userOptions.testOptions, { + envName, + inputSourceMap, + filename, + sourceMaps: true + })); + + // TODO: Check for `partialTestConfig.config` and include a hash of the file + // content in the cache key. Do the same for `partialTestConfig.babelrc`, + // though if it's a `package.json` file only include `package.json#babel` in + // the cache key. + + if (!partialTestConfig) { + return null; + } + + const {options: testOptions} = partialTestConfig; + if (!testOptions.plugins.some(containsAsyncGenerators)) { // TODO: Remove once Babel can parse this syntax unaided. + testOptions.plugins.unshift(createConfigItem('@babel/plugin-syntax-async-generators', 'plugin')); + } + if (!testOptions.plugins.some(containsObjectRestSpread)) { // TODO: Remove once Babel can parse this syntax unaided. + testOptions.plugins.unshift(createConfigItem('@babel/plugin-syntax-object-rest-spread', 'plugin')); + } + if (ensureStage4 && !testOptions.presets.some(containsStage4)) { + // Apply last. + testOptions.presets.unshift(createConfigItem('../stage-4', 'preset')); + } + if (compileEnhancements && !testOptions.presets.some(containsTransformTestFiles)) { + // Apply first. + testOptions.presets.push(createConfigItem('@ava/babel-preset-transform-test-files', 'preset', {powerAssert: true})); + } + + return babel.loadOptions(testOptions); + }; + + return filename => { + const contents = stripBomBuf(fs.readFileSync(filename)); + const ext = path.extname(filename); + const hash = md5Hex([cacheKey, contents]); + const cachePath = path.join(cacheDir, `${hash}${ext}`); + + if (fs.existsSync(cachePath)) { + return cachePath; + } + + const inputCode = contents.toString('utf8'); + const inputSourceMap = getSourceMap(filename, inputCode); + const options = loadOptions(filename, inputSourceMap); + if (!options) { + return null; + } + + const {code, map} = babel.transformSync(inputCode, options); + + // Save source map + const mapPath = `${cachePath}.map`; + writeFileAtomic.sync(mapPath, JSON.stringify(map)); + + // Append source map comment to transformed code so that other libraries + // (like nyc) can find the source map. + const comment = convertSourceMap.generateMapFileComment(mapPath); + writeFileAtomic.sync(cachePath, `${code}\n${comment}`); + return cachePath; + }; +} + +module.exports = { + validate, + build +}; diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js deleted file mode 100644 index cba756857..000000000 --- a/lib/caching-precompiler.js +++ /dev/null @@ -1,102 +0,0 @@ -'use strict'; -const path = require('path'); -const fs = require('fs'); -const convertSourceMap = require('convert-source-map'); -const cachingTransform = require('caching-transform'); -const packageHash = require('package-hash'); -const stripBomBuf = require('strip-bom-buf'); -const autoBind = require('auto-bind'); -const md5Hex = require('md5-hex'); - -function getSourceMap(filePath, code) { - let sourceMap = convertSourceMap.fromSource(code); - - if (!sourceMap) { - const dirPath = path.dirname(filePath); - sourceMap = convertSourceMap.fromMapFileSource(code, dirPath); - } - - return sourceMap ? sourceMap.toObject() : undefined; -} - -class CachingPrecompiler { - constructor(options) { - autoBind(this); - - this.getBabelOptions = options.getBabelOptions; - this.babelCacheKeys = options.babelCacheKeys; - this.cacheDirPath = options.path; - this.fileHashes = {}; - this.transform = this._createTransform(); - } - - precompileFile(filePath) { - if (!this.fileHashes[filePath]) { - const source = stripBomBuf(fs.readFileSync(filePath)); - this.transform(source, filePath); - } - - return this.fileHashes[filePath]; - } - - // Conditionally called by caching-transform when precompiling is required - _init() { - this.babel = require('@babel/core'); - return this._transform; - } - - _transform(code, filePath, hash) { - code = code.toString(); - - let result; - const originalBabelDisableCache = process.env.BABEL_DISABLE_CACHE; - try { - // Disable Babel's cache. AVA has good cache management already. - process.env.BABEL_DISABLE_CACHE = '1'; - - result = this.babel.transform(code, Object.assign(this.getBabelOptions(), { - inputSourceMap: getSourceMap(filePath, code), - filename: filePath, - sourceMaps: true, - ast: false - })); - } finally { - // Restore the original value. It is passed to workers, where users may - // not want Babel's cache to be disabled. - process.env.BABEL_DISABLE_CACHE = originalBabelDisableCache; - } - - // Save source map - const mapPath = path.join(this.cacheDirPath, `${hash}.js.map`); - fs.writeFileSync(mapPath, JSON.stringify(result.map)); - - // Append source map comment to transformed code - // So that other libraries (like nyc) can find the source map - const comment = convertSourceMap.generateMapFileComment(mapPath); - - return `${result.code}\n${comment}`; - } - - _createTransform() { - const salt = packageHash.sync([ - require.resolve('../package.json'), - require.resolve('@babel/core/package.json') - ], this.babelCacheKeys); - - return cachingTransform({ - factory: this._init, - cacheDir: this.cacheDirPath, - hash: this._generateHash, - salt, - ext: '.js' - }); - } - - _generateHash(code, filePath, salt) { - const hash = md5Hex([code, filePath, salt]); - this.fileHashes[filePath] = hash; - return hash; - } -} - -module.exports = CachingPrecompiler; diff --git a/lib/cli.js b/lib/cli.js index 0ae9f9daa..613f53dbf 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -148,11 +148,11 @@ exports.run = () => { // eslint-disable-line complexity const MiniReporter = require('./reporters/mini'); const TapReporter = require('./reporters/tap'); const Watcher = require('./watcher'); - const babelConfigHelper = require('./babel-config'); + const babelPipeline = require('./babel-pipeline'); let babelConfig = null; try { - babelConfig = babelConfigHelper.validate(conf.babel); + babelConfig = babelPipeline.validate(conf.babel); } catch (err) { exit(err.message); } diff --git a/lib/worker/precompiler-hook.js b/lib/worker/precompiler-hook.js index 9229ee8ea..39f2e73a0 100644 --- a/lib/worker/precompiler-hook.js +++ b/lib/worker/precompiler-hook.js @@ -1,12 +1,10 @@ 'use strict'; const fs = require('fs'); -const path = require('path'); const sourceMapSupport = require('source-map-support'); const installPrecompiler = require('require-precompiled'); const options = require('./options').get(); const sourceMapCache = new Map(); -const cacheDir = options.cacheDir; function installSourceMapSupport() { sourceMapSupport.install({ @@ -30,8 +28,8 @@ function install() { const precompiled = options.precompiled[filename]; if (precompiled) { - sourceMapCache.set(filename, path.join(cacheDir, `${precompiled}.js.map`)); - return fs.readFileSync(path.join(cacheDir, `${precompiled}.js`), 'utf8'); + sourceMapCache.set(filename, `${precompiled}.map`); + return fs.readFileSync(precompiled, 'utf8'); } return null; diff --git a/package-lock.json b/package-lock.json index de0f29273..a00048eeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,29 +5,29 @@ "requires": true, "dependencies": { "@ava/babel-plugin-throws-helper": { - "version": "3.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-3.0.0-beta.4.tgz", - "integrity": "sha512-Gqdcu/eOlHzOsPTm0BNjwUiZxK9I+4OEVPNXob/ViqLN+qEc480PIMjnJeWc6mq1wSax6/KE4ldjd1H4VX7Hzw==" + "version": "3.0.0-beta.5", + "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-3.0.0-beta.5.tgz", + "integrity": "sha512-c+qPCTafwSkvWlqhMY15wajNaHrOBVls38RJq+zMWVzj7T5b9djirPLeF9ffro48terghDOhmaqG9mr29/b4QQ==" }, "@ava/babel-preset-stage-4": { - "version": "2.0.0-beta.5", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-2.0.0-beta.5.tgz", - "integrity": "sha512-zOeZRiqNISj9F7YmxaxrMrDucQq4h2GIEbHEWMLx+n8jYFyjYyOGlZXc/n/zdfBWGDcSM0ykq5I6//JmAfjh3A==", + "version": "2.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-2.0.0-beta.6.tgz", + "integrity": "sha512-C9BWcYGhtwJfjpo0CkLOCkHtK7MLC7twPX/JSC4RxmrSME2uMKWhyGNLJkA4Tyu4kaQNvUn+kocwO4qS39lpFA==", "requires": { - "@babel/plugin-proposal-async-generator-functions": "7.0.0-beta.44", - "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.44", - "@babel/plugin-transform-async-to-generator": "7.0.0-beta.44", - "@babel/plugin-transform-dotall-regex": "7.0.0-beta.44", - "@babel/plugin-transform-exponentiation-operator": "7.0.0-beta.44", - "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.44" + "@babel/plugin-proposal-async-generator-functions": "7.0.0-beta.48", + "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.48", + "@babel/plugin-transform-async-to-generator": "7.0.0-beta.48", + "@babel/plugin-transform-dotall-regex": "7.0.0-beta.48", + "@babel/plugin-transform-exponentiation-operator": "7.0.0-beta.48", + "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.48" } }, "@ava/babel-preset-transform-test-files": { - "version": "4.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-4.0.0-beta.4.tgz", - "integrity": "sha512-y2j0hMn5g7ueN5pbftfYLHsRA6BEyHbquI15R/zXMlsnVZv8rIRZn2gY7e3OM//mZ/8SyKrMq8JoFmQlNOTEbQ==", + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-4.0.0-beta.5.tgz", + "integrity": "sha512-xdiRhNrow0mpM4mz9I6eg+81kXkCMobJrk18mVyVEcD7U4vZF4s4C4E/joeWuEoAqf5qhNG+0t3oon961YHK1Q==", "requires": { - "@ava/babel-plugin-throws-helper": "3.0.0-beta.4", + "@ava/babel-plugin-throws-helper": "3.0.0-beta.5", "babel-plugin-espower": "3.0.0-beta.1" } }, @@ -42,297 +42,365 @@ } }, "@babel/code-frame": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz", - "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.48.tgz", + "integrity": "sha512-zwyam2DrinaJfhmCaajZT2yRCoN3cE8dwW7uVWaHay9z2Dwn9Pidnekkz9g7kXbg2qfVqmgDKeUTVZ4+bMlfZA==", "requires": { - "@babel/highlight": "7.0.0-beta.44" + "@babel/highlight": "7.0.0-beta.48" } }, "@babel/core": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.0.0-beta.44.tgz", - "integrity": "sha512-E16ps55Av+GAO6qVTZeVR5FMVppraUPjiJEHuH0sANsbmkEjqQ70XQiv0KXPYbPzHBd+gijx6uLakSacjvtwIA==", - "requires": { - "@babel/code-frame": "7.0.0-beta.44", - "@babel/generator": "7.0.0-beta.44", - "@babel/helpers": "7.0.0-beta.44", - "@babel/template": "7.0.0-beta.44", - "@babel/traverse": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44", - "babylon": "7.0.0-beta.44", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.0.0-beta.48.tgz", + "integrity": "sha512-IDgOf/eKZjsW2Hz+/tXph1AczBe4MPWo53Eno5XKM68u7t3N86BMqdRQB8RctfDEhAww7EqB80CBFr7iWMDkqA==", + "requires": { + "@babel/code-frame": "7.0.0-beta.48", + "@babel/generator": "7.0.0-beta.48", + "@babel/helpers": "7.0.0-beta.48", + "@babel/parser": "7.0.0-beta.48", + "@babel/template": "7.0.0-beta.48", + "@babel/traverse": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48", "convert-source-map": "^1.1.0", "debug": "^3.1.0", "json5": "^0.5.0", - "lodash": "^4.2.0", + "lodash": "^4.17.5", "micromatch": "^2.3.11", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/generator": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz", - "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.48.tgz", + "integrity": "sha512-RPS4dHg3wVmivvMIHW9N/ZHPZ5vc7runskURDqz3xamcFlUXSVxoziaS9VOJeivKXGzFPqr/wY03u9wDc+4A1g==", "requires": { - "@babel/types": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.48", "jsesc": "^2.5.1", - "lodash": "^4.2.0", + "lodash": "^4.17.5", "source-map": "^0.5.0", "trim-right": "^1.0.1" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/helper-annotate-as-pure": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.44.tgz", - "integrity": "sha512-trEw653XRNMCBIno/GyuffHi7AxB4miw1EHDeA/q9uIYNdyaXahIdQuBlbzGRWWoBdObFf4Ua0cDFgWkrfgBPw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.48.tgz", + "integrity": "sha512-LBldrgCApkHFwwtMJC2P2MeH+09+vPVj3Gs+mltqSpY+LyowjjUmqLUcmrF+Kj/gmRY/DqGAbvZWwNlNDs6dGQ==", "requires": { - "@babel/types": "7.0.0-beta.44" + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.44.tgz", - "integrity": "sha512-M9+OPXXT3yqTvMlUmvXf53NX7qkzGkahXnkIyY15gNP/yWGG5ODYNa225Mq7/Vp0zMrI7JastEnn0AuEXSUQWA==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.48.tgz", + "integrity": "sha512-VBAT5LjhWATA/s+R0yjqthw27fzkAALoqIMf5zcyWq2GaBrAt8+Fwtj4KaWwS/linJDMEekC/ehb++wJOtVgiQ==", "requires": { - "@babel/helper-explode-assignable-expression": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/helper-explode-assignable-expression": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.44.tgz", - "integrity": "sha512-XM+nY15w/Hyb9yKhGnMMV3R2RUdPGl8/+pTfOKBt4/eLapozSrUh+7xrMOwgJOO+TWuQMlMbQLRJUiMsHUHNbw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.48.tgz", + "integrity": "sha512-HdKAuJM3KNwnzINIpLfvvJGu/k2EyTzvPiHXn+sEd3jfRByQU1yK2IKEEN1oJn4XPoC1OOLSYnyJbPkQnIjhXA==", "requires": { - "@babel/traverse": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/traverse": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-function-name": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz", - "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.48.tgz", + "integrity": "sha512-7QUvVTskXuu8q8ZB6/OMM/hjoNaAjZOU1u9zMuJFvSHA7xzep0QOmPMmF8y2tadNGwuRT6KpY8DiB6GNQly6Nw==", "requires": { - "@babel/helper-get-function-arity": "7.0.0-beta.44", - "@babel/template": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/helper-get-function-arity": "7.0.0-beta.48", + "@babel/template": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-get-function-arity": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz", - "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.48.tgz", + "integrity": "sha512-crZpcjFTMxoKHgS2V75YrmCam+BULh/qesfqjaf9ioT2SfHxxXQoQeanh/xf7TTLAcIlZZkUMVgab3x4XyWSGA==", "requires": { - "@babel/types": "7.0.0-beta.44" + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-module-imports": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.44.tgz", - "integrity": "sha512-V95wi6rCffcLM46XdaUJHRc3D/XSvfsQshedaX1riHQCbs0uVopdswXrykwB6E/QEPfUGxXfs7l5GubupOi+Cw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.48.tgz", + "integrity": "sha512-uuxpRHHTP7+xVAtKro9z09P4bSkBcA4B+JoMc6FsT61GGnE3iRIbqb2QxQm6dFDMshlZc51/EfOainbimZRqCw==", "requires": { - "@babel/types": "7.0.0-beta.44", - "lodash": "^4.2.0" + "@babel/types": "7.0.0-beta.48", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/helper-module-transforms": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.44.tgz", - "integrity": "sha512-mwoQuzm1xY3L00Rf6vHO0tFKkBxarODf1f5l4wClTzvBmm7ReikPKyNwgS7wp2dzlorpIKPAAw+n3IEhnOjLJg==", - "requires": { - "@babel/helper-module-imports": "7.0.0-beta.44", - "@babel/helper-simple-access": "7.0.0-beta.44", - "@babel/helper-split-export-declaration": "7.0.0-beta.44", - "@babel/template": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44", - "lodash": "^4.2.0" + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.48.tgz", + "integrity": "sha512-PTAHN19m51RBc713bQdU7yd+McGkiOVV56gMtoC9x8iYZ7mfoxvyN723t7ZUkFdMlppTW2xCzWGZ0Ok9Aw1UNA==", + "requires": { + "@babel/helper-module-imports": "7.0.0-beta.48", + "@babel/helper-simple-access": "7.0.0-beta.48", + "@babel/helper-split-export-declaration": "7.0.0-beta.48", + "@babel/template": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/helper-plugin-utils": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.44.tgz", - "integrity": "sha512-k0hZ8w9N3b0Psmlw0bB7U9Hwqc+/hh7yOPFyLi5KAX9pRZ9i+UbTg6DxsVLVuITvF/M1UZNrq7vatrlEw/IPMg==" + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.48.tgz", + "integrity": "sha512-2ocT0LL1uVUJVnAurHl9pcHfW8VaucCfM2YTQOVJC5yrL9CYx2HqrBsXIS6ZhOJUcbSot6945fsZhUiDWegtsw==" }, "@babel/helper-regex": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0-beta.44.tgz", - "integrity": "sha512-UiL6tMd2eUPK6RVpaeUzQ0jDFzGaeQ3All+YpFc+K9onz1BXDArFoJBygZfkjOgfmwBiSbXLShpRBA5QMgOSmQ==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0-beta.48.tgz", + "integrity": "sha512-ibH3eKfwlVZmh0UIDS/EbK6LvCe5IS4ZyIPI7nWWkQUWrJFa5unHastqiEVKfRPN06UqVdJkH6lXQxKBEpXBvQ==", "requires": { - "lodash": "^4.2.0" + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/helper-remap-async-to-generator": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.44.tgz", - "integrity": "sha512-Jk2mwO7QOx9n5ktVx8OOuuybyCuZ+gSnd9HqkdxqdfjF+kzJ6FvQ1QUqOf3Dg1uTFmN2/UzBpFgFV4OH71xmWw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.48.tgz", + "integrity": "sha512-+DpwvwnTyH8A+WmD9X4Ubh3AyOp0TQYU6oy+1l5Qw2wlZIqsVb2VMoppET96siPv39R01E7vii/gsgne/Oqevg==", "requires": { - "@babel/helper-annotate-as-pure": "7.0.0-beta.44", - "@babel/helper-wrap-function": "7.0.0-beta.44", - "@babel/template": "7.0.0-beta.44", - "@babel/traverse": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/helper-annotate-as-pure": "7.0.0-beta.48", + "@babel/helper-wrap-function": "7.0.0-beta.48", + "@babel/template": "7.0.0-beta.48", + "@babel/traverse": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-simple-access": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.44.tgz", - "integrity": "sha512-z6tIoPYPT9VOgVSKC7wPjobjvCP/DEfM0uvMDhofAl8p0GDMmMCCs46UNBr6hW1T55WgUGdkNiCFYVnCLjWNFQ==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.48.tgz", + "integrity": "sha512-55d2jEz4avJ+9hUIAS8stHRADIi7CeL/JcYGrUI+Ik/sDboCY3cdWRlFECC3PW3VksfI+F2BheDiupNj3rm5sw==", "requires": { - "@babel/template": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44", - "lodash": "^4.2.0" + "@babel/template": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/helper-split-export-declaration": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz", - "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.48.tgz", + "integrity": "sha512-ghYl4j1y3GMYjCxT+V3caUTXwt4kaKbpMYHDbMvTX6/yyVQ8kCxSHEU9ZX0uSTeZDvgFjPLA53s7HOP1zdFwZw==", "requires": { - "@babel/types": "7.0.0-beta.44" + "@babel/types": "7.0.0-beta.48" } }, "@babel/helper-wrap-function": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.44.tgz", - "integrity": "sha512-qCdMAdMzDhO87r7yS2adqzIl2N9FJaVkPYq6bKllkNcmHquytve+hd/jD/lruD71i3JWkH+M352U+lhW2qkToA==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.48.tgz", + "integrity": "sha512-eQhuwPxmQNUyThNIrc+c/NRRZP9UFT9JQ4jqAZYp+WtGuz3AsMqLxfaxYaeXLWGGDYELr4UTsResuXmPORWj1Q==", "requires": { - "@babel/helper-function-name": "7.0.0-beta.44", - "@babel/template": "7.0.0-beta.44", - "@babel/traverse": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/helper-function-name": "7.0.0-beta.48", + "@babel/template": "7.0.0-beta.48", + "@babel/traverse": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/helpers": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0-beta.44.tgz", - "integrity": "sha512-7qXsqiaMZzVuI0dobFGa9dQhCd6Y19lGeu4HrFHJo13/y9NKngepg/CYMzBi79TacKeaWfJNj3TeVCyRtfZqUg==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0-beta.48.tgz", + "integrity": "sha512-5qvSiDO+3tOyzZAoT+PvMMlbau+P+yI2LSDo7m38x9i1nbAMooFLQTdYqOAhFpRo8cXg2Lg1msYqpYK8CeqHYQ==", "requires": { - "@babel/template": "7.0.0-beta.44", - "@babel/traverse": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44" + "@babel/template": "7.0.0-beta.48", + "@babel/traverse": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48" } }, "@babel/highlight": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz", - "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.48.tgz", + "integrity": "sha512-nvyRS7pcfayjRjMg9KXCUdVcLq8/njx2ktvckovIx7cMJ9+aY58735xTIC0adkPZ13KJHbik6fJMfxO8PPZaLg==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^3.0.0" } }, + "@babel/parser": { + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0-beta.48.tgz", + "integrity": "sha512-X3pKxvy7vL79zc/6XS6cCObyuRMnsRGRu7d3zVSPZGCdxkK0/wTeFRwseRjcvhReV/6LW2D8H8qHVFFL0c+5+w==" + }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.44.tgz", - "integrity": "sha512-FW6MZpaFERkozQ5eS3PG/645nubF+d6JjgcyBGlhB98qKd9NmdRLHZJ0eKmpA6yG8TeDzpsUve0BE/+XNAYLrw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.48.tgz", + "integrity": "sha512-gBVjr30royW56cgLuuVuk73s/7vFQb9R407WAg1iDkJOeplMo+C0esblPR/5qAHCkpktoA1PizGl3vwfVSvo9w==", "requires": { - "@babel/helper-plugin-utils": "7.0.0-beta.44", - "@babel/helper-remap-async-to-generator": "7.0.0-beta.44", - "@babel/plugin-syntax-async-generators": "7.0.0-beta.44" + "@babel/helper-plugin-utils": "7.0.0-beta.48", + "@babel/helper-remap-async-to-generator": "7.0.0-beta.48", + "@babel/plugin-syntax-async-generators": "7.0.0-beta.48" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.44.tgz", - "integrity": "sha512-56Pqyeq3weYZccmcyzS4DVyVQ11SGWS6xCj/a5SmhvKXGHC2pEVovIBF63dFoQTlYFOzix9sZyW5oNVWicbTRg==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.48.tgz", + "integrity": "sha512-lBgqbSVX7HwsBN3//GZ+LIAtHcJm2mk0YxSigqc8JYbY6Kw27pNtvLtfGFPW7KJd4h1hFmfDkkxFk0uKhVIHSA==", "requires": { - "@babel/helper-plugin-utils": "7.0.0-beta.44", - "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.44" + "@babel/helper-plugin-utils": "7.0.0-beta.48", + "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.48" } }, "@babel/plugin-syntax-async-generators": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.44.tgz", - "integrity": "sha512-42MXWQvAN2IPPcW4HUbqgeyqkAwAsCGIHzxgSYoI7aOgkfOwHf5LRqSlJ56HAH+WwlWDQUvXeT/2PrQQY1vSCw==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.48.tgz", + "integrity": "sha512-cDLSZqUeTFhu11zwyFQw6tFsgH2SrPSXVUisaON1OnMG7A05E4M6rhfDGvv0aLHpX2njSD4nUwVoFsIitJE5Kg==", "requires": { - "@babel/helper-plugin-utils": "7.0.0-beta.44" + "@babel/helper-plugin-utils": "7.0.0-beta.48" } }, "@babel/plugin-syntax-object-rest-spread": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.44.tgz", - "integrity": "sha512-pVk9nFH7AAmn9Zor8Rv6g/JVXFwBW4FSFV1/3W84bw9s8yc8LZ7KqrCCpcHgBACVWJYnAtoxsaf7FFcQFl/z7Q==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.48.tgz", + "integrity": "sha512-xsezu/icfJxRpNxWG3AvvCyueKdpEZRVaPEISoSYPSiGqsFAaCozUu6XBTwDG2htcFcNfxHAdyar+TllJvQdxA==", "requires": { - "@babel/helper-plugin-utils": "7.0.0-beta.44" + "@babel/helper-plugin-utils": "7.0.0-beta.48" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.44.tgz", - "integrity": "sha512-+LTuKGnAd8w7FV45N+CvNE77GdcVMDT/w7so9++3jbG28w5id6VtQZ9cpFbqdvkZlpTy68Saw9zZcQeRZV3bmg==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.48.tgz", + "integrity": "sha512-XMwqQtmAYT1luf1WeOgRIIMNmvdqpPoWf3bdcqT8hGRJHTFxWdfkgIW/Zq6KqExnSOHFKmWF9cN7jqf/flQhGQ==", "requires": { - "@babel/helper-module-imports": "7.0.0-beta.44", - "@babel/helper-plugin-utils": "7.0.0-beta.44", - "@babel/helper-remap-async-to-generator": "7.0.0-beta.44" + "@babel/helper-module-imports": "7.0.0-beta.48", + "@babel/helper-plugin-utils": "7.0.0-beta.48", + "@babel/helper-remap-async-to-generator": "7.0.0-beta.48" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.44.tgz", - "integrity": "sha512-4oF4gIPOUbljRGzdMdTAKVojOurkoMh3QLsGTPgNp1HrGtIKAQMprojA9O6gXwseIqiaVSnx3RwaVo3nHzS0oA==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.48.tgz", + "integrity": "sha512-V1aVbyLT4dZGdDU45D5Bh/H8IVrVfY3xZYfHeEIPhR47Qs0gIn54xlJmaUVTLIYp5kx3qEwBPKI07BZbHd/P2g==", "requires": { - "@babel/helper-plugin-utils": "7.0.0-beta.44", - "@babel/helper-regex": "7.0.0-beta.44", + "@babel/helper-plugin-utils": "7.0.0-beta.48", + "@babel/helper-regex": "7.0.0-beta.48", "regexpu-core": "^4.1.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.44.tgz", - "integrity": "sha512-6muSWR3UxdAnVnk8a4rxESNQk7F+djM+oeKkETMgWbw6TyaNaTD7OYkKGTdyTT5jn2UO97sPdgOBIBdnzQsKQg==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.48.tgz", + "integrity": "sha512-oyUXYa3WMzVTtJIp2cjDBoFME8DRlxW1yBZVOdtI0MDLIkOrZjHMGVwCUblQgT10qfpiMfRYKJTN1t8zx98axw==", "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "7.0.0-beta.44", - "@babel/helper-plugin-utils": "7.0.0-beta.44" + "@babel/helper-builder-binary-assignment-operator-visitor": "7.0.0-beta.48", + "@babel/helper-plugin-utils": "7.0.0-beta.48" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.44.tgz", - "integrity": "sha512-wi1CPE/1G+EhJwFMgF0zhtE427dspqakhkl4na0KW0xmzh1Q3EKhfHsK/gizzNQlNtHRaW/Ks/vafJD3bAlk1Q==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.48.tgz", + "integrity": "sha512-tSBaAoYYE/mD7ZuFVH8TNj7uKe/SMSzLS18DQm+PxStI1bohcc/3nJpIYNK4JVVw11IWp9C/trCb4aLNK20lfA==", "requires": { - "@babel/helper-module-transforms": "7.0.0-beta.44", - "@babel/helper-plugin-utils": "7.0.0-beta.44", - "@babel/helper-simple-access": "7.0.0-beta.44" + "@babel/helper-module-transforms": "7.0.0-beta.48", + "@babel/helper-plugin-utils": "7.0.0-beta.48", + "@babel/helper-simple-access": "7.0.0-beta.48" } }, "@babel/template": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz", - "integrity": "sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng==", - "requires": { - "@babel/code-frame": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44", - "babylon": "7.0.0-beta.44", - "lodash": "^4.2.0" + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.48.tgz", + "integrity": "sha512-mFrSP6UZR02YGsqlnH/8IUENCnqs749RfujSGQ/CqeJYpeZ73PAJqk1Wg2khl+Huv4L4LW8dJh7qOQ/CBkRqEg==", + "requires": { + "@babel/code-frame": "7.0.0-beta.48", + "@babel/parser": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48", + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/traverse": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz", - "integrity": "sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA==", - "requires": { - "@babel/code-frame": "7.0.0-beta.44", - "@babel/generator": "7.0.0-beta.44", - "@babel/helper-function-name": "7.0.0-beta.44", - "@babel/helper-split-export-declaration": "7.0.0-beta.44", - "@babel/types": "7.0.0-beta.44", - "babylon": "7.0.0-beta.44", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.48.tgz", + "integrity": "sha512-lXNTgDIFj6xyzapkpvSvqFC8x7g+sw4SzxGVLKjSbX5rK1GK7YH2XXMHii1e6yhfscfC+ski36yH23z8m9r2fQ==", + "requires": { + "@babel/code-frame": "7.0.0-beta.48", + "@babel/generator": "7.0.0-beta.48", + "@babel/helper-function-name": "7.0.0-beta.48", + "@babel/helper-split-export-declaration": "7.0.0-beta.48", + "@babel/parser": "7.0.0-beta.48", + "@babel/types": "7.0.0-beta.48", "debug": "^3.1.0", "globals": "^11.1.0", "invariant": "^2.2.0", - "lodash": "^4.2.0" + "lodash": "^4.17.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@babel/types": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz", - "integrity": "sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ==", + "version": "7.0.0-beta.48", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.48.tgz", + "integrity": "sha512-h37aY8aUmTMEDEaPrNwmYmwSTjf7SvJ4h8jCljaHOSq3785TZSZnxdCsNDVs+fKK21lOPh9X29rvOLTOwxgVmw==", "requires": { "esutils": "^2.0.2", - "lodash": "^4.2.0", + "lodash": "^4.17.5", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } } }, "@concordance/react": { @@ -948,9 +1016,9 @@ } }, "babylon": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", - "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==" + "version": "7.0.0-beta.47", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.47.tgz", + "integrity": "sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ==" }, "balanced-match": { "version": "0.4.2", @@ -1086,36 +1154,6 @@ } } }, - "caching-transform": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", - "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", - "requires": { - "md5-hex": "^1.2.0", - "mkdirp": "^0.5.1", - "write-file-atomic": "^1.1.4" - }, - "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "requires": { - "md5-o-matic": "^0.1.1" - } - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - } - } - }, "call-matcher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", @@ -2948,13 +2986,13 @@ } }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "requires": { "is-number": "^2.1.0", "isobject": "^2.0.0", - "randomatic": "^1.1.3", + "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" } @@ -3610,44 +3648,6 @@ "sshpk": "^1.7.0" } }, - "hullabaloo-config-manager": { - "version": "2.0.0-beta.4", - "resolved": "https://registry.npmjs.org/hullabaloo-config-manager/-/hullabaloo-config-manager-2.0.0-beta.4.tgz", - "integrity": "sha512-43hSeIV+wubgSC08PvaWHSLadD8d46Ceia4hoJX/A3bDhdhNgxuHMFsdhygH+ykpjKLqKHcF8wfOTDPzdrWJMw==", - "requires": { - "dot-prop": "^4.2.0", - "graceful-fs": "^4.1.11", - "indent-string": "^3.2.0", - "json5": "^1.0.1", - "lodash.isequal": "^4.5.0", - "lodash.merge": "^4.6.1", - "md5-hex": "^2.0.0", - "package-hash": "^2.0.0", - "pirates": "^3.0.2", - "pkg-dir": "^2.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -3714,9 +3714,9 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "requires": { "loose-envify": "^1.0.0" } @@ -4283,7 +4283,8 @@ "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true }, "lodash.camelcase": { "version": "4.3.0", @@ -4341,7 +4342,8 @@ "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true }, "lodash.kebabcase": { "version": "4.1.1", @@ -4470,6 +4472,11 @@ "escape-string-regexp": "^1.0.4" } }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" + }, "md5-hex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", @@ -4811,11 +4818,6 @@ "is-stream": "^1.0.1" } }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" - }, "node-pre-gyp": { "version": "0.6.39", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", @@ -8118,14 +8120,6 @@ "pinkie": "^2.0.0" } }, - "pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, "pkg-conf": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", @@ -8299,39 +8293,24 @@ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=" }, "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" }, "dependencies": { "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -8439,14 +8418,14 @@ } }, "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-5.1.3.tgz", - "integrity": "sha512-Yjy6t7jFQczDhYE+WVm7pg6gWYE258q4sUkk9qDErwXJIqx7jU9jGrMFHutJK/SRfcg7MEkXjGaYiVlOZyev/A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-6.0.0.tgz", + "integrity": "sha512-BvXxRS7RfVWxtm7vrq+0I0j7sqZ1zeSC+yzf5HS0qLnKcZPX541gFEGB39LvGuKHrkyKXrzXug+oC7xkM1Zovw==", "requires": { "regenerate": "^1.3.3" } @@ -8468,14 +8447,14 @@ } }, "regexpu-core": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.1.3.tgz", - "integrity": "sha512-mB+njEzO7oezA57IbQxxd6fVPOeWKDmnGvJ485CwmfNchjHe5jWwqKepapmzUEj41yxIAqOg+C4LbXuJlkiO8A==", - "requires": { - "regenerate": "^1.3.3", - "regenerate-unicode-properties": "^5.1.1", - "regjsgen": "^0.3.0", - "regjsparser": "^0.2.1", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.1.5.tgz", + "integrity": "sha512-3xo5pFze1F8oR4F9x3aFbdtdxAxQ9WBX6gXfLgeBt7KpDI0+oDF7WVntnhsPKqobU/GAYc2pmx+y3z0JI1+z3w==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^6.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", "unicode-match-property-ecmascript": "^1.0.3", "unicode-match-property-value-ecmascript": "^1.0.1" } @@ -8498,14 +8477,14 @@ } }, "regjsgen": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.3.0.tgz", - "integrity": "sha1-DuSj6SdkMM2iXx54nqbBW4ewy0M=" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz", + "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==" }, "regjsparser": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.2.1.tgz", - "integrity": "sha1-w3h1U/rwTndcMCEC7zRtmVAA7Bw=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz", + "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==", "requires": { "jsesc": "~0.5.0" }, @@ -8764,7 +8743,8 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true }, "resolve-url": { "version": "0.2.1", diff --git a/package.json b/package.json index 996a7e695..d12317c48 100644 --- a/package.json +++ b/package.json @@ -58,13 +58,13 @@ "flow" ], "dependencies": { - "@ava/babel-preset-stage-4": "2.0.0-beta.5", - "@ava/babel-preset-transform-test-files": "4.0.0-beta.4", + "@ava/babel-preset-stage-4": "2.0.0-beta.6", + "@ava/babel-preset-transform-test-files": "4.0.0-beta.5", "@ava/write-file-atomic": "^2.2.0", - "@babel/core": "7.0.0-beta.44", - "@babel/generator": "7.0.0-beta.44", - "@babel/plugin-syntax-async-generators": "7.0.0-beta.44", - "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.44", + "@babel/core": "7.0.0-beta.48", + "@babel/generator": "7.0.0-beta.48", + "@babel/plugin-syntax-async-generators": "7.0.0-beta.48", + "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.48", "@concordance/react": "^1.0.0", "ansi-escapes": "^3.1.0", "ansi-styles": "^3.2.1", @@ -74,7 +74,6 @@ "arrify": "^1.0.0", "auto-bind": "^1.2.0", "bluebird": "^3.5.1", - "caching-transform": "^1.0.0", "chalk": "^2.3.2", "chokidar": "^2.0.3", "clean-stack": "^1.1.1", @@ -95,7 +94,6 @@ "figures": "^2.0.0", "get-port": "^3.2.0", "globby": "^7.1.1", - "hullabaloo-config-manager": "2.0.0-beta.4", "ignore-by-default": "^1.0.0", "import-local": "^1.0.0", "indent-string": "^3.2.0", diff --git a/profile.js b/profile.js index 8c6ba7437..2c7545e07 100644 --- a/profile.js +++ b/profile.js @@ -12,8 +12,7 @@ const pkgConf = require('pkg-conf'); const uniqueTempDir = require('unique-temp-dir'); const arrify = require('arrify'); const resolveCwd = require('resolve-cwd'); -const babelConfigHelper = require('./lib/babel-config'); -const CachingPrecompiler = require('./lib/caching-precompiler'); +const babelPipeline = require('./lib/babel-pipeline'); const RunStatus = require('./lib/run-status'); const VerboseReporter = require('./lib/reporters/verbose'); @@ -75,92 +74,84 @@ if (cli.input.length === 0) { const file = path.resolve(cli.input[0]); const cacheDir = conf.cacheEnabled === false ? uniqueTempDir() : path.join(projectDir, 'node_modules', '.cache', 'ava'); -babelConfigHelper.build(process.cwd(), cacheDir, babelConfigHelper.validate(conf.babel), conf.compileEnhancements === true) - .then(result => { - const precompiled = {}; - if (result) { - const precompiler = new CachingPrecompiler({ - path: cacheDir, - getBabelOptions: result.getOptions, - babelCacheKeys: result.cacheKeys - }); - - precompiled[file] = precompiler.precompileFile(file); - } +const precompileFile = babelPipeline.build(process.cwd(), cacheDir, babelPipeline.validate(conf.babel), conf.compileEnhancements === true); +const precompiled = {}; +if (precompileFile) { + precompiled[file] = precompileFile(file); +} - const opts = { - file, - failFast: cli.flags.failFast, - serial: cli.flags.serial, - tty: false, - cacheDir, - precompiled, - require: resolveModules(conf.require) - }; +const opts = { + file, + failFast: cli.flags.failFast, + serial: cli.flags.serial, + tty: false, + cacheDir, + precompiled, + require: resolveModules(conf.require) +}; + +// Mock the behavior of a parent process +process.connected = true; +process.channel = {ref() {}, unref() {}}; + +const reporter = new VerboseReporter({ + reportStream: process.stdout, + stdStream: process.stderr, + watching: false +}); - // Mock the behavior of a parent process - process.connected = true; - process.channel = {ref() {}, unref() {}}; - - const reporter = new VerboseReporter({ - reportStream: process.stdout, - stdStream: process.stderr, - watching: false - }); - - const runStatus = new RunStatus([file]); - runStatus.observeWorker({ - file, - onStateChange(listener) { - const emit = evt => listener(Object.assign(evt, {testFile: file})); - process.send = data => { - if (data && data.ava) { - const evt = data.ava; - if (evt.type === 'ping') { - if (console.profileEnd) { - console.profileEnd(); - } - - if (process.exitCode) { - emit({type: 'worker-failed', nonZeroExitCode: process.exitCode}); - } else { - emit({type: 'worker-finished', forcedExit: false}); - process.exitCode = runStatus.suggestExitCode({matching: false}); - } - - setImmediate(() => { - reporter.endRun(); - process.emit('message', {ava: {type: 'pong'}}); - }); - } else { - emit(data.ava); - } +const runStatus = new RunStatus([file]); +runStatus.observeWorker({ + file, + onStateChange(listener) { + const emit = evt => listener(Object.assign(evt, {testFile: file})); + process.send = data => { + if (data && data.ava) { + const evt = data.ava; + if (evt.type === 'ping') { + if (console.profileEnd) { + console.profileEnd(); } - }; + + if (process.exitCode) { + emit({type: 'worker-failed', nonZeroExitCode: process.exitCode}); + } else { + emit({type: 'worker-finished', forcedExit: false}); + process.exitCode = runStatus.suggestExitCode({matching: false}); + } + + setImmediate(() => { + reporter.endRun(); + process.emit('message', {ava: {type: 'pong'}}); + }); + } else { + emit(data.ava); + } } - }, file); - - reporter.startRun({ - failFastEnabled: false, - files: [file], - matching: false, - previousFailures: 0, - status: runStatus - }); - - process.on('beforeExit', () => { - process.exitCode = process.exitCode || runStatus.suggestExitCode({matching: false}); - }); - - // The "subprocess" will read process.argv[2] for options - process.argv[2] = JSON.stringify(opts); - process.argv.length = 3; - - if (console.profile) { - console.profile('AVA test-worker process'); - } + }; + } +}, file); + +reporter.startRun({ + failFastEnabled: false, + files: [file], + matching: false, + previousFailures: 0, + status: runStatus +}); - setImmediate(() => { - require('./lib/worker/subprocess'); // eslint-disable-line import/no-unassigned-import - }); - }); +process.on('beforeExit', () => { + process.exitCode = process.exitCode || runStatus.suggestExitCode({matching: false}); +}); + +// The "subprocess" will read process.argv[2] for options +process.argv[2] = JSON.stringify(opts); +process.argv.length = 3; + +if (console.profile) { + console.profile('AVA test-worker process'); +} + +setImmediate(() => { + require('./lib/worker/subprocess'); // eslint-disable-line import/no-unassigned-import +}); diff --git a/test/api.js b/test/api.js index 4a4a537b4..155593f78 100644 --- a/test/api.js +++ b/test/api.js @@ -1,19 +1,34 @@ 'use strict'; require('../lib/chalk').set(); +const assert = require('assert'); const path = require('path'); const fs = require('fs'); const del = require('del'); const test = require('tap').test; const Api = require('../api'); +const babelPipeline = require('../lib/babel-pipeline'); const testCapitalizerPlugin = require.resolve('./fixture/babel-plugin-test-capitalizer'); const ROOT_DIR = path.join(__dirname, '..'); +function withNodeEnv(value, run) { + assert(!('NODE_ENV' in process.env)); + process.env.NODE_ENV = value; + const reset = () => { + delete process.env.NODE_ENV; + }; + const promise = new Promise(resolve => { + resolve(run()); + }); + promise.then(reset, reset); + return promise; +} + function apiCreator(options) { options = options || {}; - options.babelConfig = options.babelConfig || {testOptions: {}}; + options.babelConfig = babelPipeline.validate(options.babelConfig); options.concurrency = 2; options.projectDir = options.projectDir || ROOT_DIR; options.resolveTestsFrom = options.resolveTestsFrom || options.projectDir; @@ -593,16 +608,11 @@ test('caching is enabled by default', t => { return api.run([path.join(__dirname, 'fixture/caching/test.js')]) .then(() => { const files = fs.readdirSync(path.join(__dirname, 'fixture/caching/node_modules/.cache/ava')); - t.ok(files.length, 4); - t.is(files.filter(x => endsWithBin(x)).length, 1); - t.is(files.filter(x => endsWithJs(x)).length, 2); + t.is(files.filter(x => endsWithJs(x)).length, 1); t.is(files.filter(x => endsWithMap(x)).length, 1); + t.is(files.length, 2); }); - function endsWithBin(filename) { - return /\.bin$/.test(filename); - } - function endsWithJs(filename) { return /\.js$/.test(filename); } @@ -797,7 +807,7 @@ test('babel.testOptions.babelrc can explicitly be false', t => { }); }); -test('babelConfig.testOptions merges plugins with .babelrc', t => { +test('babel.testOptions merges plugins with .babelrc', t => { t.plan(3); const api = apiCreator({ @@ -825,7 +835,58 @@ test('babelConfig.testOptions merges plugins with .babelrc', t => { }); }); -test('babelConfig.testOptions with extends still merges plugins with .babelrc', t => { +test('babel.testOptions.babelrc (when true) picks up .babelrc.js files', t => { + t.plan(3); + + const api = apiCreator({ + babelConfig: { + testOptions: { + babelrc: true + } + }, + projectDir: path.join(__dirname, 'fixture/babelrc-js') + }); + + api.on('run', plan => { + plan.status.on('stateChange', evt => { + if (evt.type === 'test-passed') { + t.ok((evt.title === 'foo') || (evt.title === 'repeated test: foo')); + } + }); + }); + + return api.run() + .then(runStatus => { + t.is(runStatus.stats.passedTests, 2); + }); +}); + +test('babel.testOptions can disable ava/stage-4', t => { + t.plan(1); + + const api = apiCreator({ + babelConfig: { + testOptions: { + babelrc: false, + presets: [[require.resolve('../stage-4'), false]] + } + }, + cacheEnabled: false, + projectDir: path.join(__dirname, 'fixture/babelrc') + }); + + api.on('run', plan => { + plan.status.on('stateChange', evt => { + if (evt.type === 'uncaught-exception') { + t.is(evt.err.name, 'SyntaxError'); + } + }); + }); + + return api.run(); +}); + +test('babel.testOptions with extends still merges plugins with .babelrc', t => { t.plan(3); const api = apiCreator({ @@ -853,6 +914,78 @@ test('babelConfig.testOptions with extends still merges plugins with .babelrc', }); }); +test('extended config can disable ava/stage-4', t => { + t.plan(1); + + const api = apiCreator({ + babelConfig: { + testOptions: { + babelrc: false, + extends: path.join(__dirname, 'fixture/babelrc/disable-stage-4.babelrc') + } + }, + cacheEnabled: false, + projectDir: path.join(__dirname, 'fixture/babelrc') + }); + + api.on('run', plan => { + plan.status.on('stateChange', evt => { + if (evt.type === 'uncaught-exception') { + t.is(evt.err.name, 'SyntaxError'); + } + }); + }); + + return api.run(); +}, {skip: true}); // FIXME https://github.com/babel/babel/issues/7920 + +test('babel can be disabled for particular files', t => { + t.plan(1); + + const api = apiCreator({ + babelConfig: { + testOptions: { + babelrc: false, + ignore: [path.join(__dirname, 'fixture/babelrc/test.js')] + } + }, + cacheEnabled: false, + projectDir: path.join(__dirname, 'fixture/babelrc') + }); + + api.on('run', plan => { + plan.status.on('stateChange', evt => { + if (evt.type === 'uncaught-exception') { + t.is(evt.err.name, 'SyntaxError'); + } + }); + }); + + return api.run(); +}); + +test('uses "development" Babel environment if NODE_ENV is the empty string', t => { + t.plan(2); + + const api = apiCreator({ + cacheEnabled: false, + projectDir: path.join(__dirname, 'fixture/babelrc') + }); + + api.on('run', plan => { + plan.status.on('stateChange', evt => { + if (evt.type === 'test-passed') { + t.is(evt.title, 'FOO'); + } + }); + }); + + return withNodeEnv('', () => api.run()) + .then(runStatus => { + t.is(runStatus.stats.passedTests, 1); + }); +}); + test('using --match with matching tests will only report those passing tests', t => { t.plan(3); diff --git a/test/babel-config.js b/test/babel-config.js deleted file mode 100644 index f74160258..000000000 --- a/test/babel-config.js +++ /dev/null @@ -1,217 +0,0 @@ -'use strict'; -require('../lib/chalk').set(); - -const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); -const test = require('tap').test; -const makeDir = require('make-dir'); -const uniqueTempDir = require('unique-temp-dir'); - -const babelConfigHelper = require('../lib/babel-config'); - -const fixture = name => path.join(__dirname, 'fixture', name); -const NUM_SYNTAX_PLUGINS = 2; - -function withNodeEnv(value, run) { - assert(!('NODE_ENV' in process.env)); - process.env.NODE_ENV = value; - const reset = () => { - delete process.env.NODE_ENV; - }; - const promise = new Promise(resolve => { - resolve(run()); - }); - promise.then(reset, reset); - return promise; -} - -test('includes testOptions in Babel compilation', t => { - const customFile = require.resolve(fixture('babel-noop-plugin-or-preset')); - const custom = require(fixture('babel-noop-plugin-or-preset')); - const testOptions = { - plugins: [customFile], - presets: [customFile] - }; - const compileEnhancements = true; - - const projectDir = fixture('no-babel-config'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, compileEnhancements) - .then(result => { - const options = result.getOptions(); - t.false(options.babelrc); - t.is(options.plugins[NUM_SYNTAX_PLUGINS][0].wrapped, custom); - t.is(options.presets[0][0].wrapped, require('@ava/babel-preset-stage-4')); - t.is(options.presets[1][0].wrapped, custom); - t.is(options.presets[2][0].wrapped, require('@ava/babel-preset-transform-test-files')); - t.same(options.presets[2][1], {powerAssert: true}); - }); -}); - -test('testOptions can disable ava/stage-4', t => { - const testOptions = { - presets: [['module:ava/stage-4', false]] - }; - const transpileEnhancements = true; - - const projectDir = uniqueTempDir(); - const cacheDir = path.join(projectDir, 'cache'); - fs.mkdirSync(projectDir); - fs.mkdirSync(path.join(projectDir, 'node_modules')); - fs.mkdirSync(path.join(projectDir, 'node_modules', 'ava')); - fs.writeFileSync(path.join(projectDir, 'node_modules', 'ava', 'stage-4.js'), `module.exports = require(${JSON.stringify(require.resolve('@ava/babel-preset-stage-4'))})`); - - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, transpileEnhancements) - .then(result => { - const options = result.getOptions(); - t.false(options.babelrc); - t.is(options.presets[0][0].wrapped, require('@ava/babel-preset-stage-4')); - t.is(options.presets[0][1], false); - }); -}); - -test('uses "development" environment if NODE_ENV is the empty string', t => { - const compileEnhancements = true; - - const projectDir = fixture('babelrc'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - return withNodeEnv('', () => babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, compileEnhancements)) - .then(result => { - const options = result.getOptions(); - - t.false(options.babelrc); - t.is(options.plugins[0][0].wrapped, require(fixture('babel-plugin-test-capitalizer'))); - t.is(options.presets[0][0].wrapped, require('@ava/babel-preset-stage-4')); - t.is(options.presets[1][0].wrapped, require('@ava/babel-preset-transform-test-files')); - t.same(options.presets[1][1], {powerAssert: true}); - }); -}); - -test('supports .babelrc.js files', t => { - const compileEnhancements = true; - - const projectDir = fixture('babelrc-js'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, compileEnhancements) - .then(result => { - const options = result.getOptions(); - - t.false(options.babelrc); - t.is(options.plugins[0][0].wrapped, require(fixture('babel-plugin-test-doubler'))); - t.is(options.presets[0][0].wrapped, require('@ava/babel-preset-stage-4')); - t.is(options.presets[1][0].wrapped, require('@ava/babel-preset-transform-test-files')); - t.same(options.presets[1][1], {powerAssert: true}); - }); -}); - -test('should not include transform-test-files when compileEnhancements is false', t => { - const compileEnhancements = false; - - const projectDir = fixture('no-babel-config'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, compileEnhancements) - .then(result => { - const options = result.getOptions(); - - t.false(options.babelrc); - t.is(options.presets.length, 1); - }); -}); - -test('caches and uses results', t => { - const projectDir = fixture('no-babel-config'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, true) - .then(result => { - const files = fs.readdirSync(cacheDir); - t.is(files.length, 2); - t.is(files.filter(f => /\.babel-options\.js$/.test(f)).length, 1); - t.is(files.filter(f => /\.verifier\.bin$/.test(f)).length, 1); - - const firstCacheKeys = result.cacheKeys; - const stats = files.map(f => fs.statSync(path.join(cacheDir, f))); - delete stats[0].atime; - delete stats[0].atimeMs; - delete stats[1].atime; - delete stats[1].atimeMs; - - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, true) - .then(result => { - const newStats = files.map(f => fs.statSync(path.join(cacheDir, f))); - delete newStats[0].atime; - delete newStats[0].atimeMs; - delete newStats[1].atime; - delete newStats[1].atimeMs; - - t.same(newStats, stats); - t.same(result.cacheKeys, firstCacheKeys); - }); - }); -}); - -test('discards cache if testOptions change', t => { - const projectDir = fixture('no-babel-config'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - const testOptions = {}; - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, true) - .then(result => { - const files = fs.readdirSync(cacheDir); - const contents = files.map(f => fs.readFileSync(path.join(cacheDir, f), 'utf8')); - const firstCacheKeys = result.cacheKeys; - - testOptions.foo = 'bar'; - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, true) - .then(result => { - t.notSame(files.map(f => fs.readFileSync(path.join(cacheDir, f), 'utf8')), contents); - t.notSame(result.cacheKeys, firstCacheKeys); - }); - }); -}); - -test('updates cached verifier if dependency hashes change', t => { - const projectDir = fixture('no-babel-config'); - const tempDir = uniqueTempDir(); - const cacheDir = path.join(tempDir, 'cache'); - const depFile = path.join(tempDir, 'plugin.js'); - - makeDir.sync(cacheDir); - fs.writeFileSync(depFile, 'module.exports = () => ({})'); - - const testOptions = { - plugins: [depFile] - }; - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, true) - .then(result => { - const verifierFile = fs.readdirSync(cacheDir).find(f => /\.verifier\.bin$/.test(f)); - const contents = fs.readFileSync(path.join(cacheDir, verifierFile), 'utf8'); - const firstCacheKeys = result.cacheKeys; - - fs.writeFileSync(depFile, 'bar'); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions}, true) - .then(result => { - t.notSame(contents, fs.readFileSync(path.join(cacheDir, verifierFile), 'utf8')); - t.notSame(result.cacheKeys.dependencies, firstCacheKeys.dependencies); - t.same(result.cacheKeys.sources, firstCacheKeys.sources); - }); - }); -}); - -test('crashes if cached files cannot be read', t => { - const projectDir = fixture('no-babel-config'); - const cacheDir = path.join(uniqueTempDir(), 'cache'); - - t.plan(1); - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, true) - .then(() => { - for (const f of fs.readdirSync(cacheDir)) { - fs.unlinkSync(path.join(cacheDir, f)); - fs.mkdirSync(path.join(cacheDir, f)); - } - - return babelConfigHelper.build(projectDir, cacheDir, {testOptions: {}}, true) - .catch(err => { - t.is(err.code, 'EISDIR'); - }); - }); -}); diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js deleted file mode 100644 index dedfcc5f7..000000000 --- a/test/caching-precompiler.js +++ /dev/null @@ -1,104 +0,0 @@ -'use strict'; -const fs = require('fs'); -const path = require('path'); -const test = require('tap').test; -const uniqueTempDir = require('unique-temp-dir'); -const sinon = require('sinon'); -const proxyquire = require('proxyquire'); -const babel = require('@babel/core'); -const babelTransform = require('@babel/core/lib/transform'); -const fromMapFileSource = require('convert-source-map').fromMapFileSource; -const CachingPrecompiler = require('../lib/caching-precompiler'); - -const fixture = name => path.join(__dirname, 'fixture', name); -const endsWithJs = filename => /\.js$/.test(filename); -const endsWithMap = filename => /\.js\.map$/.test(filename); - -function getBabelOptions() { - return { - babelrc: false - }; -} - -const babelCacheKeys = {}; - -const transformSpy = sinon.spy(babelTransform, 'default'); - -test('creation with new', t => { - const tempDir = uniqueTempDir(); - const precompiler = new CachingPrecompiler({path: tempDir, getBabelOptions, babelCacheKeys}); - t.is(precompiler.cacheDirPath, tempDir); - t.end(); -}); - -test('adds files and source maps to the cache directory as needed', t => { - const tempDir = uniqueTempDir(); - const precompiler = new CachingPrecompiler({path: tempDir, getBabelOptions, babelCacheKeys}); - - t.false(fs.existsSync(tempDir), 'cache directory is not created before it is needed'); - - precompiler.precompileFile(fixture('es2015.js')); - t.true(fs.existsSync(tempDir), 'cache directory is lazily created'); - - const files = fs.readdirSync(tempDir); - t.is(files.length, 2); - t.is(files.filter(x => endsWithJs(x)).length, 1, 'one .js file is saved to the cache'); - t.is(files.filter(x => endsWithMap(x)).length, 1, 'one .js.map file is saved to the cache'); - t.end(); -}); - -test('adds a map file comment to the cached files', t => { - const tempDir = uniqueTempDir(); - const precompiler = new CachingPrecompiler({path: tempDir, getBabelOptions, babelCacheKeys}); - - precompiler.precompileFile(fixture('es2015.js')); - - let cachedCode; - let cachedMap; - fs.readdirSync(tempDir).map(file => path.join(tempDir, file)).forEach(file => { - if (endsWithJs(file)) { - cachedCode = fs.readFileSync(file, 'utf8'); - } else if (endsWithMap(file)) { - cachedMap = fs.readFileSync(file, 'utf8'); - } - }); - - // This is comparable to how nyc resolves the source map. It has access to the - // cached code but believes it to come from the original es2015.js fixture. - // Ensure the cached map can be resolved from the cached code. Also see - // . - const foundMap = fromMapFileSource(cachedCode, path.join(__dirname, 'fixture')); - t.ok(foundMap); - t.is(foundMap.toJSON(), cachedMap); - t.end(); -}); - -test('should reuse existing source maps', t => { - const tempDir = uniqueTempDir(); - const precompiler = new CachingPrecompiler({path: tempDir, getBabelOptions, babelCacheKeys}); - - precompiler.precompileFile(fixture('es2015-source-maps.js')); - const options = transformSpy.lastCall.args[1]; - t.ok(options.inputSourceMap); - t.end(); -}); - -test('disables babel cache', t => { - t.plan(2); - - const tempDir = uniqueTempDir(); - const CachingPrecompiler = proxyquire('../lib/caching-precompiler', { - '@babel/core': Object.assign({}, babel, { - transform(code, options) { - t.same(process.env.BABEL_DISABLE_CACHE, '1'); - return babel.transform(code, options); - } - }) - }); - const precompiler = new CachingPrecompiler({path: tempDir, getBabelOptions, babelCacheKeys}); - - process.env.BABEL_DISABLE_CACHE = 'foo'; - precompiler.precompileFile(fixture('es2015.js')); - t.same(process.env.BABEL_DISABLE_CACHE, 'foo'); - t.end(); -}); diff --git a/test/fixture/babelrc-js/test.js b/test/fixture/babelrc-js/test.js index c22364862..625909b6e 100644 --- a/test/fixture/babelrc-js/test.js +++ b/test/fixture/babelrc-js/test.js @@ -1,11 +1,11 @@ import test from '../../..'; -const fixture = [1, 2]; +const one = {one: 1}; +const two = {two: 2}; test('foo', t => { - // Using destructuring to ensure it transpiles on Node.js 4 - // since that is a Node.js 6 feature - const [one, two] = fixture; - t.is(one, 1); - t.is(two, 2); + // Using object rest/spread to ensure it transpiles on Node.js 6, since this + // is a Node.js 8 feature + const actual = {...one, ...two}; + t.deepEqual(actual, {one: 1, two: 2}); }); diff --git a/test/fixture/babelrc/disable-stage-4.babelrc b/test/fixture/babelrc/disable-stage-4.babelrc new file mode 100644 index 000000000..228f9e627 --- /dev/null +++ b/test/fixture/babelrc/disable-stage-4.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [["../../../stage-4", false]] +} diff --git a/test/fixture/babelrc/test.js b/test/fixture/babelrc/test.js index c22364862..625909b6e 100644 --- a/test/fixture/babelrc/test.js +++ b/test/fixture/babelrc/test.js @@ -1,11 +1,11 @@ import test from '../../..'; -const fixture = [1, 2]; +const one = {one: 1}; +const two = {two: 2}; test('foo', t => { - // Using destructuring to ensure it transpiles on Node.js 4 - // since that is a Node.js 6 feature - const [one, two] = fixture; - t.is(one, 1); - t.is(two, 2); + // Using object rest/spread to ensure it transpiles on Node.js 6, since this + // is a Node.js 8 feature + const actual = {...one, ...two}; + t.deepEqual(actual, {one: 1, two: 2}); });