Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit d076aed312948225c65444bb43400a9caa2025b1 0 parents
@arian authored
1  .gitignore
@@ -0,0 +1 @@
+node_modules
4 .jshintrc
@@ -0,0 +1,4 @@
+{
+ "globalstrict": true,
+ "node": true
+}
50 README.md
@@ -0,0 +1,50 @@
+CoverJS (alpha)
+===============
+
+Make sure all your code is tested, don't miss anything.
+CoverJS intruments your code. Using the instrumented code with your tests
+will result in a nice object, which can be passed through one of the reporters
+to create a nice graphical output of your code.
+
+Instead of instrumenting lines (like JSCoverage), CoverJS will instrument
+statements, which should result in a more precise result.
+
+### Dependencies
+
+- [Esprima](https://github.com/ariya/esprima) a wonderful JavaScript parser
+- [Escodegen](https://github.com/Constellation/escodegen)
+- [Prime](https://github.com/mootools/prime) awesome little OOP library
+
+### Reporters
+
+ - HTML
+ - Text
+
+ ### CLI Usage
+
+To instrument the code, CoverJS comes with a CLI tool:
+
+ coverjs --output cov/ file.js test/*
+
+### Reporting
+
+The instrumented code should be executed to count the number of calls for each statement.
+Usually your tests will try to cover each statement.
+
+An example code that will capture the output and generate a HTML report would look like:
+
+```js
+
+var HTMLReporter = require('../lib/reporters/HTMLReporter');
+
+require('../test-cov/test/fixture.js');
+
+var reporter = new HTMLReporter(global.__$coverObject);
+console.log(reporter.report());
+```
+
+The output stream can be redirected to a file using
+
+ node test.js > report.html
+
+so the result can be viewed in a browser
51 bin/coverjs.js
@@ -0,0 +1,51 @@
+#! /usr/bin/env node
+
+"use strict";
+
+var fs = require('node-fs');
+var path = require('path');
+var Instrument = require('../lib/Instrument');
+
+var files = [];
+var dir;
+
+for (var i = 2; i < process.argv.length; i++){
+ var arg = process.argv[i];
+
+ if (arg == '--output' || arg == '-o'){
+ dir = process.argv[++i];
+ continue;
+ }
+
+ files.push(arg);
+
+}
+
+if (!dir){
+ console.warn('the --output option is required');
+ process.exit(1);
+}
+
+files.forEach(function(file){
+
+ var code;
+ try {
+ var filePath = path.resolve(process.cwd, file);
+ code = fs.readFileSync(filePath);
+ } catch (e){
+ console.warn('Could not read ' + file);
+ return;
+ }
+
+ var instrument = new Instrument(code, file);
+ var instrumented = instrument.instrument();
+
+ var newFile = path.resolve(dir, file);
+ var newDir = path.dirname(newFile);
+ console.log(newDir);
+ fs.mkdir(newDir, 511 /* 0777 */, true, function(err){
+ if (err) throw err;
+ fs.writeFileSync(newFile, instrumented);
+ });
+
+});
140 lib/Instrument.js
@@ -0,0 +1,140 @@
+"use strict";
+
+
+var fs = require('fs');
+var esprima = require('esprima');
+var escodegen = require('escodegen');
+
+// create coverage line
+
+var id = 0;
+
+var Instrument = function(code, name){
+
+ if (!name) name = (id++).toString(36);
+
+ this.code = code + '';
+ this.name = name + '';
+
+ var quotedName = this.quotedName = JSON.stringify(this.name);
+ var quotedCode = this.quotedCode = JSON.stringify(this.code);
+
+ this.ranges = [];
+
+ this.headCode = ''+
+ 'if (typeof __$coverObject === "undefined"){\n' +
+ ' if (typeof window !== "undefined") window.__$coverObject = {};\n' +
+ ' else if (typeof global !== "undefined") global.__$coverObject = {};\n' +
+ ' else throw new Error("cannot find the global scope");\n' +
+ '}\n' +
+ 'function __$cover(start, end){\n' +
+ ' __$coverObject[' + quotedName + '][start + ":" + end] = (__$coverObject[' + quotedName + '][start + ":" + end] || 0) + 1;\n' +
+ '}\n' +
+ '__$coverObject[' + quotedName + '] = {};\n' +
+ '__$coverObject[' + quotedName + '].__code = ' + quotedCode + ';\n';
+
+ this.rangesCode = '';
+
+ this.tailCode = '';
+
+};
+
+Instrument.prototype = {
+
+ // Short method to instrument the code
+
+ instrument: function(){
+ this.parse();
+ this.walk();
+ return this.generate();
+ },
+
+ // generate AST with esprima
+
+ parse: function(){
+ return (this.ast = esprima.parse(this.code, {
+ range: true
+ }));
+ },
+
+ // generate new instrumented code from AST
+
+ generate: function(){
+ this._generateInitialRanges();
+ return this.headCode + this.rangesCode + escodegen.generate(this.ast) + this.tailCode;
+ },
+
+ _generateInitialRanges: function(){
+ for (var i = 0, l = this.ranges.length; i < l; i++){
+ var range = this.ranges[i];
+ this.rangesCode += '__$coverObject[' + this.quotedName + ']["' + range[0] + ':' + range[1] + '"] = 0;\n';
+ }
+ },
+
+ // Modify AST by injecting extra instrumenting code
+
+ walk: function(){
+ this._walk(this.ast);
+ return this.ast;
+ },
+
+ _walk: function(ast, index, parent){
+
+ // iterator variables
+ var i, l, k;
+
+ switch (index){
+ case 'body':
+ case 'consequent':
+ if (Array.isArray(ast)){
+ for (i = 0, l = ast.length; i < l; i++){
+ var range = ast[i * 2].range;
+ ast.splice(i * 2, 0, this._statementCallAST(range));
+ this.ranges.push(range);
+ }
+ }
+ break;
+ }
+
+ // recurse through the AST
+
+ if (Array.isArray(ast)){
+
+ for (i = 0, l = ast.length; i < l; i++) this._walk(ast[i], i, parent);
+
+ } else if (typeof ast === 'object'){
+
+ for (k in ast) this._walk(ast[k], k, parent);
+
+ }
+
+ },
+
+ _statementCallAST: function(range){
+
+ return {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "__$cover"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": range[0]
+ },
+ {
+ "type": "Literal",
+ "value": range[1]
+ }
+ ]
+ }
+ };
+
+ }
+
+};
+
+module.exports = Instrument;
78 lib/reporters/HTMLReporter.js
@@ -0,0 +1,78 @@
+"use strict";
+
+var Reporter = require('./Reporter');
+var prime = require('prime');
+
+var HTMLReporter = prime({
+
+ inherits: Reporter,
+
+ constructor: function(object){
+ HTMLReporter.parent.constructor(object);
+
+ // TODO would be cool to use some nicer templating solution for this
+ this.head = '' +
+ '<!DOCTYPE html>\n' +
+ '<html>\n<head>\n' +
+ '<meta charset="utf-8">\n' +
+ '<title>Coverate Results</title>\n' +
+ '<style>\n' +
+ ' .error { background: #F8D5D8 }\n' +
+ ' .count { font-weight: bold; border-radius: 3px }\n' +
+ ' .pass .count { background: #BFFFBF;}' +
+ ' .error .count { background: #F8D5D8; color: red}' +
+ '</style>\n' +
+ '</head>\n<body>\n';
+
+ this.tail = '\n</body>\n</html>';
+
+ },
+
+ report: function(){
+
+ var result = this.head;
+
+ for (var file in this.object){
+ var fileReporter = new HTMLFileReporter(this.object[file]);
+
+ this.error += fileReporter.error;
+ this.pass += fileReporter.pass;
+ this.total += fileReporter.total;
+
+ var fileReport = fileReporter.report();
+ var percentage = fileReporter.pass / fileReporter.total * 100;
+
+ result += '<h1>' + file + ' (' + Math.round(percentage) + '%)</h1>\n\n';
+ result += '<pre>' + fileReport + '</pre>';
+ }
+
+ return result + this.tail;
+
+ }
+
+});
+
+var HTMLFileReporter = prime({
+
+ inherits: Reporter.FileReporter,
+
+ constructor: function(object){
+
+ var open = '<span class="{class}" data-count="{count}"><span class="count">{count}</span>';
+ var close = '</span>';
+
+ HTMLFileReporter.parent.constructor(object, open, close);
+
+ },
+
+ generateOpen: function(count){
+ return this.substitute(this.open, {
+ 'count': count,
+ 'class': count ? 'pass' : 'error'
+ });
+ }
+
+});
+
+HTMLReporter.FileReporter = HTMLFileReporter;
+module.exports = HTMLReporter;
134 lib/reporters/Reporter.js
@@ -0,0 +1,134 @@
+"use strict";
+
+var prime = require('prime');
+
+var Reporter = prime({
+
+ constructor: function(object){
+ this.object = object;
+
+ this.error = 0;
+ this.pass = 0;
+ this.total = 0;
+
+ },
+
+ report: function(){
+ var result = '';
+ for (var file in this.object){
+
+ var fileReporter = new FileReporter(this.object[file], '<<<', '>>>');
+
+ this.error += fileReporter.error;
+ this.pass += fileReporter.pass;
+ this.total += fileReporter.total;
+
+ var fileReport = fileReporter.report();
+ var percentage = fileReporter.pass / fileReporter.total * 100;
+
+ result += '+++ ' + result + ' (' + Math.round(percentage) + ') +++ \n\n';
+ result += fileReport;
+ result += '\n\n\n\n';
+ }
+ return result;
+ }
+
+});
+
+var FileReporter = prime({
+
+ constructor: function(object, open, close){
+
+ this.object = object;
+ this.open = open;
+ this.close = close;
+
+ this.error = 0;
+ this.pass = 0;
+ this.total = 0;
+
+ },
+
+ // substitute credits: MooTools
+ substitute: function(string, object){
+ return string.replace(/\\?\{([^{}]+)\}/g, function(match, name){
+ if (match.charAt(0) == '\\') return match.slice(1);
+ return (object[name] !== null) ? object[name] : '';
+ });
+ },
+
+ generateOpen: function(count){
+ return this.substitute(this.open, {
+ count: count
+ });
+ },
+
+ generateClose: function(count){
+ return this.substitute(this.close, {
+ count: count
+ });
+ },
+
+ report: function(){
+
+ var i, l, k;
+
+ var code = this.object.__code;
+
+ // generate array of all tokens
+ var codez = [];
+ for (i = 0, l = code.length; i < l; i++){
+ codez.push({
+ pos: i,
+ value: code.slice(i, i + 1)
+ });
+ }
+
+ // insert new strings that wrap the statements
+ for (k in this.object){
+ if (k == '__code') continue;
+
+ var count = this.object[k];
+ var range = k.split(':');
+
+ this.total++;
+ if (count) this.pass++;
+ else this.error++;
+
+ for (i = 0, l = codez.length; i < l; i++){
+
+ if (codez[i].pos == range[0]){
+ codez.splice(i, 0, {
+ pos: -1,
+ value: this.generateOpen(count)
+ });
+ i++;
+ continue;
+ }
+
+ if (codez[i].pos == range[1]){
+ codez.splice(i + 1, 0, {
+ pos: -1,
+ value: this.generateClose(count)
+ });
+ i++;
+ continue;
+ }
+
+ }
+
+ }
+
+ var result = '';
+ for (i = 0, l = codez.length; i < l; i++){
+ result += codez[i].value;
+ }
+
+ return result;
+
+ }
+
+});
+
+Reporter.FileReporter = FileReporter;
+module.exports = Reporter;
24 package.json
@@ -0,0 +1,24 @@
+{
+ "author": "Arian Stolwijk (http://github.com/arian)",
+ "name": "coverjs",
+ "description": "JSCoverage compatible JavaScript code coverage tool",
+ "version": "0.0.1",
+ "repository": {
+ "url": "git://github.com/arian/classy.git"
+ },
+ "main": "cover.js",
+ "dependencies": {
+ "esprima": "0.9",
+ "escodegen": "0.x",
+ "prime": "0.0.5-alpha",
+ "node-fs": "0.1"
+ },
+ "devDependencies": {
+ "mocha": "1.0",
+ "expect.js": "0.1"
+ },
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ }
+}
85 result.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Coverate Results</title>
+<style>
+ .error { background: #F8D5D8 }
+ .count { font-weight: bold; border-radius: 3px }
+ .pass .count { background: #BFFFBF;} .error .count { background: #F8D5D8; color: red}</style>
+</head>
+<body>
+<h1>test/fixture.js (70%)</h1>
+
+<pre><span class="pass" data-count="1"><span class="count">1</span>"use strict";</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>var a = 1;</span>
+<span class="pass" data-count="1"><span class="count">1</span>var b = 3;</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>var esprima = require('esprima');</span>
+<span class="pass" data-count="1"><span class="count">1</span>var escodegen = require('escodegen');</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>function c(a, b){
+ <span class="pass" data-count="3"><span class="count">3</span>return a + b;</span>
+}</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>if (b){
+ <span class="pass" data-count="1"><span class="count">1</span>a++;</span>
+} else {
+ <span class="error" data-count="0"><span class="count">0</span>b--;</span>
+}</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>var d = function(){
+ <span class="error" data-count="0"><span class="count">0</span>console.warn('bar');</span>
+};</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>switch (a){
+ case 1:
+ <span class="error" data-count="0"><span class="count">0</span>c(a, b);</span>
+ <span class="error" data-count="0"><span class="count">0</span>c(a, c(a, b));</span>
+ <span class="error" data-count="0"><span class="count">0</span>break;</span>
+ case 2: <span class="pass" data-count="1"><span class="count">1</span>c(b, a);</span> <span class="pass" data-count="1"><span class="count">1</span>break;</span>
+}</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>c(3, 4);</span>
+<span class="pass" data-count="1"><span class="count">1</span>c(5, 2);</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>function Cover(){
+
+}</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>Cover.prototype = {
+
+ parse: function(){
+ <span class="error" data-count="0"><span class="count">0</span>return (this.ast = esprima.parse(this.code, {
+ range: true
+ }));</span>
+ },
+
+ generate: function(ast){
+ <span class="error" data-count="0"><span class="count">0</span>return escodegen.generate(ast);</span>
+ },
+
+ walk: function(ast, index, parent){
+ <span class="error" data-count="0"><span class="count">0</span>console.warn('foo bar');</span>
+ <span class="error" data-count="0"><span class="count">0</span>console.warn('yello');</span>
+ }
+
+};</span>
+
+<span class="pass" data-count="1"><span class="count">1</span>try {
+ <span class="pass" data-count="1"><span class="count">1</span>throw new Error('whops');</span>
+
+ <span class="error" data-count="0"><span class="count">0</span>console.warn('not here!');</span>
+
+} catch (e){
+ <span class="pass" data-count="1"><span class="count">1</span>console.warn(e);</span>
+ <span class="pass" data-count="1"><span class="count">1</span>console.warn(e);</span>
+} finally {
+ <span class="pass" data-count="1"><span class="count">1</span>console.warn('finally');</span> <span class="pass" data-count="1"><span class="count">1</span>console.warn('more finally');</span>
+}</span>
+
+
+</pre>
+</body>
+</html>
129 test-cov/test/fixture.js
@@ -0,0 +1,129 @@
+if (typeof __$coverObject === "undefined"){
+ if (typeof window !== "undefined") window.__$coverObject = {};
+ else if (typeof global !== "undefined") global.__$coverObject = {};
+ else throw new Error("cannot find the global scope");
+}
+function __$cover(start, end){
+ __$coverObject["test/fixture.js"][start + ":" + end] = (__$coverObject["test/fixture.js"][start + ":" + end] || 0) + 1;
+}
+__$coverObject["test/fixture.js"] = {};
+__$coverObject["test/fixture.js"].__code = "\"use strict\";\n\nvar a = 1;\nvar b = 3;\n\nvar esprima = require('esprima');\nvar escodegen = require('escodegen');\n\nfunction c(a, b){\n\treturn a + b;\n}\n\nif (b){\n\ta++;\n} else {\n\tb--;\n}\n\nvar d = function(){\n\tconsole.warn('bar');\n};\n\nswitch (a){\n\tcase 1:\n\t\tc(a, b);\n\t\tc(a, c(a, b));\n\t\tbreak;\n\tcase 2: c(b, a); break;\n}\n\nc(3, 4);\nc(5, 2);\n\nfunction Cover(){\n\n}\n\nCover.prototype = {\n\n\tparse: function(){\n\t\treturn (this.ast = esprima.parse(this.code, {\n\t\t\trange: true\n\t\t}));\n\t},\n\n\tgenerate: function(ast){\n\t\treturn escodegen.generate(ast);\n\t},\n\n\twalk: function(ast, index, parent){\n\t\tconsole.warn('foo bar');\n\t\tconsole.warn('yello');\n\t}\n\n};\n\ntry {\n\tthrow new Error('whops');\n\n\tconsole.warn('not here!');\n\n} catch (e){\n\tconsole.warn(e);\n\tconsole.warn(e);\n} finally {\n\tconsole.warn('finally'); console.warn('more finally');\n}\n\n\n";
+__$coverObject["test/fixture.js"]["0:12"] = 0;
+__$coverObject["test/fixture.js"]["15:24"] = 0;
+__$coverObject["test/fixture.js"]["26:35"] = 0;
+__$coverObject["test/fixture.js"]["38:70"] = 0;
+__$coverObject["test/fixture.js"]["72:108"] = 0;
+__$coverObject["test/fixture.js"]["111:144"] = 0;
+__$coverObject["test/fixture.js"]["147:176"] = 0;
+__$coverObject["test/fixture.js"]["179:222"] = 0;
+__$coverObject["test/fixture.js"]["225:308"] = 0;
+__$coverObject["test/fixture.js"]["311:318"] = 0;
+__$coverObject["test/fixture.js"]["320:327"] = 0;
+__$coverObject["test/fixture.js"]["330:349"] = 0;
+__$coverObject["test/fixture.js"]["352:627"] = 0;
+__$coverObject["test/fixture.js"]["630:810"] = 0;
+__$coverObject["test/fixture.js"]["130:142"] = 0;
+__$coverObject["test/fixture.js"]["156:159"] = 0;
+__$coverObject["test/fixture.js"]["171:174"] = 0;
+__$coverObject["test/fixture.js"]["200:219"] = 0;
+__$coverObject["test/fixture.js"]["248:255"] = 0;
+__$coverObject["test/fixture.js"]["259:272"] = 0;
+__$coverObject["test/fixture.js"]["276:281"] = 0;
+__$coverObject["test/fixture.js"]["292:299"] = 0;
+__$coverObject["test/fixture.js"]["301:306"] = 0;
+__$coverObject["test/fixture.js"]["395:461"] = 0;
+__$coverObject["test/fixture.js"]["496:526"] = 0;
+__$coverObject["test/fixture.js"]["572:595"] = 0;
+__$coverObject["test/fixture.js"]["599:620"] = 0;
+__$coverObject["test/fixture.js"]["637:661"] = 0;
+__$coverObject["test/fixture.js"]["665:690"] = 0;
+__$coverObject["test/fixture.js"]["707:722"] = 0;
+__$coverObject["test/fixture.js"]["725:740"] = 0;
+__$coverObject["test/fixture.js"]["755:778"] = 0;
+__$coverObject["test/fixture.js"]["780:808"] = 0;
+__$cover(0, 12);
+'use strict';
+__$cover(15, 24);
+var a = 1;
+__$cover(26, 35);
+var b = 3;
+__$cover(38, 70);
+var esprima = require('esprima');
+__$cover(72, 108);
+var escodegen = require('escodegen');
+__$cover(111, 144);
+function c(a, b) {
+ __$cover(130, 142);
+ return a + b;
+}
+__$cover(147, 176);
+if (b) {
+ __$cover(156, 159);
+ a++;
+} else {
+ __$cover(171, 174);
+ b--;
+}
+__$cover(179, 222);
+var d = function () {
+ __$cover(200, 219);
+ console.warn('bar');
+};
+__$cover(225, 308);
+switch (a) {
+case 1:
+ __$cover(248, 255);
+ c(a, b);
+ __$cover(259, 272);
+ c(a, c(a, b));
+ __$cover(276, 281);
+ break;
+case 2:
+ __$cover(292, 299);
+ c(b, a);
+ __$cover(301, 306);
+ break;
+}
+__$cover(311, 318);
+c(3, 4);
+__$cover(320, 327);
+c(5, 2);
+__$cover(330, 349);
+function Cover() {
+}
+__$cover(352, 627);
+Cover.prototype = {
+ parse: function () {
+ __$cover(395, 461);
+ return this.ast = esprima.parse(this.code, {
+ range: true
+ });
+ },
+ generate: function (ast) {
+ __$cover(496, 526);
+ return escodegen.generate(ast);
+ },
+ walk: function (ast, index, parent) {
+ __$cover(572, 595);
+ console.warn('foo bar');
+ __$cover(599, 620);
+ console.warn('yello');
+ }
+};
+__$cover(630, 810);
+try {
+ __$cover(637, 661);
+ throw new Error('whops');
+ __$cover(665, 690);
+ console.warn('not here!');
+} catch (e) {
+ __$cover(707, 722);
+ console.warn(e);
+ __$cover(725, 740);
+ console.warn(e);
+} finally {
+ __$cover(755, 778);
+ console.warn('finally');
+ __$cover(780, 808);
+ console.warn('more finally');
+}
0  test/bar/foo.js
No changes.
8 test/cover.js
@@ -0,0 +1,8 @@
+"use strict";
+
+var HTMLReporter = require('../lib/reporters/HTMLReporter');
+
+require('../test-cov/test/fixture.js');
+
+var reporter = new HTMLReporter(global.__$coverObject);
+console.log(reporter.report());
69 test/fixture.js
@@ -0,0 +1,69 @@
+"use strict";
+
+var a = 1;
+var b = 3;
+
+var esprima = require('esprima');
+var escodegen = require('escodegen');
+
+function c(a, b){
+ return a + b;
+}
+
+if (b){
+ a++;
+} else {
+ b--;
+}
+
+var d = function(){
+ console.warn('bar');
+};
+
+switch (a){
+ case 1:
+ c(a, b);
+ c(a, c(a, b));
+ break;
+ case 2: c(b, a); break;
+}
+
+c(3, 4);
+c(5, 2);
+
+function Cover(){
+
+}
+
+Cover.prototype = {
+
+ parse: function(){
+ return (this.ast = esprima.parse(this.code, {
+ range: true
+ }));
+ },
+
+ generate: function(ast){
+ return escodegen.generate(ast);
+ },
+
+ walk: function(ast, index, parent){
+ console.warn('foo bar');
+ console.warn('yello');
+ }
+
+};
+
+try {
+ throw new Error('whops');
+
+ console.warn('not here!');
+
+} catch (e){
+ console.warn(e);
+ console.warn(e);
+} finally {
+ console.warn('finally'); console.warn('more finally');
+}
+
+
128 test/fixture_instrumented.js
@@ -0,0 +1,128 @@
+if (typeof __$coverObject === "undefined"){
+ if (typeof window !== "undefined") window.__$coverObject = {};
+ else if (typeof global !== "undefined") global.__$coverObject = {};
+ else throw new Error("cannot find the global scope");
+}
+function __$cover(start, end){
+ __$coverObject["0"][start + ":" + end] = (__$coverObject["0"][start + ":" + end] || 0) + 1;
+}
+__$coverObject["0"] = {};
+__$coverObject["0"].__code = "\"use strict\";\n\nvar a = 1;\nvar b = 3;\n\nvar esprima = require('esprima');\nvar escodegen = require('escodegen');\n\nfunction c(a, b){\n\treturn a + b;\n}\n\nif (b){\n\ta++;\n} else {\n\tb--;\n}\n\nvar d = function(){\n\tconsole.log('bar');\n};\n\nswitch (a){\n\tcase 1:\n\t\tc(a, b);\n\t\tc(a, c(a, b));\n\t\tbreak;\n\tcase 2: c(b, a); break;\n}\n\nc(3, 4);\nc(5, 2);\n\nfunction Cover(){\n\n}\n\nCover.prototype = {\n\n\tparse: function(){\n\t\treturn (this.ast = esprima.parse(this.code, {\n\t\t\trange: true\n\t\t}));\n\t},\n\n\tgenerate: function(ast){\n\t\treturn escodegen.generate(ast);\n\t},\n\n\twalk: function(ast, index, parent){\n\t\tconsole.log('foo bar');\n\t\tconsole.log('yello');\n\t}\n\n};\n\ntry {\n\tthrow new Error('whops');\n} catch (e){\n\tconsole.log(e);\n\tconsole.log(e);\n} finally {\n\tconsole.log('finally');\n\tconsole.log('more finally');\n}\n\n\n";
+__$coverObject["0"]["0:12"] = 0;
+__$coverObject["0"]["15:24"] = 0;
+__$coverObject["0"]["26:35"] = 0;
+__$coverObject["0"]["38:70"] = 0;
+__$coverObject["0"]["72:108"] = 0;
+__$coverObject["0"]["111:144"] = 0;
+__$coverObject["0"]["147:176"] = 0;
+__$coverObject["0"]["179:221"] = 0;
+__$coverObject["0"]["224:307"] = 0;
+__$coverObject["0"]["310:317"] = 0;
+__$coverObject["0"]["319:326"] = 0;
+__$coverObject["0"]["329:348"] = 0;
+__$coverObject["0"]["351:624"] = 0;
+__$coverObject["0"]["627:774"] = 0;
+__$coverObject["0"]["130:142"] = 0;
+__$coverObject["0"]["156:159"] = 0;
+__$coverObject["0"]["171:174"] = 0;
+__$coverObject["0"]["200:218"] = 0;
+__$coverObject["0"]["247:254"] = 0;
+__$coverObject["0"]["258:271"] = 0;
+__$coverObject["0"]["275:280"] = 0;
+__$coverObject["0"]["291:298"] = 0;
+__$coverObject["0"]["300:305"] = 0;
+__$coverObject["0"]["394:460"] = 0;
+__$coverObject["0"]["495:525"] = 0;
+__$coverObject["0"]["571:593"] = 0;
+__$coverObject["0"]["597:617"] = 0;
+__$coverObject["0"]["634:658"] = 0;
+__$coverObject["0"]["674:688"] = 0;
+__$coverObject["0"]["691:705"] = 0;
+__$coverObject["0"]["720:742"] = 0;
+__$coverObject["0"]["745:772"] = 0;
+__$cover(0, 12);
+'use strict';
+__$cover(15, 24);
+var a = 1;
+__$cover(26, 35);
+var b = 3;
+__$cover(38, 70);
+var esprima = require('esprima');
+__$cover(72, 108);
+var escodegen = require('escodegen');
+__$cover(111, 144);
+function c(a, b) {
+ __$cover(130, 142);
+ return a + b;
+}
+__$cover(147, 176);
+if (b) {
+ __$cover(156, 159);
+ a++;
+} else {
+ __$cover(171, 174);
+ b--;
+}
+__$cover(179, 221);
+var d = function () {
+ __$cover(200, 218);
+ console.log('bar');
+};
+__$cover(224, 307);
+switch (a) {
+case 1:
+ __$cover(247, 254);
+ c(a, b);
+ __$cover(258, 271);
+ c(a, c(a, b));
+ __$cover(275, 280);
+ break;
+case 2:
+ __$cover(291, 298);
+ c(b, a);
+ __$cover(300, 305);
+ break;
+}
+__$cover(310, 317);
+c(3, 4);
+__$cover(319, 326);
+c(5, 2);
+__$cover(329, 348);
+function Cover() {
+}
+__$cover(351, 624);
+Cover.prototype = {
+ parse: function () {
+ __$cover(394, 460);
+ return this.ast = esprima.parse(this.code, {
+ range: true
+ });
+ },
+ generate: function (ast) {
+ __$cover(495, 525);
+ return escodegen.generate(ast);
+ },
+ walk: function (ast, index, parent) {
+ __$cover(571, 593);
+ console.log('foo bar');
+ __$cover(597, 617);
+ console.log('yello');
+ }
+};
+__$cover(627, 774);
+try {
+ __$cover(634, 658);
+ throw new Error('whops');
+} catch (e) {
+ __$cover(674, 688);
+ console.log(e);
+ __$cover(691, 705);
+ console.log(e);
+} finally {
+ __$cover(720, 742);
+ console.log('finally');
+ __$cover(745, 772);
+ console.log('more finally');
+}
+console.log(__$coverObject);
+
Please sign in to comment.
Something went wrong with that request. Please try again.