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;
 | |
| }
 |