From 33b842d65360fc912a9fca610f29fdaa3a6ceab5 Mon Sep 17 00:00:00 2001 From: James Talmage Date: Thu, 3 Mar 2016 19:29:58 -0500 Subject: [PATCH 01/12] add a naive Babel plugin that can be used by integration tests --- package.json | 1 + test/fixture/babel-plugin-test-doubler.js | 46 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/fixture/babel-plugin-test-doubler.js diff --git a/package.json b/package.json index 6e19c80f1..7ae1cd89d 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,7 @@ "update-notifier": "^0.6.0" }, "devDependencies": { + "babel-cli": "^6.6.4", "cli-table2": "^0.1.9", "coveralls": "^2.11.4", "delay": "^1.3.0", diff --git a/test/fixture/babel-plugin-test-doubler.js b/test/fixture/babel-plugin-test-doubler.js new file mode 100644 index 000000000..775ac1f1d --- /dev/null +++ b/test/fixture/babel-plugin-test-doubler.js @@ -0,0 +1,46 @@ +/* + A Babel plugin that causes each AVA test to be duplicated with a new title. + + test('foo', t => {}); + + becomes + + test('foo', t => {}); + test('repeated test: foo', t => {}); + + This is used by some integration tests to validate correct handling of Babel config options. +*/ + +function plugin(babel) { + var t = babel.types; + var anonCount = 1; + + return { + visitor: { + CallExpression: function (path) { + var node = path.node; + var callee = node.callee; + var args = node.arguments; + if (!path.generated && callee.type === 'Identifier' && callee.name === 'test') { + if (args.length === 1) { + args = [t.StringLiteral('repeated test: anonymous' + anonCount++), args[0]]; + } else if (args.length === 2 && args[0].type === 'StringLiteral') { + if (/^repeated test/.test(args[0].value)) { + return; + } + args = args.slice(); + args[0] = t.StringLiteral('repeated test: ' + args[0].value); + } else { + throw new Error('the plugin does not know how to handle this call to test'); + } + path.insertAfter(t.CallExpression( + t.Identifier('test'), + args + )); + } + } + } + }; +} + +module.exports = plugin; From c664aa1e6bc334b39eb9fee3cd0a187d3a5ea7ee Mon Sep 17 00:00:00 2001 From: James Talmage Date: Thu, 3 Mar 2016 19:49:51 -0500 Subject: [PATCH 02/12] remove useless `path.generated` check. (squash this) Babel no longer sets that property (if it ever did) --- test/fixture/babel-plugin-test-doubler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixture/babel-plugin-test-doubler.js b/test/fixture/babel-plugin-test-doubler.js index 775ac1f1d..279dcb941 100644 --- a/test/fixture/babel-plugin-test-doubler.js +++ b/test/fixture/babel-plugin-test-doubler.js @@ -21,7 +21,7 @@ function plugin(babel) { var node = path.node; var callee = node.callee; var args = node.arguments; - if (!path.generated && callee.type === 'Identifier' && callee.name === 'test') { + if (callee.type === 'Identifier' && callee.name === 'test') { if (args.length === 1) { args = [t.StringLiteral('repeated test: anonymous' + anonCount++), args[0]]; } else if (args.length === 2 && args[0].type === 'StringLiteral') { From 1742a3f9d86aec5b59be40c5d3be3da3180085fe Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Thu, 25 Feb 2016 15:25:13 -0500 Subject: [PATCH 03/12] Added support for babel config under package.json/ava key --- api.js | 2 +- cli.js | 3 ++- lib/caching-precompiler.js | 30 +++++++++++++++++++++--------- profile.js | 2 +- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/api.js b/api.js index 77f6d1ee5..cedd69db2 100644 --- a/api.js +++ b/api.js @@ -187,7 +187,7 @@ Api.prototype.run = function (files) { uniqueTempDir(); self.options.cacheDir = cacheDir; - self.precompiler = new CachingPrecompiler(cacheDir); + self.precompiler = new CachingPrecompiler(cacheDir, self.options.babelConfig); self.fileCount = files.length; self.base = path.relative('.', commonPathPrefix(files)) + path.sep; diff --git a/cli.js b/cli.js index 3ab2dfe9e..c04cb744c 100755 --- a/cli.js +++ b/cli.js @@ -102,7 +102,8 @@ var api = new Api({ require: arrify(cli.flags.require), cacheEnabled: cli.flags.cache !== false, explicitTitles: cli.flags.watch, - match: arrify(cli.flags.match) + match: arrify(cli.flags.match), + babelConfig: conf.babel }); var reporter; diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index bdb5deb7f..75b58594c 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -3,20 +3,21 @@ var path = require('path'); var cachingTransform = require('caching-transform'); var md5Hex = require('md5-hex'); var stripBom = require('strip-bom'); +var objectAssign = require('object-assign'); module.exports = CachingPrecompiler; -function CachingPrecompiler(cacheDir) { +function CachingPrecompiler(cacheDir, babelConfig) { if (!(this instanceof CachingPrecompiler)) { throw new TypeError('Class constructor CachingPrecompiler cannot be invoked without \'new\''); } this.cacheDir = cacheDir; this.filenameToHash = {}; - this.transform = this._createTransform(); + this.transform = this._createTransform(babelConfig); } -CachingPrecompiler.prototype._factory = function (cacheDir) { +CachingPrecompiler.prototype._factory = function (babelConfig, cacheDir) { // This factory method is only called once per process, and only as needed, to defer loading expensive dependencies. var babel = require('babel-core'); var convertSourceMap = require('convert-source-map'); @@ -30,15 +31,26 @@ CachingPrecompiler.prototype._factory = function (cacheDir) { // Extract existing source maps from the code. var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename)); - return { - presets: [presetStage2, presetES2015], - plugins: [powerAssert, transformRuntime], + var baseOptions = { filename: filename, sourceMaps: true, ast: false, - babelrc: false, inputSourceMap: sourceMap && sourceMap.toObject() }; + + if (!babelConfig || babelConfig === 'default') { + return objectAssign({}, baseOptions, { + babelrc: false, + presets: [presetStage2, presetES2015], + plugins: [powerAssert, transformRuntime] + }); + } + + if (babelConfig === 'inherit') { + return objectAssign({}, baseOptions, {babelrc: true}); + } + + return objectAssign({}, baseOptions, babelConfig); } return function (code, filename, hash) { @@ -61,9 +73,9 @@ CachingPrecompiler.prototype._createEspowerPlugin = function (babel) { }); }; -CachingPrecompiler.prototype._createTransform = function () { +CachingPrecompiler.prototype._createTransform = function (babelConfig) { return cachingTransform({ - factory: this._factory.bind(this), + factory: this._factory.bind(this, babelConfig), cacheDir: this.cacheDir, salt: new Buffer(JSON.stringify({ 'babel-plugin-espower': require('babel-plugin-espower/package.json').version, diff --git a/profile.js b/profile.js index 273d1ecf4..88ca318fd 100644 --- a/profile.js +++ b/profile.js @@ -63,7 +63,7 @@ var opts = { require: arrify(cli.flags.require), tty: false, cacheDir: cacheDir, - precompiled: new CachingPrecompiler(cacheDir).generateHashForFile(file) + precompiled: new CachingPrecompiler(cacheDir, conf.babel).generateHashForFile(file) }; var events = new EventEmitter(); From bc493644cf6615725827c558d830b185d1bd869e Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Fri, 26 Feb 2016 09:38:10 -0500 Subject: [PATCH 04/12] added tests for customizable babel config --- lib/caching-precompiler.js | 4 +- test/caching-precompiler.js | 99 +++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 5 deletions(-) diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index 75b58594c..81a2a2497 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -35,12 +35,12 @@ CachingPrecompiler.prototype._factory = function (babelConfig, cacheDir) { filename: filename, sourceMaps: true, ast: false, - inputSourceMap: sourceMap && sourceMap.toObject() + inputSourceMap: sourceMap && sourceMap.toObject(), + babelrc: false }; if (!babelConfig || babelConfig === 'default') { return objectAssign({}, baseOptions, { - babelrc: false, presets: [presetStage2, presetES2015], plugins: [powerAssert, transformRuntime] }); diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js index 27b972911..d9373892e 100644 --- a/test/caching-precompiler.js +++ b/test/caching-precompiler.js @@ -3,6 +3,8 @@ var fs = require('fs'); var path = require('path'); var test = require('tap').test; var uniqueTempDir = require('unique-temp-dir'); +var sinon = require('sinon'); +var babel = require('babel-core'); var CachingPrecompiler = require('../lib/caching-precompiler'); @@ -18,9 +20,14 @@ function endsWithMap(filename) { return /\.js$/.test(filename); } +test('before', t => { + sinon.spy(babel, 'transform'); + t.end(); +}); + test('creation with new', function (t) { var tempDir = uniqueTempDir(); - var precompiler = new CachingPrecompiler(tempDir); + var precompiler = new CachingPrecompiler(tempDir, null); t.is(precompiler.cacheDir, tempDir); t.end(); }); @@ -28,14 +35,14 @@ test('creation with new', function (t) { test('must be called with new', function (t) { t.throws(function () { var cachingPrecompiler = CachingPrecompiler; - cachingPrecompiler(uniqueTempDir()); + cachingPrecompiler(uniqueTempDir(), null); }, {message: 'Class constructor CachingPrecompiler cannot be invoked without \'new\''}); t.end(); }); test('adds files and source maps to the cache directory as needed', function (t) { var tempDir = uniqueTempDir(); - var precompiler = new CachingPrecompiler(tempDir); + var precompiler = new CachingPrecompiler(tempDir, null); t.false(fs.existsSync(tempDir), 'cache directory is not created before it is needed'); @@ -48,3 +55,89 @@ test('adds files and source maps to the cache directory as needed', function (t) t.is(files.filter(endsWithMap).length, 1, 'one .map file is saved to the cache'); t.end(); }); + +test('uses default babel options when !babelConfig', function (t) { + var tempDir = uniqueTempDir(); + var precompiler = new CachingPrecompiler(tempDir, null); + babel.transform.reset(); + + precompiler.precompileFile(fixture('es2015.js')); + + t.true(babel.transform.calledOnce); + var options = babel.transform.firstCall.args[1]; + + t.true('filename' in options); + t.true(options.sourceMaps); + t.false(options.ast); + t.true('inputSourceMap' in options); + t.false(options.babelrc); + t.true(Array.isArray(options.presets)); + t.true(Array.isArray(options.plugins)); + t.end(); +}); + +test('uses default babel options when babelConfig === "default"', function (t) { + var tempDir = uniqueTempDir(); + var precompiler = new CachingPrecompiler(tempDir, 'default'); + babel.transform.reset(); + + precompiler.precompileFile(fixture('es2015.js')); + + t.true(babel.transform.calledOnce); + var options = babel.transform.firstCall.args[1]; + + t.true('filename' in options); + t.true(options.sourceMaps); + t.false(options.ast); + t.true('inputSourceMap' in options); + t.false(options.babelrc); + t.true(Array.isArray(options.presets)); + t.true(Array.isArray(options.plugins)); + t.end(); +}); + +test('allows babel config from package.json/babel when babelConfig === "inherit"', function (t) { + var tempDir = uniqueTempDir(); + var precompiler = new CachingPrecompiler(tempDir, 'inherit'); + babel.transform.reset(); + + precompiler.precompileFile(fixture('es2015.js')); + + t.true(babel.transform.calledOnce); + var options = babel.transform.firstCall.args[1]; + + t.true('filename' in options); + t.true(options.sourceMaps); + t.false(options.ast); + t.true('inputSourceMap' in options); + t.true(options.babelrc); + t.end(); +}); + +test('uses babelConfig for babel options when babelConfig is an object', function (t) { + var tempDir = uniqueTempDir(); + var precompiler = new CachingPrecompiler(tempDir, { + presets: ['stage-2', 'es2015'], + plugins: [] + }); + babel.transform.reset(); + + precompiler.precompileFile(fixture('es2015.js')); + + t.true(babel.transform.calledOnce); + var options = babel.transform.firstCall.args[1]; + + t.true('filename' in options); + t.true(options.sourceMaps); + t.false(options.ast); + t.true('inputSourceMap' in options); + t.false(options.babelrc); + t.deepEqual(options.presets, ['stage-2', 'es2015']); + t.deepEqual(options.plugins, []); + t.end(); +}); + +test('after', t => { + babel.transform.restore(); + t.end(); +}); From 0044f9a5e82382d8ab7de93085caa77b7c295ca6 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Fri, 26 Feb 2016 10:07:09 -0500 Subject: [PATCH 05/12] added documentation for customizable babel config --- readme.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 567b9c62a..16d338536 100644 --- a/readme.md +++ b/readme.md @@ -154,7 +154,8 @@ All of the CLI options can be configured in the `ava` section of your `package.j "tap": true, "require": [ "babel-register" - ] + ], + "babel": "inherit" } } ``` @@ -423,6 +424,41 @@ AVA comes with builtin support for ES2015 through [Babel 6](https://babeljs.io). AVA includes typings for TypeScript. You have to setup transpilation yourself. When you set `module` to `commonjs` in your `tsconfig.json` file, TypeScript will automatically find the type definitions for AVA. You should set `target` to `es2015` to use Promises and async functions. +If you want to customize the babel transpiler for test files, you can do so by adding a `"babel"` key to the `"ava"` section in your package.json file. + +```json +{ + "ava": { + "babel": { + "presets": [ + "es2015", + "stage-0", + "react" + ] + } + }, +} +``` + +In addition to specifying a custom babel config, you can also use the special `inherit` keyword. When you do this, AVA will allow tests to be transpiled using the configuration defined in your .babelrc file or in package.json/babel. This way, your test files will be transpiled using the same options as your source files, but you won't have to define the options twice. + +```json +{ + "babel": { + "presets": [ + "es2015", + "stage-0", + "react" + ] + }, + "ava": { + "babel": "inherit", + }, +} +``` + +If you do not specify a "babel" key in your ava configuration, or if you set it to `"default"`, AVA will transpile the test files with AVA's default babel configuration. + #### Transpiling Imported Modules AVA currently only transpiles the tests you ask it to run. *It will not transpile modules you ```import``` from outside of the test.* While there are valid reasons for taking this approach, it may not be what you expect! From 9a62bed1a747abe8ffb4f6cf561c1ff00dca4f96 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Fri, 26 Feb 2016 10:30:22 -0500 Subject: [PATCH 06/12] fixed test for node 0.12 compatibility --- test/caching-precompiler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js index d9373892e..3a8b55534 100644 --- a/test/caching-precompiler.js +++ b/test/caching-precompiler.js @@ -20,7 +20,7 @@ function endsWithMap(filename) { return /\.js$/.test(filename); } -test('before', t => { +test('before', function (t) { sinon.spy(babel, 'transform'); t.end(); }); @@ -137,7 +137,7 @@ test('uses babelConfig for babel options when babelConfig is an object', functio t.end(); }); -test('after', t => { +test('after', function (t) { babel.transform.restore(); t.end(); }); From d833f529a2c70d064dbe7274572357686fcb4d87 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Tue, 1 Mar 2016 10:03:56 -0500 Subject: [PATCH 07/12] enforced constraints on babel config --- cli.js | 6 +++++- lib/caching-precompiler.js | 33 +++++++++++++++++---------------- profile.js | 6 +++++- readme.md | 26 +++++++++++++++++++++++--- test/caching-precompiler.js | 32 ++------------------------------ 5 files changed, 52 insertions(+), 51 deletions(-) diff --git a/cli.js b/cli.js index c04cb744c..5c269b11a 100755 --- a/cli.js +++ b/cli.js @@ -35,7 +35,11 @@ var Api = require('./api'); // Bluebird specific Promise.longStackTraces(); -var conf = pkgConf.sync('ava'); +var conf = pkgConf.sync('ava', { + defaults: { + babel: 'default' + } +}); var cli = meow([ 'Usage', diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index 81a2a2497..d1874d60d 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -31,26 +31,27 @@ CachingPrecompiler.prototype._factory = function (babelConfig, cacheDir) { // Extract existing source maps from the code. var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename)); - var baseOptions = { + var options = {babelrc: false}; + + if (babelConfig === 'default') { + objectAssign(options, {presets: [presetStage2, presetES2015]}); + } else if (babelConfig === 'inherit') { + objectAssign(options, {babelrc: true}); + } else { + objectAssign(options, babelConfig); + } + + objectAssign(options, { + inputSourceMap: sourceMap && sourceMap.toObject(), filename: filename, sourceMaps: true, - ast: false, - inputSourceMap: sourceMap && sourceMap.toObject(), - babelrc: false - }; - - if (!babelConfig || babelConfig === 'default') { - return objectAssign({}, baseOptions, { - presets: [presetStage2, presetES2015], - plugins: [powerAssert, transformRuntime] - }); - } + ast: false + }); - if (babelConfig === 'inherit') { - return objectAssign({}, baseOptions, {babelrc: true}); - } + options.plugins = options.plugins || []; + options.plugins.push(powerAssert, transformRuntime); - return objectAssign({}, baseOptions, babelConfig); + return options; } return function (code, filename, hash) { diff --git a/profile.js b/profile.js index 88ca318fd..524d044ff 100644 --- a/profile.js +++ b/profile.js @@ -20,7 +20,11 @@ globals.setTimeout = setTimeout.bind(null); globals.clearTimeout = clearTimeout.bind(null); Promise.longStackTraces(); -var conf = pkgConf.sync('ava'); +var conf = pkgConf.sync('ava', { + defaults: { + babel: 'default' + } +}); // Define a minimal set of options from the main CLI. var cli = meow([ diff --git a/readme.md b/readme.md index 16d338536..56dab8438 100644 --- a/readme.md +++ b/readme.md @@ -424,7 +424,9 @@ AVA comes with builtin support for ES2015 through [Babel 6](https://babeljs.io). AVA includes typings for TypeScript. You have to setup transpilation yourself. When you set `module` to `commonjs` in your `tsconfig.json` file, TypeScript will automatically find the type definitions for AVA. You should set `target` to `es2015` to use Promises and async functions. -If you want to customize the babel transpiler for test files, you can do so by adding a `"babel"` key to the `"ava"` section in your package.json file. +### Babel Configuration for Test Scripts + +If you want to customize the babel transpiler for test files, you can do so by adding a `"babel"` key to the `ava` section in your `package.json` file. ```json { @@ -440,7 +442,7 @@ If you want to customize the babel transpiler for test files, you can do so by a } ``` -In addition to specifying a custom babel config, you can also use the special `inherit` keyword. When you do this, AVA will allow tests to be transpiled using the configuration defined in your .babelrc file or in package.json/babel. This way, your test files will be transpiled using the same options as your source files, but you won't have to define the options twice. +In addition to specifying a custom Babel config, you can also use the special `"inherit"` keyword. When you do this, AVA will allow tests to be transpiled using the configuration defined in your `.babelrc` file or in package.json/babel. This way, your test files will be transpiled using the same options as your source files, but you won't have to define the options twice. ```json { @@ -457,7 +459,25 @@ In addition to specifying a custom babel config, you can also use the special `i } ``` -If you do not specify a "babel" key in your ava configuration, or if you set it to `"default"`, AVA will transpile the test files with AVA's default babel configuration. +Note: When configuring Babel for tests manually, the espower and transform-runtime plugins will be +added for you. + +## Default Babel Configuration for Test Scripts + +If you don't explicitly configure Babel for your tests using the `"babel"` key in package.json, your tests will be transpiled using AVA's default Babel configuration, which is as follows: + +```json +{ + "presets": [ + "es2015", + "stage-0", + ], + "plugins": [ + "espower", + "transform-runtime" + ] +} +``` #### Transpiling Imported Modules diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js index 3a8b55534..5a2c2a2bb 100644 --- a/test/caching-precompiler.js +++ b/test/caching-precompiler.js @@ -20,10 +20,7 @@ function endsWithMap(filename) { return /\.js$/.test(filename); } -test('before', function (t) { - sinon.spy(babel, 'transform'); - t.end(); -}); +sinon.spy(babel, 'transform'); test('creation with new', function (t) { var tempDir = uniqueTempDir(); @@ -56,26 +53,6 @@ test('adds files and source maps to the cache directory as needed', function (t) t.end(); }); -test('uses default babel options when !babelConfig', function (t) { - var tempDir = uniqueTempDir(); - var precompiler = new CachingPrecompiler(tempDir, null); - babel.transform.reset(); - - precompiler.precompileFile(fixture('es2015.js')); - - t.true(babel.transform.calledOnce); - var options = babel.transform.firstCall.args[1]; - - t.true('filename' in options); - t.true(options.sourceMaps); - t.false(options.ast); - t.true('inputSourceMap' in options); - t.false(options.babelrc); - t.true(Array.isArray(options.presets)); - t.true(Array.isArray(options.plugins)); - t.end(); -}); - test('uses default babel options when babelConfig === "default"', function (t) { var tempDir = uniqueTempDir(); var precompiler = new CachingPrecompiler(tempDir, 'default'); @@ -133,11 +110,6 @@ test('uses babelConfig for babel options when babelConfig is an object', functio t.true('inputSourceMap' in options); t.false(options.babelrc); t.deepEqual(options.presets, ['stage-2', 'es2015']); - t.deepEqual(options.plugins, []); - t.end(); -}); - -test('after', function (t) { - babel.transform.restore(); + t.equal(options.plugins.length, 2); t.end(); }); From eb6d0241c596f9f7e79562fe09c78c3411351cc2 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Wed, 2 Mar 2016 12:00:49 -0500 Subject: [PATCH 08/12] handle undefined babelConfig to fix api unit tests --- lib/caching-precompiler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index d1874d60d..0e509eb1f 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -33,7 +33,7 @@ CachingPrecompiler.prototype._factory = function (babelConfig, cacheDir) { var options = {babelrc: false}; - if (babelConfig === 'default') { + if (!babelConfig || babelConfig === 'default') { objectAssign(options, {presets: [presetStage2, presetES2015]}); } else if (babelConfig === 'inherit') { objectAssign(options, {babelrc: true}); From 8517681f32f5c9e1f08a91c8ab6723df1008ca33 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Thu, 3 Mar 2016 07:37:17 -0500 Subject: [PATCH 09/12] better tests for appending powerAssert and transformRuntime to list of babel plugins --- test/caching-precompiler.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js index 5a2c2a2bb..b524ab3e1 100644 --- a/test/caching-precompiler.js +++ b/test/caching-precompiler.js @@ -5,6 +5,7 @@ var test = require('tap').test; var uniqueTempDir = require('unique-temp-dir'); var sinon = require('sinon'); var babel = require('babel-core'); +var transformRuntime = require('babel-plugin-transform-runtime'); var CachingPrecompiler = require('../lib/caching-precompiler'); @@ -93,10 +94,13 @@ test('allows babel config from package.json/babel when babelConfig === "inherit" test('uses babelConfig for babel options when babelConfig is an object', function (t) { var tempDir = uniqueTempDir(); + var customPlugin = sinon.stub().returns({visitor: {}}); + var powerAssert = sinon.stub().returns({visitor: {}}); var precompiler = new CachingPrecompiler(tempDir, { presets: ['stage-2', 'es2015'], - plugins: [] + plugins: [customPlugin] }); + sinon.stub(precompiler, '_createEspowerPlugin').returns(powerAssert); babel.transform.reset(); precompiler.precompileFile(fixture('es2015.js')); @@ -109,7 +113,7 @@ test('uses babelConfig for babel options when babelConfig is an object', functio t.false(options.ast); t.true('inputSourceMap' in options); t.false(options.babelrc); - t.deepEqual(options.presets, ['stage-2', 'es2015']); - t.equal(options.plugins.length, 2); + t.same(options.presets, ['stage-2', 'es2015']); + t.same(options.plugins, [customPlugin, powerAssert, transformRuntime]); t.end(); }); From c052757bee176bf1c3b5833af6583850618b8eb3 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Fri, 4 Mar 2016 11:12:47 -0500 Subject: [PATCH 10/12] added integration tests for custom babel config --- test/api.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/api.js b/test/api.js index b08a2d8a1..e06739aea 100644 --- a/test/api.js +++ b/test/api.js @@ -5,6 +5,7 @@ var rimraf = require('rimraf'); var fs = require('fs'); var test = require('tap').test; var Api = require('../api'); +var testDoublerPlugin = require('./fixture/babel-plugin-test-doubler'); test('must be called with new', function (t) { t.throws(function () { @@ -684,3 +685,39 @@ test('verify test count', function (t) { t.is(api.todoCount, 1); }); }); + +test('Custom Babel Plugin Support', function (t) { + t.plan(1); + + var api = new Api({ + cacheEnabled: false, + babelConfig: { + presets: ['es2015', 'stage-2'], + plugins: [testDoublerPlugin] + } + }); + + api.run([path.join(__dirname, 'fixture/es2015.js')]) + .then( + function () { + t.is(api.passCount, 2); + }, + t.threw + ); +}); + +test('Default babel config doesn\'t use .babelrc', function (t) { + t.plan(1); + + var api = new Api({ + cacheEnabled: false + }); + + api.run([path.join(__dirname, 'fixture/babelrc/test.js')]) + .then( + function () { + t.is(api.passCount, 1); + }, + t.threw + ); +}); From 03850ad8760e65853c4f1f276229f560ff377cc2 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Fri, 4 Mar 2016 11:24:20 -0500 Subject: [PATCH 11/12] added babelConfig to compiler cache salt --- lib/caching-precompiler.js | 3 ++- test/api.js | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index 0e509eb1f..8b6f63bac 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -81,7 +81,8 @@ CachingPrecompiler.prototype._createTransform = function (babelConfig) { salt: new Buffer(JSON.stringify({ 'babel-plugin-espower': require('babel-plugin-espower/package.json').version, 'ava': require('../package.json').version, - 'babel-core': require('babel-core/package.json').version + 'babel-core': require('babel-core/package.json').version, + 'babelConfig': babelConfig })), ext: '.js', hash: this._hash.bind(this) diff --git a/test/api.js b/test/api.js index e06739aea..6039d2a95 100644 --- a/test/api.js +++ b/test/api.js @@ -690,7 +690,6 @@ test('Custom Babel Plugin Support', function (t) { t.plan(1); var api = new Api({ - cacheEnabled: false, babelConfig: { presets: ['es2015', 'stage-2'], plugins: [testDoublerPlugin] @@ -709,9 +708,7 @@ test('Custom Babel Plugin Support', function (t) { test('Default babel config doesn\'t use .babelrc', function (t) { t.plan(1); - var api = new Api({ - cacheEnabled: false - }); + var api = new Api(); api.run([path.join(__dirname, 'fixture/babelrc/test.js')]) .then( From f167ea375a0f98ad1f39406efa972d7055d74035 Mon Sep 17 00:00:00 2001 From: Stephen Sorensen Date: Mon, 7 Mar 2016 08:10:44 -0500 Subject: [PATCH 12/12] return promise in api test --- test/api.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/test/api.js b/test/api.js index 6039d2a95..980d202a7 100644 --- a/test/api.js +++ b/test/api.js @@ -710,11 +710,8 @@ test('Default babel config doesn\'t use .babelrc', function (t) { var api = new Api(); - api.run([path.join(__dirname, 'fixture/babelrc/test.js')]) - .then( - function () { - t.is(api.passCount, 1); - }, - t.threw - ); + return api.run([path.join(__dirname, 'fixture/babelrc/test.js')]) + .then(function () { + t.is(api.passCount, 1); + }); });