diff --git a/index.js b/index.js index bcc8ee72a6..230fe70cb9 100644 --- a/index.js +++ b/index.js @@ -3,12 +3,26 @@ var setImmediate = require('set-immediate-shim'); var relative = require('path').relative; var hasFlag = require('has-flag'); var chalk = require('chalk'); +var join = require('path').join; +var relative = require('path').relative; var serializeError = require('./lib/serialize-value'); var Runner = require('./lib/runner'); var send = require('./lib/send'); var log = require('./lib/logger'); var runner = new Runner(); +var xdgBasedir = require('xdg-basedir'); +var cache = require('cacha')(join(xdgBasedir.cache, 'ava')); +var Configstore = require('configstore'); +var config = new Configstore('ava', { + lastCacheClean: Date.now() +}); +var WEEK = 7 * 24 * 60 * 60 * 1000; + +if (Date.now() - config.get('lastCacheClean') > WEEK) { + config.set('lastCacheClean', Date.now()); + cache.clean(); +} // note that test files have require('ava') require('./lib/babel').avaRequired = true; diff --git a/lib/babel.js b/lib/babel.js index a6b8890ea2..d4eeadd863 100644 --- a/lib/babel.js +++ b/lib/babel.js @@ -6,6 +6,11 @@ var resolveFrom = require('resolve-from'); var hasGenerator = require('has-generator'); var serializeValue = require('./serialize-value'); var send = require('./send'); +var hasha = require('hasha'); +var hashObj = require('hash-obj'); +var xdgBasedir = require('xdg-basedir'); +var path = require('path'); +var cache = require('cacha')(path.join(xdgBasedir.cache, 'ava')); var testPath = process.argv[2]; @@ -31,24 +36,6 @@ var options = { plugins: [powerAssert] }; -// check if test files required ava and show error, when they didn't -exports.avaRequired = false; - -process.on('uncaughtException', function (exception) { - send('uncaughtException', {exception: serializeValue(exception)}); -}); - -// include test file -var transpiled = babel.transformFileSync(testPath, options); -requireFromString(transpiled.code, testPath, { - appendPaths: module.paths -}); - -// if ava was not required, show an error -if (!exports.avaRequired) { - throw new Error('No tests found in ' + testPath + ', make sure to import "ava" at the top of your test file'); -} - // parse and re-emit ava messages process.on('message', function (message) { if (!message.ava) { @@ -82,6 +69,35 @@ process.on('ava-teardown', function () { setTimeout(exit, 100); }); +process.on('uncaughtException', function (exception) { + send('uncaughtException', {exception: serializeValue(exception)}); +}); + +var hash = hashObj({ + code: hasha.fromFileSync(testPath), + avaVersion: require('../package.json').version +}); + +var code = cache.getSync(hash, 'utf8'); + +if (code === undefined) { + code = babel.transformFileSync(testPath, options).code; + cache.setSync(hash, code, 'utf8'); +} + +// check if test files required ava and show error, when they didn't +exports.avaRequired = false; + +// include test file +requireFromString(code, testPath, { + appendPaths: module.paths +}); + +// if ava was not required, show an error +if (!exports.avaRequired) { + throw new Error('No tests found in ' + testPath + ', make sure to import "ava" at the top of your test file'); +} + function exit() { send('teardown'); } diff --git a/package.json b/package.json index e5851dbdaf..642d86b2d2 100644 --- a/package.json +++ b/package.json @@ -77,8 +77,10 @@ "babel-plugin-espower": "^1.1.0", "babel-runtime": "^5.8.29", "bluebird": "^3.0.0", + "cacha": "^1.0.3", "chalk": "^1.0.0", "co-with-promise": "^4.6.0", + "configstore": "^1.3.0", "core-assert": "^0.1.0", "debug": "^2.2.0", "destroy-circular": "jamestalmage/destroy-circular#feeb7d1", @@ -88,6 +90,8 @@ "globby": "^4.0.0", "has-flag": "^1.0.0", "has-generator": "^1.0.0", + "hash-obj": "^1.0.0", + "hasha": "^2.0.2", "is-generator-fn": "^1.0.0", "is-promise": "^2.1.0", "loud-rejection": "^1.2.0", @@ -102,7 +106,8 @@ "resolve-from": "^1.0.0", "set-immediate-shim": "^1.0.1", "squeak": "^1.2.0", - "update-notifier": "^0.5.0" + "update-notifier": "^0.5.0", + "xdg-basedir": "^2.0.0" }, "devDependencies": { "coveralls": "^2.11.4",