87 lines
2.6 KiB
JavaScript
87 lines
2.6 KiB
JavaScript
// This module provides a customFileHandler for karma
|
|
// that serves files with urls like /packages_<timestamp>/...
|
|
// with maximum cache.
|
|
// We are using these urls when we spawn isolates
|
|
// so that the isolates don't reload files every time.
|
|
|
|
var common = require('karma/lib/middleware/common');
|
|
var fs = require('fs');
|
|
|
|
var DART_EVAL_PATH_RE = /.*\/packages_\d+\/(.*)$/;
|
|
|
|
module.exports = createFactory;
|
|
|
|
function createFactory(proxyPaths) {
|
|
return {
|
|
'framework:dart-evalcache': ['factory', dartEvalCacheFactory]
|
|
};
|
|
|
|
function dartEvalCacheFactory(emitter, logger, customFileHandlers) {
|
|
var filesPromise = new common.PromiseContainer();
|
|
emitter.on('file_list_modified', function(files) {
|
|
filesPromise.set(Promise.resolve(files));
|
|
});
|
|
|
|
var serveFile = common.createServeFile(fs);
|
|
var log = logger.create('dart-evalcache');
|
|
|
|
customFileHandlers.push({
|
|
urlRegex: DART_EVAL_PATH_RE,
|
|
handler: handler
|
|
});
|
|
|
|
// See source_files handler
|
|
function handler(request, response, fa, fb, basePath) {
|
|
return filesPromise.then(function(files) {
|
|
try {
|
|
var requestedFilePath = mapUrlToFile(request.url, proxyPaths, basePath, log);
|
|
// TODO(vojta): change served to be a map rather then an array
|
|
var file = findByPath(files.served, requestedFilePath);
|
|
if (file) {
|
|
serveFile(file.contentPath || file.path, response, function() {
|
|
common.setHeavyCacheHeaders(response);
|
|
}, file.content);
|
|
} else {
|
|
response.writeHead(404);
|
|
response.end('Not found');
|
|
}
|
|
} catch (e) {
|
|
log.error(e.stack);
|
|
response.writeHead(500);
|
|
response.end('Error', e.stack);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
function mapUrlToFile(url, proxyPaths, basePath, log) {
|
|
var originalUrl = url;
|
|
url = url.indexOf('?') > -1 ? url.substring(0, url.indexOf('?')) : url;
|
|
var match = DART_EVAL_PATH_RE.exec(url);
|
|
var packagePath = match[1];
|
|
var result = null;
|
|
var lastProxyFromLength = 0;
|
|
Object.keys(proxyPaths).forEach(function(proxyFrom) {
|
|
if (startsWith(packagePath, proxyFrom) && proxyFrom.length > lastProxyFromLength) {
|
|
lastProxyFromLength = proxyFrom.length;
|
|
result = proxyPaths[proxyFrom] + packagePath.substring(proxyFrom.length);
|
|
}
|
|
});
|
|
return basePath + '/' + result;
|
|
}
|
|
|
|
function startsWith(string, subString) {
|
|
return string.length >= subString.length && string.slice(0, subString.length) === subString;
|
|
}
|
|
|
|
function findByPath(files, path) {
|
|
for (var i = 0; i < files.length; i++) {
|
|
if (files[i].path === path) {
|
|
return files[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|