Skip to content

Commit c738c78

Browse files
committed
add caching
1 parent 30831a8 commit c738c78

File tree

6 files changed

+66
-78
lines changed

6 files changed

+66
-78
lines changed

api.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var chalk = require('chalk');
1111
var assign = require('object-assign');
1212
var fork = require('./lib/fork');
1313
var formatter = require('./lib/enhance-assert').formatter();
14-
var precompileTest = require('./lib/test-transformer');
14+
var precompile = require('./lib/test-transformer');
1515

1616
function Api(files, options) {
1717
if (!(this instanceof Api)) {
@@ -43,14 +43,11 @@ module.exports = Api;
4343

4444
Api.prototype._runFile = function (file) {
4545
var precompiled = {};
46-
precompiled[file.testPath] = {
47-
sourcePath: file.tempPath,
48-
mapPath: file.mapPath
49-
};
46+
precompiled[file] = precompile(file);
5047
var options = assign({}, this.options, {
5148
precompiled: precompiled
5249
});
53-
return fork(file.testPath, options)
50+
return fork(file, options)
5451
.on('stats', this._handleStats)
5552
.on('test', this._handleTest)
5653
.on('unhandledRejections', this._handleRejections)
@@ -139,7 +136,6 @@ Api.prototype.run = function () {
139136
.map(function (file) {
140137
return path.resolve(file);
141138
})
142-
.map(precompileTest)
143139
.then(function (files) {
144140
if (files.length === 0) {
145141
return Promise.reject(new Error('Couldn\'t find any files to test'));

lib/babel.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ var loudRejection = require('loud-rejection/api')(process);
4141
var serializeError = require('serialize-error');
4242
var send = require('./send');
4343
var installPrecompiler = require('require-precompiled');
44+
var path = require('path');
45+
var cacheDir = path.join(module.paths[1], '.cache', 'ava');
4446

4547
var testPath = opts.file;
4648

@@ -50,8 +52,8 @@ exports.avaRequired = false;
5052
installPrecompiler(function (filename) {
5153
var precompiled = opts.precompiled[filename];
5254
if (precompiled) {
53-
sourceMapCache[filename] = precompiled.mapPath;
54-
return fs.readFileSync(precompiled.sourcePath, 'utf8');
55+
sourceMapCache[filename] = path.join(cacheDir, precompiled + '.map');
56+
return fs.readFileSync(path.join(cacheDir, precompiled + '.js'), 'utf8');
5557
}
5658
return null;
5759
});

lib/test-transformer.js

+54-58
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,64 @@
1-
var createEspowerPlugin = require('babel-plugin-espower/create');
2-
var sourceMapSupport = require('source-map-support');
3-
var babel = require('babel-core');
4-
var Promise = require('bluebird');
5-
var tempWrite = require('temp-write');
6-
var transformFile = Promise.promisify(babel.transformFile);
7-
var enhanceAssert = require('./enhance-assert');
1+
var cachingTransform = require('caching-transform');
2+
var fs = require('fs');
3+
var path = require('path');
4+
var crypto = require('crypto');
5+
var cacheDir = path.join(module.paths[1], '.cache', 'ava');
6+
var filenameToHash = {};
87

9-
var cache = {};
8+
function factory(cacheDir) {
9+
var createEspowerPlugin = require('babel-plugin-espower/create');
10+
var babel = require('babel-core');
11+
var enhanceAssert = require('./enhance-assert');
12+
var convertSourceMap = require('convert-source-map');
1013

11-
module.exports = precompile;
12-
module.exports.sync = sync;
13-
14-
function precompile(testPath) {
15-
return cache[testPath] || (cache[testPath] = _precompile(testPath));
16-
}
17-
18-
function buildOptions(testPath) {
19-
// initialize power-assert
20-
var powerAssert = createEspowerPlugin(babel, {
21-
patterns: enhanceAssert.PATTERNS
22-
});
14+
function buildOptions(filename, code) {
15+
// initialize power-assert
16+
var powerAssert = createEspowerPlugin(babel, {
17+
patterns: enhanceAssert.PATTERNS
18+
});
2319

24-
// if generators are not supported, use regenerator
25-
var options = {
26-
presets: [require('babel-preset-stage-2'), require('babel-preset-es2015')],
27-
plugins: [powerAssert, require('babel-plugin-transform-runtime')],
28-
sourceMaps: true,
29-
ast: false,
30-
inputSourceMap: null
31-
};
20+
var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename));
3221

33-
// try to load an input source map for the test file, in case the file was
34-
// already compiled once by the user
35-
var inputSourceMap = sourceMapSupport.retrieveSourceMap(testPath);
36-
if (inputSourceMap) {
37-
// source-map-support returns the source map as a json-encoded string, but
38-
// babel requires an actual object
39-
options.inputSourceMap = JSON.parse(inputSourceMap.map);
22+
return {
23+
presets: [require('babel-preset-stage-2'), require('babel-preset-es2015')],
24+
plugins: [powerAssert, require('babel-plugin-transform-runtime')],
25+
filename: filename,
26+
sourceMaps: true,
27+
ast: false,
28+
inputSourceMap: sourceMap && sourceMap.toObject()
29+
};
4030
}
4131

42-
return options;
32+
return function (code, filename, hash) {
33+
var options = buildOptions(filename, code);
34+
var result = babel.transform(code, options);
35+
var mapFile = path.join(cacheDir, hash + '.map');
36+
fs.writeFileSync(mapFile, JSON.stringify(result.map));
37+
return result.code;
38+
};
4339
}
4440

45-
function _precompile(testPath) {
46-
return transformFile(testPath, buildOptions(testPath))
47-
.then(function (result) {
48-
return Promise.all([
49-
tempWrite(result.code, testPath),
50-
tempWrite(JSON.stringify(result.map), testPath + '.map')
51-
])
52-
.spread(function (tempPath, mapPath) {
53-
result.mapPath = mapPath;
54-
result.tempPath = tempPath;
55-
result.testPath = testPath;
56-
return result;
57-
});
58-
});
59-
}
41+
var transform = cachingTransform({
42+
factory: factory,
43+
cacheDir: cacheDir,
44+
ext: '.js',
45+
hash: function (code, filename, salt) {
46+
var hash = crypto
47+
.createHash('md5')
48+
.update(code, 'utf8')
49+
.update(filename || 'unknown file', 'utf8')
50+
.update(salt || '', 'utf8')
51+
.digest('hex');
6052

61-
function sync(testPath) {
62-
var result = babel.transformFileSync(testPath, buildOptions(testPath));
63-
result.tempPath = tempWrite.sync(result.code, testPath);
64-
result.mapPath = tempWrite.sync(JSON.stringify(result.map), testPath + '.map');
65-
result.testPath = testPath;
66-
return result;
67-
}
53+
filenameToHash[filename] = hash;
6854

55+
return hash;
56+
}
57+
});
58+
59+
module.exports = function (filename) {
60+
if (!filenameToHash[filename]) {
61+
transform(fs.readFileSync(filename, 'utf8'), filename);
62+
}
63+
return filenameToHash[filename];
64+
};

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"node": ">=0.10.0"
3838
},
3939
"scripts": {
40+
"pretest": "rm -rf ./node_modules/.cache",
4041
"test": "xo && nyc --reporter=lcov tap --no-cov --timeout=150 test/*.js",
4142
"test-win": "tap --no-cov --timeout=150 test/*.js"
4243
},
@@ -87,8 +88,10 @@
8788
"babel-preset-stage-2": "^6.3.13",
8889
"babel-runtime": "^6.3.19",
8990
"bluebird": "^3.0.0",
91+
"caching-transform": "0.0.3",
9092
"chalk": "^1.0.0",
9193
"co-with-promise": "^4.6.0",
94+
"convert-source-map": "^1.1.2",
9295
"core-assert": "^0.1.0",
9396
"debug": "^2.2.0",
9497
"deeper": "^2.1.0",
@@ -116,7 +119,6 @@
116119
"set-immediate-shim": "^1.0.1",
117120
"source-map-support": "^0.4.0",
118121
"squeak": "^1.2.0",
119-
"temp-write": "^2.1.0",
120122
"time-require": "^0.1.2",
121123
"update-notifier": "^0.5.0"
122124
},

test/fork.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,8 @@ function fixture(name) {
99
}
1010

1111
function fork(testPath) {
12-
var result = precompile.sync(testPath);
1312
var precompiled = {};
14-
precompiled[testPath] = {
15-
sourcePath: result.tempPath,
16-
mapPath: result.mapPath
17-
};
13+
precompiled[testPath] = precompile(testPath);
1814
return _fork(testPath, {precompiled: precompiled});
1915
}
2016

test/hooks.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@ var _fork = require('../lib/fork');
66
var precompile = require('../lib/test-transformer');
77

88
function fork(testPath) {
9-
var result = precompile.sync(testPath);
109
var precompiled = {};
11-
precompiled[testPath] = {
12-
sourcePath: result.tempPath,
13-
mapPath: result.mapPath
14-
};
10+
precompiled[testPath] = precompile(testPath);
1511
return _fork(testPath, {precompiled: precompiled});
1612
}
1713

0 commit comments

Comments
 (0)