Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add code

  • Loading branch information...
commit 7913ea6a952201af0f410e86fb472fd58af728e3 1 parent c63c9bb
@chrisdickinson authored
Showing with 127 additions and 0 deletions.
  1. +127 −0 index.js
View
127 index.js
@@ -0,0 +1,127 @@
+var bunker = require('bunker'),
+ Module = require('module').Module,
+ path = require('path'),
+ fs = require('fs'),
+ vm = require('vm');
+
+function CoverageData (filename, bunker) {
+ this.bunker = bunker;
+ this.filename = filename;
+ this.nodes = {};
+};
+
+CoverageData.prototype.visit = function(node) {
+ ++(this.nodes[node.id] = this.nodes[node.id] || {node:node, count:0}).count;
+};
+
+CoverageData.prototype.missing = function() {
+ var nodes = this.nodes,
+ missing = this.bunker.nodes.filter(function(node) {
+ return !nodes[node.id];
+ });
+
+ return missing;
+};
+
+CoverageData.prototype.stats = function() {
+ var missing = this.missing(),
+ filedata = fs.readFileSync(this.filename, 'utf8').split('\n');
+
+ var seenLines = [],
+ lines =
+ missing.sort(function(lhs, rhs) {
+ return lhs.node[0].start.line < rhs.node[0].start.line ? -1 :
+ lhs.node[0].start.line > rhs.node[0].start.line ? 1 :
+ 0;
+ }).filter(function(node) {
+
+ var okay = (seenLines.indexOf(node.node[0].start.line) < 0);
+ if(okay)
+ seenLines.push(node.node[0].start.line);
+ return okay;
+
+ }).map(function(node, idx, all) {
+ return {
+ lineno:node.node[0].start.line + 1,
+ source:function() { return filedata[node.node[0].start.line]; }
+ };
+ });
+
+ return {
+ percentage:(filedata.length-seenLines.length)/filedata.length,
+ lines:lines,
+ missing:seenLines.length,
+ seen:(filedata.length-seenLines.length)
+ };
+};
+
+module.exports.createEnvironment = function(module, filename) {
+ var req = function(path) {
+ return Module._load(path, module);
+ };
+ req.resolve = function(request) {
+ return Module._resolveFilename(request, module)[1];
+ }
+ req.paths = Module._paths;
+ req.main = process.mainModule;
+ req.extensions = Module._extensions;
+ req.registerExtension = function() {
+ throw new Error('require.registerExtension() removed. Use ' +
+ 'require.extensions instead.');
+ }
+ require.cache = Module._cache;
+
+ var ctxt = {};
+ for(var k in global)
+ ctxt[k] = global[k];
+
+ ctxt.require = req;
+ ctxt.exports = module.exports;
+ ctxt.__filename = filename;
+ ctxt.__dirname = path.dirname(filename);
+ ctxt.process = process;
+ ctxt.console = console;
+ ctxt.module = module;
+ ctxt.global = ctxt;
+
+ return ctxt;
+};
+
+module.exports.cover = function(fileRegex) {
+ var originalRequire = require.extensions['.js'],
+ coverageData = {},
+ match = fileRegex instanceof RegExp ?
+ fileRegex : new RegExp(
+ fileRegex ? fileRegex.replace(/\//g, '\\/').replace(/\./g, '\\.') : '.*'
+ , 'g'),
+ target = this;
+
+ require.extensions['.js'] = function(module, filename) {
+ if(!match.test(filename)) return originalRequire(module, filename);
+
+ var context = target.createEnvironment(module, filename),
+ data = fs.readFileSync(filename, 'utf8'),
+ bunkerized = bunker(data),
+ coverage = coverageData[filename] = new CoverageData(filename, bunkerized);
+
+ bunkerized.on('node', coverage.visit.bind(coverage));
+ bunkerized.assign(context);
+
+ var wrapper = '(function(ctxt) { with(ctxt) { return '+Module.wrap(bunkerized.compile())+'; } })',
+ compiledWrapper = vm.runInThisContext(wrapper, filename, true)(context);
+
+ var args = [context.exports, context.require, module, filename, context.__dirname];
+ return compiledWrapper.apply(module.exports, args);
+ };
+
+ var retval = function(ready) {
+ ready(coverageData);
+ };
+
+ retval.release = function() {
+ require.extensions['.js'] = originalRequire;
+ };
+
+ return retval;
+};
+
Please sign in to comment.
Something went wrong with that request. Please try again.